anchor.diff:  
   subgraph(_Options) ->
       % XXX use search options
  -    fun(Identifier, Metadata, [], Acc) ->
  +    fun(Identifier, Metadata, [], {Identifiers, Links}) ->
           {continue,
  -            dict:store(Identifier, {identifier, Identifier, Metadata}, Acc)};
  -       (Identifier, Metadata, [{Neighbor, _, LinkMetadata} | _], Acc) ->
  +            {
  +                dict:store(Identifier, {Identifier, Metadata}, Identifiers),
  +                Links
  +            }
  +        };
  +       (Identifier, Metadata, [{Neighbor, _, LinkMetadata} | _],
  +                                                    {Identifiers, Links}) ->
           {continue, 
  -            dict:store(Identifier, {identifier, Identifier, Metadata},
  +            {
  +                dict:store(Identifier,
  +                            {Identifier, Metadata},
  +                            Identifiers),
                   dict:store(normal_link(Identifier, Neighbor),
  -                            {link, Identifier, Neighbor, LinkMetadata},
  -                            Acc))}
  +                            {Identifier, Neighbor, LinkMetadata},
  +                            Links)
  +            }
  +        }
       end.
   
   normal_link(Id1, Id2) when Id1 < Id2 ->
  
positive.code: search(Identifier, Options) ->
      % XXX optimization - only install module once, not once per search
      {module, ?MODULE} = dby:install(?MODULE),
      case dby:search(subgraph(Options), dict:new(), Identifier,
                                  [{loop, link} | search_options(Options)]) of
          {error, Reason} ->
              {error, Reason};
          GraphD ->
              [format_element(E) || {_, E} <- dict:to_list(GraphD)]
      end.
  
  % ==============================================================================
  
negative.code: normal_link(Id1, Id2) ->
      {Id2, Id1}.
  
  uri_encode(B) when is_binary(B) ->
      list_to_binary(http_uri:encode(binary_to_list(B)));
  uri_encode(S) ->
  