   @spec move(%Snake{}, %World{}) :: Response.t
   def move(%{url: url, id: id}, world, request \\ &HTTP.post/4) do
     data = Poison.encode!(world, me: id)
-    response(url <> "/move", request, Move, @move_whitelist, data)
+    (url <> "/move")
+    |> response(request, data)
+    |> do_move
   end
 
-  defp response(url, request, type, whitelist, data) do
-    st = struct(type)
+  def do_move(response) do
+    update_in response.parsed_response, fn
+      {:ok, map} ->
+      (
+        {:ok, cast_move(map)}
+      )
+      response ->
+        response
+    end
+  end
+
+  def cast_move(map) do
+    data = %Move{}
+    types = %{move: :string, taunt: :string}
+    {data, types}
+    |> Changeset.cast(map, Map.keys(types))
+    |> Changeset.validate_required([:move])
+    |> Changeset.validate_inclusion(:move, ~w(up down left right))
+    |> Changeset.apply_changes
+  end
+
+  defp response(url, request, data) do
     api_response = url
     |> request.(data, [], [])
-    |> Response.new(as: st)
+    |> Response.new(as: %{})
 
     update_in(api_response.parsed_response, fn
-      {:ok, snake} ->
+      {:ok, map} ->
       (
-        map = Map.take(snake, whitelist)
-        snake = struct(type, map)
-        {:ok, snake}
+        {:ok, map}
       )
       error ->
       (

  @spec load(%SnakeForm{}, %GameForm{}) :: Response.t
  def load(%{url: url}, data, request \\ &HTTP.post/4) do
    request_url = url <> "/start"
    api_response = response(request_url, request, Snake, @load_whitelist, data)
    update_in(api_response.parsed_response, fn
      {:ok, snake} ->
      (
        snake = put_in(snake.url, url)
        {:ok, snake}
      )
      error ->

        error
      )
    end)
    |> do_load
  end

  def do_load(response) do
    update_in response.parsed_response, fn
      {:ok, map} ->
      (
        {:ok, cast_load(map)}
      )
      response ->
        response
    end
  end

  def cast_load(map) do
    data = %Snake{}
    types = %{color: :string,
              head_url: :string,
              name: :string,
              taunt: :string, url: :string}
    {data, types}
    |> Changeset.cast(map, Map.keys(types))
    |> Changeset.validate_required([:name])
    |> Changeset.apply_changes
  end


  @doc """
  Get the move for a single snake.
