[jboss-cvs] JBossAS SVN: r99462 - in projects/kernel/branches: resolver/dependency/src/main/java/org/jboss/dependency/plugins and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Jan 15 07:19:29 EST 2010


Author: kabir.khan at jboss.com
Date: 2010-01-15 07:19:28 -0500 (Fri, 15 Jan 2010)
New Revision: 99462

Added:
   projects/kernel/branches/resolver/
   projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java
   projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml
   projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml
   projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml
   projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml
   projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml
   projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml
   projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml
Removed:
   projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java
   projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java
Log:
Branch to work on the resolvers


Copied: projects/kernel/branches/resolver (from rev 99451, projects/kernel/trunk)

Deleted: projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java
===================================================================
--- projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,2541 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.dependency.plugins;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.jboss.dependency.plugins.action.ControllerContextAction;
-import org.jboss.dependency.plugins.action.SimpleControllerContextAction;
-import org.jboss.dependency.plugins.tracker.AbstractContextRegistry;
-import org.jboss.dependency.spi.CallbackItem;
-import org.jboss.dependency.spi.Controller;
-import org.jboss.dependency.spi.ControllerContext;
-import org.jboss.dependency.spi.ControllerContextActions;
-import org.jboss.dependency.spi.ControllerMode;
-import org.jboss.dependency.spi.ControllerState;
-import org.jboss.dependency.spi.ControllerStateModel;
-import org.jboss.dependency.spi.DependencyInfo;
-import org.jboss.dependency.spi.DependencyItem;
-import org.jboss.dependency.spi.LifecycleCallbackItem;
-import org.jboss.dependency.spi.asynchronous.AsynchronousController;
-import org.jboss.dependency.spi.graph.GraphController;
-import org.jboss.dependency.spi.graph.LookupStrategy;
-import org.jboss.dependency.spi.graph.SearchInfo;
-import org.jboss.dependency.spi.tracker.ContextFilter;
-import org.jboss.dependency.spi.tracker.ContextQueries;
-import org.jboss.dependency.spi.tracker.ContextRegistry;
-import org.jboss.util.JBossObject;
-import org.jboss.util.collection.CollectionsFactory;
-
-/**
- * Abstract controller.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
- * @version $Revision$
- */
-public class AbstractController extends JBossObject implements Controller, GraphController, AbstractControllerMBean, AsynchronousController, ContextQueries, ContextRegistry
-{
-   /** The lock */
-   private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-
-   /**
-    * The executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
-    * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy 
-    */
-   private Executor executor;
-
-   /** Whether we are shutdown */
-   private boolean shutdown = false;
-
-   /** The controller state model */
-   private AbstractControllerStateModel stateModel = new MapControllerStateModel();
-   
-   /** All contexts by name Map<Object, ControllerContext> */
-   private Map<Object, ControllerContext> allContexts = new ConcurrentHashMap<Object, ControllerContext>();
-
-   /** The contexts by state Map<ControllerState, Set<ControllerContext>> */
-   private Map<ControllerState, Set<ControllerContext>> contextsByState = new ConcurrentHashMap<ControllerState, Set<ControllerContext>>();
-
-   /** The error contexts Map<Name, ControllerContext> */
-   private Map<Object, ControllerContext> errorContexts = new ConcurrentHashMap<Object, ControllerContext>();
-
-   /** The contexts that are currently being resolved/installed */
-   private Set<ControllerContext> installing = new CopyOnWriteArraySet<ControllerContext>();
-   
-   /** The contexts that are currently being installed by the executor */
-   ContextsInstalledByExecutor contextsInstalledByExecutor = new ContextsInstalledByExecutor();
-   
-   /** The parent controller */
-   private AbstractController parentController;
-
-   /** The child controllers */
-   private Set<AbstractController> childControllers = new CopyOnWriteArraySet<AbstractController>();
-
-   /** The callback items */
-   private Map<Object, Set<CallbackItem<?>>> installCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
-   private Map<Object, Set<CallbackItem<?>>> uninstallCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
-
-   /** Whether an on demand context has been enabled */
-   private boolean onDemandEnabled = true;
-
-   /** Whether stats are enabled */
-   private boolean collectStats = false;
-   
-   /** The install stats */
-   private volatile StateStatistics installStats = null;
-
-   /** The context tracker */
-   private AbstractContextRegistry registry;
-
-   /**
-    * Create an abstract controller
-    */
-   public AbstractController()
-   {
-      addState(ControllerState.NOT_INSTALLED, null);
-      addState(ControllerState.PRE_INSTALL, null);
-      addState(ControllerState.DESCRIBED, null);
-      addState(ControllerState.INSTANTIATED, null);
-      addState(ControllerState.CONFIGURED, null);
-      addState(ControllerState.CREATE, null);
-      addState(ControllerState.START, null);
-      addState(ControllerState.INSTALLED, null);
-
-      registry = createContextRegistry();
-   }
-
-   /**
-    * Create context registry.
-    *
-    * @return the context registry
-    */
-   protected AbstractContextRegistry createContextRegistry()
-   {
-      return new AbstractContextRegistry(this);
-   }
-
-   /**
-    * Set the executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
-    * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy.
-    *
-    * @param executor the executor
-    */
-   public void setExecutor(Executor executor)
-   {
-      // TODO - security
-      lockWrite();
-      try
-      {
-         this.executor = executor;
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Get the executor.
-    *
-    * @return the executor
-    */
-   public Executor getExecutor()
-   {
-      // TODO - security
-      return getExecutionEnvironment();
-   }
-
-   /**
-    * Get the executor internal w/o security check.
-    *
-    * @return the executor
-    */
-   protected Executor getExecutionEnvironment()
-   {
-      lockRead();
-      try
-      {
-         return executor;
-      }
-      finally
-      {
-         unlockRead();
-      }
-   }
-
-   public boolean isShutdown()
-   {
-      lockWrite();
-      try
-      {
-         return shutdown;
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Check whether the controller is shutdown
-    *
-    * @throws IllegalStateException when already shutdown
-    */
-   public void checkShutdown()
-   {
-      lockWrite();
-      try
-      {
-         if (shutdown)
-            throw new IllegalStateException("Already shutdown");
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   public void shutdown()
-   {
-      lockWrite();
-      try
-      {
-         Set<AbstractController> children = getControllers();
-         if (children != null && children.isEmpty() == false)
-         {
-            for (AbstractController child : children)
-            {
-               try
-               {
-                  child.shutdown();
-               }
-               catch (Throwable t)
-               {
-                  log.warn("Error during shutdown of child: " + child, t);
-               }
-            }
-         }
-
-         Set<ControllerContext> contexts = getAllContexts();
-         if (contexts != null && contexts.isEmpty() == false)
-         {
-            for (ControllerContext context : contexts)
-            {
-               try
-               {
-                  uninstall(context.getName());
-               }
-               catch (Throwable t)
-               {
-                  log.warn("Error during shutdown while uninstalling: " + context, t);
-               }
-            }
-         }
-      }
-      finally
-      {
-         shutdown = true;
-         unlockWrite();
-      }
-
-   }
-
-   /**
-    * Get the collectStats.
-    * 
-    * @return the collectStats.
-    */
-   public boolean isCollectStats()
-   {
-      return collectStats;
-   }
-
-   /**
-    * Set the collectStats.
-    * 
-    * @param collectStats the collectStats.
-    */
-   public void setCollectStats(boolean collectStats)
-   {
-      this.collectStats = collectStats;
-   }
-
-   public String listStateTimes(boolean details)
-   {
-      synchronized (this)
-      {
-         if (installStats == null)
-            return "No statistics available";
-         return installStats.listTimes(details);
-      }
-   }
-
-   public void addState(ControllerState state, ControllerState before)
-   {
-      lockWrite();
-      try
-      {
-         if (stateModel.addState(state, before))
-         {
-            Set<ControllerContext> contexts =  new CopyOnWriteArraySet<ControllerContext>();
-            contextsByState.put(state, contexts);
-         }
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Add controller context.
-    *
-    * This is normally used when switching from top
-    * level controller to a scoped one.
-    *
-    * @param context the controller context
-    */
-   void addControllerContext(ControllerContext context)
-   {
-      lockWrite();
-      try
-      {
-         registerControllerContext(context);
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Remove controller context.
-    *
-    * This is normally used when switching from scoped
-    * level controller to a top one.
-    *
-    * @param context the controller context
-    */
-   void removeControllerContext(ControllerContext context)
-   {
-      lockWrite();
-      try
-      {
-         unregisterControllerContext(context);
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Get the parent controller.
-    *
-    * @return the parent controller
-    */
-   public AbstractController getParentController()
-   {
-      return parentController;
-   }
-
-   /**
-    * Set the parent controller.
-    *
-    * @param parentController the parent controller
-    */
-   protected void setParentController(AbstractController parentController)
-   {
-      this.parentController = parentController;
-   }
-
-   /**
-    * Get child controllers.
-    *
-     * @return the child controllers
-    */
-   public Set<AbstractController> getControllers()
-   {
-      lockRead();
-      try
-      {
-         return Collections.unmodifiableSet(childControllers);
-      }
-      finally
-      {
-         unlockRead();
-      }
-   }
-
-   /**
-    * Add child controller.
-    *
-    * @param controller the child controller
-    * @return true if equal controller has been already added, see Set.add usage 
-    */
-   public boolean addController(AbstractController controller)
-   {
-      lockWrite();
-      try
-      {
-         return childControllers.add(controller);
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Remove child controller.
-    *
-    * @param controller the child controller
-    * @return true if equal controller was present, see Set.remove usage
-    */
-   public boolean removeController(AbstractController controller)
-   {
-      lockWrite();
-      try
-      {
-         return childControllers.remove(controller);
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Whether the controller has contexts
-    *
-    * @return true when there are registered contexts
-    */
-   public boolean isActive()
-   {
-      lockRead();
-      try
-      {
-         // is this active
-         if (allContexts.isEmpty() == false)
-            return true;
-
-         // any of the children still active
-         for (AbstractController child : getControllers())
-         {
-            if (child.isActive())
-               return true;
-         }
-
-         return false;
-      }
-      finally
-      {
-         unlockRead();
-      }
-   }
-
-   public ControllerContext getContext(Object name, ControllerState state, SearchInfo info)
-   {
-      if (info == null)
-         throw new IllegalArgumentException("Null search info.");
-
-      LookupStrategy strategy = info.getStrategy();
-      if (strategy == null)
-         throw new IllegalArgumentException("AbstractController doesn't implement this search info: " + info);
-
-      if (log.isTraceEnabled())
-         log.trace("Executing search " + info.getType());
-
-      return strategy.getContext(this, name, state);
-   }
-
-   /**
-    * Get all the contexts.
-    * In state decending order.
-    *
-    * @return all contexts
-    */
-   public Set<ControllerContext> getAllContexts()
-   {
-      lockRead();
-      try
-      {
-         LinkedHashSet<ControllerContext> result = new LinkedHashSet<ControllerContext>();
-         ListIterator<ControllerState> it = stateModel.listIteraror();
-         if (it.hasNext())
-         {
-            result.addAll(getContextsByState(it.next()));
-            while (it.hasPrevious())
-            {
-               result.addAll(getContextsByState(it.previous()));
-            }
-         }
-         result.addAll(errorContexts.values());
-         return result;
-      }
-      finally
-      {
-         unlockRead();
-      }
-   }
-
-   public ControllerContext getContext(Object name, ControllerState state)
-   {
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-
-      lockRead();
-      try
-      {
-         ControllerContext result = getRegisteredControllerContext(name, false);
-         if (result == null && name instanceof Class) // check type matching
-            result = getContextByClass((Class<?>)name);
-
-         if (result != null && state != null && stateModel.isBeforeState(result.getState(), state))
-         {
-            return null;
-         }
-         return result;
-      }
-      finally
-      {
-         unlockRead();
-      }
-   }
-
-   public ControllerContext getInstalledContext(Object name)
-   {
-      return getContext(name, ControllerState.INSTALLED);
-   }
-
-   public Set<ControllerContext> getNotInstalled()
-   {
-      lockWrite();
-      try
-      {
-         Set<ControllerContext> result = new HashSet<ControllerContext>(errorContexts.values());
-         for (ControllerState state : stateModel)
-         {
-            if (ControllerState.INSTALLED.equals(state))
-               break;
-            
-            Set<ControllerContext> stateContexts = getContextsByState(state);
-            result.addAll(stateContexts);
-         }
-         return result;
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   public ControllerStateModel getStates()
-   {
-      return stateModel;
-   }
-
-   public Set<ControllerContext> getContextsByState(ControllerState state)
-   {
-      return contextsByState.get(state);
-   }
-
-   public void install(ControllerContext context) throws Throwable
-   {
-      boolean trace = log.isTraceEnabled();
-
-      if (context == null)
-         throw new IllegalArgumentException("Null context");
-
-      Object name = context.getName();
-      if (name == null)
-         throw new IllegalArgumentException("Null name " + context.toShortString());
-
-      install(context, trace);
-   }
-
-   public void change(ControllerContext context, ControllerState state) throws Throwable
-   {
-      boolean trace = log.isTraceEnabled();
-
-      if (context == null)
-         throw new IllegalArgumentException("Null context");
-
-      if (state == null)
-         throw new IllegalArgumentException("Null state");
-
-      change(context, state, trace);
-   }
-
-   public void enableOnDemand(ControllerContext context) throws Throwable
-   {
-      boolean trace = log.isTraceEnabled();
-
-      if (context == null)
-         throw new IllegalArgumentException("Null context");
-
-      enableOnDemand(context, trace);
-   }
-
-   public ControllerContext uninstall(Object name)
-   {
-      return uninstall(name, 0);
-   }
-
-   /**
-    * Get controller id - impl detail.
-    * It should be unique.
-    *
-    * @return controller's id
-    */
-   protected String getId()
-   {
-      StringBuffer buffer = new StringBuffer();
-      buffer.append(getClass().getSimpleName());
-      buffer.append("[").append(System.identityHashCode(this)).append("]");
-      return buffer.toString();
-   }
-
-   public void addAlias(Object alias, Object original) throws Throwable
-   {
-      Map<ControllerState, ControllerContextAction> map = createAliasActions();
-      ControllerContextActions actions = new AbstractControllerContextActions(map);
-      AliasControllerContext context = new InnerAliasControllerContext(alias, getId(), original, actions);
-      preAliasInstall(context);
-      install(context);
-      // is alias in error
-      Throwable error = context.getError();
-      if (error != null)
-         throw error;      
-      if (ControllerState.ERROR.equals(context.getState()))
-         throw new IllegalArgumentException("Alias " + context + " is in error.");
-   }
-
-   /**
-    * Create alias controller context actions.
-    *
-    * @return the alias controller context actions
-    */
-   protected Map<ControllerState, ControllerContextAction> createAliasActions()
-   {
-      return Collections.<ControllerState, ControllerContextAction>singletonMap(ControllerState.INSTALLED, new AliasControllerContextAction());
-   }
-
-   /**
-    * Apply pre install - e.g. scope key in scoped controller.
-    *
-    * @param aliasContext the new alias context
-    */
-   protected void preAliasInstall(ControllerContext aliasContext)
-   {
-   }
-
-   public void removeAlias(Object alias)
-   {
-      uninstall(alias + "_Alias_" + getId());
-   }
-
-   /**
-    * Uninstall the context.
-    *
-    * @param name the context name
-    * @param level the controller level
-    * @return uninstalled controller context
-    */
-   // todo - some better way to find context's by name
-   // currently the first one found is used
-   protected ControllerContext uninstall(Object name, int level)
-   {
-      boolean trace = log.isTraceEnabled();
-
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-
-      lockWrite();
-      try
-      {
-         if (errorContexts.remove(name) != null && trace)
-            log.trace("Tidied up context in error state: " + name);
-
-         ControllerContext context = getRegisteredContextAndInterruptAsynchronousInstall(name);
-         if (context != null)
-         {
-            if (trace)
-               log.trace("Uninstalling " + context.toShortString());
-
-            // get a hold on possible parent before its nullified in uninstall
-            AbstractController parent = getParentController();
-
-            uninstallContext(context, stateModel.getInitialState(), trace);
-
-            try
-            {
-               unregisterControllerContext(context);
-            }
-            catch (Throwable t)
-            {
-               log.warn("Error unregistering context: " + context.toShortString() + " with name: " + name);
-            }
-
-            while (parent != null)
-            {
-               try
-               {
-                  parent.unregisterControllerContext(context);
-               }
-               catch (Throwable t)
-               {
-                  log.warn("Error unregistering context in parent controller: " + context.toShortString() + " with name: " + name);
-               }
-               parent = parent.getParentController();
-            }
-         }
-         else
-         {
-            for (AbstractController controller : getControllers())
-            {
-               context = controller.uninstall(name, level + 1);
-               if (context != null)
-                  break;
-            }
-         }
-         if (context == null && level == 0)
-            throw new IllegalStateException("Not installed: " + name);
-         return context;
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   
-   /**
-    * Obtains the context, having interrupted its installation process if it is an asynchronous context 
-    * currently being installed
-    * @param name The name of the context 
-    * @return the context or null if not found
-    */
-   private ControllerContext getRegisteredContextAndInterruptAsynchronousInstall(Object name)
-   {
-      ControllerContext context = getRegisteredControllerContext(name, false);
-      if (context != null)
-      {
-         contextsInstalledByExecutor.interruptTaskAndBlock(context, this);
-         context = getRegisteredControllerContext(name, false);
-      }
-      return context;
-   }
-       
-   /**
-    * Install a context
-    *
-    * @param context the context
-    * @param trace   whether trace is enabled
-    * @throws Throwable for any error
-    */
-   protected void install(ControllerContext context, boolean trace) throws Throwable
-   {
-      lockWrite();
-      try
-      {
-         checkShutdown();
-
-         Object name = context.getName();
-
-         // Check the name is not already registered
-         if (getRegisteredControllerContext(name, false) != null)
-            throw new IllegalStateException(name + " is already installed.");
-
-         // Check any alias is not already registered
-         Set<Object> aliases = context.getAliases();
-         if (aliases != null && aliases.isEmpty() == false)
-         {
-            for (Object alias : aliases)
-            {
-               if (getRegisteredControllerContext(alias, false) != null)
-                  throw new IllegalStateException(alias + " an alias of " + name + " is already installed.");
-            }
-         }
-
-         // set the required state
-         ControllerMode mode = context.getMode();
-         context.setRequiredState(mode.getRequiredState());
-
-         if (trace)
-            log.trace("Installing " + context.toShortString());
-
-         context.setController(this);
-         DependencyInfo dependencies = context.getDependencyInfo();
-         if (trace)
-         {
-            String dependsOn = "[]";
-            if (dependencies != null)
-            {
-               try
-               {
-                  Set<DependencyItem> set = dependencies.getIDependOn(null);
-                  if (set != null)
-                     dependsOn = set.toString();
-               }
-               catch (Throwable t)
-               {
-                  log.warn("Exception getting dependencies: " + t);
-                  dependsOn = null;
-               }
-            }
-            if (dependsOn != null)
-               log.trace("Dependencies for " + name + ": " + dependsOn);
-         }
-
-         boolean ok = incrementState(context, trace);
-         if (ok)
-         {
-            try
-            {
-               registerControllerContext(context);
-            }
-            catch (Throwable t)
-            {
-               // This is probably unreachable? But let's be paranoid
-               ok = false;
-               throw t;
-            }
-         }
-         if (ok)
-         {
-            resolveContexts(trace);
-         }
-         else
-         {
-            errorContexts.remove(context);
-            throw context.getError();
-         }
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Change a context's state
-    *
-    * @param context the context
-    * @param state   the required state
-    * @param trace   whether trace is enabled
-    * @throws Throwable for any error
-    */
-   protected void change(ControllerContext context, ControllerState state, boolean trace) throws Throwable
-   {
-      lockWrite();
-      try
-      {
-         checkShutdown();
-
-         if (!stateModel.isValidState(state))
-            throw new IllegalArgumentException("Unknown state: " + state);
-
-         if (context.getState().equals(state))
-         {
-            if (trace)
-               log.trace("No change required toState=" + state.getStateString() + " " + context.toShortString());
-            return;
-         }
-
-         if (trace)
-            log.trace("Change toState=" + state.getStateString() + " " + context.toShortString());
-
-         context.setRequiredState(state);
-
-         if (stateModel.isBeforeState(context.getState(), state))
-            resolveContexts(trace);
-         else
-         {
-            while (stateModel.isAfterState(context.getState(), state))
-            {
-               uninstallContext(context, trace);
-            }
-         }
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Enable an on demand context
-    *
-    * @param context the context
-    * @param trace   whether trace is enabled
-    * @throws Throwable for any error
-    */
-   protected void enableOnDemand(ControllerContext context, boolean trace) throws Throwable
-   {
-      lockWrite();
-      try
-      {
-         checkShutdown();
-
-         if (ControllerMode.ON_DEMAND.equals(context.getMode()) == false)
-            throw new IllegalStateException("Context is not ON DEMAND: " + context.toShortString());
-
-         // Sanity check
-         getRegisteredControllerContext(context.getName(), true);
-
-         // Already done
-         if (ControllerState.INSTALLED.equals(context.getRequiredState()))
-            return;
-         context.setRequiredState(ControllerState.INSTALLED);
-
-         if (trace)
-            log.trace("Enable onDemand: " + context.toShortString());
-
-         onDemandEnabled = true;
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Increment state<p>
-    * <p/>
-    * This method must be invoked with the write lock taken.
-    *
-    * @param context the context
-    * @param trace   whether trace is enabled
-    * @return whether the suceeded
-    */
-   protected boolean incrementState(ControllerContext context, boolean trace)
-   {
-      ControllerState fromState = context.getState();
-
-      Controller fromController = context.getController();
-      Set<ControllerContext> fromContexts;
-
-      ControllerState toState;
-      if (ControllerState.ERROR.equals(fromState))
-      {
-         ControllerState initialState = stateModel.getInitialState();
-         errorContexts.remove(context);
-         Throwable error = null;
-         unlockWrite();
-         try
-         {
-            install(context, ControllerState.ERROR, initialState);
-         }
-         catch (Throwable t)
-         {
-            error = t;
-         }
-         finally
-         {
-            lockWrite();
-            if (error != null)
-            {
-               log.error("Error during initial installation: " + context.toShortString(), error);
-               context.setError(error);
-               errorContexts.put(context.getName(), context);
-               return false;
-            }
-         }
-         Set<ControllerContext> notInstalled = fromController.getContextsByState(initialState);
-         notInstalled.add(context);
-         context.setState(initialState);
-         return true;
-      }
-      else
-      {
-         fromContexts = fromController.getContextsByState(fromState);
-         if (fromContexts.contains(context) == false)
-            throw new IllegalStateException("Context not found in previous state (" + fromState + "): " + context.toShortString());
-         toState = stateModel.getNextState(fromState);
-         if (toState == null)
-            throw new IllegalStateException("No state after " + fromState);
-      }
-
-      unlockWrite();
-      Throwable error = null;
-      try
-      {
-         install(context, fromState, toState);
-
-         if (fromContexts != null)
-            fromContexts.remove(context);
-         Controller toController = context.getController();
-         Set<ControllerContext> toContexts = toController.getContextsByState(toState);
-         toContexts.add(context);
-         context.setState(toState);
-
-         handleInstallLifecycleCallbacks(context, toState);
-         resolveCallbacks(context, toState, true);
-      }
-      catch (Throwable t)
-      {
-         error = t;
-      }
-      finally
-      {
-         lockWrite();
-         if (error != null)
-         {
-            log.error("Error installing to " + toState.getStateString() + ": " + context.toShortString(), error);
-            uninstallContext(context, stateModel.getInitialState(), trace);
-            errorContexts.put(context.getName(), context);
-            context.setError(error);
-            return false;
-         }
-      }
-
-      return true;
-   }
-
-   /**
-    * Resolve unresolved contexts<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param trace whether trace is enabled
-    */
-   protected void resolveContexts(boolean trace)
-   {
-      boolean resolutions = true;
-      while (resolutions || onDemandEnabled)
-      {
-         onDemandEnabled = false;
-         resolutions = false;
-         for (ControllerState fromState : stateModel)
-         {
-            ControllerState toState = stateModel.getNextState(fromState);
-            if (resolveContexts(fromState, toState, trace))
-            {
-               resolutions = true;
-               break;
-            }
-         }
-      }
-
-      if (trace)
-      {
-         for (ControllerState state : stateModel)
-         {
-            ControllerState nextState = stateModel.getNextState(state);
-            Set<ControllerContext> stillUnresolved = getContextsByState(state);
-            if (stillUnresolved.isEmpty() == false)
-            {
-               for (ControllerContext ctx : stillUnresolved)
-               {
-                  if (advance(ctx))
-                     log.trace("Still unresolved " + nextState.getStateString() + ": " + ctx);
-               }
-            }
-         }
-      }
-
-      // resolve child controllers
-      for (AbstractController controller : childControllers)
-      {
-         controller.lockWrite();
-         try
-         {
-            controller.resolveContexts(trace);
-         }
-         finally
-         {
-            controller.unlockWrite();
-         }
-      }
-   }
-
-   /**
-    * Resolve contexts<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param fromState the from state
-    * @param toState   the to state
-    * @param trace     whether trace is enabled
-    * @return true when there were resolutions
-    */
-   protected boolean resolveContexts(ControllerState fromState, ControllerState toState, boolean trace)
-   {
-      boolean resolutions = false;
-      Set<ControllerContext> unresolved = getContextsByState(fromState);
-      Set<ControllerContext> resolved = resolveContexts(unresolved, fromState, toState, trace);
-      if (resolved.isEmpty() == false)
-      {
-         Set<ControllerContext> toProcess = new HashSet<ControllerContext>();
-         for (ControllerContext context : resolved)
-         {
-            Object name = context.getName();
-            if (fromState.equals(context.getState()) == false)
-            {
-               if (trace)
-                  log.trace("Skipping already installed " + name + " for " + toState.getStateString());
-               installing.remove(context);
-            }
-            else
-            {
-               toProcess.add(context);
-            }
-         }
-         try
-         {
-            if (toProcess.isEmpty() == false)
-            {
-               for (Iterator<ControllerContext> iter = toProcess.iterator(); iter.hasNext(); )
-               {
-                  ControllerContext context = iter.next();
-                  iter.remove();
-                  Object name = context.getName();
-                  try
-                  {
-                     if (fromState.equals(context.getState()) == false)
-                     {
-                        if (trace)
-                           log.trace("Skipping already installed " + name + " for " + toState.getStateString());
-                     }
-                     else
-                     {
-                        if (trace)
-                           log.trace("Dependencies resolved " + name + " for " + toState.getStateString());
-
-                        if (executeOrIncrementStateDirectly(context, trace))
-                        {
-                           resolutions = true;
-                           if (trace)
-                              log.trace(name + " " + toState.getStateString());
-                        }
-                        
-                     }
-                  }
-                  finally
-                  {
-                     installing.remove(context);
-                  }
-               }
-            }
-         }
-         finally
-         {
-            // If we get here something has gone seriously wrong,
-            // but try to tidyup as much state as possible
-            if (toProcess.isEmpty() == false)
-            {
-               for (ControllerContext context : toProcess)
-                  installing.remove(context);
-            }
-         }
-      }
-
-      return resolutions;
-   }
-   
-   /**
-    * Increment state in the current thread, or asynchonously if the context has {@link ControllerMode#ASYNCHRONOUS} and we find an executor<p>
-    * <p/>
-    * This method must be invoked with the write lock taken.
-    *
-    * @param context the context
-    * @param trace   whether trace is enabled
-    * @return whether the increment suceeded. If the context could be incremented asynchronously false is returned
-    */
-   private boolean executeOrIncrementStateDirectly(ControllerContext context, boolean trace)
-   {
-      boolean asynch = contextsInstalledByExecutor.shouldInstallAsynchronously(context);
-      
-      if (asynch)
-      {
-         if (executor == null)
-         {
-            Object ctx = trace ? context : context.getName();
-            log.warn("No executor in controller " + this + " to use installing asynchronous context " + ctx);
-            
-         }
-
-         Executor foundExecutor = searchForExecutor();
-         if (foundExecutor != null)
-         {
-            InstallControllerContextTask task = new InstallControllerContextTask(context, trace);
-            contextsInstalledByExecutor.markForTaskExecution(context, task);
-
-            if (trace)
-               log.trace("Recorded for asynchronous installation " + context.getName());
-            
-            try
-            {
-               foundExecutor.execute(task);
-               return false;
-            }
-            catch(RejectedExecutionException e)
-            {
-               Object ctx = trace ? context : context.getName();
-               log.warn("Asynchronous execution rejected by executor for context " + ctx + ":" + e.getMessage());
-               contextsInstalledByExecutor.disassociateWithTask(context);
-            }
-         }
-      }
-
-      return incrementState(context, trace);
-   }
-   
-   /**
-    * Return the executor stored in this controller or in its parent hierarchy. The nearest executor is returned.
-    * <p/>
-    * This method must be called with the write or read lock taken
-    * @return The found executor
-    */
-   protected Executor searchForExecutor()
-   {
-      if (executor != null)
-      {
-         return executor;
-      }
-      AbstractController parent = getParentController();
-      if (parent != null)
-      {
-        try
-        {
-           parent.lockRead();
-           return parent.searchForExecutor();
-        }
-        finally
-        {
-           parent.unlockRead();
-        }
-      }
-      return null;
-   }
-
-   /**
-    * Resolve contexts<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param contexts the contexts
-    * @param fromState the from state
-    * @param toState   the to state
-    * @param trace    whether trace is enabled
-    * @return the set of resolved contexts
-    */
-   protected Set<ControllerContext> resolveContexts(Set<ControllerContext> contexts, ControllerState fromState, ControllerState toState, boolean trace)
-   {
-      HashSet<ControllerContext> result = new HashSet<ControllerContext>();
-
-      if (contexts.isEmpty() == false)
-      {
-         for (ControllerContext ctx : contexts)
-         {
-            Object name = ctx.getName();
-            if (fromState.equals(ctx.getState()) == false)
-            {
-               if (trace)
-                  log.trace("Skipping already installed " + name + " for " + toState.getStateString());
-            }
-            else if (contextsInstalledByExecutor.isInstalledByOtherThread(ctx))
-            {
-               if (trace)
-                  log.trace("Installed by other thread " + name);
-            }
-            else if (installing.add(ctx) == false)
-            {
-               if (trace)
-                  log.trace("Already installing " + name + " for " + toState.getStateString());
-            }
-            else if (contextsInstalledByExecutor.isBeingInstalled(ctx) == true)
-            {
-               if (trace)
-                  log.trace("Already installing " + name + " for " + toState.getStateString());
-               installing.remove(ctx);
-            }
-            else if (advance(ctx))
-            {
-               try
-               {
-                  if (resolveDependencies(ctx, toState))
-                     result.add(ctx);
-                  else
-                     installing.remove(ctx);
-               }
-               catch (Throwable error)
-               {
-                  installing.remove(ctx);
-                  log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx.toShortString(), error);
-                  uninstallContext(ctx, stateModel.getInitialState(), trace);
-                  errorContexts.put(ctx.getName(), ctx);
-                  ctx.setError(error);
-               }
-            }
-            else
-            {
-               installing.remove(ctx);
-            }
-         }
-      }
-
-      return result;
-   }
-   
-   /**
-    * See if the context has its dependencies resolved to move to the given state.
-    * <p/>
-    * This method must be invoked with the write lock taken
-    * 
-    * @param ctx The context
-    * @param state The state we want to move to
-    * @return true if the dependencies are resolved
-    */
-   private boolean resolveDependencies(ControllerContext ctx, ControllerState state)
-   {
-      DependencyInfo dependencies = ctx.getDependencyInfo();
-      return dependencies == null || dependencies.resolveDependencies(this, state);
-   }
-
-   /**
-    * Uninstall a context
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param context the context to uninstall
-    * @param toState the target state
-    * @param trace   whether trace is enabled
-    */
-   protected void uninstallContext(ControllerContext context, ControllerState toState, boolean trace)
-   {
-      if (!stateModel.isValidState(toState))
-         log.error("INTERNAL ERROR: unknown state " + toState + " states=" + stateModel, new Exception("STACKTRACE"));
-
-      while (true)
-      {
-         ControllerState fromState = context.getState();
-         if (ControllerState.ERROR.equals(fromState))
-            return;
-         if (!stateModel.isValidState(fromState))
-            log.error("INTERNAL ERROR: current state not found: " + context.toShortString(), new Exception("STACKTRACE"));
-         
-         if (stateModel.isAfterState(toState, fromState))
-            return;
-         else
-            uninstallContext(context, trace);
-      }
-   }
-
-   /**
-    * Uninstall a context<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param context the context to uninstall
-    * @param trace   whether trace is enabled
-    */
-   protected void uninstallContext(ControllerContext context, boolean trace)
-   {
-      Object name = context.getName();
-
-      ControllerState fromState = context.getState();
-
-      if (trace)
-         log.trace("Uninstalling " + name + " from " + fromState.getStateString());
-
-      Controller fromController = context.getController();
-
-      Set<ControllerContext> fromContexts = fromController.getContextsByState(fromState);
-      if (fromContexts == null || fromContexts.remove(context) == false)
-         throw new Error("INTERNAL ERROR: context not found in previous state " + fromState.getStateString() + " context=" + context.toShortString(), new Exception("STACKTRACE"));
-
-      DependencyInfo dependencies = context.getDependencyInfo();
-      if (dependencies != null)
-      {
-         try
-         {
-            Set<DependencyItem> dependsOnMe = dependencies.getDependsOnMe(null);
-            if (dependsOnMe.isEmpty() == false)
-            {
-               for (DependencyItem item : dependsOnMe)
-               {
-                  if (item.isResolved())
-                  {
-                     ControllerState dependentState = item.getDependentState();
-                     if (dependentState == null || dependentState.equals(fromState))
-                     {
-                        if (item.unresolved(this))
-                        {
-                           Set<ControllerContext> dependents = CollectionsFactory.createLazySet();
-                           getContexts(item.getName(), dependents);
-                           if (dependents.isEmpty() == false)
-                           {
-                              ControllerState whenRequired = item.getWhenRequired();
-                              if (whenRequired == null)
-                                 whenRequired = stateModel.getInitialState();
-
-                              for (ControllerContext dependent : dependents)
-                              {
-                                 boolean selfDependency = (dependent == context);
-                                 if (!selfDependency)
-                                 {
-                                    contextsInstalledByExecutor.interruptTaskAndBlock(dependent, this);
-                                    if (stateModel.isBeforeState(dependent.getState(), whenRequired) == false)
-                                    {  
-                                       uninstallContext(dependent, whenRequired, trace);
-                                    }
-                                 }
-                              }
-                           }
-                        }
-                     }
-                  }
-               }
-            }
-         }
-         catch (Throwable error)
-         {
-            log.error("Error resolving dependencies for " + fromState.getStateString() + ": " + context.toShortString(), error);
-            // Not much else we can do - no uninstall, since we are at uninstall ;-)
-            errorContexts.put(context.getName(), context);
-            context.setError(error);
-         }
-      }
-
-      // The state could have changed while calling out to dependents
-      fromState = context.getState();
-      if (ControllerState.ERROR.equals(fromState))
-         return;
-      
-      ControllerState toState = stateModel.getPreviousState(fromState);
-      if (toState == null)
-      {
-         // This is hack, we signal true uninstalled status by putting it in the error state
-         context.setState(ControllerState.ERROR);
-         return;
-      }
-
-      unlockWrite();
-      try
-      {
-         resolveCallbacks(context, fromState, false);
-         handleUninstallLifecycleCallbacks(context, toState);
-
-         uninstall(context, fromState, toState);
-
-         Controller toController = context.getController();
-         Set<ControllerContext> toContexts = toController.getContextsByState(toState);
-         toContexts.add(context);
-         context.setState(toState);
-
-         uninstallUnusedOnDemandContexts(context, trace);
-      }
-      catch (Throwable t)
-      {
-         log.warn("Error uninstalling from " + fromState.getStateString() + ": " + context.toShortString(), t);
-      }
-      finally
-      {
-         lockWrite();
-      }
-   }
-
-   /**
-    * If the context being uninstalled depends on On_Demand contexts that are not used anymore
-    * those On_Demand contexts are uninstalled back to the DESCRIBED state.<p>
-    * 
-    * This method must be called with NO locks taken.
-    *
-    * @param context the context which is being uninstalled.
-    * @param trace do trace log
-    */
-   protected void uninstallUnusedOnDemandContexts(ControllerContext context, boolean trace)
-   {
-      lockWrite();
-      try
-      {
-         DependencyInfo dependencies = context.getDependencyInfo();
-         if (dependencies != null)
-         {
-            Set<DependencyItem> iDependOn = dependencies.getIDependOn(null);
-            if (iDependOn.isEmpty() == false)
-            {
-               for (DependencyItem item : iDependOn)
-               {
-                  if (item.isResolved()) //TODO Is this check necessary
-                  {
-                     Object name = item.getIDependOn();
-                     if (name == null)
-                        continue;
-   
-                     ControllerContext other = getContext(name, null);
-                     if (other == null)
-                     {
-                        log.warn("Could not find dependency while uninstalling on demand contexts for " + item);
-                        continue;
-                     }
-                     if (other.getMode() != ControllerMode.ON_DEMAND)
-                        continue;
-   
-                     DependencyInfo otherDependencies = other.getDependencyInfo();
-                     if (otherDependencies == null)
-                        continue;
-                     
-                     Set<DependencyItem> dependsOnOther = otherDependencies.getDependsOnMe(null);
-                     boolean isRequired = false;
-                     for (DependencyItem dependsOnOtherItem : dependsOnOther)
-                     {
-                        ControllerContext dependsContext = getContext(dependsOnOtherItem.getName(), null);
-                        if (dependsContext == null)
-                        {
-                           log.warn("Could not find dependency while uninstalling on demand contexts for " + item);
-                           continue;
-                        }
-                           
-                        ControllerState requiredState = item.getWhenRequired();
-                        ControllerState actualState = dependsContext.getState();
-                        
-                        if (requiredState.equals(actualState) || stateModel.isBeforeState(requiredState, actualState))
-                        {
-                           isRequired = true;
-                           break;
-                        }
-                     }
-                     if (!isRequired)
-                     {
-                        //For some reason uninstallContext() uninstalls to the state below the passed in one, add one
-                        ControllerState state = stateModel.getNextState(ControllerMode.ON_DEMAND.getRequiredState());
-                        uninstallContext(other, state, trace);
-                     }
-                  }
-               }
-            }
-         }
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Get all contexts by name,
-    * check child controllers as well.
-    *
-    * @param name the name of the context
-    * @param contexts found contexts
-    */
-   protected void getContexts(Object name, Set<ControllerContext> contexts)
-   {
-      ControllerContext context = getContext(name, null);
-      if (context != null)
-      {
-         Set<Object> aliases = context.getAliases();
-         // only pick up unique name
-         // TODO also ignore alises from @Aliases?
-         if (aliases == null || aliases.contains(name) == false)
-            contexts.add(context);
-      }
-
-      Set<AbstractController> children = getControllers();
-      if (children != null && children.isEmpty() == false)
-      {
-         for (AbstractController child : children)
-         {
-            child.getContexts(name, contexts);
-         }
-      }
-   }
-
-   /**
-    * Add callback item under demand name.
-    *
-    * @param <T> the callback item type
-    * @param name demand name
-    * @param isInstallPhase install or uninstall phase
-    * @param callback callback item
-    */
-   protected <T> void addCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
-   {
-      lockWrite();
-      try
-      {
-         Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
-         Set<CallbackItem<?>> callbacks = map.get(name);
-         if (callbacks == null)
-         {
-            callbacks = new HashSet<CallbackItem<?>>();
-            map.put(name, callbacks);
-         }
-         callbacks.add(callback);
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Remove callback item under demand name.
-    *
-    * @param <T> the callback item type
-    * @param name demand name
-    * @param isInstallPhase install or uninstall phase
-    * @param callback callback item
-    */
-   protected <T> void removeCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
-   {
-      lockWrite();
-      try
-      {
-         Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
-         Set<CallbackItem<?>> callbacks = map.get(name);
-         if (callbacks != null)
-         {
-            callbacks.remove(callback);
-            if (callbacks.isEmpty())
-               map.remove(name);
-         }
-      }
-      finally
-      {
-         unlockWrite();
-      }
-   }
-
-   /**
-    * Get calbacks from context.
-    *
-    * @param context current context
-    * @param isInstallPhase install or uninstall phase
-    * @return callback items from dependency info
-    */
-   protected Set<CallbackItem<?>> getDependencyCallbacks(ControllerContext context, boolean isInstallPhase)
-   {
-      DependencyInfo di = context.getDependencyInfo();
-      if (di != null)
-      {
-         return isInstallPhase ? di.getInstallItems() : di.getUninstallItems();
-      }
-      return null;
-   }
-
-   /**
-    * Get the matching callbacks.
-    *
-    * @param name demand name
-    * @param isInstallPhase install or uninstall phase
-    * @return all matching registered callbacks or empty set if no such item
-    */
-   protected Set<CallbackItem<?>> getCallbacks(Object name, boolean isInstallPhase)
-   {
-      lockRead();
-      try
-      {
-         Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
-         Set<CallbackItem<?>> callbacks = map.get(name);
-         return callbacks != null ? callbacks : Collections.<CallbackItem<?>>emptySet();
-      }
-      finally
-      {
-         unlockRead();
-      }
-   }
-
-   /**
-    * Resolve callbacks.
-    *
-    * @param callbacks the callbacks
-    * @param state current context state
-    * @param execute do execute callback
-    * @param isInstallPhase install or uninstall phase
-    * @param type install or uninstall type
-    */
-   protected void resolveCallbacks(Set<CallbackItem<?>> callbacks, ControllerState state, boolean execute, boolean isInstallPhase, boolean type)
-   {
-      if (callbacks != null && callbacks.isEmpty() == false)
-      {
-         for (CallbackItem<?> callback : callbacks)
-         {
-            if (callback.getWhenRequired().equals(state))
-            {
-               if (isInstallPhase)
-               {
-                  addCallback(callback.getIDependOn(), type, callback);
-               }
-               else
-               {
-                  removeCallback(callback.getIDependOn(), type, callback);
-               }
-               if (execute)
-               {
-                  try
-                  {
-                     callback.ownerCallback(this, isInstallPhase);
-                  }
-                  catch (Throwable t)
-                  {
-                     log.warn("Broken callback: " + callback, t);
-                  }
-               }
-            }
-         }
-      }
-   }
-
-   /**
-    * Resolve callback items.
-    *
-    * @param context current context
-    * @param state current context state
-    * @param isInstallPhase install or uninstall phase
-    */
-   protected void resolveCallbacks(ControllerContext context, ControllerState state, boolean isInstallPhase)
-   {
-      ClassLoader previous = null;
-      try
-      {
-         previous = SecurityActions.setContextClassLoader(context);
-         // existing owner callbacks
-         Set<CallbackItem<?>> installs = getDependencyCallbacks(context, true);
-         resolveCallbacks(installs, state, isInstallPhase, isInstallPhase, true);
-         Set<CallbackItem<?>> uninstalls = getDependencyCallbacks(context, false);
-         resolveCallbacks(uninstalls, state, isInstallPhase == false, isInstallPhase, false);
-
-         // change callbacks, applied only if context is autowire candidate
-         DependencyInfo dependencyInfo = context.getDependencyInfo();
-         if (dependencyInfo != null && dependencyInfo.isAutowireCandidate())
-         {
-            // match callbacks by name
-            Set<CallbackItem<?>> existingCallbacks = new HashSet<CallbackItem<?>>();
-            existingCallbacks.addAll(getCallbacks(context.getName(), isInstallPhase));
-            // match by classes
-            Collection<Class<?>> classes = getExposedClasses(context);
-            if (classes != null && classes.isEmpty() == false)
-            {
-               for (Class<?> clazz : classes)
-               {
-                  existingCallbacks.addAll(getCallbacks(clazz, isInstallPhase));
-               }
-            }
-
-            // Do the installs if we are at the required state
-            if (existingCallbacks != null && existingCallbacks.isEmpty() == false)
-            {
-               for(CallbackItem<?> callback : existingCallbacks)
-               {
-                  if (state.equals(callback.getDependentState()))
-                  {
-                     try
-                     {
-                        callback.changeCallback(this, context, isInstallPhase);
-                     }
-                     catch (Throwable t)
-                     {
-                        log.warn("Broken callback: " + callback, t);
-                     }
-                  }
-               }
-            }
-         }
-      }
-      // let's make sure we suppress any exceptions
-      catch (Throwable t)
-      {
-         log.warn("Cannot resolve callbacks, state= " + state + ", isInstall= " + isInstallPhase + ", context= " + context, t);
-      }
-      finally
-      {
-         if (previous != null)
-            SecurityActions.resetContextClassLoader(previous);
-      }
-   }
-
-   /**
-    * Handle install lifecycle callbacks.
-    *
-    * @param context the context
-    * @param state the state
-    * @throws Throwable for any error
-    */
-   protected void handleInstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
-   {
-      handleLifecycleCallbacks(context, state, true);
-   }
-
-   /**
-    * Handle uninstall lifecycle callbacks.
-    *
-    * @param context the context
-    * @param state the state
-    * @throws Throwable for any error
-    */
-   protected void handleUninstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
-   {
-      ControllerState oldState = stateModel.getNextState(state);
-      handleLifecycleCallbacks(context, oldState, false);
-   }
-
-   /**
-    * Handle lifecycle callbacks.
-    *
-    * @param context the context
-    * @param state the state
-    * @param install is it install or uninstall
-    * @throws Throwable for any error
-    */
-   protected void handleLifecycleCallbacks(ControllerContext context, ControllerState state, boolean install) throws Throwable
-   {
-      DependencyInfo di = context.getDependencyInfo();
-      if (di != null)
-      {
-         List<LifecycleCallbackItem> callbacks = di.getLifecycleCallbacks();
-         for (LifecycleCallbackItem callback : callbacks)
-         {
-            if (callback.getWhenRequired().equals(state))
-            {
-               if (install)
-                  callback.install(context);
-               else
-                  callback.uninstall(context);
-            }
-         }
-      }
-   }
-
-   /**
-    * Install a context<p>
-    * <p/>
-    * This method must be invoked with NO locks taken
-    *
-    * @param context   the context
-    * @param fromState the from state
-    * @param toState   the toState
-    * @throws Throwable for any error
-    */
-   protected void install(ControllerContext context, ControllerState fromState, ControllerState toState) throws Throwable
-   {
-      long time = 0;
-      boolean collectStats = this.collectStats;
-      if (collectStats)
-         time = System.currentTimeMillis();
-      try
-      {
-         context.install(fromState, toState);
-      }
-      finally
-      {
-         if (collectStats)
-         {
-            time = System.currentTimeMillis() - time;
-            if (time > 0)
-            {
-               synchronized (this)
-               {
-                  if (installStats == null)
-                     installStats = new StateStatistics();
-
-                  String state = toState.getStateString();
-                  String name = context.getName().toString();
-                  installStats.addStatistic(state, name, time);
-               }
-            }
-         }
-      }
-   }
-
-   /**
-    * Uninstall a context<p>
-    * <p/>
-    * This method must be invoked with NO locks taken
-    *
-    * @param context   the context
-    * @param fromState the from state
-    * @param toState   the to state
-    */
-   protected void uninstall(ControllerContext context, ControllerState fromState, ControllerState toState)
-   {
-      context.uninstall(fromState, toState);
-   }
-
-   /**
-    * Whether we should advance the context<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param context the context
-    * @return true when we should advance the context
-    */
-   protected boolean advance(ControllerContext context)
-   {
-      ControllerMode mode = context.getMode();
-
-      // Never advance for disabled
-      if (ControllerMode.DISABLED.equals(mode))
-         return false;
-
-      return stateModel.isBeforeState(context.getState(), context.getRequiredState());
-   }
-
-   /**
-    * Lock for read
-    */
-   protected void lockRead()
-   {
-      lock.readLock().lock();
-   }
-
-   /**
-    * Unlock for read
-    */
-   protected void unlockRead()
-   {
-      lock.readLock().unlock();
-   }
-
-   /**
-    * Lock for write
-    */
-   protected void lockWrite()
-   {
-      lock.writeLock().lock();
-   }
-
-   /**
-    * Unlock for write
-    */
-   protected void unlockWrite()
-   {
-      lock.writeLock().unlock();
-   }
-
-   /**
-    * Get a registered context<p>
-    * <p/>
-    * This method should be invoked with at least the read lock taken
-    *
-    * @param name      the name with which to register it
-    * @param mustExist whether to throw an error when the context does not exist
-    * @return context the registered context
-    * @throws IllegalArgumentException for null parameters
-    * @throws IllegalStateException    if the context if must exist is true and the context does not exist
-    */
-   protected ControllerContext getRegisteredControllerContext(Object name, boolean mustExist)
-   {
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-
-      ControllerContext result = allContexts.get(name);
-      if (mustExist && result == null)
-         throw new IllegalStateException("Context does not exist with name: " + name);
-      return result;
-   }
-
-   /**
-    * Register a context and all its aliases<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param context the context to register
-    * @throws IllegalArgumentException for null parameters
-    * @throws IllegalStateException    if the context is already registered with that name or alias
-    */
-   protected void registerControllerContext(ControllerContext context)
-   {
-      if (context == null)
-         throw new IllegalArgumentException("Null context");
-
-      Set<Object> aliases = context.getAliases();
-
-      // Register the context
-      Object name = context.getName();
-      registerControllerContext(name, context);
-
-      // Register the aliases
-      if (aliases != null && aliases.isEmpty() == false)
-      {
-         int ok = 0;
-         try
-         {
-            for (Object alias : aliases)
-            {
-               registerControllerContext(alias, context);
-               ++ok;
-            }
-         }
-         finally
-         {
-            // It didn't work
-            if (ok != aliases.size() && ok > 0)
-            {
-               // Unregister the aliases we added
-               for (Object alias : aliases)
-               {
-                  if (ok-- == 0)
-                     break;
-                  try
-                  {
-                     unregisterControllerContext(alias);
-                  }
-                  catch (Throwable ignored)
-                  {
-                     log.debug("Error unregistering alias: " + alias, ignored);
-                  }
-               }
-
-               // Unregister the context
-               try
-               {
-                  unregisterControllerContext(name);
-               }
-               catch (Throwable ignored)
-               {
-                  log.debug("Error unregistering context with name: " + name, ignored);
-               }
-            }
-         }
-      }
-   }
-
-   /**
-    * Unregister a context and all its aliases<p>
-    * <p/>
-    * This method must be invoked with the write lock taken
-    *
-    * @param context the context
-    * @throws IllegalArgumentException for null parameters
-    * @throws IllegalStateException    if the context is not registered
-    */
-   protected void unregisterControllerContext(ControllerContext context)
-   {
-      if (context == null)
-         throw new IllegalArgumentException("Null context");
-
-      Set<Object> aliases = context.getAliases();
-
-      // Unregister the context
-      Object name = context.getName();
-      unregisterControllerContext(name);
-
-      // Unegister the aliases
-      if (aliases != null && aliases.isEmpty() == false)
-      {
-         for (Object alias : aliases)
-         {
-            try
-            {
-               unregisterControllerContext(alias);
-            }
-            catch (Throwable ignored)
-            {
-               log.debug("Error unregistering alias: " + alias, ignored);
-            }
-         }
-      }
-   }
-
-   /**
-    * Register a context<p>
-    * <p/>
-    * This method must be invoked with the write lock taken<p>
-    * <p/>
-    * NOTE: You probably want to use the {@link #registerControllerContext(ControllerContext)}
-    *
-    * @param name    the name with which to register it
-    * @param context the context to register
-    * @throws IllegalArgumentException for null parameters
-    * @throws IllegalStateException    if the context is already registered with that name
-    */
-   protected void registerControllerContext(Object name, ControllerContext context)
-   {
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-      if (context == null)
-         throw new IllegalArgumentException("Null context");
-
-      if (allContexts.containsKey(name) == false)
-         allContexts.put(name, context);
-      else
-         throw new IllegalStateException("Unable to register context " + context.toShortString() + ", name already exists: " + name);
-   }
-
-   /**
-    * Unregister a context<p>
-    * <p/>
-    * This method must be invoked with the write lock taken<p>
-    * <p/>
-    * NOTE: You probably want to use the {@link #unregisterControllerContext(ControllerContext)}
-    *
-    * @param name the name it was registered with
-    * @throws IllegalArgumentException for null parameters
-    */
-   protected void unregisterControllerContext(Object name)
-   {
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-      allContexts.remove(name);
-   }
-
-   // --- alias dependency
-
-   private static class InnerAliasControllerContext extends AbstractAliasControllerContext
-   {
-      private InnerAliasControllerContext(Object alias, String id, Object original, ControllerContextActions actions)
-      {
-         super(alias, id, original, actions);
-      }
-   }
-
-   private class AliasControllerContextAction extends SimpleControllerContextAction<AliasControllerContext>
-   {
-      protected AliasControllerContext contextCast(ControllerContext context)
-      {
-         return AliasControllerContext.class.cast(context);
-      }
-
-      protected boolean validateContext(ControllerContext context)
-      {
-         return (context instanceof AliasControllerContext);
-      }
-
-      protected void installAction(AliasControllerContext context) throws Throwable
-      {
-         Object alias = context.getAlias();
-         Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
-         if (jmxAlias != null)
-            alias = jmxAlias;
-
-         Object original = context.getOriginal();
-         Object jmxOriginal = JMXObjectNameFix.needsAnAlias(original);
-         if (jmxOriginal != null)
-            original = jmxOriginal;
-
-         // get the context's controller - not the one we registered with
-         AbstractController controller = (AbstractController)context.getController();
-         lockWrite();
-         try
-         {
-            ControllerContext lookup = controller.getRegisteredControllerContext(original, true);
-            controller.registerControllerContext(alias, lookup);
-            if (log.isTraceEnabled())
-               log.trace("Added alias " + alias + " for context " + context);
-         }
-         finally
-         {
-            unlockWrite();
-         }
-      }
-
-      protected void uninstallAction(AliasControllerContext context)
-      {
-         lockWrite();
-         try
-         {
-            Object alias = context.getAlias();
-            Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
-            if (jmxAlias != null)
-               alias = jmxAlias;
-
-            // get the context's controller - not the one we registered with
-            AbstractController controller = (AbstractController)context.getController();
-            controller.unregisterControllerContext(alias);
-            if (log.isTraceEnabled())
-               log.trace("Removed alias " + alias);
-         }
-         finally
-         {
-            unlockWrite();
-         }
-      }
-   }
-
-   public boolean isAsynchronousInstallInProgress(ControllerContext context)
-   {
-      if (context.getMode() != ControllerMode.ASYNCHRONOUS)
-         return false;
-
-      return contextsInstalledByExecutor.isBeingInstalled(context);
-   }
-
-   /**
-    * A task being handled asyynchronously by the executor
-    * 
-    */
-   abstract class InterruptibleControllerTask implements Runnable
-   {
-      /**
-       * The thread used to handle the asynchronous task
-       */
-      Thread thread;
-      
-      /**
-       * True if the task is interrupted  
-       */
-      volatile boolean interrupted;
-
-      /**
-       * Latch counted down by interrupted tasks once they have reached a state where they finish 
-       */
-      CountDownLatch interruptedLatch;
-      
-      /**
-       * Gets the thread that is currently used to install the asyncronous task
-       * @return The thread, or null if still queued in the executor
-       */
-      synchronized Thread getThread()
-      {
-         return thread;
-      }      
-      
-      /**
-       * Interrupt the task, and if associated with a thread
-       * return a countdown latch that will have a count of 0
-       * once the job has broken out
-       * @return the latch or null if not yet interrupted
-       */
-      synchronized CountDownLatch interrupt()
-      {
-         interrupted = true;
-         if (thread != null)
-         {
-            interruptedLatch = new CountDownLatch(1);
-            return interruptedLatch;
-         }
-         return null;
-      }
-
-      /**
-       * Check the interrupted status
-       * @return true if interrupted
-       */
-      boolean isInterrupted()
-      {
-         return interrupted;
-      }
-      
-      /**
-       * Associate the current thread with the task, or clear it in contextsInstalledByExecutor
-       * if it has been interrupted. This should be the first thing tasks do once they run.
-       *
-       * @param context the context
-       * @return true if interrupted
-       */
-      synchronized boolean associateWithThreadOrDisassociateIfInterrupted(ControllerContext context)
-      {
-         if (interrupted)
-         {
-            contextsInstalledByExecutor.disassociateWithTask(context);
-            return true;
-         }
-         thread = Thread.currentThread();
-         return false;
-      }
-      
-      /**
-       * Disassociate the thread with the task, and if interrupted count down the latch so those
-       * awaiting the latch know the task has finished.
-       */
-      synchronized void disassociateWithThreadAndSignalEnd()
-      {
-         thread = null;
-         if (interruptedLatch != null)
-         {
-            interruptedLatch.countDown();
-         }
-      }
-   }
-
-   
-   /**
-    * Interruptible task used to install a controller context asynchronously.
-    * It will install the context as far as possible towards its required state,
-    * before resolving the other contexts.
-    */
-   class InstallControllerContextTask extends InterruptibleControllerTask
-   {
-      ControllerContext context;
-      ClassLoader classLoader;
-      boolean trace;
-
-      public InstallControllerContextTask(ControllerContext context, boolean trace)
-      {
-         this.context = context;
-         this.classLoader = SecurityActions.getContextClassLoader();
-         this.trace = trace;
-      }
-      
-      public void run()
-      {
-         if (associateWithThreadOrDisassociateIfInterrupted(context))
-            return;
-         
-         if (trace)
-            log.trace(Thread.currentThread().getName() + " starting asyncronous install of " + context.getName());
-         
-         lockWrite();
-         ClassLoader tcl = SecurityActions.setContextClassLoader(classLoader);
-         try
-         {
-            //Move the given context as far through the states as possible
-            boolean stateChanged = false;
-            try
-            {
-               stateChanged = installMyContext();
-            }
-            finally
-            {
-               contextsInstalledByExecutor.disassociateWithTask(context);
-            }
-            
-            //The given context had its state changed, now see if anybody was dependent on it
-            if (stateChanged && !interrupted)
-            {
-               resolveContexts(trace);
-            }
-         }
-         catch (Throwable t)
-         {
-            Object ctx = trace ? context : context.getName();
-            log.error("Problem installing context asynchronously " + ctx, t);
-         }
-         finally
-         {
-            if (trace)
-               log.trace(Thread.currentThread().getName() + " asynchronous install done for " + context.getName());
-            SecurityActions.resetContextClassLoader(tcl);
-            unlockWrite();
-            
-            disassociateWithThreadAndSignalEnd();
-         }
-      }
-      
-      boolean installMyContext()
-      {
-         boolean stateChanged = false;
-
-         if (!stateModel.isValidState(context.getRequiredState()))
-            throw new IllegalArgumentException("Unknown state: " + context.getRequiredState());
-         
-         boolean resolved = true;
-
-         while(resolved && stateModel.isBeforeState(context.getState(), context.getRequiredState()) && !interrupted)
-         {
-            resolved = false;
-            ControllerState toState = stateModel.getNextState(context.getState());
-            if (advance(context))
-            {
-               try
-               {
-                  if (resolveDependencies(context, toState))
-                  {
-                     resolved = true;
-                  }
-               }
-               catch (Throwable error)
-               {
-                  Object ctx = trace ? context : context.getName();
-                  log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx, error);
-                  uninstallContext(context, stateModel.getInitialState(), trace);
-                  errorContexts.put(context.getName(), context);
-                  context.setError(error);
-               }
-               
-               if (resolved)
-               {
-                  resolved = incrementState(context, trace);
-                  if (resolved)
-                  {
-                     stateChanged = true;
-                  }
-               }
-            }
-         }
-
-         return stateChanged;
-      }
-   }
-
-   
-   
-   /**
-    * Class used to keep track of contexts that are scheduled for asynchronous install, 
-    * or are in the process of being installed asynchronously. 
-    * 
-    */
-   private static class ContextsInstalledByExecutor
-   {
-      /** The contexts that are currently being installed by the executor */
-      Map<ControllerContext, InterruptibleControllerTask> executorTasksByContext = new ConcurrentHashMap<ControllerContext, InterruptibleControllerTask>();
-      /**
-       * Checks whether context should be installed asynchronously, by checking the controller mode and the current thread
-       * @param context The context
-       * @return Whether the context should be installed in the executor
-       */
-      boolean shouldInstallAsynchronously(ControllerContext context)
-      {
-         if (context.getMode() == ControllerMode.ASYNCHRONOUS)
-         {
-            final InterruptibleControllerTask task = executorTasksByContext.get(context);
-            return task == null || task.getThread() != Thread.currentThread();
-         }
-         return false;
-      }
-      
-      /**
-       * Records the context and the asynchronous task to install it
-       * @param context The context to be installed asynchronously
-       * @param task The task that will be used to install the context 
-       */
-      void markForTaskExecution(ControllerContext context, InterruptibleControllerTask task)
-      {
-         executorTasksByContext.put(context, task);
-      }
-      
-      /**
-       * Removes the task that was used to install the context
-       * @param context The context whose task we want to remove
-       */
-      void disassociateWithTask(ControllerContext context)
-      {
-         executorTasksByContext.remove(context);
-      }
-      
-      /**
-       * Checks if the context is recorded for asynchronous install, and if the thread used is different
-       * from the current thread. 
-       * @param context The context to check
-       * @return true if installed by another thread
-       */
-      boolean isInstalledByOtherThread(ControllerContext context)
-      {
-         final InterruptibleControllerTask task = executorTasksByContext.get(context);
-         return task != null && Thread.currentThread() != task.getThread();         
-      }
-      
-      /**
-       * Checks in the context is recorded for asynchronous install
-       * @param context The context to check
-       * @return true if recorded for asynchronous install
-       */
-      boolean isBeingInstalled(ControllerContext context)
-      {
-         return executorTasksByContext.get(context) != null;
-      }
-      
-      /**
-       * Checks if the passed in context is recorded for asynchronous install,
-       * and if it is interrupts the asynchronous task.<p>
-       *
-       * This method must be called with the write lock taken
-       * 
-       * @param context The context to interrupt
-       * @param controller the controller
-       */
-      void interruptTaskAndBlock(ControllerContext context, AbstractController controller)
-      {
-         InterruptibleControllerTask task = executorTasksByContext.get(context);
-         if (task != null)
-         {
-            controller.unlockWrite();
-            try
-            {
-               CountDownLatch latch = task.interrupt();
-               if (latch != null)
-               {
-                  try
-                  {
-                     latch.await();
-                  }
-                  catch(InterruptedException e)
-                  {
-                     Thread.currentThread().interrupt();
-                  }
-               }
-            }
-            finally
-            {
-               controller.lockWrite();
-            }
-         }
-      }
-   }
-
-   // Context queries & registry
-
-   public Set<ControllerContext> filter(Iterable<ControllerContext> contexts, ContextFilter filter)
-   {
-      return registry.filter(contexts, filter);
-   }
-
-   public Set<ControllerContext> getInstantiatedContexts(Class<?> clazz)
-   {
-      return registry.getInstantiatedContexts(clazz);
-   }
-
-   public Set<ControllerContext> getContexts(Class<?> clazz, ControllerState state)
-   {
-      return registry.getContexts(clazz, state);
-   }
-
-   public ControllerContext getContextByClass(Class<?> clazz)
-   {
-      return registry.getContextByClass(clazz);
-   }
-
-   public void addInstantiatedContext(ControllerContext context)
-   {
-      registry.addInstantiatedContext(context);
-   }
-
-   public void registerInstantiatedContext(ControllerContext context, Class<?>... classes)
-   {
-      registry.registerInstantiatedContext(context, classes);
-   }
-
-   public void unregisterInstantiatedContext(ControllerContext context, Class<?>... classes)
-   {
-      registry.unregisterInstantiatedContext(context, classes);
-   }
-
-   public void removeInstantiatedContext(ControllerContext context)
-   {
-      registry.removeInstantiatedContext(context);
-   }
-
-   public Set<Class<?>> getExposedClasses(ControllerContext context)
-   {
-      return registry.getExposedClasses(context);
-   }
-}

Copied: projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java (from rev 99452, projects/kernel/trunk/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java)
===================================================================
--- projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	                        (rev 0)
+++ projects/kernel/branches/resolver/dependency/src/main/java/org/jboss/dependency/plugins/AbstractController.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,2596 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.dependency.plugins;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.jboss.dependency.plugins.action.ControllerContextAction;
+import org.jboss.dependency.plugins.action.SimpleControllerContextAction;
+import org.jboss.dependency.plugins.tracker.AbstractContextRegistry;
+import org.jboss.dependency.spi.CallbackItem;
+import org.jboss.dependency.spi.Controller;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerContextActions;
+import org.jboss.dependency.spi.ControllerMode;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.dependency.spi.ControllerStateModel;
+import org.jboss.dependency.spi.DependencyInfo;
+import org.jboss.dependency.spi.DependencyItem;
+import org.jboss.dependency.spi.LifecycleCallbackItem;
+import org.jboss.dependency.spi.asynchronous.AsynchronousController;
+import org.jboss.dependency.spi.graph.GraphController;
+import org.jboss.dependency.spi.graph.LookupStrategy;
+import org.jboss.dependency.spi.graph.SearchInfo;
+import org.jboss.dependency.spi.tracker.ContextFilter;
+import org.jboss.dependency.spi.tracker.ContextQueries;
+import org.jboss.dependency.spi.tracker.ContextRegistry;
+import org.jboss.util.JBossObject;
+import org.jboss.util.collection.CollectionsFactory;
+
+/**
+ * Abstract controller.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision$
+ */
+public class AbstractController extends JBossObject implements Controller, GraphController, AbstractControllerMBean, AsynchronousController, ContextQueries, ContextRegistry
+{
+   /** The lock */
+   private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+   /**
+    * The executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
+    * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy 
+    */
+   private Executor executor;
+
+   /** Whether we are shutdown */
+   private boolean shutdown = false;
+
+   /** The controller state model */
+   private final AbstractControllerStateModel stateModel = new MapControllerStateModel();
+   
+   /** All contexts by name Map<Object, ControllerContext> */
+   private final Map<Object, ControllerContext> allContexts = new ConcurrentHashMap<Object, ControllerContext>();
+
+   /** The contexts by state Map<ControllerState, Set<ControllerContext>> */
+   private final Map<ControllerState, Set<ControllerContext>> contextsByState = new ConcurrentHashMap<ControllerState, Set<ControllerContext>>();
+
+   /** The error contexts Map<Name, ControllerContext> */
+   private final Map<Object, ControllerContext> errorContexts = new ConcurrentHashMap<Object, ControllerContext>();
+
+   /** The contexts that are currently being resolved/installed */
+   private final Set<ControllerContext> installing = new CopyOnWriteArraySet<ControllerContext>();
+   
+   /** The contexts that are currently being installed by the executor */
+   private final ContextsInstalledByExecutor contextsInstalledByExecutor = new ContextsInstalledByExecutor();
+   
+   /** The parent controller */
+   private volatile AbstractController parentController;
+
+   /** The child controllers */
+   private final Set<AbstractController> childControllers = new CopyOnWriteArraySet<AbstractController>();
+
+   /** The callback items */
+   private final Map<Object, Set<CallbackItem<?>>> installCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
+   private final Map<Object, Set<CallbackItem<?>>> uninstallCallbacks = new ConcurrentHashMap<Object, Set<CallbackItem<?>>>();
+
+   /** Whether an on demand context has been enabled */
+   private boolean onDemandEnabled = true;
+
+   /** Whether stats are enabled */
+   private boolean collectStats = false;
+   
+   /** The install stats */
+   private volatile StateStatistics installStats = null;
+
+   /** The context tracker */
+   private final AbstractContextRegistry registry;
+
+   /**
+    * Create an abstract controller
+    */
+   public AbstractController()
+   {
+      addState(ControllerState.NOT_INSTALLED, null);
+      addState(ControllerState.PRE_INSTALL, null);
+      addState(ControllerState.DESCRIBED, null);
+      addState(ControllerState.INSTANTIATED, null);
+      addState(ControllerState.CONFIGURED, null);
+      addState(ControllerState.CREATE, null);
+      addState(ControllerState.START, null);
+      addState(ControllerState.INSTALLED, null);
+
+      registry = createContextRegistry();
+   }
+
+   /**
+    * Create context registry.
+    *
+    * @return the context registry
+    */
+   protected AbstractContextRegistry createContextRegistry()
+   {
+      return new AbstractContextRegistry(this);
+   }
+
+   /**
+    * Set the executor used to install ASYNCHRONOUS contexts. It must have a saturation policy of
+    * (or semantically similar to) ThreadPoolExecutor.AbortPolicy or ThreadPoolExecutor.CallerRunsPolicy.
+    *
+    * @param executor the executor
+    */
+   public void setExecutor(Executor executor)
+   {
+      // TODO - security
+      lockWrite();
+      try
+      {
+         this.executor = executor;
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Get the executor.
+    *
+    * @return the executor
+    */
+   public Executor getExecutor()
+   {
+      // TODO - security
+      return getExecutionEnvironment();
+   }
+
+   /**
+    * Get the executor internal w/o security check.
+    *
+    * @return the executor
+    */
+   protected Executor getExecutionEnvironment()
+   {
+      lockRead();
+      try
+      {
+         return executor;
+      }
+      finally
+      {
+         unlockRead();
+      }
+   }
+
+   public boolean isShutdown()
+   {
+      lockWrite();
+      try
+      {
+         return shutdown;
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Check whether the controller is shutdown
+    *
+    * @throws IllegalStateException when already shutdown
+    */
+   public void checkShutdown()
+   {
+      lockWrite();
+      try
+      {
+         if (shutdown)
+            throw new IllegalStateException("Already shutdown");
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   public void shutdown()
+   {
+      lockWrite();
+      try
+      {
+         Set<AbstractController> children = getControllers();
+         if (children != null && children.isEmpty() == false)
+         {
+            for (AbstractController child : children)
+            {
+               try
+               {
+                  child.shutdown();
+               }
+               catch (Throwable t)
+               {
+                  log.warn("Error during shutdown of child: " + child, t);
+               }
+            }
+         }
+
+         Set<ControllerContext> contexts = getAllContexts();
+         if (contexts != null && contexts.isEmpty() == false)
+         {
+            for (ControllerContext context : contexts)
+            {
+               try
+               {
+                  uninstall(context.getName());
+               }
+               catch (Throwable t)
+               {
+                  log.warn("Error during shutdown while uninstalling: " + context, t);
+               }
+            }
+         }
+      }
+      finally
+      {
+         shutdown = true;
+         unlockWrite();
+      }
+
+   }
+
+   /**
+    * Get the collectStats.
+    * 
+    * @return the collectStats.
+    */
+   public boolean isCollectStats()
+   {
+      return collectStats;
+   }
+
+   /**
+    * Set the collectStats.
+    * 
+    * @param collectStats the collectStats.
+    */
+   public void setCollectStats(boolean collectStats)
+   {
+      this.collectStats = collectStats;
+   }
+
+   public String listStateTimes(boolean details)
+   {
+      synchronized (this)
+      {
+         if (installStats == null)
+            return "No statistics available";
+         return installStats.listTimes(details);
+      }
+   }
+
+   public void addState(ControllerState state, ControllerState before)
+   {
+      lockWrite();
+      try
+      {
+         if (stateModel.addState(state, before))
+         {
+            Set<ControllerContext> contexts =  new CopyOnWriteArraySet<ControllerContext>();
+            contextsByState.put(state, contexts);
+         }
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Add controller context.
+    *
+    * This is normally used when switching from top
+    * level controller to a scoped one.
+    *
+    * @param context the controller context
+    */
+   void addControllerContext(ControllerContext context)
+   {
+      lockWrite();
+      try
+      {
+         registerControllerContext(context);
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Remove controller context.
+    *
+    * This is normally used when switching from scoped
+    * level controller to a top one.
+    *
+    * @param context the controller context
+    */
+   void removeControllerContext(ControllerContext context)
+   {
+      lockWrite();
+      try
+      {
+         unregisterControllerContext(context);
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Get the parent controller.
+    *
+    * @return the parent controller
+    */
+   public AbstractController getParentController()
+   {
+      return parentController;
+   }
+
+   /**
+    * Set the parent controller.
+    *
+    * @param parentController the parent controller
+    */
+   protected void setParentController(AbstractController parentController)
+   {
+      this.parentController = parentController;
+   }
+
+   /**
+    * Get child controllers.
+    *
+     * @return the child controllers
+    */
+   public Set<AbstractController> getControllers()
+   {
+      lockRead();
+      try
+      {
+         return Collections.unmodifiableSet(childControllers);
+      }
+      finally
+      {
+         unlockRead();
+      }
+   }
+
+   /**
+    * Add child controller.
+    *
+    * @param controller the child controller
+    * @return true if equal controller has been already added, see Set.add usage 
+    */
+   public boolean addController(AbstractController controller)
+   {
+      lockWrite();
+      try
+      {
+         return childControllers.add(controller);
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Remove child controller.
+    *
+    * @param controller the child controller
+    * @return true if equal controller was present, see Set.remove usage
+    */
+   public boolean removeController(AbstractController controller)
+   {
+      lockWrite();
+      try
+      {
+         return childControllers.remove(controller);
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Whether the controller has contexts
+    *
+    * @return true when there are registered contexts
+    */
+   public boolean isActive()
+   {
+      lockRead();
+      try
+      {
+         // is this active
+         if (allContexts.isEmpty() == false)
+            return true;
+
+         // any of the children still active
+         for (AbstractController child : getControllers())
+         {
+            if (child.isActive())
+               return true;
+         }
+
+         return false;
+      }
+      finally
+      {
+         unlockRead();
+      }
+   }
+
+   public ControllerContext getContext(Object name, ControllerState state, SearchInfo info)
+   {
+      if (info == null)
+         throw new IllegalArgumentException("Null search info.");
+
+      LookupStrategy strategy = info.getStrategy();
+      if (strategy == null)
+         throw new IllegalArgumentException("AbstractController doesn't implement this search info: " + info);
+
+      if (log.isTraceEnabled())
+         log.trace("Executing search " + info.getType());
+
+      return strategy.getContext(this, name, state);
+   }
+
+   /**
+    * Get all the contexts.
+    * In state decending order.
+    *
+    * @return all contexts
+    */
+   public Set<ControllerContext> getAllContexts()
+   {
+      lockRead();
+      try
+      {
+         LinkedHashSet<ControllerContext> result = new LinkedHashSet<ControllerContext>();
+         ListIterator<ControllerState> it = stateModel.listIteraror();
+         if (it.hasNext())
+         {
+            result.addAll(getContextsByState(it.next()));
+            while (it.hasPrevious())
+            {
+               result.addAll(getContextsByState(it.previous()));
+            }
+         }
+         result.addAll(errorContexts.values());
+         return result;
+      }
+      finally
+      {
+         unlockRead();
+      }
+   }
+
+   public ControllerContext getContext(Object name, ControllerState state)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+
+      lockRead();
+      try
+      {
+         ControllerContext result = getRegisteredControllerContext(name, false);
+         if (result == null && name instanceof Class) // check type matching
+            result = getContextByClass((Class<?>)name);
+
+         if (result != null && state != null && stateModel.isBeforeState(result.getState(), state))
+         {
+            return null;
+         }
+         return result;
+      }
+      finally
+      {
+         unlockRead();
+      }
+   }
+
+   public ControllerContext getInstalledContext(Object name)
+   {
+      return getContext(name, ControllerState.INSTALLED);
+   }
+
+   public Set<ControllerContext> getNotInstalled()
+   {
+      lockWrite();
+      try
+      {
+         Set<ControllerContext> result = new HashSet<ControllerContext>(errorContexts.values());
+         for (ControllerState state : stateModel)
+         {
+            if (ControllerState.INSTALLED.equals(state))
+               break;
+            
+            Set<ControllerContext> stateContexts = getContextsByState(state);
+            result.addAll(stateContexts);
+         }
+         return result;
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   public ControllerStateModel getStates()
+   {
+      return stateModel;
+   }
+
+   public Set<ControllerContext> getContextsByState(ControllerState state)
+   {
+      return contextsByState.get(state);
+   }
+
+   public void install(ControllerContext context) throws Throwable
+   {
+      boolean trace = log.isTraceEnabled();
+
+      if (context == null)
+         throw new IllegalArgumentException("Null context");
+
+      Object name = context.getName();
+      if (name == null)
+         throw new IllegalArgumentException("Null name " + context.toShortString());
+
+      install(context, trace);
+   }
+
+   public void change(ControllerContext context, ControllerState state) throws Throwable
+   {
+      boolean trace = log.isTraceEnabled();
+
+      if (context == null)
+         throw new IllegalArgumentException("Null context");
+
+      if (state == null)
+         throw new IllegalArgumentException("Null state");
+
+      change(context, state, trace);
+   }
+
+   public void enableOnDemand(ControllerContext context) throws Throwable
+   {
+      boolean trace = log.isTraceEnabled();
+
+      if (context == null)
+         throw new IllegalArgumentException("Null context");
+
+      enableOnDemand(context, trace);
+   }
+
+   public ControllerContext uninstall(Object name)
+   {
+      return uninstall(name, 0);
+   }
+
+   /**
+    * Get controller id - impl detail.
+    * It should be unique.
+    *
+    * @return controller's id
+    */
+   protected String getId()
+   {
+      StringBuffer buffer = new StringBuffer();
+      buffer.append(getClass().getSimpleName());
+      buffer.append("[").append(System.identityHashCode(this)).append("]");
+      return buffer.toString();
+   }
+
+   public void addAlias(Object alias, Object original) throws Throwable
+   {
+      Map<ControllerState, ControllerContextAction> map = createAliasActions();
+      ControllerContextActions actions = new AbstractControllerContextActions(map);
+      AliasControllerContext context = new InnerAliasControllerContext(alias, getId(), original, actions);
+      preAliasInstall(context);
+      install(context);
+      // is alias in error
+      Throwable error = context.getError();
+      if (error != null)
+         throw error;      
+      if (ControllerState.ERROR.equals(context.getState()))
+         throw new IllegalArgumentException("Alias " + context + " is in error.");
+   }
+
+   /**
+    * Create alias controller context actions.
+    *
+    * @return the alias controller context actions
+    */
+   protected Map<ControllerState, ControllerContextAction> createAliasActions()
+   {
+      return Collections.<ControllerState, ControllerContextAction>singletonMap(ControllerState.INSTALLED, new AliasControllerContextAction());
+   }
+
+   /**
+    * Apply pre install - e.g. scope key in scoped controller.
+    *
+    * @param aliasContext the new alias context
+    */
+   protected void preAliasInstall(ControllerContext aliasContext)
+   {
+   }
+
+   public void removeAlias(Object alias)
+   {
+      uninstall(alias + "_Alias_" + getId());
+   }
+
+   /**
+    * Uninstall the context.
+    *
+    * @param name the context name
+    * @param level the controller level
+    * @return uninstalled controller context
+    */
+   // todo - some better way to find context's by name
+   // currently the first one found is used
+   protected ControllerContext uninstall(Object name, int level)
+   {
+      boolean trace = log.isTraceEnabled();
+
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+
+      lockWrite();
+      try
+      {
+         if (errorContexts.remove(name) != null && trace)
+            log.trace("Tidied up context in error state: " + name);
+
+         ControllerContext context = getRegisteredContextAndInterruptAsynchronousInstall(name);
+         if (context != null)
+         {
+            if (trace)
+               log.trace("Uninstalling " + context.toShortString());
+
+            // get a hold on possible parent before its nullified in uninstall
+            AbstractController parent = getParentController();
+
+            uninstallContext(context, stateModel.getInitialState(), trace);
+
+            try
+            {
+               unregisterControllerContext(context);
+            }
+            catch (Throwable t)
+            {
+               log.warn("Error unregistering context: " + context.toShortString() + " with name: " + name);
+            }
+
+            while (parent != null)
+            {
+               try
+               {
+                  parent.unregisterControllerContext(context);
+               }
+               catch (Throwable t)
+               {
+                  log.warn("Error unregistering context in parent controller: " + context.toShortString() + " with name: " + name);
+               }
+               parent = parent.getParentController();
+            }
+         }
+         else
+         {
+            for (AbstractController controller : getControllers())
+            {
+               context = controller.uninstall(name, level + 1);
+               if (context != null)
+                  break;
+            }
+         }
+         if (context == null && level == 0)
+            throw new IllegalStateException("Not installed: " + name);
+         return context;
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   
+   /**
+    * Obtains the context, having interrupted its installation process if it is an asynchronous context 
+    * currently being installed
+    * @param name The name of the context 
+    * @return the context or null if not found
+    */
+   private ControllerContext getRegisteredContextAndInterruptAsynchronousInstall(Object name)
+   {
+      ControllerContext context = getRegisteredControllerContext(name, false);
+      if (context != null)
+      {
+         contextsInstalledByExecutor.interruptTaskAndBlock(context, this);
+         context = getRegisteredControllerContext(name, false);
+      }
+      return context;
+   }
+       
+   /**
+    * Install a context
+    *
+    * @param context the context
+    * @param trace   whether trace is enabled
+    * @throws Throwable for any error
+    */
+   protected void install(ControllerContext context, boolean trace) throws Throwable
+   {
+      lockWrite();
+      try
+      {
+         checkShutdown();
+
+         Object name = context.getName();
+
+         // Check the name is not already registered
+         if (getRegisteredControllerContext(name, false) != null)
+            throw new IllegalStateException(name + " is already installed.");
+
+         // Check any alias is not already registered
+         Set<Object> aliases = context.getAliases();
+         if (aliases != null && aliases.isEmpty() == false)
+         {
+            for (Object alias : aliases)
+            {
+               if (getRegisteredControllerContext(alias, false) != null)
+                  throw new IllegalStateException(alias + " an alias of " + name + " is already installed.");
+            }
+         }
+
+         // set the required state
+         ControllerMode mode = context.getMode();
+         context.setRequiredState(mode.getRequiredState());
+
+         if (trace)
+            log.trace("Installing " + context.toShortString());
+
+         context.setController(this);
+         DependencyInfo dependencies = context.getDependencyInfo();
+         if (trace)
+         {
+            String dependsOn = "[]";
+            if (dependencies != null)
+            {
+               try
+               {
+                  Set<DependencyItem> set = dependencies.getIDependOn(null);
+                  if (set != null)
+                     dependsOn = set.toString();
+               }
+               catch (Throwable t)
+               {
+                  log.warn("Exception getting dependencies: " + t);
+                  dependsOn = null;
+               }
+            }
+            if (dependsOn != null)
+               log.trace("Dependencies for " + name + ": " + dependsOn);
+         }
+
+         boolean ok = incrementState(context, trace);
+         if (ok)
+         {
+            try
+            {
+               registerControllerContext(context);
+            }
+            catch (Throwable t)
+            {
+               // This is probably unreachable? But let's be paranoid
+               ok = false;
+               throw t;
+            }
+         }
+         if (ok)
+         {
+            resolveContexts(trace);
+         }
+         else
+         {
+            errorContexts.remove(context);
+            throw context.getError();
+         }
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Change a context's state
+    *
+    * @param context the context
+    * @param state   the required state
+    * @param trace   whether trace is enabled
+    * @throws Throwable for any error
+    */
+   protected void change(ControllerContext context, ControllerState state, boolean trace) throws Throwable
+   {
+      lockWrite();
+      try
+      {
+         checkShutdown();
+
+         if (!stateModel.isValidState(state))
+            throw new IllegalArgumentException("Unknown state: " + state);
+
+         if (context.getState().equals(state))
+         {
+            if (trace)
+               log.trace("No change required toState=" + state.getStateString() + " " + context.toShortString());
+            return;
+         }
+
+         if (trace)
+            log.trace("Change toState=" + state.getStateString() + " " + context.toShortString());
+
+         context.setRequiredState(state);
+
+         if (stateModel.isBeforeState(context.getState(), state))
+            resolveContexts(trace);
+         else
+         {
+            while (stateModel.isAfterState(context.getState(), state))
+            {
+               uninstallContext(context, trace);
+            }
+         }
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Enable an on demand context
+    *
+    * @param context the context
+    * @param trace   whether trace is enabled
+    * @throws Throwable for any error
+    */
+   protected void enableOnDemand(ControllerContext context, boolean trace) throws Throwable
+   {
+      Controller controller = null;
+      lockWrite();
+      try
+      {
+         checkShutdown();
+
+         controller = context.getController();
+         
+         // Already done
+         if (ControllerState.INSTALLED.equals(context.getRequiredState()))
+            return;
+
+         if (controller == this)
+         {
+            if (ControllerMode.ON_DEMAND.equals(context.getMode()) == false)
+               throw new IllegalStateException("Context is not ON DEMAND: " + context.toShortString());
+            
+            // Sanity check
+            getRegisteredControllerContext(context.getName(), true);
+   
+            context.setRequiredState(ControllerState.INSTALLED);
+   
+            if (trace)
+               log.trace("Enable onDemand: " + context.toShortString());
+         }
+      }
+      finally
+      {
+         unlockWrite();
+      }
+      
+      if (controller != this)
+      {
+         controller.enableOnDemand(context);
+      }
+      
+      lockWrite();
+      try
+      {
+         onDemandEnabled = true;         
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Increment state<p>
+    * <p/>
+    * This method must be invoked with the write lock taken.
+    *
+    * @param context the context
+    * @param trace   whether trace is enabled
+    * @return whether the suceeded
+    */
+   protected boolean incrementState(ControllerContext context, boolean trace)
+   {
+      ControllerState fromState = context.getState();
+
+      Controller fromController = context.getController();
+      Set<ControllerContext> fromContexts;
+
+      ControllerState toState;
+      if (ControllerState.ERROR.equals(fromState))
+      {
+         ControllerState initialState = stateModel.getInitialState();
+         errorContexts.remove(context);
+         Throwable error = null;
+         unlockWrite();
+         try
+         {
+            install(context, ControllerState.ERROR, initialState);
+         }
+         catch (Throwable t)
+         {
+            error = t;
+         }
+         finally
+         {
+            lockWrite();
+            if (error != null)
+            {
+               log.error("Error during initial installation: " + context.toShortString(), error);
+               context.setError(error);
+               errorContexts.put(context.getName(), context);
+               return false;
+            }
+         }
+         Set<ControllerContext> notInstalled = fromController.getContextsByState(initialState);
+         notInstalled.add(context);
+         context.setState(initialState);
+         return true;
+      }
+      else
+      {
+         fromContexts = fromController.getContextsByState(fromState);
+         if (fromContexts.contains(context) == false)
+            throw new IllegalStateException("Context not found in previous state (" + fromState + "): " + context.toShortString());
+         toState = stateModel.getNextState(fromState);
+         if (toState == null)
+            throw new IllegalStateException("No state after " + fromState);
+      }
+
+      unlockWrite();
+      Throwable error = null;
+      try
+      {
+         install(context, fromState, toState);
+
+         if (fromContexts != null)
+            fromContexts.remove(context);
+         Controller toController = context.getController();
+         Set<ControllerContext> toContexts = toController.getContextsByState(toState);
+         toContexts.add(context);
+         context.setState(toState);
+
+         handleInstallLifecycleCallbacks(context, toState);
+         resolveCallbacks(context, toState, true);
+      }
+      catch (Throwable t)
+      {
+         error = t;
+      }
+      finally
+      {
+         lockWrite();
+         if (error != null)
+         {
+            log.error("Error installing to " + toState.getStateString() + ": " + context.toShortString(), error);
+            uninstallContext(context, stateModel.getInitialState(), trace);
+            errorContexts.put(context.getName(), context);
+            context.setError(error);
+            return false;
+         }
+      }
+
+      return true;
+   }
+
+   /**
+    * Resolve unresolved contexts<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param trace whether trace is enabled
+    */
+   protected void resolveContexts(boolean trace)
+   {
+      boolean wasOnDemandEnabled = false;
+      boolean resolutions = true;
+      while (resolutions || onDemandEnabled)
+      {
+         if (onDemandEnabled)
+            wasOnDemandEnabled = true
+            ;
+         onDemandEnabled = false;
+         resolutions = false;
+         for (ControllerState fromState : stateModel)
+         {
+            ControllerState toState = stateModel.getNextState(fromState);
+            if (resolveContexts(fromState, toState, trace))
+            {
+               resolutions = true;
+               break;
+            }
+         }
+      }
+
+      if (trace)
+      {
+         for (ControllerState state : stateModel)
+         {
+            ControllerState nextState = stateModel.getNextState(state);
+            Set<ControllerContext> stillUnresolved = getContextsByState(state);
+            if (stillUnresolved.isEmpty() == false)
+            {
+               for (ControllerContext ctx : stillUnresolved)
+               {
+                  if (advance(ctx))
+                     log.trace("Still unresolved " + nextState.getStateString() + ": " + ctx);
+               }
+            }
+         }
+      }
+
+      // resolve child controllers
+      for (AbstractController controller : childControllers)
+      {
+         controller.lockWrite();
+         try
+         {
+            controller.resolveContexts(trace);
+         }
+         finally
+         {
+            controller.unlockWrite();
+         }
+      }
+      
+      if (wasOnDemandEnabled)
+      {
+         wasOnDemandEnabled = false;
+         Controller parent = getParentController();
+         if (parent != null)
+         {
+            if (parent instanceof AbstractController == false)
+            {
+               log.warn("Parent is not an instance of AbstractController");
+            }
+            else
+            {
+               ((AbstractController)parent).resolveContexts(trace);
+            }
+         }
+      }
+   }
+
+   /**
+    * Resolve contexts<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param fromState the from state
+    * @param toState   the to state
+    * @param trace     whether trace is enabled
+    * @return true when there were resolutions
+    */
+   protected boolean resolveContexts(ControllerState fromState, ControllerState toState, boolean trace)
+   {
+      boolean resolutions = false;
+      Set<ControllerContext> unresolved = getContextsByState(fromState);
+      Set<ControllerContext> resolved = resolveContexts(unresolved, fromState, toState, trace);
+      if (resolved.isEmpty() == false)
+      {
+         Set<ControllerContext> toProcess = new HashSet<ControllerContext>();
+         for (ControllerContext context : resolved)
+         {
+            Object name = context.getName();
+            if (fromState.equals(context.getState()) == false)
+            {
+               if (trace)
+                  log.trace("Skipping already installed " + name + " for " + toState.getStateString());
+               installing.remove(context);
+            }
+            else
+            {
+               toProcess.add(context);
+            }
+         }
+         try
+         {
+            if (toProcess.isEmpty() == false)
+            {
+               for (Iterator<ControllerContext> iter = toProcess.iterator(); iter.hasNext(); )
+               {
+                  ControllerContext context = iter.next();
+                  iter.remove();
+                  Object name = context.getName();
+                  try
+                  {
+                     if (fromState.equals(context.getState()) == false)
+                     {
+                        if (trace)
+                           log.trace("Skipping already installed " + name + " for " + toState.getStateString());
+                     }
+                     else
+                     {
+                        if (trace)
+                           log.trace("Dependencies resolved " + name + " for " + toState.getStateString());
+
+                        if (executeOrIncrementStateDirectly(context, trace))
+                        {
+                           resolutions = true;
+                           if (trace)
+                              log.trace(name + " " + toState.getStateString());
+                        }
+                        
+                     }
+                  }
+                  finally
+                  {
+                     installing.remove(context);
+                  }
+               }
+            }
+         }
+         finally
+         {
+            // If we get here something has gone seriously wrong,
+            // but try to tidyup as much state as possible
+            if (toProcess.isEmpty() == false)
+            {
+               for (ControllerContext context : toProcess)
+                  installing.remove(context);
+            }
+         }
+      }
+
+      return resolutions;
+   }
+   
+   /**
+    * Increment state in the current thread, or asynchonously if the context has {@link ControllerMode#ASYNCHRONOUS} and we find an executor<p>
+    * <p/>
+    * This method must be invoked with the write lock taken.
+    *
+    * @param context the context
+    * @param trace   whether trace is enabled
+    * @return whether the increment suceeded. If the context could be incremented asynchronously false is returned
+    */
+   private boolean executeOrIncrementStateDirectly(ControllerContext context, boolean trace)
+   {
+      boolean asynch = contextsInstalledByExecutor.shouldInstallAsynchronously(context);
+      
+      if (asynch)
+      {
+         if (executor == null)
+         {
+            Object ctx = trace ? context : context.getName();
+            log.warn("No executor in controller " + this + " to use installing asynchronous context " + ctx);
+            
+         }
+
+         Executor foundExecutor = searchForExecutor();
+         if (foundExecutor != null)
+         {
+            InstallControllerContextTask task = new InstallControllerContextTask(context, trace);
+            contextsInstalledByExecutor.markForTaskExecution(context, task);
+
+            if (trace)
+               log.trace("Recorded for asynchronous installation " + context.getName());
+            
+            try
+            {
+               foundExecutor.execute(task);
+               return false;
+            }
+            catch(RejectedExecutionException e)
+            {
+               Object ctx = trace ? context : context.getName();
+               log.warn("Asynchronous execution rejected by executor for context " + ctx + ":" + e.getMessage());
+               contextsInstalledByExecutor.disassociateWithTask(context);
+            }
+         }
+      }
+
+      return incrementState(context, trace);
+   }
+   
+   /**
+    * Return the executor stored in this controller or in its parent hierarchy. The nearest executor is returned.
+    * <p/>
+    * This method must be called with the write or read lock taken
+    * @return The found executor
+    */
+   protected Executor searchForExecutor()
+   {
+      if (executor != null)
+      {
+         return executor;
+      }
+      AbstractController parent = getParentController();
+      if (parent != null)
+      {
+        try
+        {
+           parent.lockRead();
+           return parent.searchForExecutor();
+        }
+        finally
+        {
+           parent.unlockRead();
+        }
+      }
+      return null;
+   }
+
+   /**
+    * Resolve contexts<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param contexts the contexts
+    * @param fromState the from state
+    * @param toState   the to state
+    * @param trace    whether trace is enabled
+    * @return the set of resolved contexts
+    */
+   protected Set<ControllerContext> resolveContexts(Set<ControllerContext> contexts, ControllerState fromState, ControllerState toState, boolean trace)
+   {
+      HashSet<ControllerContext> result = new HashSet<ControllerContext>();
+
+      if (contexts.isEmpty() == false)
+      {
+         for (ControllerContext ctx : contexts)
+         {
+            Object name = ctx.getName();
+            if (fromState.equals(ctx.getState()) == false)
+            {
+               if (trace)
+                  log.trace("Skipping already installed " + name + " for " + toState.getStateString());
+            }
+            else if (contextsInstalledByExecutor.isInstalledByOtherThread(ctx))
+            {
+               if (trace)
+                  log.trace("Installed by other thread " + name);
+            }
+            else if (installing.add(ctx) == false)
+            {
+               if (trace)
+                  log.trace("Already installing " + name + " for " + toState.getStateString());
+            }
+            else if (contextsInstalledByExecutor.isBeingInstalled(ctx) == true)
+            {
+               if (trace)
+                  log.trace("Already installing " + name + " for " + toState.getStateString());
+               installing.remove(ctx);
+            }
+            else if (advance(ctx))
+            {
+               try
+               {
+                  if (resolveDependencies(ctx, toState))
+                     result.add(ctx);
+                  else
+                     installing.remove(ctx);
+               }
+               catch (Throwable error)
+               {
+                  installing.remove(ctx);
+                  log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx.toShortString(), error);
+                  uninstallContext(ctx, stateModel.getInitialState(), trace);
+                  errorContexts.put(ctx.getName(), ctx);
+                  ctx.setError(error);
+               }
+            }
+            else
+            {
+               installing.remove(ctx);
+            }
+         }
+      }
+
+      return result;
+   }
+   
+   /**
+    * See if the context has its dependencies resolved to move to the given state.
+    * <p/>
+    * This method must be invoked with the write lock taken
+    * 
+    * @param ctx The context
+    * @param state The state we want to move to
+    * @return true if the dependencies are resolved
+    */
+   private boolean resolveDependencies(ControllerContext ctx, ControllerState state)
+   {
+      DependencyInfo dependencies = ctx.getDependencyInfo();
+      return dependencies == null || dependencies.resolveDependencies(this, state);
+   }
+
+   /**
+    * Uninstall a context
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param context the context to uninstall
+    * @param toState the target state
+    * @param trace   whether trace is enabled
+    */
+   protected void uninstallContext(ControllerContext context, ControllerState toState, boolean trace)
+   {
+      if (!stateModel.isValidState(toState))
+         log.error("INTERNAL ERROR: unknown state " + toState + " states=" + stateModel, new Exception("STACKTRACE"));
+
+      while (true)
+      {
+         ControllerState fromState = context.getState();
+         if (ControllerState.ERROR.equals(fromState))
+            return;
+         if (!stateModel.isValidState(fromState))
+            log.error("INTERNAL ERROR: current state not found: " + context.toShortString(), new Exception("STACKTRACE"));
+         
+         if (stateModel.isAfterState(toState, fromState))
+            return;
+         else
+            uninstallContext(context, trace);
+      }
+   }
+
+   /**
+    * Uninstall a context<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param context the context to uninstall
+    * @param trace   whether trace is enabled
+    */
+   protected void uninstallContext(ControllerContext context, boolean trace)
+   {
+      Object name = context.getName();
+
+      ControllerState fromState = context.getState();
+
+      if (trace)
+         log.trace("Uninstalling " + name + " from " + fromState.getStateString());
+
+      Controller fromController = context.getController();
+
+      Set<ControllerContext> fromContexts = fromController.getContextsByState(fromState);
+      if (fromContexts == null || fromContexts.remove(context) == false)
+         throw new Error("INTERNAL ERROR: context not found in previous state " + fromState.getStateString() + " context=" + context.toShortString(), new Exception("STACKTRACE"));
+
+      DependencyInfo dependencies = context.getDependencyInfo();
+      if (dependencies != null)
+      {
+         try
+         {
+            Set<DependencyItem> dependsOnMe = dependencies.getDependsOnMe(null);
+            if (dependsOnMe.isEmpty() == false)
+            {
+               for (DependencyItem item : dependsOnMe)
+               {
+                  if (item.isResolved())
+                  {
+                     ControllerState dependentState = item.getDependentState();
+                     if (dependentState == null || dependentState.equals(fromState))
+                     {
+                        if (item.unresolved(this))
+                        {
+                           Set<ControllerContext> dependents = CollectionsFactory.createLazySet();
+                           getContexts(item.getName(), dependents);
+                           if (dependents.isEmpty() == false)
+                           {
+                              ControllerState whenRequired = item.getWhenRequired();
+                              if (whenRequired == null)
+                                 whenRequired = stateModel.getInitialState();
+
+                              for (ControllerContext dependent : dependents)
+                              {
+                                 boolean selfDependency = (dependent == context);
+                                 if (!selfDependency)
+                                 {
+                                    contextsInstalledByExecutor.interruptTaskAndBlock(dependent, this);
+                                    if (stateModel.isBeforeState(dependent.getState(), whenRequired) == false)
+                                    {  
+                                       uninstallContext(dependent, whenRequired, trace);
+                                    }
+                                 }
+                              }
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+         }
+         catch (Throwable error)
+         {
+            log.error("Error resolving dependencies for " + fromState.getStateString() + ": " + context.toShortString(), error);
+            // Not much else we can do - no uninstall, since we are at uninstall ;-)
+            errorContexts.put(context.getName(), context);
+            context.setError(error);
+         }
+      }
+
+      // The state could have changed while calling out to dependents
+      fromState = context.getState();
+      if (ControllerState.ERROR.equals(fromState))
+         return;
+      
+      ControllerState toState = stateModel.getPreviousState(fromState);
+      if (toState == null)
+      {
+         // This is hack, we signal true uninstalled status by putting it in the error state
+         context.setState(ControllerState.ERROR);
+         return;
+      }
+
+      unlockWrite();
+      try
+      {
+         resolveCallbacks(context, fromState, false);
+         handleUninstallLifecycleCallbacks(context, toState);
+
+         uninstall(context, fromState, toState);
+
+         Controller toController = context.getController();
+         Set<ControllerContext> toContexts = toController.getContextsByState(toState);
+         toContexts.add(context);
+         context.setState(toState);
+
+         uninstallUnusedOnDemandContexts(context, trace);
+      }
+      catch (Throwable t)
+      {
+         log.warn("Error uninstalling from " + fromState.getStateString() + ": " + context.toShortString(), t);
+      }
+      finally
+      {
+         lockWrite();
+      }
+   }
+
+   /**
+    * If the context being uninstalled depends on On_Demand contexts that are not used anymore
+    * those On_Demand contexts are uninstalled back to the DESCRIBED state.<p>
+    * 
+    * This method must be called with NO locks taken.
+    *
+    * @param context the context which is being uninstalled.
+    * @param trace do trace log
+    */
+   protected void uninstallUnusedOnDemandContexts(ControllerContext context, boolean trace)
+   {
+      lockWrite();
+      try
+      {
+         DependencyInfo dependencies = context.getDependencyInfo();
+         if (dependencies != null)
+         {
+            Set<DependencyItem> iDependOn = dependencies.getIDependOn(null);
+            if (iDependOn.isEmpty() == false)
+            {
+               for (DependencyItem item : iDependOn)
+               {
+                  if (item.isResolved()) //TODO Is this check necessary
+                  {
+                     Object name = item.getIDependOn();
+                     if (name == null)
+                        continue;
+   
+                     ControllerContext other = getContext(name, null);
+                     if (other == null)
+                     {
+                        log.warn("Could not find dependency '" + name + "' while uninstalling on demand contexts for " + item);
+                        continue;
+                     }
+                     if (other.getMode() != ControllerMode.ON_DEMAND)
+                        continue;
+   
+                     DependencyInfo otherDependencies = other.getDependencyInfo();
+                     if (otherDependencies == null)
+                        continue;
+                     
+                     Set<DependencyItem> dependsOnOther = otherDependencies.getDependsOnMe(null);
+                     boolean isRequired = false;
+                     for (DependencyItem dependsOnOtherItem : dependsOnOther)
+                     {
+                        ControllerContext dependsContext = getContext(dependsOnOtherItem.getName(), null);
+                        if (dependsContext == null)
+                        {
+                           log.warn("Could not find reverse dependency '" + dependsOnOtherItem.getName() + "' while uninstalling on demand contexts for " + item);
+                           continue;
+                        }
+                        
+                        ControllerState requiredState = item.getWhenRequired();
+                        ControllerState actualState = dependsContext.getState();
+                        
+                        if (requiredState.equals(actualState) || stateModel.isBeforeState(requiredState, actualState))
+                        {
+                           isRequired = true;
+                           break;
+                        }
+                     }
+                     if (!isRequired)
+                     {
+                        //For some reason uninstallContext() uninstalls to the state below the passed in one, add one
+                        ControllerState state = stateModel.getNextState(ControllerMode.ON_DEMAND.getRequiredState());
+                        uninstallContext(other, state, trace);
+                     }
+                  }
+               }
+            }
+         }
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Get all contexts by name,
+    * check child controllers as well.
+    *
+    * @param name the name of the context
+    * @param contexts found contexts
+    */
+   protected void getContexts(Object name, Set<ControllerContext> contexts)
+   {
+      ControllerContext context = getContext(name, null);
+      if (context != null)
+      {
+         Set<Object> aliases = context.getAliases();
+         // only pick up unique name
+         // TODO also ignore alises from @Aliases?
+         if (aliases == null || aliases.contains(name) == false)
+            contexts.add(context);
+      }
+
+      Set<AbstractController> children = getControllers();
+      if (children != null && children.isEmpty() == false)
+      {
+         for (AbstractController child : children)
+         {
+            child.getContexts(name, contexts);
+         }
+      }
+   }
+
+   /**
+    * Add callback item under demand name.
+    *
+    * @param <T> the callback item type
+    * @param name demand name
+    * @param isInstallPhase install or uninstall phase
+    * @param callback callback item
+    */
+   protected <T> void addCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
+   {
+      lockWrite();
+      try
+      {
+         Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
+         Set<CallbackItem<?>> callbacks = map.get(name);
+         if (callbacks == null)
+         {
+            callbacks = new HashSet<CallbackItem<?>>();
+            map.put(name, callbacks);
+         }
+         callbacks.add(callback);
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Remove callback item under demand name.
+    *
+    * @param <T> the callback item type
+    * @param name demand name
+    * @param isInstallPhase install or uninstall phase
+    * @param callback callback item
+    */
+   protected <T> void removeCallback(Object name, boolean isInstallPhase, CallbackItem<T> callback)
+   {
+      lockWrite();
+      try
+      {
+         Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
+         Set<CallbackItem<?>> callbacks = map.get(name);
+         if (callbacks != null)
+         {
+            callbacks.remove(callback);
+            if (callbacks.isEmpty())
+               map.remove(name);
+         }
+      }
+      finally
+      {
+         unlockWrite();
+      }
+   }
+
+   /**
+    * Get calbacks from context.
+    *
+    * @param context current context
+    * @param isInstallPhase install or uninstall phase
+    * @return callback items from dependency info
+    */
+   protected Set<CallbackItem<?>> getDependencyCallbacks(ControllerContext context, boolean isInstallPhase)
+   {
+      DependencyInfo di = context.getDependencyInfo();
+      if (di != null)
+      {
+         return isInstallPhase ? di.getInstallItems() : di.getUninstallItems();
+      }
+      return null;
+   }
+
+   /**
+    * Get the matching callbacks.
+    *
+    * @param name demand name
+    * @param isInstallPhase install or uninstall phase
+    * @return all matching registered callbacks or empty set if no such item
+    */
+   protected Set<CallbackItem<?>> getCallbacks(Object name, boolean isInstallPhase)
+   {
+      lockRead();
+      try
+      {
+         Map<Object, Set<CallbackItem<?>>> map = (isInstallPhase ? installCallbacks : uninstallCallbacks);
+         Set<CallbackItem<?>> callbacks = map.get(name);
+         return callbacks != null ? callbacks : Collections.<CallbackItem<?>>emptySet();
+      }
+      finally
+      {
+         unlockRead();
+      }
+   }
+
+   /**
+    * Resolve callbacks.
+    *
+    * @param callbacks the callbacks
+    * @param state current context state
+    * @param execute do execute callback
+    * @param isInstallPhase install or uninstall phase
+    * @param type install or uninstall type
+    */
+   protected void resolveCallbacks(Set<CallbackItem<?>> callbacks, ControllerState state, boolean execute, boolean isInstallPhase, boolean type)
+   {
+      if (callbacks != null && callbacks.isEmpty() == false)
+      {
+         for (CallbackItem<?> callback : callbacks)
+         {
+            if (callback.getWhenRequired().equals(state))
+            {
+               if (isInstallPhase)
+               {
+                  addCallback(callback.getIDependOn(), type, callback);
+               }
+               else
+               {
+                  removeCallback(callback.getIDependOn(), type, callback);
+               }
+               if (execute)
+               {
+                  try
+                  {
+                     callback.ownerCallback(this, isInstallPhase);
+                  }
+                  catch (Throwable t)
+                  {
+                     log.warn("Broken callback: " + callback, t);
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * Resolve callback items.
+    *
+    * @param context current context
+    * @param state current context state
+    * @param isInstallPhase install or uninstall phase
+    */
+   protected void resolveCallbacks(ControllerContext context, ControllerState state, boolean isInstallPhase)
+   {
+      ClassLoader previous = null;
+      try
+      {
+         previous = SecurityActions.setContextClassLoader(context);
+         // existing owner callbacks
+         Set<CallbackItem<?>> installs = getDependencyCallbacks(context, true);
+         resolveCallbacks(installs, state, isInstallPhase, isInstallPhase, true);
+         Set<CallbackItem<?>> uninstalls = getDependencyCallbacks(context, false);
+         resolveCallbacks(uninstalls, state, isInstallPhase == false, isInstallPhase, false);
+
+         // change callbacks, applied only if context is autowire candidate
+         DependencyInfo dependencyInfo = context.getDependencyInfo();
+         if (dependencyInfo != null && dependencyInfo.isAutowireCandidate())
+         {
+            // match callbacks by name
+            Set<CallbackItem<?>> existingCallbacks = new HashSet<CallbackItem<?>>();
+            existingCallbacks.addAll(getCallbacks(context.getName(), isInstallPhase));
+            // match by classes
+            Collection<Class<?>> classes = getExposedClasses(context);
+            if (classes != null && classes.isEmpty() == false)
+            {
+               for (Class<?> clazz : classes)
+               {
+                  existingCallbacks.addAll(getCallbacks(clazz, isInstallPhase));
+               }
+            }
+
+            // Do the installs if we are at the required state
+            if (existingCallbacks != null && existingCallbacks.isEmpty() == false)
+            {
+               for(CallbackItem<?> callback : existingCallbacks)
+               {
+                  if (state.equals(callback.getDependentState()))
+                  {
+                     try
+                     {
+                        callback.changeCallback(this, context, isInstallPhase);
+                     }
+                     catch (Throwable t)
+                     {
+                        log.warn("Broken callback: " + callback, t);
+                     }
+                  }
+               }
+            }
+         }
+      }
+      // let's make sure we suppress any exceptions
+      catch (Throwable t)
+      {
+         log.warn("Cannot resolve callbacks, state= " + state + ", isInstall= " + isInstallPhase + ", context= " + context, t);
+      }
+      finally
+      {
+         if (previous != null)
+            SecurityActions.resetContextClassLoader(previous);
+      }
+   }
+
+   /**
+    * Handle install lifecycle callbacks.
+    *
+    * @param context the context
+    * @param state the state
+    * @throws Throwable for any error
+    */
+   protected void handleInstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
+   {
+      handleLifecycleCallbacks(context, state, true);
+   }
+
+   /**
+    * Handle uninstall lifecycle callbacks.
+    *
+    * @param context the context
+    * @param state the state
+    * @throws Throwable for any error
+    */
+   protected void handleUninstallLifecycleCallbacks(ControllerContext context, ControllerState state) throws Throwable
+   {
+      ControllerState oldState = stateModel.getNextState(state);
+      handleLifecycleCallbacks(context, oldState, false);
+   }
+
+   /**
+    * Handle lifecycle callbacks.
+    *
+    * @param context the context
+    * @param state the state
+    * @param install is it install or uninstall
+    * @throws Throwable for any error
+    */
+   protected void handleLifecycleCallbacks(ControllerContext context, ControllerState state, boolean install) throws Throwable
+   {
+      DependencyInfo di = context.getDependencyInfo();
+      if (di != null)
+      {
+         List<LifecycleCallbackItem> callbacks = di.getLifecycleCallbacks();
+         for (LifecycleCallbackItem callback : callbacks)
+         {
+            if (callback.getWhenRequired().equals(state))
+            {
+               if (install)
+                  callback.install(context);
+               else
+                  callback.uninstall(context);
+            }
+         }
+      }
+   }
+
+   /**
+    * Install a context<p>
+    * <p/>
+    * This method must be invoked with NO locks taken
+    *
+    * @param context   the context
+    * @param fromState the from state
+    * @param toState   the toState
+    * @throws Throwable for any error
+    */
+   protected void install(ControllerContext context, ControllerState fromState, ControllerState toState) throws Throwable
+   {
+      long time = 0;
+      boolean collectStats = this.collectStats;
+      if (collectStats)
+         time = System.currentTimeMillis();
+      try
+      {
+         context.install(fromState, toState);
+      }
+      finally
+      {
+         if (collectStats)
+         {
+            time = System.currentTimeMillis() - time;
+            if (time > 0)
+            {
+               synchronized (this)
+               {
+                  if (installStats == null)
+                     installStats = new StateStatistics();
+
+                  String state = toState.getStateString();
+                  String name = context.getName().toString();
+                  installStats.addStatistic(state, name, time);
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * Uninstall a context<p>
+    * <p/>
+    * This method must be invoked with NO locks taken
+    *
+    * @param context   the context
+    * @param fromState the from state
+    * @param toState   the to state
+    */
+   protected void uninstall(ControllerContext context, ControllerState fromState, ControllerState toState)
+   {
+      context.uninstall(fromState, toState);
+   }
+
+   /**
+    * Whether we should advance the context<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param context the context
+    * @return true when we should advance the context
+    */
+   protected boolean advance(ControllerContext context)
+   {
+      ControllerMode mode = context.getMode();
+
+      // Never advance for disabled
+      if (ControllerMode.DISABLED.equals(mode))
+         return false;
+
+      return stateModel.isBeforeState(context.getState(), context.getRequiredState());
+   }
+
+   /**
+    * Lock for read
+    */
+   protected void lockRead()
+   {
+      lock.readLock().lock();
+   }
+
+   /**
+    * Unlock for read
+    */
+   protected void unlockRead()
+   {
+      lock.readLock().unlock();
+   }
+
+   /**
+    * Lock for write
+    */
+   protected void lockWrite()
+   {
+      lock.writeLock().lock();
+   }
+
+   /**
+    * Unlock for write
+    */
+   protected void unlockWrite()
+   {
+      lock.writeLock().unlock();
+   }
+
+   /**
+    * Get a registered context<p>
+    * <p/>
+    * This method should be invoked with at least the read lock taken
+    *
+    * @param name      the name with which to register it
+    * @param mustExist whether to throw an error when the context does not exist
+    * @return context the registered context
+    * @throws IllegalArgumentException for null parameters
+    * @throws IllegalStateException    if the context if must exist is true and the context does not exist
+    */
+   protected ControllerContext getRegisteredControllerContext(Object name, boolean mustExist)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+
+      ControllerContext result = allContexts.get(name);
+      if (mustExist && result == null)
+         throw new IllegalStateException("Context does not exist with name: " + name);
+      return result;
+   }
+
+   /**
+    * Register a context and all its aliases<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param context the context to register
+    * @throws IllegalArgumentException for null parameters
+    * @throws IllegalStateException    if the context is already registered with that name or alias
+    */
+   protected void registerControllerContext(ControllerContext context)
+   {
+      if (context == null)
+         throw new IllegalArgumentException("Null context");
+
+      Set<Object> aliases = context.getAliases();
+
+      // Register the context
+      Object name = context.getName();
+      registerControllerContext(name, context);
+
+      // Register the aliases
+      if (aliases != null && aliases.isEmpty() == false)
+      {
+         int ok = 0;
+         try
+         {
+            for (Object alias : aliases)
+            {
+               registerControllerContext(alias, context);
+               ++ok;
+            }
+         }
+         finally
+         {
+            // It didn't work
+            if (ok != aliases.size() && ok > 0)
+            {
+               // Unregister the aliases we added
+               for (Object alias : aliases)
+               {
+                  if (ok-- == 0)
+                     break;
+                  try
+                  {
+                     unregisterControllerContext(alias);
+                  }
+                  catch (Throwable ignored)
+                  {
+                     log.debug("Error unregistering alias: " + alias, ignored);
+                  }
+               }
+
+               // Unregister the context
+               try
+               {
+                  unregisterControllerContext(name);
+               }
+               catch (Throwable ignored)
+               {
+                  log.debug("Error unregistering context with name: " + name, ignored);
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * Unregister a context and all its aliases<p>
+    * <p/>
+    * This method must be invoked with the write lock taken
+    *
+    * @param context the context
+    * @throws IllegalArgumentException for null parameters
+    * @throws IllegalStateException    if the context is not registered
+    */
+   protected void unregisterControllerContext(ControllerContext context)
+   {
+      if (context == null)
+         throw new IllegalArgumentException("Null context");
+
+      Set<Object> aliases = context.getAliases();
+
+      // Unregister the context
+      Object name = context.getName();
+      unregisterControllerContext(name);
+
+      // Unegister the aliases
+      if (aliases != null && aliases.isEmpty() == false)
+      {
+         for (Object alias : aliases)
+         {
+            try
+            {
+               unregisterControllerContext(alias);
+            }
+            catch (Throwable ignored)
+            {
+               log.debug("Error unregistering alias: " + alias, ignored);
+            }
+         }
+      }
+   }
+
+   /**
+    * Register a context<p>
+    * <p/>
+    * This method must be invoked with the write lock taken<p>
+    * <p/>
+    * NOTE: You probably want to use the {@link #registerControllerContext(ControllerContext)}
+    *
+    * @param name    the name with which to register it
+    * @param context the context to register
+    * @throws IllegalArgumentException for null parameters
+    * @throws IllegalStateException    if the context is already registered with that name
+    */
+   protected void registerControllerContext(Object name, ControllerContext context)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      if (context == null)
+         throw new IllegalArgumentException("Null context");
+
+      if (allContexts.containsKey(name) == false)
+         allContexts.put(name, context);
+      else
+         throw new IllegalStateException("Unable to register context " + context.toShortString() + ", name already exists: " + name);
+   }
+
+   /**
+    * Unregister a context<p>
+    * <p/>
+    * This method must be invoked with the write lock taken<p>
+    * <p/>
+    * NOTE: You probably want to use the {@link #unregisterControllerContext(ControllerContext)}
+    *
+    * @param name the name it was registered with
+    * @throws IllegalArgumentException for null parameters
+    */
+   protected void unregisterControllerContext(Object name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+      allContexts.remove(name);
+   }
+
+   // --- alias dependency
+
+   private static class InnerAliasControllerContext extends AbstractAliasControllerContext
+   {
+      private InnerAliasControllerContext(Object alias, String id, Object original, ControllerContextActions actions)
+      {
+         super(alias, id, original, actions);
+      }
+   }
+
+   private class AliasControllerContextAction extends SimpleControllerContextAction<AliasControllerContext>
+   {
+      protected AliasControllerContext contextCast(ControllerContext context)
+      {
+         return AliasControllerContext.class.cast(context);
+      }
+
+      protected boolean validateContext(ControllerContext context)
+      {
+         return (context instanceof AliasControllerContext);
+      }
+
+      protected void installAction(AliasControllerContext context) throws Throwable
+      {
+         Object alias = context.getAlias();
+         Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
+         if (jmxAlias != null)
+            alias = jmxAlias;
+
+         Object original = context.getOriginal();
+         Object jmxOriginal = JMXObjectNameFix.needsAnAlias(original);
+         if (jmxOriginal != null)
+            original = jmxOriginal;
+
+         // get the context's controller - not the one we registered with
+         AbstractController controller = (AbstractController)context.getController();
+         lockWrite();
+         try
+         {
+            ControllerContext lookup = controller.getRegisteredControllerContext(original, true);
+            controller.registerControllerContext(alias, lookup);
+            if (log.isTraceEnabled())
+               log.trace("Added alias " + alias + " for context " + context);
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+
+      protected void uninstallAction(AliasControllerContext context)
+      {
+         lockWrite();
+         try
+         {
+            Object alias = context.getAlias();
+            Object jmxAlias = JMXObjectNameFix.needsAnAlias(alias);
+            if (jmxAlias != null)
+               alias = jmxAlias;
+
+            // get the context's controller - not the one we registered with
+            AbstractController controller = (AbstractController)context.getController();
+            controller.unregisterControllerContext(alias);
+            if (log.isTraceEnabled())
+               log.trace("Removed alias " + alias);
+         }
+         finally
+         {
+            unlockWrite();
+         }
+      }
+   }
+
+   public boolean isAsynchronousInstallInProgress(ControllerContext context)
+   {
+      if (context.getMode() != ControllerMode.ASYNCHRONOUS)
+         return false;
+
+      return contextsInstalledByExecutor.isBeingInstalled(context);
+   }
+
+   /**
+    * A task being handled asyynchronously by the executor
+    * 
+    */
+   abstract class InterruptibleControllerTask implements Runnable
+   {
+      /**
+       * The thread used to handle the asynchronous task
+       */
+      Thread thread;
+      
+      /**
+       * True if the task is interrupted  
+       */
+      volatile boolean interrupted;
+
+      /**
+       * Latch counted down by interrupted tasks once they have reached a state where they finish 
+       */
+      CountDownLatch interruptedLatch;
+      
+      /**
+       * Gets the thread that is currently used to install the asyncronous task
+       * @return The thread, or null if still queued in the executor
+       */
+      synchronized Thread getThread()
+      {
+         return thread;
+      }      
+      
+      /**
+       * Interrupt the task, and if associated with a thread
+       * return a countdown latch that will have a count of 0
+       * once the job has broken out
+       * @return the latch or null if not yet interrupted
+       */
+      synchronized CountDownLatch interrupt()
+      {
+         interrupted = true;
+         if (thread != null)
+         {
+            interruptedLatch = new CountDownLatch(1);
+            return interruptedLatch;
+         }
+         return null;
+      }
+
+      /**
+       * Check the interrupted status
+       * @return true if interrupted
+       */
+      boolean isInterrupted()
+      {
+         return interrupted;
+      }
+      
+      /**
+       * Associate the current thread with the task, or clear it in contextsInstalledByExecutor
+       * if it has been interrupted. This should be the first thing tasks do once they run.
+       *
+       * @param context the context
+       * @return true if interrupted
+       */
+      synchronized boolean associateWithThreadOrDisassociateIfInterrupted(ControllerContext context)
+      {
+         if (interrupted)
+         {
+            contextsInstalledByExecutor.disassociateWithTask(context);
+            return true;
+         }
+         thread = Thread.currentThread();
+         return false;
+      }
+      
+      /**
+       * Disassociate the thread with the task, and if interrupted count down the latch so those
+       * awaiting the latch know the task has finished.
+       */
+      synchronized void disassociateWithThreadAndSignalEnd()
+      {
+         thread = null;
+         if (interruptedLatch != null)
+         {
+            interruptedLatch.countDown();
+         }
+      }
+   }
+
+   
+   /**
+    * Interruptible task used to install a controller context asynchronously.
+    * It will install the context as far as possible towards its required state,
+    * before resolving the other contexts.
+    */
+   class InstallControllerContextTask extends InterruptibleControllerTask
+   {
+      ControllerContext context;
+      ClassLoader classLoader;
+      boolean trace;
+
+      public InstallControllerContextTask(ControllerContext context, boolean trace)
+      {
+         this.context = context;
+         this.classLoader = SecurityActions.getContextClassLoader();
+         this.trace = trace;
+      }
+      
+      public void run()
+      {
+         if (associateWithThreadOrDisassociateIfInterrupted(context))
+            return;
+         
+         if (trace)
+            log.trace(Thread.currentThread().getName() + " starting asyncronous install of " + context.getName());
+         
+         lockWrite();
+         ClassLoader tcl = SecurityActions.setContextClassLoader(classLoader);
+         try
+         {
+            //Move the given context as far through the states as possible
+            boolean stateChanged = false;
+            try
+            {
+               stateChanged = installMyContext();
+            }
+            finally
+            {
+               contextsInstalledByExecutor.disassociateWithTask(context);
+            }
+            
+            //The given context had its state changed, now see if anybody was dependent on it
+            if (stateChanged && !interrupted)
+            {
+               resolveContexts(trace);
+            }
+         }
+         catch (Throwable t)
+         {
+            Object ctx = trace ? context : context.getName();
+            log.error("Problem installing context asynchronously " + ctx, t);
+         }
+         finally
+         {
+            if (trace)
+               log.trace(Thread.currentThread().getName() + " asynchronous install done for " + context.getName());
+            SecurityActions.resetContextClassLoader(tcl);
+            unlockWrite();
+            
+            disassociateWithThreadAndSignalEnd();
+         }
+      }
+      
+      boolean installMyContext()
+      {
+         boolean stateChanged = false;
+
+         if (!stateModel.isValidState(context.getRequiredState()))
+            throw new IllegalArgumentException("Unknown state: " + context.getRequiredState());
+         
+         boolean resolved = true;
+
+         while(resolved && stateModel.isBeforeState(context.getState(), context.getRequiredState()) && !interrupted)
+         {
+            resolved = false;
+            ControllerState toState = stateModel.getNextState(context.getState());
+            if (advance(context))
+            {
+               try
+               {
+                  if (resolveDependencies(context, toState))
+                  {
+                     resolved = true;
+                  }
+               }
+               catch (Throwable error)
+               {
+                  Object ctx = trace ? context : context.getName();
+                  log.error("Error resolving dependencies for " + toState.getStateString() + ": " + ctx, error);
+                  uninstallContext(context, stateModel.getInitialState(), trace);
+                  errorContexts.put(context.getName(), context);
+                  context.setError(error);
+               }
+               
+               if (resolved)
+               {
+                  resolved = incrementState(context, trace);
+                  if (resolved)
+                  {
+                     stateChanged = true;
+                  }
+               }
+            }
+         }
+
+         return stateChanged;
+      }
+   }
+
+   
+   
+   /**
+    * Class used to keep track of contexts that are scheduled for asynchronous install, 
+    * or are in the process of being installed asynchronously. 
+    * 
+    */
+   private static class ContextsInstalledByExecutor
+   {
+      /** The contexts that are currently being installed by the executor */
+      Map<ControllerContext, InterruptibleControllerTask> executorTasksByContext = new ConcurrentHashMap<ControllerContext, InterruptibleControllerTask>();
+      /**
+       * Checks whether context should be installed asynchronously, by checking the controller mode and the current thread
+       * @param context The context
+       * @return Whether the context should be installed in the executor
+       */
+      boolean shouldInstallAsynchronously(ControllerContext context)
+      {
+         if (context.getMode() == ControllerMode.ASYNCHRONOUS)
+         {
+            final InterruptibleControllerTask task = executorTasksByContext.get(context);
+            return task == null || task.getThread() != Thread.currentThread();
+         }
+         return false;
+      }
+      
+      /**
+       * Records the context and the asynchronous task to install it
+       * @param context The context to be installed asynchronously
+       * @param task The task that will be used to install the context 
+       */
+      void markForTaskExecution(ControllerContext context, InterruptibleControllerTask task)
+      {
+         executorTasksByContext.put(context, task);
+      }
+      
+      /**
+       * Removes the task that was used to install the context
+       * @param context The context whose task we want to remove
+       */
+      void disassociateWithTask(ControllerContext context)
+      {
+         executorTasksByContext.remove(context);
+      }
+      
+      /**
+       * Checks if the context is recorded for asynchronous install, and if the thread used is different
+       * from the current thread. 
+       * @param context The context to check
+       * @return true if installed by another thread
+       */
+      boolean isInstalledByOtherThread(ControllerContext context)
+      {
+         final InterruptibleControllerTask task = executorTasksByContext.get(context);
+         return task != null && Thread.currentThread() != task.getThread();         
+      }
+      
+      /**
+       * Checks in the context is recorded for asynchronous install
+       * @param context The context to check
+       * @return true if recorded for asynchronous install
+       */
+      boolean isBeingInstalled(ControllerContext context)
+      {
+         return executorTasksByContext.get(context) != null;
+      }
+      
+      /**
+       * Checks if the passed in context is recorded for asynchronous install,
+       * and if it is interrupts the asynchronous task.<p>
+       *
+       * This method must be called with the write lock taken
+       * 
+       * @param context The context to interrupt
+       * @param controller the controller
+       */
+      void interruptTaskAndBlock(ControllerContext context, AbstractController controller)
+      {
+         InterruptibleControllerTask task = executorTasksByContext.get(context);
+         if (task != null)
+         {
+            controller.unlockWrite();
+            try
+            {
+               CountDownLatch latch = task.interrupt();
+               if (latch != null)
+               {
+                  try
+                  {
+                     latch.await();
+                  }
+                  catch(InterruptedException e)
+                  {
+                     Thread.currentThread().interrupt();
+                  }
+               }
+            }
+            finally
+            {
+               controller.lockWrite();
+            }
+         }
+      }
+   }
+
+   // Context queries & registry
+
+   public Set<ControllerContext> filter(Iterable<ControllerContext> contexts, ContextFilter filter)
+   {
+      return registry.filter(contexts, filter);
+   }
+
+   public Set<ControllerContext> getInstantiatedContexts(Class<?> clazz)
+   {
+      return registry.getInstantiatedContexts(clazz);
+   }
+
+   public Set<ControllerContext> getContexts(Class<?> clazz, ControllerState state)
+   {
+      return registry.getContexts(clazz, state);
+   }
+
+   public ControllerContext getContextByClass(Class<?> clazz)
+   {
+      return registry.getContextByClass(clazz);
+   }
+
+   public void addInstantiatedContext(ControllerContext context)
+   {
+      registry.addInstantiatedContext(context);
+   }
+
+   public void registerInstantiatedContext(ControllerContext context, Class<?>... classes)
+   {
+      registry.registerInstantiatedContext(context, classes);
+   }
+
+   public void unregisterInstantiatedContext(ControllerContext context, Class<?>... classes)
+   {
+      registry.unregisterInstantiatedContext(context, classes);
+   }
+
+   public void removeInstantiatedContext(ControllerContext context)
+   {
+      registry.removeInstantiatedContext(context);
+   }
+
+   public Set<Class<?>> getExposedClasses(ControllerContext context)
+   {
+      return registry.getExposedClasses(context);
+   }
+
+   
+   //New accessors for resolver
+   protected boolean isOnDemandEnabled()
+   {
+      return onDemandEnabled;
+   }
+
+   protected void setOnDemandEnabled(boolean onDemandEnabled)
+   {
+      this.onDemandEnabled = onDemandEnabled;
+   }
+   
+   
+}

Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/support/ScopedTestUtil.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,90 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors. 
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/ 
+package org.jboss.test.kernel.dependency.support;
+
+import java.net.URL;
+
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.dependency.plugins.AbstractController;
+import org.jboss.dependency.spi.Controller;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.kernel.Kernel;
+import org.jboss.kernel.spi.dependency.KernelControllerContext;
+import org.jboss.kernel.spi.deployment.KernelDeployment;
+import org.jboss.test.kernel.AbstractKernelTest;
+
+/**
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ScopedTestUtil extends TestUtil
+{
+   public ScopedTestUtil(Kernel kernel, AbstractKernelTest test) throws Throwable
+   {
+      super(kernel, test);
+   }
+
+   @Override
+   public ControllerContext getContext(String name)
+   {
+      return searchForContext(name, null);
+   }
+
+   @Override
+   public ControllerContext getInstalledContext(String name) throws Throwable
+   {
+      return searchForContext(name, ControllerState.INSTALLED);
+   }
+   
+   protected ControllerContext searchForContext(String name, ControllerState state)
+   {
+      Controller main = getKernel().getController();
+      if (main instanceof AbstractController == false)
+         throw new RuntimeException("Unknown controller type " + main);
+         
+      AbstractController mainController = (AbstractController)getKernel().getController();
+      ControllerContext context = mainController.getContext(name, state);
+      if (context != null)
+         return context;
+      
+      for (Controller controller : mainController.getControllers())
+      {
+         if (controller instanceof AbstractController == false)
+            throw new RuntimeException("Unknown controller type");
+         context = ((AbstractController)controller).getContext(name, state);
+         if (context != null)
+            return context;
+      }
+      
+      return null;
+   }
+
+   @Override
+   public void uninstall(String name) throws Throwable
+   {
+      super.uninstall(name);
+   }
+
+   
+}

Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java	2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,125 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.textui.TestRunner;
-
-/**
- * Dependency Test Suite.
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class DependencyTestSuite extends TestSuite
-{
-   public static void main(String[] args)
-   {
-      TestRunner.run(suite());
-   }
-
-   public static Test suite()
-   {
-      TestSuite suite = new TestSuite("Dependency Tests");
-
-      suite.addTest(PlainDependencyTestCase.suite());
-      suite.addTest(PlainDependencyXMLTestCase.suite());
-      suite.addTest(PlainDependencyAnnotationTestCase.suite());
-      suite.addTest(GenericBeanFactoryPlainDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryPlainDependencyXMLTestCase.suite());
-      suite.addTest(OnDemandDependencyTestCase.suite());
-      suite.addTest(OnDemandDependencyXMLTestCase.suite());
-      suite.addTest(GenericBeanFactoryOnDemandDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryOnDemandDependencyXMLTestCase.suite());
-      suite.addTest(PropertyDependencyTestCase.suite());
-      suite.addTest(PropertyDependencyXMLTestCase.suite());
-      suite.addTest(PropertyDependencyAnnotationTestCase.suite());
-      suite.addTest(PropertyFieldDependencyTestCase.suite());
-      suite.addTest(PropertyField2DependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryPropertyDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryPropertyDependencyXMLTestCase.suite());
-      suite.addTest(GenericBeanFactoryFieldPropertyDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryField2PropertyDependencyTestCase.suite());
-      suite.addTest(ConstructorDependencyTestCase.suite());
-      suite.addTest(ConstructorDependencyXMLTestCase.suite());
-      suite.addTest(ConstructorDependencyAnnotationTestCase.suite());
-      suite.addTest(GenericBeanFactoryConstructorDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryConstructorDependencyXMLTestCase.suite());
-      suite.addTest(DemandDependencyTestCase.suite());
-      suite.addTest(DemandDependencyXMLTestCase.suite());
-      suite.addTest(DemandDependencyAnnotationTestCase.suite());
-      suite.addTest(GenericBeanFactoryDemandDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryDemandDependencyXMLTestCase.suite());
-      suite.addTest(PlainLifecycleDependencyTestCase.suite());
-      suite.addTest(PlainLifecycleDependencyXMLTestCase.suite());
-      suite.addTest(PlainLifecycleDependencyAnnotationTestCase.suite());
-      suite.addTest(GenericBeanFactoryPlainLifecycleDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryPlainLifecycleDependencyXMLTestCase.suite());
-      suite.addTest(ComplicatedLifecycleDependencyTestCase.suite());
-      suite.addTest(ComplicatedLifecycleDependencyXMLTestCase.suite());
-      suite.addTest(ComplicatedLifecycleDependencyAnnotationTestCase.suite());
-      suite.addTest(KernelControllerContextAwareTestCase.suite());
-      suite.addTest(KernelControllerContextAwareXMLTestCase.suite());
-      suite.addTest(KernelControllerContextAwareAnnotationTestCase.suite());
-      suite.addTest(InstallDependencyTestCase.suite());
-      suite.addTest(InstallDependencyXMLTestCase.suite());
-      suite.addTest(InstallDependencyAnnotationTestCase.suite());
-      suite.addTest(GenericBeanFactoryInstallDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryInstallDependencyXMLTestCase.suite());
-      suite.addTest(GenericBeanFactoryCallbackDependencyTestCase.suite());
-      suite.addTest(GenericBeanFactoryCallbackDependencyXMLTestCase.suite());
-      suite.addTest(InstallSelfDependencyTestCase.suite());
-      suite.addTest(InstallSelfDependencyXMLTestCase.suite());
-      suite.addTest(InstallSelfDependencyAnnotationTestCase.suite());
-      suite.addTest(FromContextTestCase.suite());
-      suite.addTest(FromContextXMLTestCase.suite());
-      suite.addTest(FromContextAnnotationTestCase.suite());
-      suite.addTest(PlainAliasTestCase.suite());
-      suite.addTest(PlainAliasXMLTestCase.suite());
-      suite.addTest(PlainAliasAnnotationTestCase.suite());
-      suite.addTest(CallbackTestCase.suite());
-      suite.addTest(CallbackXMLTestCase.suite());
-      suite.addTest(CallbackAnnotationTestCase.suite());
-      suite.addTest(CallbackCollectionTestCase.suite());
-      suite.addTest(CallbackCollectionXMLTestCase.suite());
-      suite.addTest(CallbackCollectionAnnotationTestCase.suite());
-      suite.addTest(CallbackCollectionFieldsTestCase.suite());
-      suite.addTest(CallbackCollectionFields2TestCase.suite());
-      suite.addTest(MatcherDemandSupplyTestCase.suite());
-      suite.addTest(MatcherDemandSupplyXMLTestCase.suite());
-      suite.addTest(MatcherDemandSupplyAnnotationTestCase.suite());
-      suite.addTest(NestedPropertyTestCase.suite());
-      suite.addTest(NestedPropertyXMLTestCase.suite());
-      suite.addTest(BeanValidatorBridgeTestCase.suite());
-      suite.addTest(DuplicateAliasTestCase.suite());
-      suite.addTest(DuplicateAliasXMLTestCase.suite());
-      suite.addTest(DuplicateAliasAnnotationTestCase.suite());
-      suite.addTest(ScopedDuplicateAliasTestCase.suite());
-      suite.addTest(ScopedDuplicateAliasXMLTestCase.suite());
-      suite.addTest(ScopedDuplicateAliasAnnotationTestCase.suite());
-      suite.addTest(OptionalTestCase.suite());
-      suite.addTest(OptionalXMLTestCase.suite());
-      suite.addTest(OptionalAnnotationTestCase.suite());
-      return suite;
-   }
-}

Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/DependencyTestSuite.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,129 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * Dependency Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class DependencyTestSuite extends TestSuite
+{
+   public static void main(String[] args)
+   {
+      TestRunner.run(suite());
+   }
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("Dependency Tests");
+
+      suite.addTest(PlainDependencyTestCase.suite());
+      suite.addTest(PlainDependencyXMLTestCase.suite());
+      suite.addTest(PlainDependencyAnnotationTestCase.suite());
+      suite.addTest(GenericBeanFactoryPlainDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryPlainDependencyXMLTestCase.suite());
+      suite.addTest(OnDemandDependencyTestCase.suite());
+      suite.addTest(OnDemandDependencyXMLTestCase.suite());
+      suite.addTest(GenericBeanFactoryOnDemandDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryOnDemandDependencyXMLTestCase.suite());
+      suite.addTest(PropertyDependencyTestCase.suite());
+      suite.addTest(PropertyDependencyXMLTestCase.suite());
+      suite.addTest(PropertyDependencyAnnotationTestCase.suite());
+      suite.addTest(PropertyFieldDependencyTestCase.suite());
+      suite.addTest(PropertyField2DependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryPropertyDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryPropertyDependencyXMLTestCase.suite());
+      suite.addTest(GenericBeanFactoryFieldPropertyDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryField2PropertyDependencyTestCase.suite());
+      suite.addTest(ConstructorDependencyTestCase.suite());
+      suite.addTest(ConstructorDependencyXMLTestCase.suite());
+      suite.addTest(ConstructorDependencyAnnotationTestCase.suite());
+      suite.addTest(GenericBeanFactoryConstructorDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryConstructorDependencyXMLTestCase.suite());
+      suite.addTest(DemandDependencyTestCase.suite());
+      suite.addTest(DemandDependencyXMLTestCase.suite());
+      suite.addTest(DemandDependencyAnnotationTestCase.suite());
+      suite.addTest(GenericBeanFactoryDemandDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryDemandDependencyXMLTestCase.suite());
+      suite.addTest(PlainLifecycleDependencyTestCase.suite());
+      suite.addTest(PlainLifecycleDependencyXMLTestCase.suite());
+      suite.addTest(PlainLifecycleDependencyAnnotationTestCase.suite());
+      suite.addTest(GenericBeanFactoryPlainLifecycleDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryPlainLifecycleDependencyXMLTestCase.suite());
+      suite.addTest(ComplicatedLifecycleDependencyTestCase.suite());
+      suite.addTest(ComplicatedLifecycleDependencyXMLTestCase.suite());
+      suite.addTest(ComplicatedLifecycleDependencyAnnotationTestCase.suite());
+      suite.addTest(KernelControllerContextAwareTestCase.suite());
+      suite.addTest(KernelControllerContextAwareXMLTestCase.suite());
+      suite.addTest(KernelControllerContextAwareAnnotationTestCase.suite());
+      suite.addTest(InstallDependencyTestCase.suite());
+      suite.addTest(InstallDependencyXMLTestCase.suite());
+      suite.addTest(InstallDependencyAnnotationTestCase.suite());
+      suite.addTest(GenericBeanFactoryInstallDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryInstallDependencyXMLTestCase.suite());
+      suite.addTest(GenericBeanFactoryCallbackDependencyTestCase.suite());
+      suite.addTest(GenericBeanFactoryCallbackDependencyXMLTestCase.suite());
+      suite.addTest(InstallSelfDependencyTestCase.suite());
+      suite.addTest(InstallSelfDependencyXMLTestCase.suite());
+      suite.addTest(InstallSelfDependencyAnnotationTestCase.suite());
+      suite.addTest(FromContextTestCase.suite());
+      suite.addTest(FromContextXMLTestCase.suite());
+      suite.addTest(FromContextAnnotationTestCase.suite());
+      suite.addTest(PlainAliasTestCase.suite());
+      suite.addTest(PlainAliasXMLTestCase.suite());
+      suite.addTest(PlainAliasAnnotationTestCase.suite());
+      suite.addTest(CallbackTestCase.suite());
+      suite.addTest(CallbackXMLTestCase.suite());
+      suite.addTest(CallbackAnnotationTestCase.suite());
+      suite.addTest(CallbackCollectionTestCase.suite());
+      suite.addTest(CallbackCollectionXMLTestCase.suite());
+      suite.addTest(CallbackCollectionAnnotationTestCase.suite());
+      suite.addTest(CallbackCollectionFieldsTestCase.suite());
+      suite.addTest(CallbackCollectionFields2TestCase.suite());
+      suite.addTest(MatcherDemandSupplyTestCase.suite());
+      suite.addTest(MatcherDemandSupplyXMLTestCase.suite());
+      suite.addTest(MatcherDemandSupplyAnnotationTestCase.suite());
+      suite.addTest(NestedPropertyTestCase.suite());
+      suite.addTest(NestedPropertyXMLTestCase.suite());
+      suite.addTest(BeanValidatorBridgeTestCase.suite());
+      suite.addTest(DuplicateAliasTestCase.suite());
+      suite.addTest(DuplicateAliasXMLTestCase.suite());
+      suite.addTest(DuplicateAliasAnnotationTestCase.suite());
+      suite.addTest(ScopedDuplicateAliasTestCase.suite());
+      suite.addTest(ScopedDuplicateAliasXMLTestCase.suite());
+      suite.addTest(ScopedDuplicateAliasAnnotationTestCase.suite());
+      suite.addTest(OnDemandDependencyTestCase.suite());
+      suite.addTest(OnDemandDependencyXMLTestCase.suite());
+      suite.addTest(ScopedOnDemandDependencyTestCase.suite());
+      suite.addTest(ScopedOnDemandDependencyXMLTestCase.suite());
+      suite.addTest(OptionalTestCase.suite());
+      suite.addTest(OptionalXMLTestCase.suite());
+      suite.addTest(OptionalAnnotationTestCase.suite());
+      return suite;
+   }
+}

Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java	2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,207 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import java.net.URL;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.List;
-
-import org.jboss.beans.metadata.spi.BeanMetaData;
-import org.jboss.beans.metadata.spi.PropertyMetaData;
-import org.jboss.beans.metadata.spi.factory.GenericBeanFactoryMetaData;
-import org.jboss.dependency.spi.ControllerContext;
-import org.jboss.dependency.spi.ControllerState;
-import org.jboss.kernel.Kernel;
-import org.jboss.test.kernel.AbstractKernelTest;
-import org.jboss.test.kernel.dependency.support.TestUtil;
-import org.jboss.util.Classes;
-
-/**
- * An abstract kernel config test.
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class OldAbstractKernelDependencyTest extends AbstractKernelTest
-{
-   /** The test utility */
-   private TestUtil util;
-   
-   /** Whether this is an xml test */
-   private boolean xmltest;
-   
-   /** The BeanMetaDatas */
-   private BeanMetaData[] beanMetaDatas;
-   
-   public OldAbstractKernelDependencyTest(String name) throws Throwable
-   {
-      this(name, false);
-   }
-   
-   public OldAbstractKernelDependencyTest(String name, boolean xmltest) throws Throwable
-   {
-      super(name);
-      this.xmltest = xmltest;
-   }
-
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-      try
-      {
-         Kernel kernel = bootstrap();
-         this.util = new TestUtil(kernel, this);
-      }
-      catch (Exception e)
-      {
-         throw e;
-      }
-      catch (Throwable t)
-      {
-         throw new RuntimeException(t);
-      }
-   }
-
-   protected TestUtil getUtil()
-   {
-      return util;
-   }
-   
-   protected ControllerContext install(int number, String name) throws Throwable
-   {
-      if (xmltest)
-      {
-         deploy(number);
-         return util.getContext(name);
-      }
-      else
-      {
-         return util.install(beanMetaDatas[number]);
-      }
-   }
-
-   protected void uninstall(String name) throws Throwable
-   {
-      util.uninstall(name);
-   }
-   
-   protected ControllerContext assertInstall(int number, String name) throws Throwable
-   {
-      ControllerContext result = assertInstall(number, name, ControllerState.INSTALLED);
-      assertContext(name);
-      return result;
-   }
-
-   protected ControllerContext assertInstall(int number, String name, ControllerState expected) throws Throwable
-   {
-      ControllerContext context = install(number, name);
-      assertNotNull(context);
-      assertEquals(expected, context.getState());
-      return context;
-   }
-
-   protected ControllerContext assertContext(String name) throws Throwable
-   {
-      return assertContext(name, ControllerState.INSTALLED);
-   }
-
-   protected ControllerContext assertContext(String name, ControllerState expected) throws Throwable
-   {
-      ControllerContext context = util.getContext(name);
-      assertNotNull("Expected " + name + " state=" + expected.toShortString(), context);
-      assertEquals(expected, context.getState());
-      return context;
-   }
-
-   protected void assertUninstall(String name) throws Throwable
-   {
-      uninstall(name);
-      
-      assertNotInstalled(name);
-
-      ControllerContext context = util.getContext(name);
-      assertNull(context);
-   }
-
-   protected void assertNotInstalled(String name) throws Throwable
-   {
-      if (util.getInstalledContext(name) != null)
-         fail("Should not be installed");
-   }
-   
-   protected void setBeanMetaDatas(BeanMetaData[] beanMetaDatas)
-   {
-      if (xmltest)
-         return;
-      this.beanMetaDatas = beanMetaDatas;
-   }
-   
-   protected void addBeanProperty(GenericBeanFactoryMetaData factory, PropertyMetaData property)
-   {
-      Set<PropertyMetaData> propertys = factory.getProperties();
-      if (propertys == null)
-      {
-         propertys = new HashSet<PropertyMetaData>();
-         factory.setProperties(propertys);
-      }
-      propertys.add(property);
-   }
-
-   protected BeanMetaData getBeanMetaData(GenericBeanFactoryMetaData factory)
-   {
-      List<BeanMetaData> beans = factory.getBeans();
-      assertNotNull(beans);
-      assertEquals(1, beans.size());
-      return beans.get(0);
-   }
-
-   protected String createName(int number)
-   {
-      String packageName = Classes.getPackageName(getClass());
-      packageName = packageName.replace('.', '/');
-      return "/xml-test/" + packageName + '/' + getName() + number + ".xml";
-   }
-
-   protected void deploy(int number) throws Throwable
-   {
-      String name = createName(number);
-      getLog().debug("Using " + name);
-      URL url = getResource(name);
-      if (url == null)
-         throw new RuntimeException("Resource not found: " + name);
-      getLog().debug("url=" + url);
-      util.deploy(url);
-
-   }
-
-   protected void configureLoggingAfterBootstrap()
-   {
-      //enableTrace("org.jboss.beans");
-      //enableTrace("org.jboss.dependency");
-      //enableTrace("org.jboss.joinpoint.plugins.config");
-      //enableTrace("org.jboss.kernel.plugins.config");
-      //enableTrace("org.jboss.kernel.plugins.dependency");
-      //if (xmltest)
-      //   enableTrace("org.jboss.xb");
-   }
-}

Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OldAbstractKernelDependencyTest.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,229 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import java.net.URL;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.beans.metadata.spi.PropertyMetaData;
+import org.jboss.beans.metadata.spi.factory.GenericBeanFactoryMetaData;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.kernel.Kernel;
+import org.jboss.test.kernel.AbstractKernelTest;
+import org.jboss.test.kernel.dependency.support.ScopedTestUtil;
+import org.jboss.test.kernel.dependency.support.TestUtil;
+import org.jboss.util.Classes;
+
+/**
+ * An abstract kernel config test.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class OldAbstractKernelDependencyTest extends AbstractKernelTest
+{
+   /** The test utility */
+   private TestUtil util;
+   
+   /** Whether this is an xml test */
+   private boolean xmlTest;
+   
+   /** Whether this test uses scoped controllers */
+   private boolean scoped;
+   
+   /** The BeanMetaDatas */
+   private BeanMetaData[] beanMetaDatas;
+   
+   public OldAbstractKernelDependencyTest(String name) throws Throwable
+   {
+      this(name, false, false);
+   }
+   
+   public OldAbstractKernelDependencyTest(String name, boolean xmltest) throws Throwable
+   {
+      this(name, xmltest, false);
+   }
+   
+   public OldAbstractKernelDependencyTest(String name, boolean xmlTest, boolean scoped)
+   {
+      super(name);
+      this.xmlTest = xmlTest;
+      this.scoped = scoped;
+   }
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+      try
+      {
+         Kernel kernel = bootstrap();
+         if (scoped)
+            this.util = new ScopedTestUtil(kernel, this);
+         else
+            this.util = new TestUtil(kernel, this);
+      }
+      catch (Exception e)
+      {
+         throw e;
+      }
+      catch (Throwable t)
+      {
+         throw new RuntimeException(t);
+      }
+   }
+
+   protected TestUtil getUtil()
+   {
+      return util;
+   }
+   
+   protected ControllerContext install(int number, String name) throws Throwable
+   {
+      if (xmlTest)
+      {
+         deploy(number);
+         return util.getContext(name);
+      }
+      else
+      {
+         return util.install(beanMetaDatas[number]);
+      }
+   }
+
+   protected void uninstall(String name) throws Throwable
+   {
+      util.uninstall(name);
+   }
+   
+   protected ControllerContext assertInstall(int number, String name) throws Throwable
+   {
+      ControllerContext result = assertInstall(number, name, ControllerState.INSTALLED);
+      assertContext(name);
+      return result;
+   }
+
+   protected ControllerContext assertInstall(int number, String name, ControllerState expected) throws Throwable
+   {
+      ControllerContext context = install(number, name);
+      assertNotNull(context);
+      assertEquals(expected, context.getState());
+      return context;
+   }
+
+   protected ControllerContext assertContext(String name) throws Throwable
+   {
+      return assertContext(name, ControllerState.INSTALLED);
+   }
+
+   protected ControllerContext assertContext(String name, ControllerState expected) throws Throwable
+   {
+      ControllerContext context = util.getContext(name);
+      assertNotNull("Expected " + name + " state=" + expected.toShortString(), context);
+      assertEquals(expected, context.getState());
+      return context;
+   }
+
+   protected void assertUninstall(String name) throws Throwable
+   {
+      uninstall(name);
+      
+      assertNotInstalled(name);
+
+      ControllerContext context = util.getContext(name);
+      assertNull(context);
+   }
+
+   protected void assertNotInstalled(String name) throws Throwable
+   {
+      if (util.getInstalledContext(name) != null)
+         fail("Should not be installed");
+   }
+   
+   protected void setBeanMetaDatas(BeanMetaData[] beanMetaDatas)
+   {
+      if (xmlTest)
+         return;
+      this.beanMetaDatas = beanMetaDatas;
+   }
+   
+   protected void addBeanProperty(GenericBeanFactoryMetaData factory, PropertyMetaData property)
+   {
+      Set<PropertyMetaData> propertys = factory.getProperties();
+      if (propertys == null)
+      {
+         propertys = new HashSet<PropertyMetaData>();
+         factory.setProperties(propertys);
+      }
+      propertys.add(property);
+   }
+
+   protected BeanMetaData getBeanMetaData(GenericBeanFactoryMetaData factory)
+   {
+      List<BeanMetaData> beans = factory.getBeans();
+      assertNotNull(beans);
+      assertEquals(1, beans.size());
+      return beans.get(0);
+   }
+
+   protected String createName(int number)
+   {
+      String packageName = Classes.getPackageName(getClass());
+      packageName = packageName.replace('.', '/');
+      return "/xml-test/" + packageName + '/' + getName() + number + ".xml";
+   }
+
+   protected void deploy(int number) throws Throwable
+   {
+      String name = createName(number);
+      getLog().debug("Using " + name);
+      URL url = getResource(name);
+      if (url == null)
+         throw new RuntimeException("Resource not found: " + name);
+      getLog().debug("url=" + url);
+      util.deploy(url);
+
+   }
+
+   protected void configureLoggingAfterBootstrap()
+   {
+      //enableTrace("org.jboss.beans");
+      //enableTrace("org.jboss.dependency");
+      //enableTrace("org.jboss.joinpoint.plugins.config");
+      //enableTrace("org.jboss.kernel.plugins.config");
+      //enableTrace("org.jboss.kernel.plugins.dependency");
+      //if (xmltest)
+      //   enableTrace("org.jboss.xb");
+   }
+
+   /**
+    * Get the xmltest
+    * @return the xmltest
+    */
+   public boolean isXmlTest()
+   {
+      return xmlTest;
+   }
+}

Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java	2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,252 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import java.util.HashSet;
-
-import junit.framework.Test;
-
-import org.jboss.beans.metadata.plugins.AbstractBeanMetaData;
-import org.jboss.beans.metadata.plugins.AbstractDependencyValueMetaData;
-import org.jboss.beans.metadata.plugins.AbstractPropertyMetaData;
-import org.jboss.beans.metadata.spi.BeanMetaData;
-import org.jboss.beans.metadata.spi.PropertyMetaData;
-import org.jboss.dependency.spi.ControllerContext;
-import org.jboss.dependency.spi.ControllerMode;
-import org.jboss.dependency.spi.ControllerState;
-import org.jboss.test.kernel.dependency.support.SimpleBean;
-import org.jboss.test.kernel.dependency.support.SimpleBeanImpl;
-import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependency;
-import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl;
-
-/**
- * OnDemand Dependency Test Case.
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class OnDemandDependencyTestCase extends OldAbstractKernelDependencyTest
-{
-   public static Test suite()
-   {
-      return suite(OnDemandDependencyTestCase.class);
-   }
-
-   public OnDemandDependencyTestCase(String name) throws Throwable
-   {
-      super(name);
-   }
-
-   public OnDemandDependencyTestCase(String name, boolean xmltest) throws Throwable
-   {
-      super(name, xmltest);
-   }
-
-   public void testOnDemandDependencyOnDemandFirst() throws Throwable
-   {
-      onDemandDependencyOnDemandFirst();
-
-      ControllerContext context1 = assertInstall(0, "Name1", ControllerState.DESCRIBED);
-      ControllerContext context2 = assertInstall(1, "Name2");
-      assertContext("Name1");
-      
-      SimpleBean bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-      
-      SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
-      assertNotNull(bean2);
-      assertEquals("String2", bean2.getString());
-      assertEquals(bean1, bean2.getSimpleBean());
-   }
-
-   public void onDemandDependencyOnDemandFirst() throws Throwable
-   {
-      buildMetaData();
-   }
-
-   public void testOnDemandDependencyOnDemandSecond() throws Throwable
-   {
-      onDemandDependencyOnDemandSecond();
-      
-      ControllerContext context2 = assertInstall(1, "Name2", ControllerState.INSTANTIATED);
-      ControllerContext context1 = assertInstall(0, "Name1");
-      assertEquals(ControllerState.INSTALLED, context2.getState());
-      
-      SimpleBean bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-      
-      SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
-      assertNotNull(bean2);
-      assertEquals("String2", bean2.getString());
-      assertEquals(bean1, bean2.getSimpleBean());
-   }
-
-   public void onDemandDependencyOnDemandSecond() throws Throwable
-   {
-      buildMetaData();
-   }
-
-   public void testOnDemandDependencyReinstall() throws Throwable
-   {
-      onDemandDependencyReinstall();
-
-      ControllerContext context1 = assertInstall(0, "Name1", ControllerState.DESCRIBED);
-      ControllerContext context2 = assertInstall(1, "Name2");
-      ControllerContext context3 = assertInstall(2, "Name3");
-      assertContext("Name1");
-      
-      SimpleBean bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-      
-      SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
-      assertNotNull(bean2);
-      assertEquals("String2", bean2.getString());
-      assertEquals(bean1, bean2.getSimpleBean());
-      
-      SimpleBeanWithDependency bean3 = (SimpleBeanWithDependency) context3.getTarget();
-      assertNotNull(bean3);
-      assertEquals("String3", bean3.getString());
-      assertEquals(bean1, bean3.getSimpleBean());
-
-      assertUninstall("Name1");
-
-      assertEquals(ControllerState.ERROR, context1.getState());
-      assertEquals(ControllerState.INSTANTIATED, context2.getState());
-      assertNotInstalled("Name2");
-      assertEquals(ControllerState.INSTANTIATED, context3.getState());
-      assertNotInstalled("Name3");
-
-      context2 = assertContext("Name2", ControllerState.INSTANTIATED);
-      context3 = assertContext("Name3", ControllerState.INSTANTIATED);
-      
-      context1 = assertInstall(0, "Name1");
-      assertEquals(ControllerState.INSTALLED, context2.getState());
-      assertEquals(ControllerState.INSTALLED, context3.getState());
-
-      bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-      
-      bean2 = (SimpleBeanWithDependency) context2.getTarget();
-      assertNotNull(bean2);
-      assertEquals("String2", bean2.getString());
-      assertEquals(bean1, bean2.getSimpleBean());
-      
-      bean3 = (SimpleBeanWithDependency) context3.getTarget();
-      assertNotNull(bean3);
-      assertEquals("String3", bean3.getString());
-      assertEquals(bean1, bean3.getSimpleBean());
-      
-      assertUninstall("Name2");
-      
-      context1 = assertContext("Name1");
-      bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-      
-      context3 = assertContext("Name3");
-      bean3 = (SimpleBeanWithDependency) context3.getTarget();
-      assertNotNull(bean3);
-      assertEquals("String3", bean3.getString());
-      assertEquals(bean1, bean3.getSimpleBean());
-
-      context2 = assertInstall(1, "Name2");
-      
-      bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-      
-      bean2 = (SimpleBeanWithDependency) context2.getTarget();
-      assertNotNull(bean2);
-      assertEquals("String2", bean2.getString());
-      assertEquals(bean1, bean2.getSimpleBean());
-      
-      bean3 = (SimpleBeanWithDependency) context3.getTarget();
-      assertNotNull(bean3);
-      assertEquals("String3", bean3.getString());
-      assertEquals(bean1, bean3.getSimpleBean());
-
-      assertUninstall("Name2");
-      context1 = assertContext("Name1");
-      bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-
-      context3 = assertContext("Name3");
-      bean3 = (SimpleBeanWithDependency) context3.getTarget();
-      assertNotNull(bean3);
-      assertEquals("String3", bean3.getString());
-      assertEquals(bean1, bean3.getSimpleBean());
-      
-      assertUninstall("Name3");
-      context1 = assertContext("Name1", ControllerState.DESCRIBED);
-      assertNull(context1.getTarget());
-      
-      context2 = assertInstall(1, "Name2");
-      
-      bean1 = (SimpleBean) context1.getTarget();
-      assertNotNull(bean1);
-      assertEquals("String1", bean1.getString());
-
-      bean2 = (SimpleBeanWithDependency) context2.getTarget();
-      assertNotNull(bean2);
-      assertEquals("String2", bean2.getString());
-      assertEquals(bean1, bean2.getSimpleBean());
-
-      context3 = assertInstall(2, "Name3");
-      bean3 = (SimpleBeanWithDependency) context3.getTarget();
-      assertNotNull(bean3);
-      assertEquals("String3", bean3.getString());
-      assertEquals(bean1, bean3.getSimpleBean());
-   }
-
-   public void onDemandDependencyReinstall() throws Throwable
-   {
-      buildMetaData();
-   }
-
-   protected void buildMetaData()
-   {
-      AbstractBeanMetaData metaData1 = new AbstractBeanMetaData("Name1", SimpleBeanImpl.class.getName());
-      metaData1.setMode(ControllerMode.ON_DEMAND);
-      HashSet<PropertyMetaData> attributes1 = new HashSet<PropertyMetaData>();
-      attributes1.add(new AbstractPropertyMetaData("string", "String1"));
-      metaData1.setProperties(attributes1);
-
-      AbstractBeanMetaData metaData2 = new AbstractBeanMetaData("Name2", SimpleBeanWithDependencyImpl.class.getName());
-      HashSet<PropertyMetaData> attributes2 = new HashSet<PropertyMetaData>();
-      attributes2.add(new AbstractPropertyMetaData("string", "String2"));
-      attributes2.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
-      metaData2.setProperties(attributes2);
-
-      AbstractBeanMetaData metaData3 = new AbstractBeanMetaData("Name3", SimpleBeanWithDependencyImpl.class.getName());
-      HashSet<PropertyMetaData> attributes3 = new HashSet<PropertyMetaData>();
-      attributes3.add(new AbstractPropertyMetaData("string", "String3"));
-      attributes3.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
-      metaData3.setProperties(attributes3);
-
-      setBeanMetaDatas(new BeanMetaData[] { metaData1, metaData2, metaData3});
-   }
-}
\ No newline at end of file

Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyTestCase.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,285 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.beans.metadata.plugins.AbstractAnnotationMetaData;
+import org.jboss.beans.metadata.plugins.AbstractBeanMetaData;
+import org.jboss.beans.metadata.plugins.AbstractDependencyValueMetaData;
+import org.jboss.beans.metadata.plugins.AbstractPropertyMetaData;
+import org.jboss.beans.metadata.spi.AnnotationMetaData;
+import org.jboss.beans.metadata.spi.BeanMetaData;
+import org.jboss.beans.metadata.spi.PropertyMetaData;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.dependency.spi.ControllerMode;
+import org.jboss.dependency.spi.ControllerState;
+import org.jboss.metadata.plugins.scope.DeploymentScope;
+import org.jboss.test.kernel.dependency.support.SimpleBean;
+import org.jboss.test.kernel.dependency.support.SimpleBeanImpl;
+import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependency;
+import org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl;
+
+/**
+ * OnDemand Dependency Test Case.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class OnDemandDependencyTestCase extends OldAbstractKernelDependencyTest
+{
+   public static Test suite()
+   {
+      return suite(OnDemandDependencyTestCase.class);
+   }
+
+   public OnDemandDependencyTestCase(String name) throws Throwable
+   {
+      super(name);
+   }
+
+   public OnDemandDependencyTestCase(String name, boolean xmltest, boolean scoped) throws Throwable
+   {
+      super(name, xmltest, scoped);
+   }
+
+   public void testOnDemandDependencyOnDemandFirst() throws Throwable
+   {
+      onDemandDependencyOnDemandFirst();
+
+      ControllerContext context1 = assertInstall(offSetNumber(0), "Name1", ControllerState.DESCRIBED);
+      ControllerContext context2 = assertInstall(offSetNumber(1), "Name2");
+      assertContext("Name1");
+      
+      assertControllers(context1, context2);
+      
+      SimpleBean bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+      
+      SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
+      assertNotNull(bean2);
+      assertEquals("String2", bean2.getString());
+      assertEquals(bean1, bean2.getSimpleBean());
+   }
+
+   public void onDemandDependencyOnDemandFirst() throws Throwable
+   {
+      buildMetaData();
+   }
+
+   public void testOnDemandDependencyOnDemandSecond() throws Throwable
+   {
+      onDemandDependencyOnDemandSecond();
+      
+      ControllerContext context2 = assertInstall(offSetNumber(1), "Name2", ControllerState.INSTANTIATED);
+      ControllerContext context1 = assertInstall(offSetNumber(0), "Name1");
+      assertEquals(ControllerState.INSTALLED, context2.getState());
+
+      assertControllers(context1, context2);
+
+      SimpleBean bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+      
+      SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
+      assertNotNull(bean2);
+      assertEquals("String2", bean2.getString());
+      assertEquals(bean1, bean2.getSimpleBean());
+   }
+
+   public void onDemandDependencyOnDemandSecond() throws Throwable
+   {
+      buildMetaData();
+   }
+
+   public void testOnDemandDependencyReinstall() throws Throwable
+   {
+      onDemandDependencyReinstall();
+
+      ControllerContext context1 = assertInstall(offSetNumber(0), "Name1", ControllerState.DESCRIBED);
+      ControllerContext context2 = assertInstall(offSetNumber(1), "Name2");
+      ControllerContext context3 = assertInstall(offSetNumber(2), "Name3");
+      assertContext("Name1");
+
+      assertControllers(context1, context2, context3);
+
+      SimpleBean bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+      
+      SimpleBeanWithDependency bean2 = (SimpleBeanWithDependency) context2.getTarget();
+      assertNotNull(bean2);
+      assertEquals("String2", bean2.getString());
+      assertEquals(bean1, bean2.getSimpleBean());
+      
+      SimpleBeanWithDependency bean3 = (SimpleBeanWithDependency) context3.getTarget();
+      assertNotNull(bean3);
+      assertEquals("String3", bean3.getString());
+      assertEquals(bean1, bean3.getSimpleBean());
+
+      assertUninstall("Name1");
+
+      assertEquals(ControllerState.ERROR, context1.getState());
+      assertEquals(ControllerState.INSTANTIATED, context2.getState());
+      assertNotInstalled("Name2");
+      assertEquals(ControllerState.INSTANTIATED, context3.getState());
+      assertNotInstalled("Name3");
+
+      context2 = assertContext("Name2", ControllerState.INSTANTIATED);
+      context3 = assertContext("Name3", ControllerState.INSTANTIATED);
+      
+      context1 = assertInstall(offSetNumber(0), "Name1");
+      assertEquals(ControllerState.INSTALLED, context2.getState());
+      assertEquals(ControllerState.INSTALLED, context3.getState());
+
+      bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+      
+      bean2 = (SimpleBeanWithDependency) context2.getTarget();
+      assertNotNull(bean2);
+      assertEquals("String2", bean2.getString());
+      assertEquals(bean1, bean2.getSimpleBean());
+      
+      bean3 = (SimpleBeanWithDependency) context3.getTarget();
+      assertNotNull(bean3);
+      assertEquals("String3", bean3.getString());
+      assertEquals(bean1, bean3.getSimpleBean());
+      
+      assertUninstall("Name2");
+      
+      context1 = assertContext("Name1");
+      bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+      
+      context3 = assertContext("Name3");
+      bean3 = (SimpleBeanWithDependency) context3.getTarget();
+      assertNotNull(bean3);
+      assertEquals("String3", bean3.getString());
+      assertEquals(bean1, bean3.getSimpleBean());
+
+      context2 = assertInstall(offSetNumber(1), "Name2");
+      
+      bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+      
+      bean2 = (SimpleBeanWithDependency) context2.getTarget();
+      assertNotNull(bean2);
+      assertEquals("String2", bean2.getString());
+      assertEquals(bean1, bean2.getSimpleBean());
+      
+      bean3 = (SimpleBeanWithDependency) context3.getTarget();
+      assertNotNull(bean3);
+      assertEquals("String3", bean3.getString());
+      assertEquals(bean1, bean3.getSimpleBean());
+
+      assertUninstall("Name2");
+      context1 = assertContext("Name1");
+      bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+
+      context3 = assertContext("Name3");
+      bean3 = (SimpleBeanWithDependency) context3.getTarget();
+      assertNotNull(bean3);
+      assertEquals("String3", bean3.getString());
+      assertEquals(bean1, bean3.getSimpleBean());
+      
+      assertUninstall("Name3");
+      context1 = assertContext("Name1", ControllerState.DESCRIBED);
+      assertNull(context1.getTarget());
+      
+      context2 = assertInstall(offSetNumber(1), "Name2");
+      
+      bean1 = (SimpleBean) context1.getTarget();
+      assertNotNull(bean1);
+      assertEquals("String1", bean1.getString());
+
+      bean2 = (SimpleBeanWithDependency) context2.getTarget();
+      assertNotNull(bean2);
+      assertEquals("String2", bean2.getString());
+      assertEquals(bean1, bean2.getSimpleBean());
+
+      context3 = assertInstall(offSetNumber(2), "Name3");
+      bean3 = (SimpleBeanWithDependency) context3.getTarget();
+      assertNotNull(bean3);
+      assertEquals("String3", bean3.getString());
+      assertEquals(bean1, bean3.getSimpleBean());
+   }
+
+   public void onDemandDependencyReinstall() throws Throwable
+   {
+      buildMetaData();
+   }
+
+   protected void buildMetaData()
+   {
+      AbstractBeanMetaData metaData1 = new AbstractBeanMetaData("Name1", SimpleBeanImpl.class.getName());
+      metaData1.setMode(ControllerMode.ON_DEMAND);
+      HashSet<PropertyMetaData> attributes1 = new HashSet<PropertyMetaData>();
+      attributes1.add(new AbstractPropertyMetaData("string", "String1"));
+      metaData1.setProperties(attributes1);
+
+      AbstractBeanMetaData metaData2 = new AbstractBeanMetaData("Name2", SimpleBeanWithDependencyImpl.class.getName());
+      HashSet<PropertyMetaData> attributes2 = new HashSet<PropertyMetaData>();
+      attributes2.add(new AbstractPropertyMetaData("string", "String2"));
+      attributes2.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
+      metaData2.setProperties(attributes2);
+      addAnnotation(metaData2);
+
+      AbstractBeanMetaData metaData3 = new AbstractBeanMetaData("Name3", SimpleBeanWithDependencyImpl.class.getName());
+      HashSet<PropertyMetaData> attributes3 = new HashSet<PropertyMetaData>();
+      attributes3.add(new AbstractPropertyMetaData("string", "String3"));
+      attributes3.add(new AbstractPropertyMetaData("simpleBean", new AbstractDependencyValueMetaData("Name1")));
+      metaData3.setProperties(attributes3);
+      addAnnotation(metaData3);
+
+      setBeanMetaDatas(new BeanMetaData[] { metaData1, metaData2, metaData3});
+   }
+   
+   protected void addAnnotation(AbstractBeanMetaData bmd)
+   {
+   }
+   
+   protected int offSetNumber(int i)
+   {
+      return i;
+   }
+   
+   protected void assertControllers(ControllerContext...contexts)
+   {
+      if (contexts.length <= 1)
+         return;
+      
+      for (int i = 1 ; i < contexts.length ; i++)
+      {
+         if (i > 1)
+            assertSame(contexts[i].getController(), contexts[i-1].getController());
+      }
+   }
+}
\ No newline at end of file

Deleted: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java
===================================================================
--- projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java	2010-01-15 10:05:32 UTC (rev 99451)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -1,43 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.test.kernel.dependency.test;
-
-import junit.framework.Test;
-
-/**
- * OnDemand Dependency Test Case.
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision$
- */
-public class OnDemandDependencyXMLTestCase extends OnDemandDependencyTestCase
-{
-   public static Test suite()
-   {
-      return suite(OnDemandDependencyXMLTestCase.class);
-   }
-
-   public OnDemandDependencyXMLTestCase(String name) throws Throwable
-   {
-      super(name, true);
-   }
-}
\ No newline at end of file

Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/OnDemandDependencyXMLTestCase.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,43 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.kernel.dependency.test;
+
+import junit.framework.Test;
+
+/**
+ * OnDemand Dependency Test Case.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision$
+ */
+public class OnDemandDependencyXMLTestCase extends OnDemandDependencyTestCase
+{
+   public static Test suite()
+   {
+      return suite(OnDemandDependencyXMLTestCase.class);
+   }
+
+   public OnDemandDependencyXMLTestCase(String name) throws Throwable
+   {
+      super(name, true, false);
+   }
+}
\ No newline at end of file

Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyTestCase.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,76 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors. 
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/ 
+package org.jboss.test.kernel.dependency.test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.beans.metadata.plugins.AbstractAnnotationMetaData;
+import org.jboss.beans.metadata.plugins.AbstractBeanMetaData;
+import org.jboss.beans.metadata.spi.AnnotationMetaData;
+import org.jboss.dependency.spi.ControllerContext;
+import org.jboss.metadata.plugins.scope.DeploymentScope;
+
+/**
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ScopedOnDemandDependencyTestCase extends OnDemandDependencyTestCase
+{
+   public static Test suite()
+   {
+      return suite(ScopedOnDemandDependencyTestCase.class);
+   }
+
+   public ScopedOnDemandDependencyTestCase(String name) throws Throwable
+   {
+      super(name, false, true);
+   }
+
+   public ScopedOnDemandDependencyTestCase(String name, boolean xmltest) throws Throwable
+   {
+      super(name, xmltest, true);
+   }
+
+   protected void addAnnotation(AbstractBeanMetaData bmd)
+   {
+      Set<AnnotationMetaData> annotations = new HashSet<AnnotationMetaData>();
+      annotations.add(new AbstractAnnotationMetaData("@" + DeploymentScope.class.getName() + "(\"somedeployment\")"));
+      bmd.setAnnotations(annotations);
+   }
+   
+   protected void assertControllers(ControllerContext...contexts)
+   {
+      if (contexts.length <= 1)
+         return;
+      
+      for (int i = 1 ; i < contexts.length ; i++)
+      {
+         assertNotSame(contexts[0].getController(), contexts[i].getController());
+         if (i > 1)
+            assertSame(contexts[i].getController(), contexts[i-1].getController());
+      }
+   }
+}

Copied: projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java (from rev 99452, projects/kernel/trunk/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/java/org/jboss/test/kernel/dependency/test/ScopedOnDemandDependencyXMLTestCase.java	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,52 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors. 
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/ 
+package org.jboss.test.kernel.dependency.test;
+
+import junit.framework.Test;
+
+/**
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ScopedOnDemandDependencyXMLTestCase extends ScopedOnDemandDependencyTestCase
+{
+   public static Test suite()
+   {
+      return suite(ScopedOnDemandDependencyXMLTestCase.class);
+   }
+
+   public ScopedOnDemandDependencyXMLTestCase(String name) throws Throwable
+   {
+      super(name, true);
+   }
+
+   @Override
+   protected void buildMetaData()
+   {
+   }
+   
+   protected int offSetNumber(int i)
+   {
+      return i + 10;
+   }
+}

Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst10.xml	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+            xmlns="urn:jboss:bean-deployer">
+   <bean name="Name1" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl" mode="On Demand">
+      <property name="string">String1</property>
+   </bean>
+</deployment>

Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandFirst11.xml	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+            xmlns="urn:jboss:bean-deployer">
+   <bean name="Name2" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+      <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+      <property name="string">String2</property>
+      <property name="simpleBean"><inject bean="Name1"/></property>
+   </bean>
+</deployment>

Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond10.xml	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+            xmlns="urn:jboss:bean-deployer">
+   <bean name="Name1" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl" mode="On Demand">
+      <property name="string">String1</property>
+   </bean>
+</deployment>

Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyOnDemandSecond11.xml	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+            xmlns="urn:jboss:bean-deployer">
+   <bean name="Name2" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+       <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+       <property name="string">String2</property>
+      <property name="simpleBean"><inject bean="Name1"/></property>
+   </bean>
+</deployment>

Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall10.xml	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+            xmlns="urn:jboss:bean-deployer">
+   <bean name="Name1" class="org.jboss.test.kernel.dependency.support.SimpleBeanImpl" mode="On Demand">
+      <property name="string">String1</property>
+   </bean>
+</deployment>

Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall11.xml	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+            xmlns="urn:jboss:bean-deployer">
+   <bean name="Name2" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+      <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+      <property name="string">String2</property>
+      <property name="simpleBean"><inject bean="Name1"/></property>
+   </bean>
+</deployment>

Copied: projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml (from rev 99452, projects/kernel/trunk/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml)
===================================================================
--- projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml	                        (rev 0)
+++ projects/kernel/branches/resolver/kernel/src/test/resources/xml-test/org/jboss/test/kernel/dependency/test/testOnDemandDependencyReinstall12.xml	2010-01-15 12:19:28 UTC (rev 99462)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd"
+            xmlns="urn:jboss:bean-deployer">
+   <bean name="Name3" class="org.jboss.test.kernel.dependency.support.SimpleBeanWithDependencyImpl">
+      <annotation>@org.jboss.metadata.plugins.scope.DeploymentScope("somedeployment")</annotation>
+      <property name="string">String3</property>
+      <property name="simpleBean"><inject bean="Name1"/></property>
+   </bean>
+</deployment>




More information about the jboss-cvs-commits mailing list