anchor.diff:  register(Fun, Pid) ->
       gen_server:call(?MODULE, {register, Fun, Pid}).
   
  -%% Private API %%
  -
  -%% @spec init(List::list([])) -> {ok, Tab::etsatable()}
  -%% @doc Creates a new ets table of the type "set".
  +
   init(IniFiles) ->
  -    ets:new(?MODULE, [named_table, set, protected]),
  +    ets:new(?MODULE, [named_table, set, private]),
       lists:map(fun(IniFile) ->
           {ok, ParsedIniValues} = parse_ini_file(IniFile),
           ets:insert(?MODULE, ParsedIniValues)
       end, IniFiles),
  -    {ok, #config{write_filename=lists:last(IniFiles)}}.
  -
  -handle_call({set, KVs, Persist}, _From, Config) ->
  -    lists:map(
  -        fun({{Section, Key}, Value}=KV) ->
  -            true = ets:insert(?MODULE, KV),
  -            if Persist ->
  -                ok = couch_config_writer:save_to_file(KV,
  -                        Config#config.write_filename);
  -            true -> ok
  -            end,
  -            [catch F(Section, Key, Value)
  -                    || {_Pid, F} <- Config#config.notify_funs]
  -        end, KVs),
  +    WriteFile = case length(IniFiles) > 0 of
  +        true -> lists:last(IniFiles);
  +        _ -> undefined
  +    end,
  +    {ok, #config{write_filename=WriteFile}}.
  +
  +
  +terminate(_Reason, _State) ->
  +    ok.
  +
  +
  +handle_call(all, _From, Config) ->
  +    Resp = lists:sort((ets:tab2list(?MODULE))),
  +    {reply, Resp, Config};
  +handle_call({get, Section}, _From, Config) ->
  +    Matches = ets:match(?MODULE, {{Section, '$1'}, '$2'}),
  +    Resp = [{Key, Value} || [Key, Value] <- Matches],
  +    {reply, Resp, Config};
  +handle_call({get, Section, Key, Default}, _From, Config) ->
  +    Resp = case ets:lookup(?MODULE, {Section, Key}) of
  +        [] -> Default;
  +        [{_, Match}] -> Match
  +    end,
  +    {reply, Resp, Config};
  +handle_call({set, Sec, Key, Val, Persist}, _From, Config) ->
  +    true = ets:insert(?MODULE, {{Sec, Key}, Val}),
  +    case {Persist, Config#config.write_filename} of
  +        {true, undefined} ->
  +            ok;
  +        {true, FileName} ->
  +            couch_config_writer:save_to_file({{Sec, Key}, Val}, FileName);
  +        _ ->
  +            ok
  +    end,
  +    [catch F(Sec, Key, Val) || {_Pid, F} <- Config#config.notify_funs],
       {reply, ok, Config};
  -
   handle_call({register, Fun, Pid}, _From, #config{notify_funs=PidFuns}=Config) ->
       erlang:monitor(process, Pid),
       % convert 1 and 2 arity to 3 arity
  -    Fun2 = 
  -    if is_function(Fun, 1) ->
  -        fun(Section, _Key, _Value) -> Fun(Section) end;
  -    is_function(Fun, 2) ->
  -        fun(Section, Key, _Value) -> Fun(Section, Key) end;
  -    is_function(Fun, 3) ->
  -        Fun
  -    end,
  -    {reply, ok, Config#config{notify_funs=[{Pid, Fun2}|PidFuns]}}.
  -
  -%% @spec load_ini_file(IniFile::filename()) -> ok
  -%% @doc Parses an ini file and stores Key/Value Pairs into the ets table.
  -load_ini_file(IniFile) ->
  -    {ok, KVs} = parse_ini_file(IniFile),
  -    gen_server:call(?MODULE, {set, KVs, false}).
  -
  -%% @spec load_ini_file(IniFile::filename()) -> {ok, [KV]}
  -%%       KV = {{Section::string(), Key::string()}, Value::String()}
  -%% @throws {startup_error, Msg::string()}
  +    Fun2 =
  +    case Fun of
  +        _ when is_function(Fun, 1) ->
  +            fun(Section, _Key, _Value) -> Fun(Section) end;
  +        _ when is_function(Fun, 2) ->
  +            fun(Section, Key, _Value) -> Fun(Section, Key) end;
  +        _ when is_function(Fun, 3) ->
  +            Fun
  +    end,
  +    {reply, ok, Config#config{notify_funs=[{Pid, Fun2} | PidFuns]}}.
  +
  +
  +handle_cast(stop, State) ->
  +    {stop, normal, State};
  +handle_cast(_Msg, State) ->
  +    {noreply, State}.
  +
  +handle_info({'DOWN', _, _, DownPid, _}, #config{notify_funs=PidFuns}=Config) ->
  +    % remove any funs registered by the downed process
  +    FilteredPidFuns = [{Pid,Fun} || {Pid,Fun} <- PidFuns, Pid /= DownPid],
  +    {noreply, Config#config{notify_funs=FilteredPidFuns}}.
  +
  +code_change(_OldVsn, State, _Extra) ->
  +    {ok, State}.
  +
  +
   parse_ini_file(IniFile) ->
       IniFilename = couch_util:abs_pathname(IniFile),
       IniBin =
  
positive.code: get(Section, Key, Default) when is_binary(Section) and is_binary(Key) ->
      ?MODULE:get(?b2l(Section), ?b2l(Key), Default);
  get(Section, Key, Default) ->
      case ets:lookup(?MODULE, {Section, Key}) of
      [] -> Default;
      [{_,Result}] -> Result
      end.
  
  set(Section, Key, Value) ->
      set(Section, Key, Value, true).
  
  set(Section, Key, Value, Persist) when is_binary(Section) and is_binary(Key)  ->
      set(?b2l(Section), ?b2l(Key), Value, Persist);
  set(Section, Key, Value, Persist) ->
      gen_server:call(?MODULE, {set, [{{Section, Key}, Value}], Persist}).
  
  delete(Section, Key) ->
      set(Section, Key, "").
  
  register(Fun) ->
      ?MODULE:register(Fun, self()).
  
negative.code:         {ok, IniBin0} ->
              IniBin0;
          {error, enoent} ->
              Fmt = "Couldn't find server configuration file ~s.",
              Msg = ?l2b(io_lib:format(Fmt, [IniFilename])),
              ?LOG_ERROR("~s~n", [Msg]),
              throw({startup_error, Msg})
      end,
  