anchor.diff:  -behaviour(gen_server).
   
   -export([start_link/1,
  -         set/2,
  -         set/3,
            get/1,
            get/2]).
   
  
positive.code: 
  terminate(_Reason, _State) ->
      ok.
  
negative.code:          terminate/2]).
  
  start_link(Path) ->
      case file:consult(Path) of
          {ok, Configs} ->
              gen_server:start_link({local, ?MODULE}, ?MODULE, [Configs], []);
          {error, Reason} ->
              {error, Reason}
      end.
  
  merge(Config, Default) ->
      Config ++ merge_keys(Config, Default).
  
  merge_keys(_Config, []) ->
      [];
  merge_keys(Config, [{Key, Value}|R]) ->
      case proplists:lookup(Key, Config) of
          none ->
              [{Key, Value} | merge_keys(Config, R)];
          _ ->
              merge_keys(Config, R)
      end.
  
  get(Key) ->
      ?MODULE:get(global, Key).
  
  get(Domain, Key) ->
      gen_server:call(?MODULE, {get, Domain, Key}).
  
  init([UCEConfig]) ->
      DB = ets:new(uce_config, [duplicate_bag, private, {keypos, 1}]),
      Hosts = proplists:get_value(hosts, UCEConfig),
      lists:foreach(fun({Domain, HostConfig}) ->
                            insert_in(Domain, merge(HostConfig, UCEConfig), DB)
                    end, Hosts),
      insert_in(global, UCEConfig, DB),
      {ok, DB}.
  
  insert_in(Domain, Config, DB) ->
      lists:foreach(fun({Key, Value}) ->
                            ets:insert(DB, {Key, Value, Domain})
                    end, Config).
  
  handle_call({get, Domain, Key}, _From, DB) ->
      Reply = case ets:match_object(DB, {Key, '_', Domain}) of
                  [{Key, Value, Domain}] ->
                      Value;
                  _ ->
                      undefined
              end,
      {reply, Reply, DB}.
  
  handle_cast({set, Domain, {Key, Value}}, DB) ->
      ets:insert(DB, {Key, Value, Domain}),
      {noreply, DB}.
  
  handle_info(_Info, State) ->
      {reply, State}.
  