anchor.diff:    param_early_value = ''
     param_cache_value = ''
     subscribe_method = 'Type'
  +  key = "#{repository.imit.qualified_graph_enum_name}.#{Domgen::Naming.uppercase_constantize(graph.name)}"
  +  graph_id = "null"
  +  cache_key = "null"
  +  graph_id_param = nil
     if graph.instance_root?
  -    # Names are fully qualified so take any random data module
       entity = repository.entity_by_name(graph.instance_root)
  -    type = entity.primary_key.imit.primitive_java_type
  -    varname = "#{Domgen::Naming.camelize(entity.name)}#{entity.primary_key.name}"
  -    param = "final #{type} #{varname}"
  -    param_value = ", #{varname}"
  -    param_early_value = varname
  -    subscribe_method = 'Instance'
  +    graph_id = "#{Domgen::Naming.camelize(entity.name)}#{entity.primary_key.name}"
  +    graph_id_param = "final #{Domgen::Java.primitive_java_type(entity.primary_key, :imit, :default)} #{graph_id}"
     elsif graph.cacheable?
  -    param_cache_value = 'eTag, cacheCurrentAction, '
  +    cache_key = "#{key}.name()"
     end
  -  filter_param = ''
  -  update_param = param.dup
  -  update_param_early_value = param_early_value.dup
  -  if graph.filter_parameter
  -    p = graph.filter_parameter
  -    java_type = "#{nullability_annotation(p.nullable?)} #{Domgen::Java.java_type(p, :imit, :default)}"
  -    update_param = "#{update_param}, " if update_param.size > 0
  -    filter_param = "#{java_type} filter"
  -    update_param = "#{update_param}#{filter_param}"
  -    update_param_early_value = "#{update_param_early_value}, " if update_param_early_value.size > 0
  -    update_param_early_value = "#{update_param_early_value}filter"
  -  end
  -  suffix = "@javax.annotation.Nullable final Runnable action"
  +  filter_type = graph.filter_parameter ? "#{nullability_annotation(graph.filter_parameter.nullable?)} final #{Domgen::Java.java_type(graph.filter_parameter, :imit, :default)}" : nil
  +  filter_var = filter_type ? 'filter': 'null'
  +  filter_param = filter_type ? "#{filter_type} #{filter_var}" : nil
  +  std_param = "@javax.annotation.Nullable final Runnable action"
   %>
     @Override
  -  public boolean isSubscribedTo<%= graph.name %>(<%= param %>)
  +  public boolean isSubscribedTo<%= graph.name %>(<%= graph_id_param %>)
     {
  -    return null != find<%= subscribe_method %>GraphSubscription( <%= repository.imit.qualified_graph_enum_name %>.<%= Domgen::Naming.uppercase_constantize(graph.name) %><%= param_value %> );
  +    return null != find<%= graph.instance_root? ? 'Instance' : 'Type' %>GraphSubscription( <%= key %><%= graph.instance_root? ? ", #{graph_id}" : '' %> );
     }
   
   <% if graph.instance_root? -%>
  
positive.code: <% end -%>
  
    @Override
    public void subscribeTo<%= graph.name %>(<%= update_param %><%= update_param.size > 0 ? ", #{suffix}" : suffix %>)
    {
      final SubscriptionEntry<<%= repository.imit.qualified_graph_enum_name %>> entry =
        subscribeTo<%= subscribe_method %>Graph( <%= repository.imit.qualified_graph_enum_name %>.<%= Domgen::Naming.uppercase_constantize(graph.name) %><%= param_value %> );
      if( null != entry )
      {
        final Runnable runnable = new Runnable()
        {
          @Override
          public void run()
          {
            entry.markAsPresent();
            LOG.info( "subscribeTo<%= graph.name %>(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) completed." );
            if( null != action )
            {
              action.run();
            }
          }
        };
  <% if graph.cacheable? -%>
        final org.realityforge.replicant.client.transport.CacheEntry cacheEntry = _context.getCacheService().lookup( <%= repository.imit.qualified_graph_enum_name %>.<%= Domgen::Naming.uppercase_constantize(graph.name) %>.name() );
        final String eTag = null != cacheEntry ? cacheEntry.getETag() : null;
        final String content = null != cacheEntry ? cacheEntry.getContent() : null;
        if( null != content )
        {
          LOG.info( "Found locally cached data for graph <%= graph.name %> with etag " + eTag + "." );
        }
        final Runnable cacheCurrentAction = new Runnable()
        {
          public void run()
          {
            assert null != content;
            LOG.info( "Loading cached data for graph <%= graph.name %> with etag " + eTag );
            //TODO: Figure out how to make the bulkLoad configurable
            _context.loadCachedContent( content, runnable, true );
          }
        };
  <% end -%>
        LOG.info( "subscribeTo<%= graph.name %>(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) requested." );
        _context.remoteSubscribeTo<%= graph.name %>( <%= param_cache_value %><%= update_param_early_value %><%= update_param_early_value.size > 0 ? ', ' : '' %>runnable );
      }
  <% if graph.filter_parameter -%>
      else
      {
        update<%= graph.name %>Subscription(<%= update_param_early_value %><%= update_param_early_value.size > 0 ? ', ' : '' %>action);
      }
  <% end -%>
    }
  
  <% if graph.filter_parameter %>
    public void update<%= graph.name %>Subscription(<%= update_param %><%= update_param.size > 0 ? ", #{suffix}" : suffix %>)
    {
      final SubscriptionEntry<<%= repository.imit.qualified_graph_enum_name %>> entry =
        find<%= subscribe_method %>GraphSubscription( <%= repository.imit.qualified_graph_enum_name %>.<%= Domgen::Naming.uppercase_constantize(graph.name) %><%= param_value %> );
      if( null != entry )
      {
        final Runnable runnable = new Runnable()
        {
          @Override
          public void run()
          {
            entry.setSubscriptionUpdateInProgress( false );
            LOG.info( "update<%= graph.name %>Subscription(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) completed." );
            if( null != action )
            {
              action.run();
            }
          }
        };
        LOG.info( "update<%= graph.name %>Subscription(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) requested." );
        entry.setSubscriptionData( filter );
        entry.setSubscriptionUpdateInProgress( true );
        _context.remoteUpdate<%= graph.name %>Subscription( <%= update_param_early_value %><%= update_param_early_value.size > 0 ? ', ' : '' %>runnable );
      }
      else
      {
        LOG.warning( "update<%= graph.name %>Subscription(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) request but not currently subscribed." );
      }
    }
  <% end %>
  
    @Override
    public void unsubscribeFrom<%= graph.name %>(<%= param %><%= param.size > 0 ? ", #{suffix}" : suffix %>)
    {
      final SubscriptionEntry<<%= repository.imit.qualified_graph_enum_name %>> entry =
        unsubscribeFrom<%= subscribe_method %>Graph( <%= repository.imit.qualified_graph_enum_name %>.<%= Domgen::Naming.uppercase_constantize(graph.name) %><%= param_value %> );
      if( null != entry )
      {
        LOG.info( "unsubscribeFrom<%= graph.name %>(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) requested." );
        entry.markDeregisterInProgress();
        _context.remoteUnsubscribeFrom<%= graph.name %>( <%= param_early_value %><%= param_early_value.size > 0 ? ', ' : '' %>new Runnable()
        {
          @Override
          public void run()
          {
            entry.markAsDeregistered();
  <% if !graph.instance_root? -%>
            unload<%= graph.name %>();
  <%
    else
      entity = repository.entity_by_name(graph.instance_root)
  %>
            final <%= entity.imit.qualified_name %> e = _context.getRepository().findByID( <%= entity.imit.qualified_name %>.class, <%= varname %> );
            if( null != e )
            {
              unload<%= graph.name %>_<%= entity.name %>( e );
            }
  <% end %>
            LOG.info( "unsubscribeFrom<%= graph.name %>(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) completed." );
            if( null != action )
            {
              action.run();
            }
          }
        } );
      }
      else
      {
        LOG.info( "unsubscribeFrom<%= graph.name %>(<%= graph.instance_root? ? "\" + #{varname} + \"" : "" %>) requested but no such subscription." );
        if( null != action )
        {
          action.run();
        }
      }
    }
  
  <% if !graph.instance_root? -%>
    @Override
    public void unload<%= graph.name %>()
    {
      _context.getEntityChangeBroker().pause();
  <%
    graph.type_roots.reverse.each do |root|
      entity = repository.entity_by_name(root)
  -%>
      for ( final <%= entity.imit.qualified_name %> e : _context.getRepository().findAll( <%= entity.imit.qualified_name %>.class ) )
      {
        _context.getRepository().deregisterEntity( <%= entity.imit.qualified_name %>.class, e.get<%= entity.primary_key.name %>() );
      }
  <% end -%>
      _context.getEntityChangeBroker().resume();
    }
  <% else %>
  <%
  
negative.code: import org.realityforge.replicant.client.transport.SubscriptionEntry;
  
  public class <%= repository.imit.client_session_name %>
    extends org.realityforge.replicant.client.transport.ClientSession<<%= repository.imit.client_session_name %>, <%= repository.imit.qualified_graph_enum_name %>>
    implements <%= repository.imit.qualified_client_session_interface_name %>
  {
    private final org.realityforge.replicant.client.EntityRepository _repository;
    private final org.realityforge.replicant.client.EntityChangeBroker _broker;
  
    // TODO: We should generate  an abstract data loader that does unloads
    public <%= repository.imit.client_session_name %>( @javax.annotation.Nonnull final org.realityforge.replicant.client.transport.AbstractDataLoaderService<<%= repository.imit.client_session_name %>, <%= repository.imit.qualified_graph_enum_name %>> dataLoaderService, @javax.annotation.Nonnull final String sessionID, @javax.annotation.Nonnull final org.realityforge.replicant.client.EntityRepository repository, @javax.annotation.Nonnull final org.realityforge.replicant.client.EntityChangeBroker broker )
    {
      super( dataLoaderService, sessionID );
      _repository = repository;
      _broker = broker;
    }
  
  <%
  