anchor.diff:      rescan(State#state{scan_pid = nil}).
   
   process_update(State, DbName, {Change}) ->
  -    {RepProps} = JsonRepDoc = get_value(doc, Change),
  -    DocId = get_value(<<"_id">>, RepProps),
  -    case {mem3_util:owner(DbName, DocId), get_value(deleted, Change, false)} of
  +    {RepProps} = JsonRepDoc = get_json_value(doc, Change),
  +    DocId = get_json_value(<<"_id">>, RepProps),
  +    case {is_owner(DbName, DocId), get_json_value(deleted, Change, false)} of
       {false, _} ->
           replication_complete(DbName, DocId),
           State;
  
positive.code:     io_lib:format("-~2..0w:~2..0w", [abs(Hr), abs(Min)]).
  
  
  ensure_rep_db_exists() ->
      DbName = ?l2b(couch_config:get("replicator", "db", "_replicator")),
      UserCtx = #user_ctx{roles = [<<"_admin">>, <<"_replicator">>]},
      case couch_db:open_int(DbName, [sys_db, {user_ctx, UserCtx}, nologifmissing]) of
      {ok, Db} ->
          Db;
      _Error ->
          {ok, Db} = couch_db:create(DbName, [sys_db, {user_ctx, UserCtx}])
      end,
      ensure_rep_ddoc_exists(Db, <<"_design/_replicator">>),
      {ok, Db}.
  
  
  ensure_rep_ddoc_exists(RepDb, DDocID) ->
      case couch_db:open_doc(RepDb, DDocID, []) of
      {ok, _Doc} ->
          ok;
      _ ->
          DDoc = couch_doc:from_json_obj({[
              {<<"_id">>, DDocID},
              {<<"language">>, <<"javascript">>},
              {<<"validate_doc_update">>, ?REP_DB_DOC_VALIDATE_FUN}
          ]}),
          {ok, _Rev} = couch_db:update_doc(RepDb, DDoc, [])
       end.
  
  
  % pretty-print replication id
  
negative.code: 
  is_replicator_db_fun() ->
      {ok, RegExp} = re:compile("^([a-z][a-z0-9\\_\\$()\\+\\-\\/]*/)?_replicator$"),
      fun
          (<<"shards/", _/binary>>=DbName) ->
              match =:= re:run(mem3:dbname(DbName), RegExp, [{capture,none}]);
          (DbName) ->
              LocalRepDb = ?l2b(config:get("replicator", "db", "_replicator")),
              DbName == LocalRepDb
      end.
  
  get_json_value(Key, Props) ->
      get_json_value(Key, Props, undefined).
  
  get_json_value(Key, Props, Default) when is_atom(Key) ->
      Ref = make_ref(),
      case couch_util:get_value(Key, Props, Ref) of
          Ref ->
              couch_util:get_value(?l2b(atom_to_list(Key)), Props, Default);
          Else ->
              Else
      end;
  get_json_value(Key, Props, Default) when is_binary(Key) ->
      Ref = make_ref(),
      case couch_util:get_value(Key, Props, Ref) of
          Ref ->
              couch_util:get_value(list_to_atom(?b2l(Key)), Props, Default);
          Else ->
              Else
      end.
  