/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.geronimo.gshell.spring;

import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
import org.springframework.beans.FatalBeanException;
import org.springframework.context.ConfigurableApplicationContext;

import java.net.URL;
import java.util.List;

/**
 * Default {@link BeanContainer} implementation.
 *
 * @version $Rev$ $Date$
 */
public class BeanContainerImpl
    extends BeanContainerSupport
{
    private static final String REALM_ID = "gshell";

    private BeanContainer parent;

    private BeanContainerContext context;

    private ClassRealm classRealm;
    
    public BeanContainerImpl(final ClassLoader classLoader) {
        assert classLoader != null;

        ClassRealm realm;
        try {
            realm = new ClassWorld().newRealm(REALM_ID, classLoader);
        }
        catch (DuplicateRealmException e) {
            // Should never happen
            throw new Error(e);
        }

        configureContext(realm, null);
    }

    /**
     * Child container constructor.
     */
    private BeanContainerImpl(final ClassRealm classRealm, final BeanContainerImpl parent) {
        assert parent != null;
        assert classRealm != null;

        configureContext(classRealm, parent);
    }

    private void configureContext(final ClassRealm classRealm, final BeanContainerImpl parent) {
        assert classRealm != null;
        // parent may be null

        this.parent = parent;
        this.classRealm = classRealm;

        // Construct the container and add customizations
        context = new BeanContainerContext(classRealm, parent != null ? parent.context : null);
        context.registerShutdownHook();
        context.addBeanPostProcessor(new BeanContainerAwareProcessor(this));

        // Refresh to load things up
        context.refresh();
    }

    protected ConfigurableApplicationContext getContext() {
        return context;
    }

    public BeanContainer getParent() {
        return parent;
    }

    public ClassRealm getClassRealm() {
        return classRealm;
    }

    public BeanContainer createChild(final String id, final List<URL> classPath) {
        assert id != null;
        // classPath may be null

        if (log.isTraceEnabled()) {
            log.trace("Creating child container: {}", id);
            if (classPath != null) {
                log.trace("Classpath:");
                for (URL url : classPath) {
                    log.trace("    {}", url);
                }
            }
        }

        ClassRealm childRealm;
        try {
            childRealm = classRealm.createChildRealm(id);
        }
        catch (DuplicateRealmException e) {
            throw new FatalBeanException("Failed to create child container realm: " + id, e);
        }

        if (classPath != null) {
            for (URL url : classPath) {
                childRealm.addURL(url);
            }
        }

        return new BeanContainerImpl(childRealm, this);
    }

    /*
    public Object configure(final Object bean) {
        assert bean != null;

        context.getAutowireCapableBeanFactory().autowireBean(bean);

        return bean;
    }
    */
}
@@ -1398,32 +1398,38 @@
 %22;%0A%0A    private 
+final 
 BeanContainer pa
@@ -1439,32 +1439,38 @@
 t;%0A%0A    private 
+final 
 BeanContainerCon
@@ -1496,16 +1496,22 @@
 private 
+final 
 ClassRea
@@ -1529,41 +1529,62 @@
 lm;%0A
-    
 %0A    p
-ublic BeanContainerImpl
+rivate static ClassRealm createDefaultClassRealm
 (fin
@@ -1600,25 +1600,16 @@
 oader cl
-assLoader
 ) %7B%0A    
@@ -1621,25 +1621,16 @@
 ssert cl
-assLoader
  != null
@@ -1636,34 +1636,8 @@
 l;%0A%0A
-        ClassRealm realm;%0A
     
@@ -1660,21 +1660,20 @@
       re
-alm =
+turn
  new Cla
@@ -1703,25 +1703,16 @@
 M_ID, cl
-assLoader
 );%0A     
@@ -1841,310 +1841,114 @@
   %7D%0A
-%0A        configureContext(realm, null);%0A    %7D%0A%0A    /**%0A     * Child container constructor.%0A     */%0A    private BeanContainerImpl(final ClassRealm classRealm, final BeanContainerImpl parent) %7B%0A        assert parent != null;%0A        assert classRealm != null;%0A%0A        configureContext(classRealm, parent
+    %7D%0A%0A    public BeanContainerImpl(final ClassLoader cl) %7B%0A        this(createDefaultClassRealm(cl), null
 );%0A 
@@ -1969,29 +1969,25 @@
 ate 
-void configureContext
+BeanContainerImpl
 (fin
@@ -2331,24 +2331,76 @@
 xt : null);%0A
+        context.setDisplayName(classRealm.getId());%0A
         cont

Refactor to allow fields to be final Use the class realm id as the containers display name