package org.realityforge.replicant.client;

import javax.annotation.Nonnull;

/**
 * Interface for interacting with the local entity broker.
 */
public interface EntityChangeBroker
{
  void addChangeListener( @Nonnull EntityChangeListener listener );

  void addChangeListener( @Nonnull Class clazz, @Nonnull EntityChangeListener listener );

  void addChangeListener( @Nonnull Object object, @Nonnull EntityChangeListener listener );

  void removeChangeListener( @Nonnull EntityChangeListener listener );

  void removeChangeListener( @Nonnull Object object, @Nonnull EntityChangeListener listener );

  void removeChangeListener( @Nonnull Class clazz, @Nonnull EntityChangeListener listener );

  /**
   * Pause the broker.
   *
   * <p>Changes sent to the broker while it is paused will be cached and transmitted when it is resumed.</p>
   */
  void pause();

  /**
   * Resume the broker.
   *
   * <p>Any changes that have been delivered since pause has been invoked will be delivered on resume.</p>
   */
  void resume();

  /**
   * @return true if the broker is paused.
   */
  boolean isPaused();

  /**
   * Disable the transmission of changes to listeners.
   *
   * <p>Changes sent to the broker while it is disabled will be discarded.</p>
   *
   * <p>Typically the broker is disabled before a bulk load of an EntityRepository and re-enabled
   * after the fact.</p>
   */
  void disable();

  /**
   * Re-enable the transmission of changes to listeners after a disable.
   */
  void enable();

  /**
   * @return true if the broker is enabled.
   */
  boolean isEnabled();

  /**
   * Notify listeners that an attribute has changed.
   *
   * @param entity the entity on which the change occurred.
   * @param name the key used to identify the property that changed.
   * @param value the value that the property changed to.
   */
  void attributeChanged( @Nonnull Object entity, @Nonnull String name, @Nonnull Object value );

  /**
   * Notify listeners that an entity was removed.
   *
   * @param entity the entity removed.
   */
  void entityRemoved( @Nonnull Object entity );

  /**
   * Notify listeners that the specified entity gained a relationship to the "other" entity.
   *
   * @param entity the entity on which the relationship was updated.
   * @param name the key used to identify the relationship that changed.
   * @param other the entity that updated to relate to this entity.
   */
  void relatedAdded( @Nonnull Object entity, @Nonnull String name, @Nonnull Object other );

  /**
   * Notify listeners that the specified entity lost a relationship to the "other" entity.
   *
   * @param entity the entity on which the relationship was updated.
   * @param name the key used to identify the relationship that changed.
   * @param other the entity that updated to no longer relate to this entity.
   */
  void relatedRemoved( @Nonnull Object entity, @Nonnull String name, @Nonnull Object other );
}

@@ -182,165 +182,723 @@
 %7B%0A  
-void addChangeListener( @Nonnull EntityChangeListener listener );%0A%0A  void addChangeListener( @Nonnull Class clazz, @Nonnull EntityChangeListener listener );%0A
+/**%0A   * Add an EntityChangeListener that receives all change messages.%0A   *%0A   * @param listener the EntityChangeListener%0A   */%0A  void addChangeListener( @Nonnull EntityChangeListener listener );%0A%0A  /**%0A   * Add an EntityChangeListener that receives all change messages for models of a particular type and all sub-types.%0A   *%0A   * @param clazz the type to subscribe to.%0A   * @param listener the EntityChangeListener%0A   */%0A  void addChangeListener( @Nonnull Class clazz, @Nonnull EntityChangeListener listener );%0A%0A  /**%0A   * Add an EntityChangeListener that receives all change messages for a particular entity.%0A   *%0A   * @param entity the entity to subscribe to.%0A   * @param listener the EntityChangeListener%0A   */
 %0A  v
@@ -928,38 +928,38 @@
 @Nonnull Object 
-object
+entity
 , @Nonnull Entit
@@ -993,77 +993,439 @@
 %0A%0A  
-void removeChangeListener( @Nonnull EntityChangeListener listener );%0A
+/**%0A   * Remove an EntityChangeListener that receives all change messages.%0A   *%0A   * @param listener the EntityChangeListener%0A   */%0A  void removeChangeListener( @Nonnull EntityChangeListener listener );%0A%0A  /**%0A   * Remove an EntityChangeListener that receives all change messages for models of a particular type and all sub-types.%0A   *%0A   * @param clazz the type to subscribe to.%0A   * @param listener the EntityChangeListener%0A   */
 %0A  v
@@ -1463,21 +1463,19 @@
 ull 
-Object object
+Class clazz
 , @N
@@ -1515,16 +1515,221 @@
 ner );%0A%0A
+  /**%0A   * Remove an EntityChangeListener that receives all change messages for a particular entity.%0A   *%0A   * @param entity the entity to subscribe to.%0A   * @param listener the EntityChangeListener%0A   */%0A
   void r
@@ -1754,35 +1754,37 @@
 r( @Nonnull 
-Class clazz
+Object entity
 , @Nonnull E

Improve the javadocs