anchor.diff:           delete/3, delete/4, delete/5,
            delete_vclock/4, delete_vclock/5, delete_vclock/6,
            delete_obj/2, delete_obj/3, delete_obj/4,
  -         list_buckets/1, list_buckets/2, list_buckets/3,
  +         list_buckets/1, list_buckets/2,
  +         stream_list_buckets/1, stream_list_buckets/2,
            list_keys/2, list_keys/3,
  -         stream_list_keys/2, stream_list_keys/3, stream_list_keys/4,
  +         stream_list_keys/2, stream_list_keys/3,
            get_bucket/2, get_bucket/3, get_bucket/4,
            set_bucket/3, set_bucket/4, set_bucket/5,
            mapred/3, mapred/4, mapred/5,
  
positive.code: %% @equiv stream_list_keys(Pid, Bucket, default_timeout(stream_list_keys_timeout))
  -spec stream_list_keys(pid(), bucket()) -> {ok, req_id()} | {error, term()}.
  stream_list_keys(Pid, Bucket) ->
      stream_list_keys(Pid, Bucket, default_timeout(stream_list_keys_timeout)).
  
  %% @doc Stream list of keys in the bucket to the calling process specifying server side
  %%      timeout.
  
negative.code: %% @equiv list_buckets(Pid, default_timeout(list_buckets_timeout))
  -spec list_buckets(pid()) -> {ok, [bucket()]} | {error, term()}.
  list_buckets(Pid) ->
      list_buckets(Pid, []).
  
  %% @doc List all buckets on the server specifying server-side timeout.
  %% <em>This is a potentially expensive operation and should not be used in production.</em>
  -spec list_buckets(pid(), timeout()|list()) -> {ok, [bucket()]} |
                                                     {error, term()}.
  list_buckets(Pid, Timeout) when is_integer(Timeout) ->
      list_buckets(Pid, [{timeout, Timeout}]);
  list_buckets(Pid, Options) ->
      case stream_list_buckets(Pid, Options) of
          {ok, ReqId} ->
              wait_for_list(ReqId);
          Error ->
              Error
      end.
  
  stream_list_buckets(Pid) ->
      stream_list_buckets(Pid, []).
  
  stream_list_buckets(Pid, Timeout) when is_integer(Timeout) ->
      stream_list_buckets(Pid, [{timeout, Timeout}]);
  stream_list_buckets(Pid, Options) ->
      ServerTimeout = 
          case proplists:get_value(timeout, Options, none) of
              none -> ?DEFAULT_TIMEOUT;
              ST -> ST
          end,
      ReqId = mk_reqid(),
      gen_server:call(Pid, {req, #rpblistbucketsreq{timeout=ServerTimeout},
                            infinity, {ReqId, self()}}, infinity).
  
  %% @doc List all keys in a bucket
  %% <em>This is a potentially expensive operation and should not be used in production.</em>
  %% @equiv list_keys(Pid, Bucket, default_timeout(list_keys_timeout))
  -spec list_keys(pid(), bucket()) -> {ok, [key()]} | {error, term()}.
  list_keys(Pid, Bucket) ->
      list_keys(Pid, Bucket, []).
  
  %% @doc List all keys in a bucket specifying timeout. This is
  %% implemented using {@link stream_list_keys/3} and then waiting for
  %% the results to complete streaming.
  %% <em>This is a potentially expensive operation and should not be used in production.</em>
  -spec list_keys(pid(), bucket(), list()|timeout()) -> {ok, [key()]} | 
                                                        {error, term()}.
  list_keys(Pid, Bucket, Timeout) when is_integer(Timeout) ->
      list_keys(Pid, Bucket, [{timeout, Timeout}]);
  list_keys(Pid, Bucket, Options) ->
      case stream_list_keys(Pid, Bucket, Options) of
          {ok, ReqId} ->
              wait_for_list(ReqId);
          Error ->
              Error
      end.
  