Index: profileservice/src/main/org/jboss/profileservice/management/ManagementViewState.java
===================================================================
--- profileservice/src/main/org/jboss/profileservice/management/ManagementViewState.java	(revision 0)
+++ profileservice/src/main/org/jboss/profileservice/management/ManagementViewState.java	(working copy)
@@ -0,0 +1,742 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2012, Red Hat 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.profileservice.management;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.deployers.spi.management.ContextStateMapper;
+import org.jboss.deployers.spi.management.RuntimeComponentDispatcher;
+import org.jboss.logging.Logger;
+import org.jboss.managed.api.ComponentType;
+import org.jboss.managed.api.DeploymentState;
+import org.jboss.managed.api.ManagedComponent;
+import org.jboss.managed.api.ManagedDeployment;
+import org.jboss.managed.api.ManagedObject;
+import org.jboss.managed.api.ManagedOperation;
+import org.jboss.managed.api.ManagedProperty;
+import org.jboss.managed.api.MutableManagedComponent;
+import org.jboss.managed.api.MutableManagedObject;
+import org.jboss.managed.api.RunState;
+import org.jboss.managed.api.annotation.ManagementComponent;
+import org.jboss.managed.api.annotation.ManagementObject;
+import org.jboss.managed.api.annotation.ManagementObjectID;
+import org.jboss.managed.api.annotation.ManagementObjectRef;
+import org.jboss.managed.api.annotation.ViewUse;
+import org.jboss.managed.plugins.ManagedComponentImpl;
+import org.jboss.managed.plugins.ManagedDeploymentImpl;
+import org.jboss.managed.plugins.factory.AbstractManagedObjectFactory;
+import org.jboss.metatype.api.types.ArrayMetaType;
+import org.jboss.metatype.api.types.CollectionMetaType;
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.values.ArrayValue;
+import org.jboss.metatype.api.values.CollectionValue;
+import org.jboss.metatype.api.values.GenericValue;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.profileservice.spi.ProfileKey;
+
+/**
+ * Maintains the current state of the mgmt components in a view.
+ * 
+ * @author Emanuel Muckenhuber
+ */
+class ManagementViewState
+{
+
+   /** The logger. */
+   private static Logger log = Logger.getLogger(ManagementViewImpl.class);
+
+   /** An index of ManagedComponent by ComponentType */
+   private final HashMap<ComponentType, Set<ManagedComponent>> compByCompType = new HashMap<ComponentType, Set<ManagedComponent>>();
+
+   /** id/type key to ManagedObject map */
+   private final Map<String, ManagedObject> moRegistry = new HashMap<String, ManagedObject>();
+
+   /** The ManagedPropertys with unresolved ManagementObjectRefs */
+   private final Map<String, Set<ManagedProperty>> unresolvedRefs = new HashMap<String, Set<ManagedProperty>>();
+
+   /** A map of runtime ManagedObjects needing to be merged with their matching ManagedObject. */
+   private final Map<String, ManagedObject> runtimeMOs = new HashMap<String, ManagedObject>();
+
+   /** The deployment name to ManagedDeployment map */
+   private final Map<String, ManagedDeployment> managedDeployments = new HashMap<String, ManagedDeployment>();
+
+   /** The root deployments to resolve the deployment name. */
+   private final List<String> rootDeployments = new ArrayList<String>();
+
+   /** The dispatcher handles ManagedOperation dispatches */
+   private final RuntimeComponentDispatcher dispatcher;
+
+   /** The managed operation proxy factory. */
+   private final ManagedOperationProxyFactory proxyFactory;
+
+   /** A proxy for pure JMX dispatch */
+   private final ManagedOperationProxyFactory mbeanProxyFactory;
+
+   private final ContextStateMapper<RunState> runStateMapper;
+   private final ContextStateMapper<DeploymentState> deploymentStateMapper;
+
+   protected ManagementViewState(RuntimeComponentDispatcher dispatcher, ManagedOperationProxyFactory proxyFactory,
+         ManagedOperationProxyFactory mbeanProxyFactory, ContextStateMapper<RunState> runStateMapper,
+         ContextStateMapper<DeploymentState> deploymentStateMapper)
+   {
+      this.dispatcher = dispatcher;
+      this.proxyFactory = proxyFactory;
+      this.mbeanProxyFactory = mbeanProxyFactory;
+      this.runStateMapper = runStateMapper;
+      this.deploymentStateMapper = deploymentStateMapper;
+   }
+
+   void release()
+   {
+      // Cleanup... actually at this point all should be GCed
+      this.compByCompType.clear();
+      this.managedDeployments.clear();
+      this.moRegistry.clear();
+      this.runtimeMOs.clear();
+      this.unresolvedRefs.clear();
+      this.rootDeployments.clear();
+   }
+
+   /**
+    * Get the mgmt components by the component type
+    * 
+    * @return the components map
+    */
+   public HashMap<ComponentType, Set<ManagedComponent>> getCompByCompType()
+   {
+      return compByCompType;
+   }
+
+   /**
+    * Get the managed deployments.
+    * 
+    * @return the managed deployments
+    */
+   public Map<String, ManagedDeployment> getManagedDeployments()
+   {
+      return managedDeployments;
+   }
+
+   /**
+    * Get all the root deployments.
+    * 
+    * @return the root deployments
+    */
+   public List<String> getRootDeployments()
+   {
+      return rootDeployments;
+   }
+
+   /**
+    * Check if the merging the runtime MOs worked.
+    *
+    */
+   protected void checkRuntimeMOs()
+   {
+      if (this.runtimeMOs.size() > 0)
+      {
+         log.warn("Failed to merged the following runtime ManagedObjects: " + runtimeMOs);
+      }
+   }
+
+   /**
+    * Process the root managed deployment. This gets
+    * the deployment state for this deployment, which will
+    * get populated to the child deployments as well.
+    *
+    * @param md the managed deployment
+    * @param profile the associated profile key
+    * @param trace is trace enabled
+    * @throws Exception for any error
+    */
+   protected void processRootManagedDeployment(ManagedDeployment md, ProfileKey profile, boolean trace)
+         throws Exception
+   {
+      DeploymentState state = getDeploymentState(md);
+      processManagedDeployment(md, profile, state, 0, trace);
+   }
+
+   /**
+    * Process managed deployment.
+    *
+    * @param md the managed deployment
+    * @param profile the associated profile key
+    * @param state the deployment state
+    * @param level depth level
+    * @param trace is trace enabled
+    * @throws Exception for any error
+    */
+   protected void processManagedDeployment(ManagedDeployment md, ProfileKey profile, DeploymentState state, int level,
+         boolean trace) throws Exception
+   {
+      String name = md.getName();
+      if (trace)
+         log.trace(name + " ManagedDeployment_" + level + ": " + md);
+      Map<String, ManagedObject> mos = md.getManagedObjects();
+      if (trace)
+         log.trace(name + " ManagedObjects_ " + level + ": " + mos);
+
+      // Set the deployment state
+      if (state != null && md instanceof ManagedDeploymentImpl)
+         ((ManagedDeploymentImpl) md).setDeploymentState(state);
+
+      // Map any existing ManagedComponent types
+      for (ManagedComponent comp : md.getComponents().values())
+      {
+         ComponentType type = comp.getType();
+         Set<ManagedComponent> typeComps = compByCompType.get(type);
+         if (typeComps == null)
+         {
+            typeComps = new HashSet<ManagedComponent>();
+            compByCompType.put(type, typeComps);
+         }
+         typeComps.add(comp);
+      }
+
+      for (ManagedObject mo : mos.values())
+      {
+         processManagedObject(mo, md);
+      }
+      managedDeployments.put(name, md);
+
+      // Associate profile with the deployment
+      if (profile != null)
+      {
+         md.setAttachment(ProfileKey.class.getName(), profile);
+      }
+
+      // Add root deployments
+      if (level == 0)
+         this.rootDeployments.add(name);
+
+      // Process children
+      List<ManagedDeployment> mdChildren = md.getChildren();
+      if (mdChildren != null && mdChildren.isEmpty() == false)
+      {
+         for (ManagedDeployment mdChild : mdChildren)
+         {
+            // process the child deployments, with the state of the parent.
+            processManagedDeployment(mdChild, profile, state, level + 1, trace);
+         }
+      }
+   }
+
+   /**
+    * Process managed object.
+    *
+    * @param mo the managed object
+    * @param md the managed deployment
+    */
+   protected void processManagedObject(ManagedObject mo, ManagedDeployment md) throws Exception
+   {
+      String key = mo.getName() + "/" + mo.getNameType();
+      log.trace("ID for ManagedObject: " + key + ", attachmentName: " + mo.getAttachmentName());
+
+      // See if this is a runtime ManagedObject
+      Map<String, Annotation> moAnns = mo.getAnnotations();
+
+      // Create ManagedComponents for ManagedObjects annotated with ManagementComponent
+      ManagementComponent mc = (ManagementComponent) moAnns.get(ManagementComponent.class.getName());
+      if (mc != null && md.getComponent(mo.getName()) == null)
+      {
+         ComponentType type = new ComponentType(mc.type(), mc.subtype());
+         MutableManagedComponent comp = new ManagedComponentImpl(type, md, mo);
+
+         if (mo.getTransientAttachment(MBeanRuntimeComponentDispatcher.class.getName()) == null)
+            comp = this.proxyFactory.createComponentProxy(comp);
+
+         md.addComponent(mo.getName(), comp);
+         log.trace("Processing ManagementComponent(" + mo.getName() + "): " + comp);
+         Set<ManagedComponent> typeComps = compByCompType.get(type);
+         if (typeComps == null)
+         {
+            typeComps = new HashSet<ManagedComponent>();
+            compByCompType.put(type, typeComps);
+         }
+         typeComps.add(comp);
+         RunState state = updateRunState(mo, comp);
+      }
+
+      ManagementObject managementObject = (ManagementObject) moAnns.get(ManagementObject.class.getName());
+      if (managementObject != null && managementObject.isRuntime())
+      {
+         boolean merged = false;
+         ManagementComponent component = managementObject.componentType();
+         boolean isMC = !(component.type().length() == 0 && component.subtype().length() == 0);
+
+         // Merge this with the ManagedObject
+         ManagedObject parentMO = moRegistry.get(key);
+         if (parentMO == null && isMC == false)
+         {
+            log.trace("Deferring resolution of runtime ManagedObject: " + managementObject);
+            // Save the runtime mo for merging
+            runtimeMOs.put(key, mo);
+         }
+         else
+         {
+            mergeRuntimeMO(parentMO, mo);
+            merged = true;
+            runtimeMOs.remove(key);
+         }
+         // Update the runtime state of any ManagedComponent associated with this runtime mo
+         ManagedComponent comp = md.getComponent(mo.getName());
+         if (comp != null)
+         {
+            RunState state = updateRunState(mo, comp);
+            log.trace("Updated component: " + comp + " run state to: " + state);
+         }
+         // There is no further processing of runtime ManagedObjects, unless its marked as a component
+         if (isMC == false)
+            return;
+         //
+         else if (merged == false)
+         {
+            Set<ManagedOperation> runtimeOps = mo.getOperations();
+            runtimeOps = createOperationProxies(mo, runtimeOps);
+            MutableManagedObject moi = (MutableManagedObject) mo;
+            moi.setOperations(runtimeOps);
+         }
+      }
+      else
+      {
+         // See if there is runtime info to merge
+         ManagedObject runtimeMO = runtimeMOs.get(key);
+         if (runtimeMO != null)
+         {
+            mergeRuntimeMO(mo, runtimeMO);
+            runtimeMOs.remove(key);
+            // Update the runtime state of any ManagedComponent associated with this runtime mo
+            ManagedComponent comp = md.getComponent(mo.getName());
+            if (comp != null)
+            {
+               RunState state = updateRunState(runtimeMO, comp);
+               log.trace("Updated component: " + comp + " run state to: " + state);
+            }
+         }
+      }
+
+      // Update the MO registry
+      // TODO - does this make sense? In case of a MetaType.isCollection we could get different results then
+      //      ManagedObject prevMO = moRegistry.put(key, mo);
+      //      if( prevMO != null )
+      //      {
+      //         // This should only matter for ManagedObjects that have a ManagementObjectID
+      //         log.trace("Duplicate mo for key: "+key+", prevMO: "+prevMO);
+      //         return;
+      //      }
+      // Check for unresolved refs
+      checkForReferences(key, mo);
+
+      // Scan for @ManagementObjectRef
+      for (ManagedProperty prop : mo.getProperties().values())
+      {
+         log.trace("Checking property: " + prop);
+         // See if this is a ManagementObjectID
+         Map<String, Annotation> pannotations = prop.getAnnotations();
+         if (pannotations != null && pannotations.isEmpty() == false)
+         {
+            ManagementObjectID id = (ManagementObjectID) pannotations.get(ManagementObjectID.class.getName());
+            if (id != null)
+            {
+               Object refName = getRefName(prop.getValue());
+               if (refName == null)
+                  refName = id.name();
+               String propKey = refName + "/" + id.type();
+               log.trace("ManagedProperty level ID for ManagedObject: " + propKey + ", attachmentName: "
+                     + mo.getAttachmentName());
+               moRegistry.put(propKey, mo);
+               checkForReferences(propKey, mo);
+            }
+            // See if this is a ManagementObjectRef
+            ManagementObjectRef ref = (ManagementObjectRef) pannotations.get(ManagementObjectRef.class.getName());
+            if (ref != null)
+            {
+               // The reference key is the prop value + ref.type()
+               log.trace("Property(" + prop.getName() + ") references: " + ref);
+               Object refName = getRefName(prop.getValue());
+               if (refName == null)
+                  refName = ref.name();
+               String targetKey = refName + "/" + ref.type();
+               ManagedObject target = moRegistry.get(targetKey);
+               if (target != null)
+               {
+                  log.trace("Resolved property(" + prop.getName() + ") reference to: " + targetKey);
+                  prop.setTargetManagedObject(target);
+               }
+               else
+               {
+                  Set<ManagedProperty> referers = unresolvedRefs.get(targetKey);
+                  if (referers == null)
+                  {
+                     referers = new HashSet<ManagedProperty>();
+                     unresolvedRefs.put(targetKey, referers);
+                  }
+                  referers.add(prop);
+               }
+            }
+         }
+
+         MetaType propType = prop.getMetaType();
+         if (propType == AbstractManagedObjectFactory.MANAGED_OBJECT_META_TYPE)
+         {
+            processGenericValue((GenericValue) prop.getValue(), md);
+         }
+         else if (propType.isArray())
+         {
+            ArrayMetaType amt = (ArrayMetaType) propType;
+            MetaType etype = amt.getElementType();
+            if (etype == AbstractManagedObjectFactory.MANAGED_OBJECT_META_TYPE)
+            {
+               ArrayValue avalue = (ArrayValue) prop.getValue();
+               int length = avalue != null ? avalue.getLength() : 0;
+               for (int n = 0; n < length; n++)
+                  processGenericValue((GenericValue) avalue.getValue(n), md);
+            }
+         }
+         else if (propType.isCollection())
+         {
+            CollectionMetaType amt = (CollectionMetaType) propType;
+            MetaType etype = amt.getElementType();
+            if (etype == AbstractManagedObjectFactory.MANAGED_OBJECT_META_TYPE)
+            {
+               CollectionValue avalue = (CollectionValue) prop.getValue();
+               if (avalue != null)
+               {
+                  MetaValue[] elements = avalue.getElements();
+                  for (int n = 0; n < avalue.getSize(); n++)
+                  {
+                     GenericValue gv = (GenericValue) elements[n];
+                     ManagedObject propMO = (ManagedObject) gv.getValue();
+                     if (propMO != null)
+                        processManagedObject(propMO, md);
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * Get ref name.
+    *
+    * @param value property value
+    * @return plain value
+    */
+   protected Object getRefName(Object value)
+   {
+      if (value instanceof MetaValue)
+      {
+         MetaValue metaValue = (MetaValue) value;
+         if (metaValue.getMetaType().isSimple() == false)
+            throw new IllegalArgumentException("Can only get ref from simple value: " + value);
+         SimpleValue svalue = (SimpleValue) metaValue;
+         return svalue.getValue();
+      }
+      return value;
+   }
+
+   protected RunState updateRunState(ManagedObject runtimeMO, ManagedComponent comp)
+   {
+      RunState state = comp.getRunState();
+      if (state == RunState.UNKNOWN && dispatcher != null)
+      {
+         Object name = comp.getComponentName();
+         if (name == null && runtimeMO != null)
+            name = runtimeMO.getComponentName();
+         if (name != null)
+         {
+            state = getComponentMappedState(comp, runtimeMO, name, runStateMapper);
+            if (comp instanceof MutableManagedComponent)
+            {
+               MutableManagedComponent mcomp = MutableManagedComponent.class.cast(comp);
+               mcomp.setRunState(state);
+            }
+         }
+      }
+      return state;
+   }
+
+   protected DeploymentState getDeploymentState(ManagedDeployment md)
+   {
+      DeploymentState state = md.getDeploymentState();
+      if (state == DeploymentState.UNKNOWN && dispatcher != null)
+      {
+         Object name = md.getName();
+         if (name != null)
+         {
+            state = getMappedState(name, deploymentStateMapper);
+         }
+      }
+      return state;
+   }
+
+   protected <T extends Enum<?>> T getMappedState(Object name, ContextStateMapper<T> mapper)
+   {
+      T state = mapper.getErrorState();
+      try
+      {
+         if (dispatcher != null)
+         {
+            state = dispatcher.mapControllerState(name, mapper);
+         }
+      }
+      catch (Exception e)
+      {
+         log.debug("Failed to get controller state", e);
+      }
+      return state;
+   }
+
+   protected <T extends Enum<?>> T getComponentMappedState(ManagedComponent comp, ManagedObject mo, Object name,
+         ContextStateMapper<T> mapper)
+   {
+      T state = mapper.getErrorState();
+      try
+      {
+         RuntimeComponentDispatcher dispatcher;
+         if (mo != null && mo.getTransientAttachment(MBeanRuntimeComponentDispatcher.class.getName()) != null)
+         {
+            dispatcher = mbeanProxyFactory.getDispatcher();
+         }
+         else
+         {
+            dispatcher = this.dispatcher;
+         }
+
+         if (dispatcher != null)
+         {
+            state = dispatcher.mapControllerState(name, mapper);
+         }
+      }
+      catch (Exception e)
+      {
+         log.debug("Failed to get controller state", e);
+      }
+      return state;
+   }
+
+   /**
+    * Process generic value.
+    *
+    * @param genericValue the generic value
+    * @param md the managed deployment
+    * @throws Exception for any error
+    */
+   protected void processGenericValue(GenericValue genericValue, ManagedDeployment md) throws Exception
+   {
+      // TODO: a null is probably an error condition
+      if (genericValue != null)
+      {
+         ManagedObject propMO = (ManagedObject) genericValue.getValue();
+         // TODO: a null is probably an error condition
+         if (propMO != null)
+            processManagedObject(propMO, md);
+      }
+   }
+
+   /**
+    * Get the component name from managed property.
+    *
+    * @param property the managed property
+    * @return component name or null if no coresponding component
+    */
+   protected Object getComponentName(ManagedProperty property)
+   {
+      // first check target
+      ManagedObject targetObject = property.getTargetManagedObject();
+      if (targetObject != null)
+         return targetObject.getComponentName();
+
+      // check owner
+      targetObject = property.getManagedObject();
+      return targetObject != null ? targetObject.getComponentName() : null;
+   }
+
+   protected void checkForReferences(String key, ManagedObject mo)
+   {
+      Set<ManagedProperty> referers = unresolvedRefs.get(key);
+      log.trace("checkForReferences, " + key + " has referers: " + referers);
+      if (referers != null)
+      {
+         for (ManagedProperty prop : referers)
+         {
+            prop.setTargetManagedObject(mo);
+         }
+         unresolvedRefs.remove(key);
+      }
+   }
+
+   /**
+    * Merge the and proxy runtime props and ops
+    *
+    * @param mo - the parent managed object to merge into. May be null if the
+    * runtimeMO is a self contained managed object as is the case for runtime
+    * components.
+    * @param runtimeMO - the managed object with isRuntime=true to merge/proxy
+    * properties and operations for.
+    */
+   protected void mergeRuntimeMO(ManagedObject mo, ManagedObject runtimeMO) throws Exception
+   {
+      Map<String, ManagedProperty> runtimeProps = runtimeMO.getProperties();
+      Set<ManagedOperation> runtimeOps = runtimeMO.getOperations();
+      // Get the runtime MO component name
+      Object componentName = runtimeMO.getComponentName();
+      log.debug("Merging runtime: " + runtimeMO.getName() + ", compnent name: " + componentName);
+      Map<String, ManagedProperty> moProps = null;
+      Set<ManagedOperation> moOps = null;
+      HashMap<String, ManagedProperty> props = null;
+      HashSet<ManagedOperation> ops = null;
+      // If mo is null, the merge target is the runtimeMO
+      if (mo == null)
+      {
+         // Just proxy the runtime props/ops
+         mo = runtimeMO;
+         moProps = mo.getProperties();
+         moOps = mo.getOperations();
+         // These will be updated with the proxied values, don't duplicate props/ops
+         props = new HashMap<String, ManagedProperty>();
+         ops = new HashSet<ManagedOperation>();
+      }
+      else
+      {
+         // Merge the runtime props/ops
+         moProps = mo.getProperties();
+         moOps = mo.getOperations();
+         props = new HashMap<String, ManagedProperty>(moProps);
+         ops = new HashSet<ManagedOperation>(moOps);
+      }
+
+      boolean trace = log.isTraceEnabled();
+      if (runtimeProps != null && runtimeProps.size() > 0)
+      {
+         if (trace)
+            log.trace("Properties before:" + props);
+         // We need to pull the runtime values for stats
+         for (ManagedProperty prop : runtimeProps.values())
+         {
+            if (prop.hasViewUse(ViewUse.STATISTIC))
+            {
+               String propName = prop.getMappedName();
+               try
+               {
+                  AbstractRuntimeComponentDispatcher.setActiveProperty(prop);
+                  MetaValue propValue = dispatcher.get(componentName, propName);
+                  if (propValue != null)
+                     prop.setValue(propValue);
+               }
+               catch (Throwable t)
+               {
+                  log.debug("Failed to get stat value, " + componentName + ":" + propName);
+               }
+               ManagedProperty proxiedProp = createPropertyProxy(prop);
+               props.put(prop.getName(), proxiedProp);
+            }
+            else
+            {
+               props.put(prop.getName(), prop);
+            }
+            // Keep the property associated with the runtime MO for invocations/updates
+            if (prop.getTargetManagedObject() == null)
+               prop.setTargetManagedObject(runtimeMO);
+         }
+
+         if (trace)
+            log.trace("Properties after:" + props);
+      }
+      if (runtimeOps != null && runtimeOps.size() > 0)
+      {
+         if (trace)
+            log.trace("Ops before:" + ops);
+         runtimeOps = createOperationProxies(runtimeMO, runtimeOps);
+         ops.addAll(runtimeOps);
+         if (trace)
+            log.trace("Ops after:" + ops);
+      }
+
+      MutableManagedObject moi = (MutableManagedObject) mo;
+      moi.setProperties(props);
+      moi.setOperations(ops);
+   }
+
+   /**
+    * Create ManagedOperation wrapper to intercept
+    * its invocation, pushing the actual invocation
+    * to runtime component.
+    *
+    * @param mo the managed object
+    * @param ops the managed operations
+    * @return set of wrapped managed operations
+    * @throws Exception for any error
+    * @see #
+    */
+   protected Set<ManagedOperation> createOperationProxies(ManagedObject mo, Set<ManagedOperation> ops) throws Exception
+   {
+      if (proxyFactory == null)
+         throw new IllegalArgumentException("Missing RuntimeComponentDispatcher.");
+
+      Object componentName = mo.getComponentName();
+      return createOperationProxies(ops, componentName);
+   }
+
+   protected Set<ManagedOperation> createOperationProxies(Set<ManagedOperation> ops, Object componentName)
+         throws Exception
+   {
+      // Create the delegate operation
+      return proxyFactory.createOperationProxies(ops, componentName);
+   }
+
+   private ManagedProperty createPropertyProxy(ManagedProperty prop) throws Exception
+   {
+      if (proxyFactory == null)
+         throw new IllegalArgumentException("Missing RuntimeComponentDispatcher.");
+
+      // Create the delegate property
+      Object componentName = prop.getManagedObject().getComponentName();
+
+      if (prop.getManagedObject().getTransientAttachment(MBeanRuntimeComponentDispatcher.class.getName()) != null)
+         return mbeanProxyFactory.createPropertyProxy(prop, componentName);
+
+      return proxyFactory.createPropertyProxy(prop, componentName);
+   }
+
+   /**
+    * Create a defensive copy of this state.
+    * 
+    * @return the view state copy
+    */
+   protected ManagementViewState copy() {
+      final ManagementViewState state = new ManagementViewState(dispatcher, proxyFactory, mbeanProxyFactory, runStateMapper, deploymentStateMapper);
+      state.compByCompType.putAll(this.compByCompType);
+      state.managedDeployments.putAll(this.managedDeployments);
+      state.moRegistry.putAll(this.moRegistry);
+      state.rootDeployments.addAll(this.rootDeployments);
+      return state;
+   }
+   
+}
Index: profileservice/src/main/org/jboss/profileservice/management/ManagementViewImpl.java
===================================================================
--- profileservice/src/main/org/jboss/profileservice/management/ManagementViewImpl.java	(revision 113127)
+++ profileservice/src/main/org/jboss/profileservice/management/ManagementViewImpl.java	(working copy)
@@ -26,7 +26,6 @@
 import java.lang.annotation.Annotation;
 import java.lang.management.ManagementFactory;
 import java.text.MessageFormat;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -37,6 +36,7 @@
 import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -63,33 +63,20 @@
 import org.jboss.managed.api.ManagedObject;
 import org.jboss.managed.api.ManagedOperation;
 import org.jboss.managed.api.ManagedProperty;
-import org.jboss.managed.api.MutableManagedComponent;
-import org.jboss.managed.api.MutableManagedObject;
 import org.jboss.managed.api.RunState;
 import org.jboss.managed.api.annotation.ActivationPolicy;
 import org.jboss.managed.api.annotation.ManagementComponent;
 import org.jboss.managed.api.annotation.ManagementObject;
-import org.jboss.managed.api.annotation.ManagementObjectID;
-import org.jboss.managed.api.annotation.ManagementObjectRef;
 import org.jboss.managed.api.annotation.ManagementOperation;
 import org.jboss.managed.api.annotation.ManagementProperties;
 import org.jboss.managed.api.annotation.ManagementProperty;
 import org.jboss.managed.api.annotation.ViewUse;
 import org.jboss.managed.api.factory.ManagedObjectFactory;
-import org.jboss.managed.plugins.ManagedComponentImpl;
 import org.jboss.managed.plugins.ManagedDeploymentImpl;
-import org.jboss.managed.plugins.factory.AbstractManagedObjectFactory;
 import org.jboss.managed.plugins.jmx.ManagementFactoryUtils;
 import org.jboss.metadata.spi.MetaData;
-import org.jboss.metatype.api.types.ArrayMetaType;
-import org.jboss.metatype.api.types.CollectionMetaType;
-import org.jboss.metatype.api.types.MetaType;
-import org.jboss.metatype.api.values.ArrayValue;
-import org.jboss.metatype.api.values.CollectionValue;
-import org.jboss.metatype.api.values.GenericValue;
 import org.jboss.metatype.api.values.MetaValue;
 import org.jboss.metatype.api.values.MetaValueFactory;
-import org.jboss.metatype.api.values.SimpleValue;
 import org.jboss.profileservice.spi.ManagedMBeanDeploymentFactory;
 import org.jboss.profileservice.spi.ManagedMBeanDeploymentFactory.MBeanComponent;
 import org.jboss.profileservice.spi.ManagedMBeanDeploymentFactory.MBeanDeployment;
@@ -125,7 +112,7 @@
    /** The last modified cache for loaded profiles */
    private Map<ProfileKey, Long> lastModified = new HashMap<ProfileKey, Long>();
    /** Force a reload of ManagementView. */
-   private boolean forceReload;
+   private volatile boolean forceReload;
 
    /** The MainDeployer only used to get the ManagedDeployments */
    private MainDeployer mainDeployer;
@@ -133,7 +120,7 @@
    private AttachmentStore store;
 
    /** The deployment templates that have been registered with the MV */
-   private HashMap<String, DeploymentTemplate> templates = new HashMap<String, DeploymentTemplate>();
+   private Map<String, DeploymentTemplate> templates = Collections.synchronizedMap(new HashMap<String, DeploymentTemplate>());
 
    /** The internationalization resource bundle */
    private ResourceBundle i18n;
@@ -142,21 +129,8 @@
    /** The formatter used for i18n messages */
    private MessageFormat formatter = new MessageFormat("");
 
-   /** An index of ManagedComponent by ComponentType */
-   private HashMap<ComponentType, Set<ManagedComponent>> compByCompType = new HashMap<ComponentType, Set<ManagedComponent>>();
-   /** id/type key to ManagedObject map */
-   private Map<String, ManagedObject> moRegistry = new HashMap<String, ManagedObject>();
-   /** The ManagedPropertys with unresolved ManagementObjectRefs */
-   private Map<String, Set<ManagedProperty>> unresolvedRefs = new HashMap<String, Set<ManagedProperty>>();
-   /** A map of runtime ManagedObjects needing to be merged with their matching ManagedObject. */
-   private Map<String, ManagedObject> runtimeMOs = new HashMap<String, ManagedObject>();
-
    /** The bootstrap deployment name to ManagedDeployment map */
    private Map<String, ManagedDeployment> bootstrapManagedDeployments = Collections.emptyMap();
-   /** The deployment name to ManagedDeployment map */
-   private Map<String, ManagedDeployment> managedDeployments = new HashMap<String, ManagedDeployment>();
-   /** The root deployments to resolve the deployment name. */
-   private List<String> rootDeployments = new ArrayList<String>();
 
    /** The state mappings. */
    private static final ContextStateMapper<RunState> runStateMapper;
@@ -175,8 +149,8 @@
    /** ManagedObjectFactory used for platform mbean ManagedObjects */
    ManagedObjectFactory managedObjFactory = ManagedObjectFactory.getInstance();
    /** A map of ManagedMBeanDeploymentFactory for proxying mbeans into the management layer */
-   private HashMap<String, ManagedMBeanDeploymentFactory> mdfs =
-      new HashMap<String, ManagedMBeanDeploymentFactory>();
+   private Map<String, ManagedMBeanDeploymentFactory> mdfs =
+      Collections.synchronizedMap(new HashMap<String, ManagedMBeanDeploymentFactory>());
 
    /** The JMX Kernel for non MC managed JMXobjects */
    private MBeanServer mbeanServer;
@@ -184,6 +158,11 @@
    /** An MO Factory using MBeanInfo */
    private MBeanManagedObjectFactory mbeanMOFactory = new MBeanManagedObjectFactory();
 
+   /** The internal state for this view. */
+   @SuppressWarnings("unused")
+   private volatile ManagementViewState state = new ManagementViewState(null, null, null, runStateMapper, deploymentStateMapper);      
+   private static final AtomicReferenceFieldUpdater<ManagementViewImpl, ManagementViewState> stateUpdater = AtomicReferenceFieldUpdater.newUpdater(ManagementViewImpl.class, ManagementViewState.class, "state");
+   
    static
    {
       // Set default run state mappings for mc beans/mbeans
@@ -212,7 +191,6 @@
 
    public ManagementViewImpl() throws IOException
    {
-
       currentLocale = Locale.getDefault();
       formatter.setLocale(currentLocale);
       i18n = ResourceBundle.getBundle(BUNDLE_NAME, currentLocale);
@@ -229,33 +207,56 @@
       release();
    }
 
-   public synchronized boolean load()
+   public boolean load()
    {
       SecurityManager sm = System.getSecurityManager();
-      if(sm != null)
+      if (sm != null)
          sm.checkPermission(MV_RUNTIME_PERMISSION);
 
-      // If the profile is not modified do nothing
-      if(isReload() == false)
-      {
-         log.trace("Not reloading profiles.");
-         return false;
-      }
-      this.forceReload = false;
-
       // Clear any thread interrupt
       boolean wasInterrupted = Thread.interrupted();
-      if(wasInterrupted)
+      if (wasInterrupted)
          log.debug("Cleared interrupted state of calling thread");
 
-      // Cleanup
-      release();
-
+      try
+      {
+         final ManagementViewState oldState;
+         synchronized (this)
+         {
+            // If the profile is not modified do nothing
+            if (requiresReload() == false)
+            {
+               log.trace("Not reloading profiles.");
+               return false;
+            }
+            this.forceReload = false;
+            oldState = internalLoad();            
+         }
+         // Release the old state outside the lock          
+         if (oldState != null)
+         {
+            oldState.release();
+         }
+      }
+      finally
+      {
+         if (wasInterrupted)
+         {
+            Thread.currentThread().interrupt();
+            log.debug("Restored interrupted state of calling thread");
+         }
+      }
+      return true;
+   }
+      
+   protected synchronized ManagementViewState internalLoad()
+   {
       //
-      boolean trace = log.isTraceEnabled();
+      boolean trace = log.isTraceEnabled();      
+      final ManagementViewState newState = createNewState();      
 
       // load the profiles
-      loadProfiles(trace);
+      loadProfiles(newState, trace);
 
       // Process mbean components that need to be exposed as ManagedDeployment/ManagedComponent
       for(ManagedMBeanDeploymentFactory mdf : mdfs.values())
@@ -295,7 +296,7 @@
             mdi.setTypes(Collections.singleton("external-mbean"));
             try
             {
-               processManagedDeployment(mdi, null, DeploymentState.STARTED, 0, trace);
+               newState.processManagedDeployment(mdi, null, DeploymentState.STARTED, 0, trace);
             }
             catch(Exception e)
             {
@@ -309,16 +310,15 @@
       {
          try
          {
-            //
-            processManagedDeployment(md, null, DeploymentState.STARTED, 0, trace);
+            newState.processManagedDeployment(md, null, DeploymentState.STARTED, 0, trace);
          }
          catch(Exception e)
          {
             log.warn("Failed to process ManagedDeployment for: " + md.getName(), e);
          }
       }
-      if(this.runtimeMOs.size() > 0)
-         log.warn("Failed to merged the following runtime ManagedObjects: "+runtimeMOs);
+      // Check if the MOs were merged successfully
+      newState.checkRuntimeMOs();
 
       // Now create a ManagedDeployment for the platform beans
       Map<String, ManagedObject> platformMBeanMOs = ManagementFactoryUtils.getPlatformMBeanMOs(managedObjFactory);
@@ -347,19 +347,14 @@
       try
       {
          // Create the ManagedComponents
-         processManagedDeployment(platformMBeans, null, DeploymentState.STARTED, 0, trace);
+         newState.processManagedDeployment(platformMBeans, null, DeploymentState.STARTED, 0, trace);
       }
       catch(Exception e)
       {
          log.warn("Failed to process ManagedDeployments for the platform beans", e);
       }
-
-      if(wasInterrupted)
-      {
-         Thread.currentThread().interrupt();
-         log.debug("Restored interrupted state of calling thread");
-      }
-      return true;
+      // Swap the states
+      return stateUpdater.getAndSet(this, newState);
    }
 
    @SuppressWarnings("all")
@@ -472,20 +467,20 @@
 
    public void release()
    {
-      // Cleanup
-      this.compByCompType.clear();
-      this.managedDeployments.clear();
-      this.moRegistry.clear();
-      this.runtimeMOs.clear();
-      this.unresolvedRefs.clear();
-      this.lastModified.clear();
-      this.rootDeployments.clear();
-      // Cleanup delegate operations
-      this.proxyFactory.clear();
-
+      final ManagementViewState oldState;
+      synchronized (this)
+      {
+         // Replace the existing view with an empty one
+         oldState = stateUpdater.getAndSet(this, createNewState());
+         lastModified.clear();
+      }
+      if (oldState != null)
+      {
+         oldState.release();
+      }
    }
 
-   protected void loadProfiles(boolean trace)
+   protected void loadProfiles(final ManagementViewState viewState, final boolean trace)
    {
       log.trace("reloading profiles: "+ this.ps.getActiveProfileKeys());
       for(ProfileKey key : this.ps.getActiveProfileKeys())
@@ -506,7 +501,7 @@
                   try
                   {
                      ManagedDeployment md = getManagedDeployment(deployment);
-                     processRootManagedDeployment(md, key, trace);
+                     viewState.processRootManagedDeployment(md, key, trace);
 
                      // Cache the deployment types
                      if(md.getTypes() != null && md.getTypes().isEmpty() == false)
@@ -543,7 +538,7 @@
                         }
                      }
 
-                     processManagedDeployment(md, key, DeploymentState.STOPPED, 0, trace);
+                     viewState.processManagedDeployment(md, key, DeploymentState.STOPPED, 0, trace);
                   }
                }
                catch(Exception e)
@@ -559,7 +554,7 @@
       }
    }
 
-   protected boolean isReload()
+   protected boolean requiresReload()
    {
       if(forceReload == true)
       {
@@ -584,399 +579,6 @@
       return false;
    }
 
-   /**
-    * Process the root managed deployment. This gets
-    * the deployment state for this deployment, which will
-    * get populated to the child deployments as well.
-    *
-    * @param md the managed deployment
-    * @param profile the associated profile key
-    * @param trace is trace enabled
-    * @throws Exception for any error
-    */
-   protected void processRootManagedDeployment(ManagedDeployment md, ProfileKey profile, boolean trace) throws Exception
-   {
-      DeploymentState state = getDeploymentState(md);
-      processManagedDeployment(md, profile, state, 0, trace);
-   }
-
-   /**
-    * Process managed deployment.
-    *
-    * @param md the managed deployment
-    * @param profile the associated profile key
-    * @param state the deployment state
-    * @param level depth level
-    * @param trace is trace enabled
-    * @throws Exception for any error
-    */
-   protected void processManagedDeployment(ManagedDeployment md, ProfileKey profile, DeploymentState state, int level, boolean trace) throws Exception
-   {
-      String name = md.getName();
-      if (trace)
-         log.trace(name + " ManagedDeployment_" + level + ": " + md);
-      Map<String, ManagedObject> mos = md.getManagedObjects();
-      if (trace)
-         log.trace(name + " ManagedObjects_ " + level + ": " + mos);
-
-      // Set the deployment state
-      if(state != null && md instanceof ManagedDeploymentImpl)
-         ((ManagedDeploymentImpl)md).setDeploymentState(state);
-
-      // Map any existing ManagedComponent types
-      for(ManagedComponent comp : md.getComponents().values())
-      {
-         ComponentType type = comp.getType();
-         Set<ManagedComponent> typeComps = compByCompType.get(type);
-         if (typeComps == null)
-         {
-            typeComps = new HashSet<ManagedComponent>();
-            compByCompType.put(type, typeComps);
-         }
-         typeComps.add(comp);
-      }
-      
-      for(ManagedObject mo : mos.values())
-      {
-         processManagedObject(mo, md);
-      }
-      managedDeployments.put(name, md);
-
-      // Associate profile with the deployment
-      if(profile != null)
-      {
-         md.setAttachment(ProfileKey.class.getName(), profile);
-      }
-
-      // Add root deployments
-      if(level == 0)
-         this.rootDeployments.add(name);
-
-      // Process children
-      List<ManagedDeployment> mdChildren = md.getChildren();
-      if(mdChildren != null && mdChildren.isEmpty() == false)
-      {
-         for(ManagedDeployment mdChild : mdChildren)
-         {
-            // process the child deployments, with the state of the parent.
-            processManagedDeployment(mdChild, profile, state, level + 1, trace);
-         }
-      }
-   }
-
-   /**
-    * Process managed object.
-    *
-    * @param mo the managed object
-    * @param md the managed deployment
-    */
-   protected void processManagedObject(ManagedObject mo, ManagedDeployment md)
-      throws Exception
-   {
-      String key = mo.getName() + "/" + mo.getNameType();
-      log.trace("ID for ManagedObject: "+key+", attachmentName: "+mo.getAttachmentName());
-
-      // See if this is a runtime ManagedObject
-      Map<String, Annotation> moAnns = mo.getAnnotations();
-      
-      // Create ManagedComponents for ManagedObjects annotated with ManagementComponent
-      ManagementComponent mc = (ManagementComponent) moAnns.get(ManagementComponent.class.getName());
-      if (mc != null && md.getComponent(mo.getName()) == null)
-      {
-         ComponentType type = new ComponentType(mc.type(), mc.subtype());
-         MutableManagedComponent comp = new ManagedComponentImpl(type, md, mo);
-         
-         if(mo.getTransientAttachment(MBeanRuntimeComponentDispatcher.class.getName()) == null)
-            comp = this.proxyFactory.createComponentProxy(comp);
-         
-         md.addComponent(mo.getName(), comp);
-         log.trace("Processing ManagementComponent("+mo.getName()+"): "+comp);
-         Set<ManagedComponent> typeComps = compByCompType.get(type);
-         if (typeComps == null)
-         {
-            typeComps = new HashSet<ManagedComponent>();
-            compByCompType.put(type, typeComps);
-         }
-         typeComps.add(comp);
-         RunState state = updateRunState(mo, comp);
-      }
-
-      ManagementObject managementObject = (ManagementObject) moAnns.get(ManagementObject.class.getName());
-      if (managementObject != null && managementObject.isRuntime())
-      {
-         boolean merged = false;
-         ManagementComponent component = managementObject.componentType();
-         boolean isMC = !(component.type().length() == 0 && component.subtype().length() == 0);
-
-         // Merge this with the ManagedObject
-         ManagedObject parentMO = moRegistry.get(key);
-         if (parentMO == null && isMC == false)
-         {
-            log.trace("Deferring resolution of runtime ManagedObject: "+managementObject);
-            // Save the runtime mo for merging
-            runtimeMOs.put(key, mo);
-         }
-         else
-         {
-            mergeRuntimeMO(parentMO, mo);
-            merged = true;
-            runtimeMOs.remove(key);
-         }
-         // Update the runtime state of any ManagedComponent associated with this runtime mo
-         ManagedComponent comp = md.getComponent(mo.getName());
-         if (comp != null)
-         {
-            RunState state = updateRunState(mo, comp);
-            log.trace("Updated component: "+comp+" run state to: "+state);
-         }
-         // There is no further processing of runtime ManagedObjects, unless its marked as a component
-         if (isMC == false)
-            return;
-         //
-         else if (merged == false)
-         {
-            Set<ManagedOperation> runtimeOps = mo.getOperations();
-            runtimeOps = createOperationProxies(mo, runtimeOps);
-            MutableManagedObject moi = (MutableManagedObject) mo;
-            moi.setOperations(runtimeOps);
-         }
-      }
-      else
-      {
-         // See if there is runtime info to merge
-         ManagedObject runtimeMO = runtimeMOs.get(key);
-         if (runtimeMO != null)
-         {
-            mergeRuntimeMO(mo, runtimeMO);
-            runtimeMOs.remove(key);
-            // Update the runtime state of any ManagedComponent associated with this runtime mo
-            ManagedComponent comp = md.getComponent(mo.getName());
-            if (comp != null)
-            {
-               RunState state = updateRunState(runtimeMO, comp);
-               log.trace("Updated component: "+comp+" run state to: "+state);
-            }
-         }
-      }
-
-      // Update the MO registry
-      // TODO - does this make sense? In case of a MetaType.isCollection we could get different results then
-//      ManagedObject prevMO = moRegistry.put(key, mo);
-//      if( prevMO != null )
-//      {
-//         // This should only matter for ManagedObjects that have a ManagementObjectID
-//         log.trace("Duplicate mo for key: "+key+", prevMO: "+prevMO);
-//         return;
-//      }
-      // Check for unresolved refs
-      checkForReferences(key, mo);
-
-      // Scan for @ManagementObjectRef
-      for(ManagedProperty prop : mo.getProperties().values())
-      {
-         log.trace("Checking property: "+prop);
-         // See if this is a ManagementObjectID
-         Map<String, Annotation> pannotations = prop.getAnnotations();
-         if (pannotations != null && pannotations.isEmpty() == false)
-         {
-            ManagementObjectID id = (ManagementObjectID) pannotations.get(ManagementObjectID.class.getName());
-            if (id != null)
-            {
-               Object refName = getRefName(prop.getValue());
-               if (refName == null)
-                  refName = id.name();
-               String propKey = refName + "/" + id.type();
-               log.trace("ManagedProperty level ID for ManagedObject: "+propKey+", attachmentName: "+mo.getAttachmentName());
-               moRegistry.put(propKey, mo);
-               checkForReferences(propKey, mo);
-            }
-            // See if this is a ManagementObjectRef
-            ManagementObjectRef ref = (ManagementObjectRef) pannotations.get(ManagementObjectRef.class.getName());
-            if ( ref != null )
-            {
-               // The reference key is the prop value + ref.type()
-               log.trace("Property("+prop.getName()+") references: "+ref);
-               Object refName = getRefName(prop.getValue());
-               if (refName == null)
-                  refName = ref.name();
-               String targetKey = refName + "/" + ref.type();
-               ManagedObject target = moRegistry.get(targetKey);
-               if (target != null)
-               {
-                  log.trace("Resolved property("+prop.getName()+") reference to: "+targetKey);
-                  prop.setTargetManagedObject(target);
-               }
-               else
-               {
-                  Set<ManagedProperty> referers =  unresolvedRefs.get(targetKey);
-                  if (referers == null)
-                  {
-                     referers = new HashSet<ManagedProperty>();
-                     unresolvedRefs.put(targetKey, referers);
-                  }
-                  referers.add(prop);
-               }
-            }
-         }
-
-         MetaType propType = prop.getMetaType();
-         if (propType == AbstractManagedObjectFactory.MANAGED_OBJECT_META_TYPE)
-         {
-            processGenericValue ((GenericValue)prop.getValue(), md);
-         }
-         else if (propType.isArray())
-         {
-            ArrayMetaType amt = (ArrayMetaType) propType;
-            MetaType etype = amt.getElementType();
-            if (etype == AbstractManagedObjectFactory.MANAGED_OBJECT_META_TYPE)
-            {
-               ArrayValue avalue = (ArrayValue) prop.getValue();
-               int length = avalue != null ? avalue.getLength() : 0;
-               for(int n = 0; n < length; n ++)
-                  processGenericValue((GenericValue) avalue.getValue(n), md);
-            }
-         }
-         else if (propType.isCollection())
-         {
-            CollectionMetaType amt = (CollectionMetaType) propType;
-            MetaType etype = amt.getElementType();
-            if (etype == AbstractManagedObjectFactory.MANAGED_OBJECT_META_TYPE)
-            {
-               CollectionValue avalue = (CollectionValue) prop.getValue();
-               if(avalue != null)
-               {
-                  MetaValue[] elements = avalue.getElements();
-                  for(int n = 0; n < avalue.getSize(); n ++)
-                  {
-                     GenericValue gv = (GenericValue) elements[n];
-                     ManagedObject propMO = (ManagedObject) gv.getValue();
-                     if(propMO != null)
-                        processManagedObject(propMO, md);
-                  }
-               }
-            }
-         }
-      }
-   }
-
-   /**
-    * Get ref name.
-    *
-    * @param value property value
-    * @return plain value
-    */
-   protected Object getRefName(Object value)
-   {
-      if (value instanceof MetaValue)
-      {
-         MetaValue metaValue = (MetaValue)value;
-         if (metaValue.getMetaType().isSimple() == false)
-            throw new IllegalArgumentException("Can only get ref from simple value: " + value);
-         SimpleValue svalue = (SimpleValue) metaValue;
-         return svalue.getValue();
-      }
-      return value;
-   }
-
-   protected RunState updateRunState(ManagedObject runtimeMO, ManagedComponent comp)
-   {
-      RunState state = comp.getRunState();
-      if (state == RunState.UNKNOWN && dispatcher != null)
-      {
-         Object name = comp.getComponentName();
-         if (name == null && runtimeMO != null)
-            name = runtimeMO.getComponentName();
-         if (name != null)
-         {
-            state = getComponentMappedState(comp, runtimeMO, name, runStateMapper);
-            if (comp instanceof MutableManagedComponent)
-            {
-               MutableManagedComponent mcomp = MutableManagedComponent.class.cast(comp);
-               mcomp.setRunState(state);
-            }
-         }
-      }
-      return state;
-   }
-
-   protected DeploymentState getDeploymentState(ManagedDeployment md)
-   {
-      DeploymentState state = md.getDeploymentState();
-      if(state == DeploymentState.UNKNOWN && dispatcher != null)
-      {
-         Object name = md.getName();
-         if(name != null)
-         {
-            state = getMappedState(name, deploymentStateMapper);
-         }
-      }
-      return state;
-   }
-
-   protected <T extends Enum<?>> T getMappedState(Object name, ContextStateMapper<T> mapper)
-   {
-      T state = mapper.getErrorState();
-      try
-      {
-         if(dispatcher != null)
-         {
-            state = dispatcher.mapControllerState(name, mapper);
-         }
-      }
-      catch(Exception e)
-      {
-         log.debug("Failed to get controller state", e);
-      }
-      return state;
-   }
-
-   protected <T extends Enum<?>> T getComponentMappedState(ManagedComponent comp, ManagedObject mo, Object name, ContextStateMapper<T> mapper)
-   {
-      T state = mapper.getErrorState();
-      try
-      {
-         RuntimeComponentDispatcher dispatcher;
-         if (mo != null && mo.getTransientAttachment(MBeanRuntimeComponentDispatcher.class.getName()) != null)
-         {
-            dispatcher = mbeanProxyFactory.getDispatcher();
-         }
-         else
-         {
-            dispatcher = this.dispatcher;
-         }
-
-         if (dispatcher != null)
-         {
-            state = dispatcher.mapControllerState(name, mapper);
-         }
-      }
-      catch(Exception e)
-      {
-         log.debug("Failed to get controller state", e);
-      }
-      return state;
-   }
-
-   /**
-    * Process generic value.
-    *
-    * @param genericValue the generic value
-    * @param md the managed deployment
-    * @throws Exception for any error
-    */
-   protected void processGenericValue(GenericValue genericValue, ManagedDeployment md) throws Exception
-   {
-      // TODO: a null is probably an error condition
-      if (genericValue != null)
-      {
-         ManagedObject propMO = (ManagedObject) genericValue.getValue();
-         // TODO: a null is probably an error condition
-         if (propMO != null)
-            processManagedObject(propMO, md);
-      }
-   }
-
-
    public Map<String, ManagedDeployment> getBootstrapManagedDeployments()
    {
       return bootstrapManagedDeployments;
@@ -1054,7 +656,6 @@
       this.dispatcher = dispatcher;
    }
 
-
    public MBeanServer getMbeanServer()
    {
       return mbeanServer;
@@ -1065,7 +666,6 @@
       this.mbeanServer = mbeanServer;
    }
 
-
    public MBeanManagedObjectFactory getMbeanMOFactory()
    {
       return mbeanMOFactory;
@@ -1084,8 +684,8 @@
       SecurityManager sm = System.getSecurityManager();
       if(sm != null)
          sm.checkPermission(MV_RUNTIME_PERMISSION);
-
-      return new TreeSet<String>(this.managedDeployments.keySet());
+      final ManagementViewState viewState = stateUpdater.get(this);
+      return new TreeSet<String>(viewState.getManagedDeployments().keySet());
    }
 
    /**
@@ -1101,7 +701,8 @@
          sm.checkPermission(MV_RUNTIME_PERMISSION);
 
      Set<String> matches = new TreeSet<String>();
-      for(ManagedDeployment md : managedDeployments.values())
+      final ManagementViewState viewState = stateUpdater.get(this);
+      for(ManagedDeployment md : viewState.getManagedDeployments().values())
       {
          String name = md.getName();
          Set<String> types = md.getTypes();
@@ -1158,8 +759,9 @@
       {
          throw new IllegalArgumentException("null deployment matcher");
       }
+      final ManagementViewState viewState = stateUpdater.get(this);
       Set<ManagedDeployment> matches = new HashSet<ManagedDeployment>();
-      for(ManagedDeployment deployment : this.managedDeployments.values())
+      for(ManagedDeployment deployment : viewState.getManagedDeployments().values())
       {
          if(matcher.matches(deployment, name))
          {
@@ -1219,18 +821,19 @@
       if(name == null)
          throw new IllegalArgumentException("Null deployment name");
 
+      final ManagementViewState viewState = stateUpdater.get(this);
       // Resolve internally.
-      ManagedDeployment md = this.managedDeployments.get(name);
+      ManagedDeployment md = viewState.getManagedDeployments().get(name);
       if (md == null)
       {
-         // Check the bootstrap deployments
+         // Check the bootstrap deployments        
          md = this.bootstrapManagedDeployments.get(name);
       }
 
       // Check the file name
       if(md == null)
       {
-         for(String deployment : this.rootDeployments)
+         for(String deployment : viewState.getRootDeployments())
          {
             String fixedDeploymentName = deployment;
             if(deployment.endsWith("/"))
@@ -1238,7 +841,7 @@
 
             if(fixedDeploymentName.endsWith(name))
             {
-               md = this.managedDeployments.get(deployment);
+               md = viewState.getManagedDeployments().get(deployment);
                break;
             }
          }
@@ -1283,8 +886,9 @@
       SecurityManager sm = System.getSecurityManager();
       if(sm != null)
          sm.checkPermission(MV_RUNTIME_PERMISSION);
-
-      HashSet<ComponentType> types = new HashSet<ComponentType>(compByCompType.keySet());
+      
+      final ManagementViewState viewState = stateUpdater.get(this);
+      HashSet<ComponentType> types = new HashSet<ComponentType>(viewState.getCompByCompType().keySet());
       return types;
    }
 
@@ -1304,10 +908,11 @@
 
      Set<ManagedComponent> comps = null;
       // Check the any component type
+      final ManagementViewState viewState = stateUpdater.get(this);
       if(type.equals(KnownComponentTypes.ANY_TYPE))
       {
          HashSet<ManagedComponent> all = new HashSet<ManagedComponent>();
-         for(Set<ManagedComponent> typeComps : compByCompType.values())
+         for(Set<ManagedComponent> typeComps : viewState.getCompByCompType().values())
          {
             for(ManagedComponent comp : typeComps)
             {
@@ -1318,7 +923,7 @@
       }
       else
       {
-        comps = compByCompType.get(type);
+        comps = viewState.getCompByCompType().get(type);
       }
       if(comps == null)
          comps = Collections.emptySet();
@@ -1331,8 +936,9 @@
       SecurityManager sm = System.getSecurityManager();
       if(sm != null)
          sm.checkPermission(MV_RUNTIME_PERMISSION);
-
-      Set<ManagedComponent> components = compByCompType.get(type);
+      
+      final ManagementViewState viewState = stateUpdater.get(this);
+      Set<ManagedComponent> components = viewState.getCompByCompType().get(type);
       ManagedComponent comp = null;
       if(components != null)
       {
@@ -1366,7 +972,8 @@
       if(sm != null)
          sm.checkPermission(MV_RUNTIME_PERMISSION);
 
-      Set<ManagedComponent> components = compByCompType.get(type);
+      final ManagementViewState viewState = stateUpdater.get(this);
+      Set<ManagedComponent> components = viewState.getCompByCompType().get(type);
       Set<ManagedComponent> matched = new HashSet<ManagedComponent>();
       if(components != null)
       {
@@ -1408,37 +1015,47 @@
       return info;
    }
 
-   public void applyTemplate(String deploymentBaseName, DeploymentTemplateInfo info)
-      throws Exception
+   public void applyTemplate(String deploymentBaseName, DeploymentTemplateInfo info) throws Exception
    {
       SecurityManager sm = System.getSecurityManager();
-      if(sm != null)
+      if (sm != null)
          sm.checkPermission(MV_RUNTIME_PERMISSION);
 
-      if(deploymentBaseName == null)
+      if (deploymentBaseName == null)
          throw new IllegalArgumentException("Null deployment base name.");
-      if(info == null)
+      if (info == null)
          throw new IllegalArgumentException("Null template info.");
 
       DeploymentTemplate template = templates.get(info.getName());
-      if( template == null )
+      if (template == null)
       {
          formatter.applyPattern(i18n.getString("ManagementView.NoSuchTemplate")); //$NON-NLS-1$
-         Object[] args = {info.getName()};
+         Object[] args =
+         {info.getName()};
          String msg = formatter.format(args);
          throw new IllegalStateException(msg);
       }
 
       // Create a deployment base from the template
-      if( log.isTraceEnabled() )
-         log.trace("applyTemplate, deploymentBaseName="+deploymentBaseName +", info="+info);
+      if (log.isTraceEnabled())
+         log.trace("applyTemplate, deploymentBaseName=" + deploymentBaseName + ", info=" + info);
 
-      // Create, distribute and start a deployment template
-      String deploymentName = super.applyTemplate(template, deploymentBaseName, info);
-
-      // Process the deployment
-      ManagedDeployment md = getMainDeployer().getManagedDeployment(deploymentName);
-      processRootManagedDeployment(md, getDefaulProfiletKey(), log.isTraceEnabled());
+      final ManagementViewState oldState;
+      synchronized (this)
+      {
+         final ManagementViewState currentState = stateUpdater.get(this);
+         final ManagementViewState newState = currentState.copy();
+         // Create, distribute and start a deployment template
+         String deploymentName = super.applyTemplate(template, deploymentBaseName, info);
+         // Process the deployment
+         ManagedDeployment md = getMainDeployer().getManagedDeployment(deploymentName);
+         newState.processRootManagedDeployment(md, getDefaulProfiletKey(), log.isTraceEnabled());
+         oldState = stateUpdater.getAndSet(this, newState);
+      }
+      if (oldState != null)
+      {
+         oldState.release();
+      }
    }
 
    public void process() throws DeploymentException
@@ -1449,7 +1066,7 @@
    /**
     * Process a component update.
     */
-   public void updateComponent(ManagedComponent comp)
+   public synchronized void updateComponent(ManagedComponent comp)
       throws Exception
    {
       SecurityManager sm = System.getSecurityManager();
@@ -1476,7 +1093,8 @@
       }
 
       // Apply the managed properties to the server ManagedDeployment/ManagedComponent
-      ManagedDeployment compMD = managedDeployments.get(md.getName());
+      final ManagementViewState viewState = stateUpdater.get(this);      
+      ManagedDeployment compMD = viewState.getManagedDeployments().get(md.getName());
       log.trace("updateComponent, deploymentName="+name+": "+compMD);
 
       ManagedComponent serverComp = null;
@@ -1572,7 +1190,7 @@
       this.forceReload = true;
    }
 
-   public void removeComponent(ManagedComponent comp) throws Exception
+   public synchronized void removeComponent(ManagedComponent comp) throws Exception
    {
       SecurityManager sm = System.getSecurityManager();
       if(sm != null)
@@ -1598,7 +1216,8 @@
       }
 
       // Apply the managed properties to the server ManagedDeployment/ManagedComponent
-      ManagedDeployment compMD = managedDeployments.get(md.getName());
+      final ManagementViewState viewState = stateUpdater.get(this);      
+      ManagedDeployment compMD = viewState.getManagedDeployments().get(md.getName());
       log.trace("updateComponent, deploymentName="+name+": "+compMD);
 
       ManagedComponent serverComp = null;
@@ -1656,156 +1275,6 @@
       return targetObject != null ? targetObject.getComponentName() : null;
    }
 
-   protected void checkForReferences(String key, ManagedObject mo)
-   {
-      Set<ManagedProperty> referers =  unresolvedRefs.get(key);
-      log.trace("checkForReferences, "+key+" has referers: "+referers);
-      if (referers != null)
-      {
-         for(ManagedProperty prop : referers)
-         {
-            prop.setTargetManagedObject(mo);
-         }
-         unresolvedRefs.remove(key);
-      }
-   }
-
-   /**
-    * Merge the and proxy runtime props and ops
-    *
-    * @param mo - the parent managed object to merge into. May be null if the
-    * runtimeMO is a self contained managed object as is the case for runtime
-    * components.
-    * @param runtimeMO - the managed object with isRuntime=true to merge/proxy
-    * properties and operations for.
-    */
-   protected void mergeRuntimeMO(ManagedObject mo, ManagedObject runtimeMO)
-      throws Exception
-   {
-      Map<String, ManagedProperty> runtimeProps = runtimeMO.getProperties();
-      Set<ManagedOperation> runtimeOps = runtimeMO.getOperations();
-      // Get the runtime MO component name
-      Object componentName = runtimeMO.getComponentName();
-      log.debug("Merging runtime: "+runtimeMO.getName()+", compnent name: "+componentName);
-      Map<String, ManagedProperty> moProps = null;
-      Set<ManagedOperation> moOps = null;
-      HashMap<String, ManagedProperty> props = null;
-      HashSet<ManagedOperation> ops = null;
-      // If mo is null, the merge target is the runtimeMO
-      if (mo == null)
-      {
-         // Just proxy the runtime props/ops
-         mo = runtimeMO;
-         moProps = mo.getProperties();
-         moOps = mo.getOperations();
-         // These will be updated with the proxied values, don't duplicate props/ops
-         props = new HashMap<String, ManagedProperty>();
-         ops = new HashSet<ManagedOperation>();
-      }
-      else
-      {
-         // Merge the runtime props/ops
-         moProps = mo.getProperties();
-         moOps = mo.getOperations();
-         props = new HashMap<String, ManagedProperty>(moProps);
-         ops = new HashSet<ManagedOperation>(moOps);
-      }
-
-      boolean trace = log.isTraceEnabled();
-      if (runtimeProps != null && runtimeProps.size() > 0)
-      {
-         if(trace)
-            log.trace("Properties before:"+props);
-         // We need to pull the runtime values for stats
-         for(ManagedProperty prop : runtimeProps.values())
-         {
-            if(prop.hasViewUse(ViewUse.STATISTIC))
-            {
-               String propName = prop.getMappedName();
-               try
-               {
-                  AbstractRuntimeComponentDispatcher.setActiveProperty(prop);
-                  MetaValue propValue = dispatcher.get(componentName, propName);
-                  if(propValue != null)
-                     prop.setValue(propValue);
-               }
-               catch(Throwable t)
-               {
-                  log.debug("Failed to get stat value, "+componentName+":"+propName);
-               }
-               ManagedProperty proxiedProp = createPropertyProxy(prop);
-               props.put(prop.getName(), proxiedProp);
-            }
-            else
-            {
-               props.put(prop.getName(), prop);
-            }
-            // Keep the property associated with the runtime MO for invocations/updates
-            if (prop.getTargetManagedObject() == null)
-               prop.setTargetManagedObject(runtimeMO);
-         }
-
-         if(trace)
-            log.trace("Properties after:"+props);
-      }
-      if (runtimeOps != null && runtimeOps.size() > 0)
-      {
-         if(trace)
-            log.trace("Ops before:"+ops);
-         runtimeOps = createOperationProxies(runtimeMO, runtimeOps);
-         ops.addAll(runtimeOps);
-         if(trace)
-            log.trace("Ops after:"+ops);
-      }
-
-      MutableManagedObject moi = (MutableManagedObject) mo;
-      moi.setProperties(props);
-      moi.setOperations(ops);
-   }
-
-   private ManagedProperty createPropertyProxy(ManagedProperty prop)
-      throws Exception
-   {
-      if (proxyFactory == null)
-         throw new IllegalArgumentException("Missing RuntimeComponentDispatcher.");
-
-      // Create the delegate property
-      Object componentName = prop.getManagedObject().getComponentName();
-
-      if (prop.getManagedObject().getTransientAttachment(MBeanRuntimeComponentDispatcher.class.getName()) != null)
-         return mbeanProxyFactory.createPropertyProxy(prop, componentName);
-
-      return proxyFactory.createPropertyProxy(prop, componentName);
-   }
-
-   /**
-    * Create ManagedOperation wrapper to intercept
-    * its invocation, pushing the actual invocation
-    * to runtime component.
-    *
-    * @param mo the managed object
-    * @param ops the managed operations
-    * @return set of wrapped managed operations
-    * @throws Exception for any error
-    * @see #
-    */
-   protected Set<ManagedOperation> createOperationProxies(ManagedObject mo, Set<ManagedOperation> ops)
-      throws Exception
-   {
-      if (proxyFactory == null)
-         throw new IllegalArgumentException("Missing RuntimeComponentDispatcher.");
-
-      Object componentName = mo.getComponentName();
-      return createOperationProxies(ops, componentName);
-   }
-
-   protected Set<ManagedOperation> createOperationProxies(Set<ManagedOperation> ops, Object componentName)
-      throws Exception
-   {
-      // Create the delegate operation
-      return proxyFactory.createOperationProxies(ops, componentName);
-   }
-
    private ManagedObject createManagedObject(ObjectName mbean, String defaultViewUse, Map<String, String> propertyMetaMappings)
       throws Exception
    {
@@ -1864,4 +1333,14 @@
    {
       this.mbeanProxyFactory = mbeanProxyFactory;
    }
+
+   /**
+    * Create the internal view state.
+    * 
+    * @return the new view state
+    */
+   private ManagementViewState createNewState() {
+      return new ManagementViewState(dispatcher, proxyFactory, mbeanProxyFactory, runStateMapper, deploymentStateMapper);      
+   }
+   
 }
