anchor.diff:  code_change(_OldVsn,State,_Extra) ->
     {ok,State}.
   
  +handle_call(state,_From,State) ->
  +  {reply,expand_recs(State),State};
   handle_call(unlink,_From,State) ->
     {links,Links} = process_info(self(),links),
     lists:foreach(fun unlink/1,Links),
  
positive.code: -author('mats cronqvist').
  
  %% the API
  -export([start/0,stop/0,unlink/0]).
  
  %% for application supervisor
  -export([start_link/0]).
  
negative.code: 
  handle_info(_What,State) ->
    {noreply,State}.
  
  %% utility to print state
  expand_recs(List) when is_list(List) ->
    [expand_recs(I) || I <- List];
  expand_recs(Tup) when is_tuple(Tup) ->
    case tuple_size(Tup) of
      L when L < 1 -> Tup;
      L ->
        try Fields = rec_info(element(1,Tup)),
            L = length(Fields)+1,
            lists:zip(Fields,expand_recs(tl(tuple_to_list(Tup))))
        catch _:_ ->
            list_to_tuple(expand_recs(tuple_to_list(Tup)))
        end
    end;
  expand_recs(Term) ->
    Term.
  
  %% end of boilerplate
  dirname() -> filename:join(code:priv_dir(?MODULE),data).
  filename() -> "SE.txt".
  tablename() -> egeonames_se.
  
  do_init(S) ->
    FN = filename:join(S#state.dirname,S#state.filename),
    {ok,FD} = file:open(FN,[read,raw,binary,read_ahead]),
    filefold(FD,mk_liner(S#state.tablename)),
    S.
  
  mk_liner(Tab) ->
    ets:new(Tab,[ordered_set,named_table]),
    ets:insert(Tab,{count,1}),
    fun({ok,_Data}) -> ets:update_counter(Tab,count,1);
       ({error,Reason}) -> error({read_line,Reason});
       (eof) -> throw(eof)
    end.
  
  filefold(FD,Fun) ->
    try
      Fun(file:read_line(FD)),
      filefold(FD,Fun)
    catch
      throw:eof -> ok
    end.
  