   # TODO: prevent dropping items which haven't had description or room_description set
   def drop_item(username, args) do
     if length(args) < 1 do
-      IO.puts "What do you want to get?"
+      IO.puts "What do you want to drop?"
     else
       name_or_id = List.first(args)
       {:ok, player} = Exedra.User.get(username)


  Must be given a nonempty args list - get_item called before this should return if len(args)<1
  """
  @spec get_currency(String.t, nonempty_list(String.t)) :: :ok
  def get_currency(username, args) do
    # TODO: combine with get_item() to only call Integer.parse, User.get once.
    [num_or_noun|noun_rest] = args
    case Integer.parse(num_or_noun) do
      {num, _} ->
        if length(noun_rest) < 1 do
          IO.puts not_here_text()
        else
          noun = List.first(noun_rest)
          get_currency_noun_num(username, noun, num)
        end
      :error ->
        noun = num_or_noun
        get_currency_noun_num(username, noun, :all)
    end
  end

  @doc """
  Checks if the given noun is an alias for currency, and gets the requested amount, which may be :all
  """
  @spec get_currency_noun_num(String.t, String.t, pos_integer|:all) :: :ok
  def get_currency_noun_num(username, noun, num) do
    {:ok, player} = Exedra.User.get(username)
    {:ok, room} = Exedra.Room.get(player.room_id)
    if !MapSet.member?(currency_nouns(), noun) || room.currency == 0 do
      IO.puts not_here_text()

  end

  # TODO use guards to reduce indentation
  @spec get_item(String.t, list(String.t)) :: :ok
  def get_item(_, args) when length(args) < 1, do: IO.puts "What do you want to get?"
  def get_item(username, args) do
    name_or_id = List.first(args)
    {:ok, player} = Exedra.User.get(username)
    {:ok, room} = Exedra.Room.get(player.room_id)
    case Integer.parse(name_or_id) do
      {id, _} ->
        get_item_by_id(player, room, id, args)
      :error ->
        name = name_or_id
        get_item_by_name(player, room, name, args)
    end
  end

  def get_item_msg(brief), do: "You pick up " <> brief <> "."
  def get_npc_fail_msg(brief), do: brief <> " stares at you awkwardly." # TODO capitalise NPC name?

  @spec get_item_by_id(Exedra.User.Data, Exedra.Room.Data, integer, list(String.t)) :: :ok
  def get_item_by_id(player, room, id, args) do
    cond do
      MapSet.member?(room.items, id) ->
        Exedra.Item.pickup(id, room, player)
        {:ok, item} = Exedra.Item.get(id)
        IO.puts get_item_msg(item.brief)
      MapSet.member?(room.npcs, id) ->
        {:ok, npc} = Exedra.NPC.get(id)
        # TODO: allow picking up NPCs with permissions
        # Exedra.NPC.pickup(id, room, player)
        # IO.puts "You pick up " <> item.brief <> "."
        IO.puts get_npc_fail_msg(npc.brief)
      true ->
        get_currency(player, args)
    end
  end

  @spec get_item_by_name(Exedra.User.Data, Exedra.Room.Data, String.t, list(String.t)) :: :ok
  def get_item_by_name(player, room, name, args) do
    item_id = Enum.find room.items, fn(item_id) ->
      {:ok, item} = Exedra.Item.get(item_id)
      item.name == name
    end
    if item_id != nil do
      Exedra.Item.pickup(item_id, room, player)
      {:ok, item} = Exedra.Item.get(item_id)
      IO.puts get_item_msg(item.brief)
    else
      get_npc_by_name(player, room, name, args)
    end
  end

  @spec get_npc_by_name(Exedra.User.Data, Exedra.Room.Data, String.t, list(String.t)) :: :ok
  def get_npc_by_name(player, room, name, args) do
    npc_id = Enum.find room.npcs, fn(npc_id) ->
      {:ok, npc} = Exedra.NPC.get(npc_id)
      npc.name == name
    end
    if npc_id != nil do
      {:ok, npc} = Exedra.NPC.get(npc_id)
      # TODO: fix duplication with get_item_by_id
      # TODO: allow picking up NPCs with permissions
      # Exedra.NPC.pickup(npc_id, room, player)
      IO.puts get_npc_fail_msg(npc.brief)
    else
      get_currency(player, args)
    end
  end

