anchor.diff:  %%% The MAIN loop.
   %%% ---------------------------------------------------
   
  -loop(Parent, Name, State, Mod, {continue, Continue} = Msg, HibernateAfterTimeout, Debug) ->
  -    Reply = try_dispatch(Mod, handle_continue, Continue, State),
  +loop(Parent, Name, State, CbCache, {continue, Continue} = Msg, HibernateAfterTimeout, Debug) ->
  +    Reply = try_handle_continue(CbCache, Continue, State),
       case Debug of
  -	[] ->
  -	    handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod,
  -				HibernateAfterTimeout, State);
  -	_ ->
  -	    Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, Msg),
  -	    handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod,
  -				HibernateAfterTimeout, State, Debug1)
  +        [] ->
  +            handle_common_reply(Reply, Parent, Name, undefined, Msg, CbCache,
  +                                HibernateAfterTimeout, State);
  +        _ ->
  +            Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, Msg),
  +            handle_common_reply(Reply, Parent, Name, undefined, Msg, CbCache,
  +                                HibernateAfterTimeout, State, Debug1)
       end;
   
  -loop(Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug) ->
  +loop(Parent, Name, State, CbCache, hibernate, HibernateAfterTimeout, Debug) ->
  +    Mod = CbCache#callback_cache.module,
       proc_lib:hibernate(?MODULE,wake_hib,[Parent, Name, State, Mod, HibernateAfterTimeout, Debug]);
   
  -loop(Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug) ->
  -	receive
  -		Msg ->
  -			decode_msg(Msg, Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug, false)
  -	after HibernateAfterTimeout ->
  -		loop(Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug)
  -	end;
  -
  -loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug) ->
  +loop(Parent, Name, State, CbCache, infinity, HibernateAfterTimeout, Debug) ->
  +    receive
  +        Msg ->
  +            decode_msg(Msg, Parent, Name, State, CbCache, infinity, HibernateAfterTimeout, Debug, false)
  +    after HibernateAfterTimeout ->
  +            loop(Parent, Name, State, CbCache, hibernate, HibernateAfterTimeout, Debug)
  +    end;
  +
  +loop(Parent, Name, State, CbCache, Time, HibernateAfterTimeout, Debug) ->
       Msg = receive
  -	      Input ->
  -		    Input
  -	  after Time ->
  -		  timeout
  -	  end,
  -    decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, false).
  +              Input ->
  +                  Input
  +          after Time ->
  +                  timeout
  +          end,
  +    decode_msg(Msg, Parent, Name, State, CbCache, Time, HibernateAfterTimeout, Debug, false).
  +
  +-spec create_callback_cache(module()) -> #callback_cache{}.
  +create_callback_cache(Mod) ->
  +    #callback_cache{module = Mod,
  +                    handle_call = fun Mod:handle_call/3,
  +                    handle_cast = fun Mod:handle_cast/2,
  +                    handle_info = fun Mod:handle_info/2}.
   
   wake_hib(Parent, Name, State, Mod, HibernateAfterTimeout, Debug) ->
       Msg = receive
  -	      Input ->
  -		  Input
  -	  end,
  -    decode_msg(Msg, Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug, true).
  -
  -decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, Hib) ->
  +              Input ->
  +                  Input
  +          end,
  +    CbCache = create_callback_cache(Mod),
  +    decode_msg(Msg, Parent, Name, State, CbCache, hibernate, HibernateAfterTimeout, Debug, true).
  +
  +decode_msg(Msg, Parent, Name, State, CbCache, Time, HibernateAfterTimeout, Debug, Hib) ->
       case Msg of
  -	{system, From, Req} ->
  -	    sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
  -				  [Name, State, Mod, Time, HibernateAfterTimeout], Hib);
  -	{'EXIT', Parent, Reason} ->
  -	    terminate(Reason, ?STACKTRACE(), Name, undefined, Msg, Mod, State, Debug);
  -	_Msg when Debug =:= [] ->
  -	    handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout);
  -	_Msg ->
  -	    Debug1 = sys:handle_debug(Debug, fun print_event/3,
  -				      Name, {in, Msg}),
  -	    handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout, Debug1)
  +        {system, From, Req} ->
  +            sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
  +                                  [Name, State, CbCache, Time, HibernateAfterTimeout], Hib);
  +        {'EXIT', Parent, Reason} ->
  +            #callback_cache{module = Mod} = CbCache,
  +            terminate(Reason, ?STACKTRACE(), Name, undefined, Msg, Mod, State, Debug);
  +        _Msg when Debug =:= [] ->
  +            handle_msg(Msg, Parent, Name, State, CbCache, HibernateAfterTimeout);
  +        _Msg ->
  +            Debug1 = sys:handle_debug(Debug, fun print_event/3,
  +                                      Name, {in, Msg}),
  +            handle_msg(Msg, Parent, Name, State, CbCache, HibernateAfterTimeout, Debug1)
       end.
   
   %%% ---------------------------------------------------
  
positive.code:     end.
  init_it(Mod, Args) ->
      try
  	{ok, Mod:init(Args)}
      catch
  	throw:R -> {ok, R};
  	Class:R:S -> {'EXIT', Class, R, S}
      end.
  
  %%%========================================================================
  
negative.code: %%% Message handling functions
  %%% ---------------------------------------------------
  
  handle_msg({'$gen_call', From, Msg}, Parent, Name, State, CbCache, HibernateAfterTimeout) ->
      Result = try_handle_call(CbCache, Msg, From, State),
      case Result of
  	{ok, {reply, Reply, NState}} ->
  	    reply(From, Reply),
  	    loop(Parent, Name, NState, CbCache, infinity, HibernateAfterTimeout, []);
  	{ok, {reply, Reply, NState, TimeoutOrHibernate}}
            when ?is_timeout(TimeoutOrHibernate);
                 TimeoutOrHibernate =:= hibernate ->
  	    reply(From, Reply),
  	    loop(Parent, Name, NState, CbCache, TimeoutOrHibernate, HibernateAfterTimeout, []);
  	{ok, {reply, Reply, NState, {continue, _}=Continue}} ->
  	    reply(From, Reply),
  	    loop(Parent, Name, NState, CbCache, Continue, HibernateAfterTimeout, []);
  	{ok, {stop, Reason, Reply, NState}} ->
  	    try
              Mod = CbCache#callback_cache.module,
  		terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, [])
  	    after
  		reply(From, Reply)
  	    end;
  	Other -> handle_common_reply(Other, Parent, Name, From, Msg, CbCache, HibernateAfterTimeout, State)
      end;
  handle_msg(Msg, Parent, Name, State, CbCache, HibernateAfterTimeout) ->
      Reply = try_dispatch(Msg, CbCache, State),
      handle_common_reply(Reply, Parent, Name, undefined, Msg, CbCache, HibernateAfterTimeout, State).
  
  handle_msg({'$gen_call', From, Msg}, Parent, Name, State, CbCache, HibernateAfterTimeout, Debug) ->
      Result = try_handle_call(CbCache, Msg, From, State),
      case Result of
  	{ok, {reply, Reply, NState}} ->
  	    Debug1 = reply(Name, From, Reply, NState, Debug),
  	    loop(Parent, Name, NState, CbCache, infinity, HibernateAfterTimeout, Debug1);
  	{ok, {reply, Reply, NState, TimeoutOrHibernate}}
            when ?is_timeout(TimeoutOrHibernate);
                 TimeoutOrHibernate =:= hibernate ->
  	    Debug1 = reply(Name, From, Reply, NState, Debug),
  	    loop(Parent, Name, NState, CbCache, TimeoutOrHibernate, HibernateAfterTimeout, Debug1);
  	{ok, {reply, Reply, NState, {continue, _}=Continue}} ->
  	    Debug1 = reply(Name, From, Reply, NState, Debug),
  	    loop(Parent, Name, NState, CbCache, Continue, HibernateAfterTimeout, Debug1);
  	{ok, {stop, Reason, Reply, NState}} ->
  	    try
              Mod = CbCache#callback_cache.module,
  		terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, Debug)
  	    after
  		_ = reply(Name, From, Reply, NState, Debug)
  	    end;
  	Other ->
  	    handle_common_reply(Other, Parent, Name, From, Msg, CbCache, HibernateAfterTimeout, State, Debug)
      end;
  handle_msg(Msg, Parent, Name, State, CbCache, HibernateAfterTimeout, Debug) ->
      Reply = try_dispatch(Msg, CbCache, State),
      handle_common_reply(Reply, Parent, Name, undefined, Msg, CbCache, HibernateAfterTimeout, State, Debug).
  
  handle_common_reply(Reply, Parent, Name, From, Msg, CbCache, HibernateAfterTimeout, State) ->
      Mod = CbCache#callback_cache.module,
      case Reply of
  	{ok, {noreply, NState}} ->
  	    loop(Parent, Name, NState, CbCache, infinity, HibernateAfterTimeout, []);
  	{ok, {noreply, NState, TimeoutOrHibernate}}
            when ?is_timeout(TimeoutOrHibernate);
                 TimeoutOrHibernate =:= hibernate ->
  	    loop(Parent, Name, NState, CbCache, TimeoutOrHibernate, HibernateAfterTimeout, []);
  	{ok, {noreply, NState, {continue, _}=Continue}} ->
  	    loop(Parent, Name, NState, CbCache, Continue, HibernateAfterTimeout, []);
  	{ok, {stop, Reason, NState}} ->
  	    terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, []);
  	{'EXIT', Class, Reason, Stacktrace} ->
  