anchor.diff:  apply_to(BaseConfig, NewConfig, SSPrepend, #cstate{re=RE}=State) ->
       orddict:merge(apply_val_factory(RE, SSPrepend), BaseConfig, NewConfig).
   
  +apply_factory(SSPrepend, State) ->
  +    fun(BaseConfig, NewConfig) ->
  +	    apply_to(BaseConfig, NewConfig, SSPrepend, State)
  +    end.
  +
   cache_store(Kind, Name, Commit, Config, #cstate{table=Cache}) ->
  -    ets:insert(Cache, {{Kind, Name, Commit}, Config}).
  +    ets:insert(Cache, {{Kind, Name, Commit}, Config}),
  +    Config.
   
   cache_find(Kind, Name, Commit, #cstate{table=Cache}) ->
       ok.
  
positive.code: transitively_reachable(Graph, StartNode, Filter) ->
      [Node || Node <- transitively_reachable(Graph, StartNode), Filter(Node)].
  
  interesting_install_edge({Kind, _, {'feature', _}}) when Kind =:= 'includes' orelse Kind =:= 'installs' ->
      true;
  interesting_install_edge(_) ->
      false.
  
  interesting_install_vertex({'feature', _}) ->
      true;
  interesting_install_vertex({'group', _}) -> 
      true;
  
negative.code:     [digraph:add_vertex(Installs, Ent) || Ent <- Entities, interesting_install_vertex(Ent)],
      [digraph:add_edge(Installs, E1, E2, Kind) || F={Kind, E1, E2} <- Relationships, interesting_install_edge(F)],
      Order = lists:reverse(digraph_utils:topsort(Installs)),
      [calc_one_config(Entity, Tree, Commit, State) || Entity <- Order].
  
  path_for_kind(feature) ->
      <<"features">>;
  path_for_kind(group) ->
      <<"groups">>;
  path_for_kind(node) ->
      <<"nodes">>;
  path_for_kind(parameter) ->
      <<"parameters">>;
  path_for_kind(X) when is_atom(X) ->
      list_to_binary(atom_to_list(X) ++ "s").
  
  %% XXX:  should store these in lightweight format
  calc_one_config({Kind, Name}, Tree, Commit, #cstate{re=RE, table=Cache, storage=StoreMod}=State) 
    when Kind =:= 'feature' ->
      %% get feature object from tree
      {value, EntityObj} = wallaroo_tree:get_path([path_for_kind(Kind), Name], Tree, StoreMod),
      %% apply included feature configs to empty config; these should already be in the cache
      BaseConfig = lists:foldl(apply_factory(true, State), [], [cache_find(Kind, Included, Commit, State) || Included <- lists:reverse(wallaby_feature:includes(EntityObj))]),
      %% resolve "defaulted" parameters
      MyConfig = orddict:map(fun(Param, 0) ->
  				   {value, PObj} = wallaroo_tree:get_path([path_for_kind(parameter), Param], Tree, StoreMod),
  				   wallaby_parameter:default_val(PObj);
  			      (_, V) ->
  				   V
  			   end, wallaby_feature:parameters(EntityObj)),
      %% apply params to generated config and store in cache
      cache_store(Kind, Name, Commit, apply_to(BaseConfig, MyConfig, true, State), State);
  calc_one_config({Kind, Name}, Tree, Commit, #cstate{re=RE, table=Cache, storage=StoreMod}=State) 
    when Kind =:= 'group' ->
      %% get group object from tree
      {value, EntityObj} = wallaroo_tree:get_path([path_for_kind(Kind), Name], Tree, StoreMod),
      %% apply installed feature configs to empty config; these should already be in the cache
      BaseConfig = lists:foldl(apply_factory(true, State), [], [cache_find(feature, Installed, Commit, State) || Installed <- lists:reverse(wallaby_group:features(EntityObj))]),
      %% apply my parameters to the base config
      cache_store(Kind, Name, Commit, apply_to(BaseConfig, wallaby_group:parameters(EntityObj), true, State), State); 
  calc_one_config({Kind, Name}, Tree, Commit, #cstate{re=RE, table=Cache, storage=StoreMod}=State) 
    when Kind =:= 'node' ->
      %% get node object from tree
      {value, EntityObj} = wallaroo_tree:get_path([path_for_kind(Kind), Name], Tree, StoreMod),
      Config = lists:foldl(apply_factory(false, State), [], [cache_find(group, Membership, Commit, State) || Membership <- lists:reverse(wallaby_node:all_memberships(EntityObj))]),
      cache_store(Kind, Name, Commit, Config, State).
      
      
  
  
  join_factory(Bin) when is_binary(Bin) ->
      fun(Old, New) ->
  	    <<New/binary, Bin/binary, Old/binary>>
      end.
  
  combine_factory(<<">=">>) ->
      join_factory(<<", ">>);
  