anchor.diff:      put(top, ErlTop),
       put(exit_code, 0),
       CachedFiles = maps:from_list([{m2a,M2A}|Files]),
  -    [validate_links(File,CachedFiles) || File <- Files],
  +    [validate_links(File,CachedFiles) ||
  +        {{App,_},_} = File <- Files,
  +        lists:member(App,["edoc","wx","eunit","syntax_tools"]) =:= false],
       erlang:halt(get(exit_code)).
   
   parse_file(Filename) ->
   %    io:format("Parse: ~p~n",[Filename]),
       case xmerl_sax_parser:file(Filename, [skip_external_dtd,
                                             {event_fun,fun handle_event/3},
  -                                          {event_state,#{ funcs => [],
  +                                          {event_state,#{ markers => [],
  +                                                          funcs => [],
                                                             datatypes => []}}]) of
           {ok, Res, _} ->
   %            [io:format("~p~n",[Res]) || maps:get(filename,Res) == {"erts","erl_tracer"}],
  -            {maps:get(filename,Res), maps:remove(filename,Res)}
  +            {maps:get(filename,Res), Res}
       end.
   
   handle_event(startDocument, _Line, State) ->
  
positive.code:             halt(1)
      end.
  
  validate_type(_Line, "seeerl","erlref") ->
      ok;
  validate_type(_Line, "seemfa","erlref") ->
      ok;
  validate_type(_Line, "seetype","erlref") ->
      ok;
  validate_type(_Line, "seeguide","chapter") ->
      ok;
  validate_type(_Line, "seeguide","index") ->
      ok;
  validate_type(_Line, "seefile","fileref") ->
      ok;
  validate_type(_Line, "seeapp","appref") ->
      ok;
  validate_type(_Line, "seeapp","index") ->
      ok;
  validate_type(_Line, "seecom","comref") ->
      ok;
  validate_type(_Line, "seecref","cref") ->
      ok;
  validate_type(Line, From, To) ->
      fail(Line, "Invalid <~s> pointing to a <~s> file",[From,To]).
  
  path2app(Path) ->
      case lists:reverse(string:lexemes(Path,"/")) of
  
negative.code:     maps:put(filename,{path2app(Path),ModuleName}, State);
  
  %% Get the see* attributes
  event({startElement, "see" ++ _ = What, Attr}, Line, State, [Parent|_])
  %% Links are not rendered when emitted in <name>, but the edoc docs still has links here
  %% So we ignore those...
    when Parent =/= "name" ->
      maps:put(What, [{Line,Attr}|maps:get(What, State, [])], State);
  
  %% Get all the marker attributes
  event({startElement, "marker", [{"id",Id}]}, _Line, State, _) ->
      maps:put(markers, [Id|maps:get(markers, State, [])], State);
  event({startElement, "title", []}, _Line, State, _) ->
      error = maps:find(characters,State),
      maps:put(characters,[],State);
  event({endElement, "title"}, _Line, State, _) ->
      Id = string:lowercase(
             re:replace(maps:get(characters,State),"[?: /()\"\r\n]","-",[global,{return,list}])),
      NewState = maps:put(markers, [Id|maps:get(markers, State, [])], State),
      maps:remove(characters,NewState);
  event({startElement, "nametext", []}, _Line, State, _) ->
      error = maps:find(characters,State),
      maps:put(characters,[],State);
  event({endElement, "nametext"}, _Line, State, _) ->
      Id = re:replace(maps:get(characters,State),"\\(.*","",[global,{return,list},dotall]),
      NewState = maps:put(markers, [Id|maps:get(markers, State, [])], State),
      maps:remove(characters,NewState);
  event({startElement, "datatype_title", []}, _Line, State, _) ->
      error = maps:find(characters,State),
      maps:put(characters,[],State);
  event({endElement, "datatype_title"}, _Line, State, _) ->
      Id = lists:flatten(maps:get(characters,State)),
      NewState = maps:put(markers, [Id|maps:get(markers, State, [])], State),
      maps:remove(characters,NewState);
  event({startElement, "description", _}, _Line, State, _) ->
      maps:put(markers, ["description"|maps:get(markers, State, [])], State);
  
  %% Get all func->name markers in erlref
  event({startElement, "name", Attr}, _Line, #{ type := "erlref" } = State, ["func" | _]) ->
      AnchorState =
          case proplists:get_value("anchor",Attr) of
              undefined -> State;
              Anchor -> maps:put(markers, [Anchor|maps:get(markers, State, [])], State)
          end,
      case {proplists:get_value("name",Attr),proplists:get_value("arity",Attr)} of
          {undefined,undefined} ->
              %% We parse the function name from the content,
              %% so have to capture characters
              error = maps:find(characters,AnchorState),
              maps:put(characters,[],AnchorState);
          {Func,Arity} when Func =/= undefined, Arity =/= undefined ->
              maps:put(funcs, [{Func,Arity}|maps:get(funcs,AnchorState,[])], AnchorState)
      end;
  event({endElement,"name"}, _Line, #{ characters := Chars} = State, ["func"|_]) ->
      FAs = docgen_xml_to_chunk:func_to_tuple(Chars),
  