/**
 * Copyright (C) 2009 - 2010 by OpenGamma Inc.
 *
 * Please see distribution for license.
 */
package com.opengamma.id;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.opengamma.util.ArgumentChecker;

/**
 * A base class for a service (e.g. a {@link PositionMaster} or {@link SecurityMaster} that delegates functionality
 * based on the scheme of a unique identifier.
 * 
 * @param <T> type of the delegate.
 */
public class DelegateByScheme<T> {

  private final T _defaultDelegate;
  private final Map<String, T> _schemeToDelegateMap = new ConcurrentHashMap<String, T>();

  protected DelegateByScheme(final T defaultDelegate) {
    ArgumentChecker.notNull(defaultDelegate, "defaultDelegate");
    _defaultDelegate = defaultDelegate;
  }

  protected DelegateByScheme(final T defaultDelegate, final Map<String, T> delegates) {
    ArgumentChecker.notNull(defaultDelegate, "defaultDelegate");
    ArgumentChecker.notNull(delegates, "delegates");
    _defaultDelegate = defaultDelegate;
    for (Map.Entry<String, T> delegate : delegates.entrySet()) {
      registerDelegate(delegate.getKey(), delegate.getValue());
    }
  }

  protected T chooseDelegate(final UniqueIdentifier uid) {
    final T delegate = _schemeToDelegateMap.get(uid.getScheme());
    return (delegate != null) ? delegate : _defaultDelegate;
  }

  protected T getDefaultDelegate() {
    return _defaultDelegate;
  }

  protected Collection<T> getDelegates() {
    return _schemeToDelegateMap.values();
  }

  public void registerDelegate(final String scheme, final T delegate) {
    ArgumentChecker.notNull(scheme, "scheme");
    ArgumentChecker.notNull(delegate, "delegate");
    _schemeToDelegateMap.put(scheme, delegate);
  }

  public void removeDelegate(final String scheme) {
    ArgumentChecker.notNull(scheme, "scheme");
    _schemeToDelegateMap.remove(scheme);
  }

}

@@ -145,16 +145,17 @@
 llection
+s
 ;%0Aimport
@@ -216,16 +216,59 @@
 HashMap;
+%0Aimport java.util.concurrent.ConcurrentMap;
 %0A%0Aimport
@@ -316,166 +316,200 @@
 %0A * 
-A base class for a service (e.g. a %7B@link PositionMaster%7D or %7B@link SecurityMaster%7D that delegates functionality%0A * based on the scheme of a unique identifier
+Delegator that switches between multiple implementations based on the scheme of a unique identifier.%0A * %3Cp%3E%0A * This class can be used on its own, however it is best used by creating a subclass
 .%0A *
@@ -523,16 +523,21 @@
 aram %3CT%3E
+  the
  type of
@@ -549,17 +549,16 @@
 delegate
-.
 %0A */%0Apub
@@ -596,41 +596,130 @@
 %0A%0A  
-private final T _defaultDelegate;
+/**%0A   * The default delegate.%0A   */%0A  private final T _defaultDelegate;%0A  /**%0A   * The map of registered delegates.%0A   */
 %0A  p
@@ -727,24 +727,34 @@
 ivate final 
+Concurrent
 Map%3CString, 
@@ -816,16 +816,168 @@
  T%3E();%0A%0A
+  /**%0A   * Creates an instance specifying the default delegate.%0A   * @param defaultDelegate  the delegate to use when no scheme matches, not null%0A   */%0A
   protec
@@ -1126,32 +1126,261 @@
 tDelegate;%0A  %7D%0A%0A
+  /**%0A   * Creates an instance specifying the default delegate.%0A   * @param defaultDelegate  the delegate to use when no scheme matches, not null%0A   * @param delegates  the map of delegates by scheme to switch on, not null%0A   */%0A
   protected Dele
@@ -1755,357 +1755,1133 @@
 %0A%0A  
-protected T chooseDelegate(final UniqueIdentifier uid) %7B%0A    final T delegate = _schemeToDelegateMap.get(uid.getScheme());%0A    return (delegate != null) ? delegate : _defaultDelegate;%0A  %7D%0A%0A  protected T getDefaultDelegate() %7B%0A    return _defaultDelegate;%0A  %7D%0A%0A  protected Collection%3CT%3E getDelegates() %7B%0A    return _schemeToDelegateMap.values();%0A  %7D%0A
+//-------------------------------------------------------------------------%0A  /**%0A   * Gets the default delegate.%0A   * @return the default delegate, not null%0A   */%0A  protected T getDefaultDelegate() %7B%0A    return _defaultDelegate;%0A  %7D%0A%0A  /**%0A   * Gets the map of registered delegates.%0A   * @return the registered delegates, unmodifiable, not null%0A   */%0A  protected Map%3CString, T%3E getDelegates() %7B%0A    return Collections.unmodifiableMap(_schemeToDelegateMap);%0A  %7D%0A%0A  //-------------------------------------------------------------------------%0A  /**%0A   * Chooses the delegate for a specific unique identifier.%0A   * @param uid  the unique identifier, not null%0A   * @return the delegate, not null%0A   */%0A  protected T chooseDelegate(final UniqueIdentifier uid) %7B%0A    final T delegate = _schemeToDelegateMap.get(uid.getScheme());%0A    return (delegate != null) ? delegate : _defaultDelegate;%0A  %7D%0A%0A  //-------------------------------------------------------------------------%0A  /**%0A   * Registers a delegate based on a scheme.%0A   * @param scheme  the scheme to match, not null%0A   * @param delegate  the delegate to use, not null%0A   */
 %0A  p
@@ -3100,16 +3100,126 @@
 );%0A  %7D%0A%0A
+  /**%0A   * Removes a delegate from those being used.%0A   * @param scheme  the scheme to remove, not null%0A   */%0A
   public

Create SecuritySource