   end
 
   defp encode_query_value(type, value) do
-    result = encode_value(type, value)
-    [<<IO.iodata_length(result)::32>>, result]
+    acc = encode_value(type, value)
+    [<<IO.iodata_length(acc)::32>>, acc]
   end
 
   defp encode_value(:ascii, ascii) when is_binary(ascii) do

    end
  end

  defp decode_paging_state(buffer, page, 0) do
    {page, buffer}
  end

  defp decode_paging_state(buffer, page, 1) do
    <<byte_count::32, paging_state::bytes-size(byte_count)>> <> buffer = buffer
    {%{page | paging_state: paging_state}, buffer}
  end

  defp decode_page_content(<<row_count::32-signed>> <> buffer, columns) do
    {content, <<>>} = decode_page_content(buffer, row_count, columns, columns, [[]])
    content
  end

  def decode_page_content(buffer, 0, columns, columns, [_ | acc]) do
    {Enum.reverse(acc), buffer}
  end

  def decode_page_content(buffer, row_count, columns, [], [values | acc]) do
    decode_page_content(buffer, row_count - 1, columns, columns, [[], Enum.reverse(values) | acc])
  end

  def decode_page_content(<<size::32-signed>> <> buffer, row_count, columns, [{_, _, _, type} | rest], [values | acc]) do
    {value, buffer} = decode_value(buffer, size, type)
    values = [value | values]
    decode_page_content(buffer, row_count, columns, rest, [values | acc])
  end

  defp decode_value(<<size::32-signed>> <> buffer, type) do
    decode_value(buffer, size, type)
  end

  defp decode_value(buffer, -1, _type) do
    {nil, buffer}
  end

  defp decode_value(buffer, size, :ascii) do
    <<value::size(size)-bytes>> <> buffer = buffer
    {value, buffer}
  end

  defp decode_value(<<value::64-signed>> <> buffer, 8, :bigint) do
    {value, buffer}
  end

  defp decode_value(buffer, size, :blob) do
    <<value::size(size)-bytes>> <> buffer = buffer
    {value, buffer}
  end

  defp decode_value(<<value::8>> <> buffer, 1, :boolean) do
    {value != 0, buffer}
  end

  defp decode_value(<<value::32, buffer::bytes>>, 4, :date) do
    {value, buffer}
  end

  defp decode_value(buffer, size, :decimal) do
    {scale, buffer} = decode_value(buffer, 4, :int)
    {value, buffer} = decode_value(buffer, size - 4, :varint)
    {{value, scale}, buffer}
  end

  defp decode_value(<<value::64-float>> <> buffer, 8, :double) do
    {value, buffer}
  end

  defp decode_value(<<value::32-float>> <> buffer, 4, :float) do
    {value, buffer}
  end

  defp decode_value(<<address::4-bytes>> <> buffer, 4, :inet) do
    <<n1, n2, n3, n4>> = address
    {{n1, n2, n3, n4}, buffer}
  end

  defp decode_value(<<address::16-bytes>> <> buffer, 16, :inet) do
    <<n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16>> = address
    {{n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16}, buffer}
  end

  defp decode_value(<<value::32-signed>> <> buffer, 4, :int) do
    {value, buffer}
  end

  defp decode_value(buffer, size, {:list, [type]}) do
    size = size - 4
    <<length::32-signed, content::bytes-size(size)>> <> buffer = buffer
    {decode_list(content, length, type, []), buffer}
  end

  defp decode_value(buffer, size, {:map, [key_type, value_type]}) do
    size = size - 4
    <<count::32-signed, content::bytes-size(size)>> <> buffer = buffer
    {decode_map(content, count, key_type, value_type, []), buffer}
  end

  defp decode_value(buffer, size, {:set, [type]}) do
    size = size - 4
    <<length::32-signed, content::bytes-size(size)>> <> buffer = buffer
    list = decode_list(content, length, type, [])
    {MapSet.new(list), buffer}
  end

  defp decode_value(<<value::16-signed, buffer::bytes>>, 2, :smallint) do
    {value, buffer}
  end

  defp decode_value(buffer, size, {:tuple, types}) do
    <<content::bytes-size(size)>> <> buffer = buffer
    {decode_tuple(content, types, []), buffer}
  end

  defp decode_value(<<value::16-bytes>> <> buffer, 16, type) when type in [:timeuuid, :uuid] do
    {value, buffer}
  end

  defp decode_value(buffer, size, :varchar) do
    <<text::size(size)-bytes>> <> buffer = buffer
    {text, buffer}
  end

  defp decode_value(buffer, size, :varint) do
    <<int::size(size)-unit(8)-signed, buffer::bytes>> = buffer
    {int, buffer}
  end

  defp decode_value(<<value::64, buffer::bytes>>, 8, :time) do
    {value, buffer}
  end

  defp decode_value(buffer, size, {:udt, fields}) do
    <<content::bytes-size(size)>> <> buffer = buffer
    {decode_value_udt(content, fields, %{}), buffer}
  end

  defp decode_value(<<value::64-signed>> <> buffer, 8, :timestamp) do
    {value, buffer}
  end

  defp decode_value(<<value::signed, buffer::bytes>>, 1, :tinyint) do
    {value, buffer}
  end

  defp decode_value_udt(<<>>, [], result) do
    result
  end

  defp decode_value_udt(buffer, [{field_name, field_type} | rest], result) do
    {value, buffer} = decode_value(buffer, field_type)
    decode_value_udt(buffer, rest, Map.put(result, field_name, value))
  end

  defp decode_list(<<>>, 0, _type, acc) do
    Enum.reverse(acc)
  end

  defp decode_list(buffer, length, type, acc) do
    {elem, buffer} = decode_value(buffer, type)
    decode_list(buffer, length - 1, type, [elem | acc])
  end

  defp decode_map(<<>>, 0, _key_type, _value_type, acc) do
    Map.new(acc)
  end

  defp decode_map(buffer, count, key_type, value_type, acc) do
    {key, buffer} = decode_value(buffer, key_type)
    {value, buffer} = decode_value(buffer, value_type)
    decode_map(buffer, count - 1, key_type, value_type, [{key, value} | acc])
  end

  def decode_tuple(<<>>, [], acc) do
    acc |> Enum.reverse |> List.to_tuple
  end

  def decode_tuple(buffer, [type | types], acc) do
    {item, buffer} = decode_value(buffer, type)
    decode_tuple(buffer, types, [item | acc])
  end

  defp decode_columns(buffer, 0, _table_spec, acc) do
    {Enum.reverse(acc), buffer}
  end

  defp decode_columns(buffer, column_count, nil, acc) do
    {keyspace, buffer} = decode_string(buffer)
    {table, buffer} = decode_string(buffer)
    {name, buffer} = decode_string(buffer)
    {type, buffer} = decode_type(buffer)
    entry = {keyspace, table, name, type}
    decode_columns(buffer, column_count - 1, nil, [entry | acc])
  end

  defp decode_columns(buffer, column_count, table_spec, acc) do
    {keyspace, table} = table_spec
    {name, buffer} = decode_string(buffer)
    {type, buffer} = decode_type(buffer)
    entry = {keyspace, table, name, type}
    decode_columns(buffer, column_count - 1, table_spec, [entry | acc])
  end

  defp decode_type(<<0x0000::16>> <> buffer) do
    {class, buffer} = decode_string(buffer)
    {custom_type_to_native(class), buffer}
  end

  defp decode_type(<<0x0001::16>> <> buffer) do
    {:ascii, buffer}
  end

  defp decode_type(<<0x0002::16>> <> buffer) do
    {:bigint, buffer}
  end

  defp decode_type(<<0x0003::16>> <> buffer) do
    {:blob, buffer}
  end

  defp decode_type(<<0x0004::16>> <> buffer) do
    {:boolean, buffer}
  end

  defp decode_type(<<0x0005::16>> <> buffer) do
    {:counter, buffer}
  end

  defp decode_type(<<0x0006::16>> <> buffer) do
    {:decimal, buffer}
  end

  defp decode_type(<<0x0007::16>> <> buffer) do
    {:double, buffer}
  end

  defp decode_type(<<0x0008::16>> <> buffer) do
    {:float, buffer}
  end

  defp decode_type(<<0x0009::16>> <> buffer) do
    {:int, buffer}
  end

  defp decode_type(<<0x000B::16>> <> buffer) do
    {:timestamp, buffer}
  end

  defp decode_type(<<0x000C::16>> <> buffer) do
    {:uuid, buffer}
  end

  defp decode_type(<<0x000D::16>> <> buffer) do
    {:varchar, buffer}
  end

  defp decode_type(<<0x000E::16>> <> buffer) do
    {:varint, buffer}
  end

  defp decode_type(<<0x000F::16>> <> buffer) do
    {:timeuuid, buffer}
  end

  defp decode_type(<<0x0010::16>> <> buffer) do
    {:inet, buffer}
  end

  defp decode_type(<<0x0020::16>> <> buffer) do
    {type, buffer} = decode_type(buffer)
    {{:list, [type]}, buffer}
  end

  defp decode_type(<<0x0021::16>> <> buffer) do
    {key_type, buffer} = decode_type(buffer)
    {value_type, buffer} = decode_type(buffer)
    {{:map, [key_type, value_type]}, buffer}
  end

  defp decode_type(<<0x0022::16>> <> buffer) do
    {type, buffer} = decode_type(buffer)
    {{:set, [type]}, buffer}
  end

  defp decode_type(<<0x0030::16>> <> buffer) do
    {_keyspace, buffer} = decode_string(buffer)
    {_name, buffer} = decode_string(buffer)
    <<count::16>> <> buffer = buffer
    decode_type_udt(buffer, count, [])
  end

  defp decode_type(<<0x0031::16, count::16>> <> buffer) do
    decode_type_tuple(buffer, count, [])
  end


      no_metadata == 1 ->
        {page, buffer}
      global_table_spec == 1 ->
        decode_string(keyspace <- buffer)
        decode_string(table <- buffer)
        {columns, buffer} = decode_columns(buffer, column_count, {keyspace, table}, [])
        {%{page | columns: columns}, buffer}
      true ->
