anchor.diff:  future(F) -> future_get(F, none).
   
   future_get(F, FQuery) -> 
  +  maybe_fdb_do([
  +    fun() -> wait_non_blocking(F, fdb_nif:fdb_future_is_ready(F)) end,
  +    fun() -> fdb_nif:fdb_future_get_error(F) end,
  +    fun() -> get_future_property(F, FQuery) end
  +  ]).
  +
  +get_future_property(_F,none) ->
  +  ok;
  +get_future_property(F,FQuery) ->
     FullQuery = list_to_atom("fdb_future_get_" ++ atom_to_list(FQuery)),
  -  ok = wait_non_blocking(F, fdb_nif:fdb_future_is_ready(F)),
  -  ErrCode = 0, %% no longer needed
  -  check_future_error(ErrCode, F, FullQuery).
  +  apply(fdb_nif, FullQuery, [F]).
   
   wait_non_blocking(nif_not_loaded, nif_not_loaded) ->
     {error, nif_not_loaded};
   wait_non_blocking(F, false) ->
     Ref = make_ref(),
  -  0 = fdb_nif:send_on_complete(F,self(),Ref),
  -  receive
  -    Ref -> ok
  -    after ?FUTURE_TIMEOUT -> timeout
  -  end;
  -wait_non_blocking(_F, true) ->
  -  ok.
  -
  -check_future_error(0, F, FQuery) ->
  -  ErrCode = fdb_nif:fdb_future_get_error(F),
  -  maybe_get_future_value(ErrCode, F, FQuery);
  -check_future_error(ErrCode, _F, _FQuery) -> handle_fdb_result(ErrCode).
  -
  -maybe_get_future_value(0, _F, fdb_future_get_none) ->
  -  ok;
  -maybe_get_future_value(0, F, FQuery) ->
  -  handle_fdb_result(apply(fdb_nif, FQuery, [F]));
  -maybe_get_future_value(ErrCode, _F, _FQuery) -> 
  -  handle_fdb_result(ErrCode).
  +  maybe_fdb_do([
  +  fun ()-> fdb_nif:send_on_complete(F,self(),Ref),
  +    receive
  +      Ref -> {ok, F}
  +      after ?FUTURE_TIMEOUT -> {error, timeout}
  +    end
  +  end]);
  +wait_non_blocking(F, true) ->
  +  {ok, F}.
  +
  
positive.code: next(Iterator = #iterator{tx = Transaction, iteration = Iteration, select = Select}) ->
    {FstKey, FstIsEq, FstOfs} = fst_gt(Select#select.gt, Select#select.gte),
    {LstKey, LstIsEq, LstOfs} = lst_lt(Select#select.lt, Select#select.lte),
    F = fdb_nif:fdb_transaction_get_range(Transaction, 
      FstKey, FstIsEq, Select#select.offset_begin + FstOfs,
      <<LstKey/binary>>, LstIsEq, Select#select.offset_end + LstOfs,
      Select#select.limit, 
      Select#select.target_bytes, 
      Select#select.streaming_mode, 
      Iteration, 
      Select#select.is_snapshot, 
      Select#select.is_reverse),
    {ok, EncodedData} = future_get(F, keyvalue_array),
    Data = lists:map(fun({X, Y})-> {tuple:unpack(X), binary_to_term(Y)} end, EncodedData),
    Iterator#iterator{ data = Data, iteration = Iteration + 1, out_more = false}.
  
  fst_gt(nil, nil) -> {<<0>>, true, 0};
  fst_gt(nil, Value) -> { tuple:pack(Value), true, 0  };
  
negative.code: get(DB={db, _Database}, Key, DefaultValue) ->
    transact(DB, fun(Tx) -> get(Tx, Key, DefaultValue) end);
  get({tx, Tx}, Key, DefaultValue) ->
    maybe_fdb_do([
    fun()-> fdb_nif:fdb_transaction_get(Tx, tuple:pack(Key)) end,
    fun(GetF) -> future_get(GetF, value) end,
    fun(Result) -> case Result of
        not_found -> DefaultValue;
        _ -> binary_to_term(Result)
     end
    end]).
  
  %% @doc Binds a range of data to an iterator; use `fdb:next` to iterate it
  -spec bind(fdb_handle(), #select{}) -> #iterator{}.
  