You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xbean-scm@geronimo.apache.org by gn...@apache.org on 2012/10/03 10:38:37 UTC

svn commit: r1393346 [2/8] - in /geronimo/xbean/trunk: ./ maven-xbean-plugin/ maven-xbean-plugin/src/main/java/org/apache/xbean/maven/ xbean-asm-shaded/src/main/appended-resources/META-INF/ xbean-blueprint/ xbean-blueprint/src/main/java/org/apache/xbea...

Modified: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java?rev=1393346&r1=1393345&r2=1393346&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java (original)
+++ geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java Wed Oct  3 08:38:26 2012
@@ -1,860 +1,860 @@
-/**
- * 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.xbean.naming.context;
-
-import javax.naming.CompositeName;
-import javax.naming.Context;
-import javax.naming.InvalidNameException;
-import javax.naming.Name;
-import javax.naming.NameAlreadyBoundException;
-import javax.naming.NameParser;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.NotContextException;
-import javax.naming.LinkRef;
-import javax.naming.NameNotFoundException;
-import javax.naming.InitialContext;
-import javax.naming.OperationNotSupportedException;
-import javax.naming.NameClassPair;
-import javax.naming.Binding;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.Map;
-
-public abstract class AbstractContext implements Context, NestedContextFactory, Serializable {
-    private static final long serialVersionUID = 6481918425692261483L;
-    private final String nameInNamespace;
-    private final Name parsedNameInNamespace;
-    private final ContextAccess contextAccess;
-    private final boolean modifiable;
-    private final ThreadLocal<Name> inCall = new ThreadLocal<Name>();
-
-    protected AbstractContext(String nameInNamespace) {
-        this(nameInNamespace, ContextAccess.MODIFIABLE);
-    }
-
-    public AbstractContext(String nameInNamespace, ContextAccess contextAccess) {
-        this.nameInNamespace = nameInNamespace;
-        try {
-            this.parsedNameInNamespace = getNameParser().parse(nameInNamespace);
-        } catch (NamingException e) {
-            throw new RuntimeException(e);
-        }
-        this.contextAccess = contextAccess;
-        this.modifiable = contextAccess.isModifiable(getParsedNameInNamespace());
-    }
-
-    public void close() throws NamingException {
-        //Ignore. Explicitly do not close the context
-    }
-
-    protected ContextAccess getContextAccess() {
-        return contextAccess;
-    }
-
-    //
-    //  Lookup Binding
-    //
-
-    /**
-     * Gets the object bound to the name.  The name may contain slashes.
-     * @param name the name
-     * @return the object bound to the name, or null if not found
-     */
-    protected Object getDeepBinding(String name) {
-        return null;
-    }
-
-    /**
-     * Gets the object bound to the name.  The name will not contain slashes.
-     * @param name the name
-     * @return the object bound to the name, or null if not found
-     * @throws javax.naming.NamingException on error
-     */
-    protected Object getBinding(String name) throws NamingException {
-        Map<String, Object> bindings = getBindings();
-        return bindings.get(name);
-    }
-
-    /**
-     * Finds the specified entry.  Normally there is no need to override this method; instead you should
-     * simply implement the getDeepBindings(String) and getBindings(String) method.
-     *
-     * This method will follow links except for the final element which is always just returned without
-     * inspection.  This means this method can be used to implement lookupLink.
-     *
-     * @param stringName the string version of the name; maybe null
-     * @param parsedName the parsed name; may be null
-     * @return the value bound to the name
-     * @throws NamingException if no value is bound to that name or if a problem occurs during the lookup
-     */
-    protected Object lookup(String stringName, Name parsedName) throws NamingException {
-        if (stringName == null && parsedName == null) {
-            throw new IllegalArgumentException("Both stringName and parsedName are null");
-        }
-        if (stringName == null) stringName = parsedName.toString();
-
-        // try to look up the name directly (this is the fastest path)
-        Object directLookup = getDeepBinding(stringName);
-        if (directLookup != null) {
-            return ContextUtil.resolve(directLookup, stringName, parsedName, this);
-        }
-
-        // if the parsed name has no parts, they are asking for the current context
-        if (parsedName == null) parsedName = getNameParser().parse(stringName);
-        if (parsedName.isEmpty()) {
-            return this;
-        }
-
-        // we didn't find an entry, pop the first element off the parsed name and attempt to
-        // get a context from the bindings and delegate to that context
-        Object localValue;
-        String firstNameElement = parsedName.get(0);
-        if (firstNameElement.length() == 0) {
-            // the element is null... this is normally caused by looking up with a trailing '/' character
-            localValue = this;
-        } else {
-            localValue = getBinding(firstNameElement);
-        }
-
-        if (localValue != null) {
-
-            // if the name only had one part, we've looked up everything
-            if (parsedName.size() == 1) {
-                localValue = ContextUtil.resolve(localValue, stringName, parsedName, this);
-                return localValue;
-            }
-
-            // if we have a link ref, follow it
-            if (localValue instanceof LinkRef) {
-                LinkRef linkRef = (LinkRef) localValue;
-                localValue = lookup(linkRef.getLinkName());
-            }
-
-            // we have more to lookup so we better have a context object
-            if (!(localValue instanceof Context)) {
-                throw new NameNotFoundException(stringName);
-            }
-
-            // delegate to the sub-context
-            return ((Context) localValue).lookup(parsedName.getSuffix(1));
-        }
-
-        // if we didn't find an entry, it may be an absolute name
-        Object value = faultLookup(stringName, parsedName);
-        if (value != null) {
-            return value;
-        }
-        if (parsedName.size() > 1) {
-            throw new NotContextException(stringName);
-        } else {
-            throw new NameNotFoundException(stringName);
-        }
-    }
-
-    /**
-     * When a value can not be found within this context, this method is called as a last ditch effort befrore
-     * thowing a null pointer exception.
-     * @param stringName the string version of the name; will not be null
-     * @param parsedName the parsed name; will not be null
-     * @return the value or null if no fault value could be found
-     */
-    protected Object faultLookup(String stringName, Name parsedName) {
-        if (!stringName.startsWith(nameInNamespace) && stringName.indexOf(':') > 0 && inCall.get() == null) {
-            inCall.set(parsedName);
-            try {
-                Context ctx = new InitialContext();
-                return ctx.lookup(parsedName);
-            } catch (NamingException ignored) {
-                // thrown below
-            } finally {
-                inCall.set(null);                
-            }
-        }
-        return null;
-    }
-
-    protected Context lookupFinalContext(Name name) throws NamingException {
-        Object value;
-        try {
-            value = lookup(name.getPrefix(name.size() - 1));
-        } catch (NamingException e) {
-            throw new NotContextException("The intermediate context " + name.get(name.size() - 1) + " does not exist");
-        }
-
-        if (value == null) {
-            throw new NotContextException("The intermediate context " + name.get(name.size() - 1) + " does not exist");
-        } else if (!(value instanceof Context)) {
-            throw new NotContextException("The intermediate context " + name.get(name.size() - 1) + " is not a context");
-        } else {
-            return (Context) value;
-        }
-    }
-
-    //
-    //  List Bindings
-    //
-
-    /**
-     * Gets a map of the bindings for the current node (i.e., no names with slashes).
-     * This method must not return null.
-     *
-     * @return a Map from binding name to binding value
-     * @throws NamingException if a problem occurs while getting the bindigns
-     */
-    protected abstract Map<String, Object> getBindings() throws NamingException;
-
-    //
-    //  Add Binding
-    //
-
-    protected void addDeepBinding(Name name, Object value, boolean rebind, boolean createIntermediateContexts) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-        if (value == null) throw new NullPointerException("value is null for name: " + name);
-
-        if (name.isEmpty()) {
-            throw new InvalidNameException("Name is empty");
-        }
-
-        if (name.size() == 1) {
-            addBinding(name.get(0), value, rebind);
-            return;
-        }
-
-        if (!createIntermediateContexts) {
-            Context context = lookupFinalContext(name);
-
-            String lastSegment = name.get(name.size() - 1);
-            addBinding(context, lastSegment, value, rebind);
-        } else {
-            Context currentContext = this;
-            for (int i = 0; i < name.size(); i++) {
-                String part = name.get(i);
-
-                // empty path parts are not allowed
-                if (part.length() == 0) {
-                    // this could be supported but it would be tricky
-                    throw new InvalidNameException("Name part " + i + " is empty: " + name);
-                }
-
-                // Is this the last element in the name?
-                if (i == name.size() - 1) {
-                    // we're at the end... (re)bind the value into the parent context
-                    addBinding(currentContext, part, value, rebind);
-
-                    // all done... this is redundant but makes the code more readable
-                    break;
-                } else {
-                    Object currentValue = getBinding(currentContext, part);
-                    if (currentValue == null) {
-                        // the next step in the tree is not present, so create everything down
-                        // and add it to the current bindings
-                        Context subcontext = createSubcontextTree(name.getPrefix(i).toString(), name.getSuffix(i), value);
-                        addBinding(currentContext, part, subcontext, rebind);
-
-                        // all done
-                        break;
-                    } else {
-                        // the current value must be a nested subcontext
-                        if (!(currentValue instanceof Context)) {
-                            throw new NotContextException("Expected an instance of context to be bound at " +
-                                    part + " but found an instance of " + currentValue.getClass().getName());
-                        }
-                        currentContext = (Context) currentValue;
-                        // now we recurse into the current context
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Gets the value bound to the specified name within the specified context.  If the specified context is an
-     * AbstractContext this method will call the faster getBinding method, otherwise it will call lookup.
-     *
-     * @param context the context to get the binding from
-     * @param name the binding name
-     * @return the bound value or null if no value was bound
-     */
-    private static Object getBinding(Context context, String name) {
-        try {
-            if (context instanceof AbstractContext) {
-                AbstractContext abstractContext = (AbstractContext) context;
-                return abstractContext.getBinding(name);
-            } else {
-                return context.lookup(name);
-            }
-        } catch (NamingException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Binds the specified value to the specified name within the specified context.  If the specified context is an
-     * AbstractContext and is a nested subcontext, this method will call the direct addBinding method, otherwise it
-     * will call public (re)bind method.
-     *
-     * @param context the context to add the binding to
-     * @param name the binding name
-     * @param value the value to bind
-     * @param rebind if true, this method will replace any exsiting binding, otherwise a NamingException will be thrown
-     * @throws NamingException if a problem occurs while (re)binding
-     */
-    protected void addBinding(Context context, String name, Object value, boolean rebind) throws NamingException {
-        if (context == this || (context instanceof AbstractContext && isNestedSubcontext(context))) {
-            AbstractContext abstractContext = (AbstractContext) context;
-            abstractContext.addBinding(name, value, rebind);
-        } else {
-            if (rebind) {
-                context.rebind(name, value);
-            } else {
-                context.bind(name, value);
-            }
-        }
-    }
-
-    protected abstract boolean addBinding(String name, Object value, boolean rebind) throws NamingException;
-
-    /**
-     * Creates a context tree which will be rooted at the specified path and contain a single entry located down
-     * a path specified by the name.  All necessary intermediate contexts will be created using the createContext method.
-     * @param path the path to the context that will contains this context
-     * @param name the name under which the value should be bound
-     * @param value the value
-     * @return a context with the value bound at the specified name
-     * @throws NamingException if a problem occurs while creating the subcontext tree
-     */
-    protected Context createSubcontextTree(String path, Name name, Object value) throws NamingException {
-        if (path == null) throw new NullPointerException("path is null");
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.size() < 2) throw new InvalidNameException("name must have at least 2 parts " + name);
-
-        if (path.length() > 0 && !path.endsWith("/")) path += "/";
-
-        for (int i = name.size() - 1; i > 0; i--) {
-            String fullPath = path + name.getPrefix(i);
-            String key = name.get(i);
-            value = createNestedSubcontext(fullPath, Collections.singletonMap(key, value));
-        }
-        return (Context) value;
-    }
-
-
-    //
-    //  Remove Binding
-    //
-
-    /**
-     * Removes the binding from the context.  The name will not contain a path and the value will not
-     * be a nested context although it may be a foreign context.
-     * @param name name under which the value should be bound
-     * @param removeNotEmptyContext ??? TODO figure this out
-     * @return whether removal was successful
-     * @throws NamingException if a problem occurs during the bind such as a value already being bound
-     */
-    protected abstract boolean removeBinding(String name, boolean removeNotEmptyContext) throws NamingException;
-
-    protected void removeDeepBinding(Name name, boolean pruneEmptyContexts) throws NamingException {
-        removeDeepBinding(name, pruneEmptyContexts, false);
-    }
-
-    protected void removeDeepBinding(Name name, boolean pruneEmptyContexts, boolean removeNotEmptyContext) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.isEmpty()) {
-            throw new InvalidNameException("Name is empty");
-        }
-
-        if (name.size() == 1) {
-            removeBinding(name.get(0), removeNotEmptyContext);
-            return;
-        }
-
-        if (!pruneEmptyContexts) {
-            Context context = lookupFinalContext(name);
-            context.unbind(name.getSuffix(name.size() - 1));
-        } else {
-            // we serch the tree for a target context and name to remove
-            // this is normally the last context in the tree and the final name part, but
-            // it may be farther up the path if the intervening nodes are empty
-            Context targetContext = this;
-            String targetName = name.get(0);
-
-            Context currentContext = this;
-            for (int i = 0; i < name.size(); i++) {
-                String part = name.get(i);
-
-                // empty path parts are not allowed
-                if (part.length() == 0) {
-                    throw new InvalidNameException("Name part " + i + " is empty: " + name);
-                }
-
-                // update targets
-                if (getSize(currentContext) > 1) {
-                    targetContext = currentContext;
-                    targetName = part;
-                }
-
-
-                // Is this the last element in the name?
-                if (i == name.size() - 1) {
-                    // we're at the end... unbind value
-                    unbind(targetContext, targetName, true);
-
-                    // all done... this is redundant but makes the code more readable
-                    break;
-                } else {
-                    Object currentValue = getBinding(currentContext, part);
-                    if (currentValue == null) {
-                        // path not found we are done, but first prune the empty contexts
-                        if (targetContext != currentContext) {
-                            unbind(targetContext, targetName, false);
-                        }
-                        break;
-                    } else {
-                        // the current value must be a context
-                        if (!(currentValue instanceof Context)) {
-                            throw new NotContextException("Expected an instance of context to be bound at " +
-                                    part + " but found an instance of " + currentValue.getClass().getName());
-                        }
-                        currentContext = (Context) currentValue;
-                        // now we recurse into the current context
-                    }
-                }
-            }
-        }
-    }
-
-    protected static boolean isEmpty(Context context) throws NamingException {
-        if (context instanceof AbstractContext) {
-            AbstractContext abstractContext = (AbstractContext) context;
-            Map<String, Object> currentBindings = abstractContext.getBindings();
-            return currentBindings.isEmpty();
-        } else {
-            NamingEnumeration namingEnumeration = context.list("");
-            return namingEnumeration.hasMore();
-        }
-    }
-
-    protected static int getSize(Context context) throws NamingException {
-        if (context instanceof AbstractContext) {
-            AbstractContext abstractContext = (AbstractContext) context;
-            Map<String, Object> currentBindings = abstractContext.getBindings();
-            return currentBindings.size();
-        } else {
-            NamingEnumeration namingEnumeration = context.list("");
-            int size = 0;
-            while (namingEnumeration.hasMore()) size++;
-            return size;
-        }
-    }
-
-    /**
-     * Unbinds any value bound to the specified name within the specified context.  If the specified context is an
-     * AbstractContext and is a nested context, this method will call the direct removeBinding method, otherwise it
-     * will call public unbind.
-     *
-     * @param context the context to remove the binding from
-     * @param name the binding name
-     * @param removeNotEmptyContext ??? TODO figure this out
-     * @throws NamingException if a problem occurs while unbinding
-     */
-    private void unbind(Context context, String name, boolean removeNotEmptyContext) throws NamingException {
-        if (context == this || (context instanceof AbstractContext && isNestedSubcontext(context))) {
-            AbstractContext abstractContext = (AbstractContext) context;
-            abstractContext.removeBinding(name, removeNotEmptyContext);
-        } else {
-            context.unbind(name);
-        }
-    }
-
-    //
-    // Environment
-    //
-
-    /**
-     * Always returns a new (empty) Hashtable.
-     * @return a new (empty) Hashtable
-     */
-    public Hashtable getEnvironment() {
-        return new Hashtable();
-    }
-
-    public Object addToEnvironment(String propName, Object propVal) throws NamingException {
-        if (propName == null) throw new NullPointerException("propName is null");
-        if (propVal == null) throw new NullPointerException("propVal is null");
-
-        Map env = getEnvironment();
-        return env.put(propName, propVal);
-    }
-
-    public Object removeFromEnvironment(String propName) throws NamingException {
-        if (propName == null) throw new NullPointerException("propName is null");
-
-        Map env = getEnvironment();
-        return env.remove(propName);
-    }
-
-    //
-    // Name handling
-    //
-
-    /**
-     * Gets the name of this context withing the global namespace.  This method may return null
-     * if the location of the node in the global namespace is not known
-     * @return the name of this context within the global namespace or null if unknown.
-     */
-    public String getNameInNamespace() {
-        return nameInNamespace;
-    }
-
-    /**
-     * Gets the name of this context withing the global namespace.  This method may return null
-     * if the location of the node in the global namespace is not known
-     * @return the name of this context within the global namespace or null if unknown.
-     */
-    protected Name getParsedNameInNamespace() {
-        return parsedNameInNamespace;
-    }
-
-    /**
-     * Gets the name of a path withing the global namespace context.
-     * @param path path to extend
-     * @return full path in namespace
-     */
-    protected String getNameInNamespace(String path) {
-        String nameInNamespace = getNameInNamespace();
-        if (nameInNamespace == null || nameInNamespace.length() == 0) {
-            return path;
-        } else {
-            return nameInNamespace + "/" + path;
-        }
-    }
-
-    /**
-     * Gets the name of a path withing the global namespace context.
-     * @param path path to extend
-     * @return full path in namespace
-     * @throws javax.naming.NamingException on error
-     */
-    protected Name getNameInNamespace(Name path) throws NamingException {
-        Name nameInNamespace = getParsedNameInNamespace();
-        if (nameInNamespace == null || nameInNamespace.size() == 0) {
-            return path;
-        } else {
-            return composeName(nameInNamespace, path);
-        }
-    }
-
-    /**
-     * A parser that can turn Strings into javax.naming.Name objects.
-     * @return ContextUtil.NAME_PARSER
-     */
-    protected NameParser getNameParser() {
-        return ContextUtil.NAME_PARSER;
-    }
-
-    public NameParser getNameParser(Name name) {
-        return getNameParser();
-    }
-
-    public NameParser getNameParser(String name) {
-        return getNameParser();
-    }
-
-    public Name composeName(Name name, Name prefix) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-        if (prefix == null) throw new NullPointerException("prefix is null");
-
-        Name result = (Name) prefix.clone();
-        result.addAll(name);
-        return result;
-    }
-
-    public String composeName(String name, String prefix) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-        if (prefix == null) throw new NullPointerException("prefix is null");
-
-        CompositeName result = new CompositeName(prefix);
-        result.addAll(new CompositeName(name));
-        return result.toString();
-    }
-
-    //
-    // Lookup
-    //
-
-    public Object lookup(String name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-
-        Object value = lookup(name, null);
-
-        // if we got a link back we need to resolve it
-        if (value instanceof LinkRef) {
-            LinkRef linkRef = (LinkRef) value;
-            value = lookup(linkRef.getLinkName());
-        }
-
-        return value;
-    }
-
-    public Object lookup(Name name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-
-        Object value = lookup(null, name);
-
-
-        // if we got a link back we need to resolve it
-        if (value instanceof LinkRef) {
-            LinkRef linkRef = (LinkRef) value;
-            value = lookup(linkRef.getLinkName());
-        }
-
-        return value;
-    }
-
-    public Object lookupLink(String name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-        return lookup(name, null);
-    }
-
-    public Object lookupLink(Name name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-        return lookup(null, name);
-    }
-
-    //
-    // Bind, rebind, rename and unbind
-    //
-
-    public void bind(String name, Object obj) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.length() == 0) {
-            throw new NameAlreadyBoundException("Cannot bind to an empty name (this context)");
-        }
-        bind(new CompositeName(name), obj);
-    }
-
-    public void bind(Name name, Object obj) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.isEmpty()) {
-            throw new NameAlreadyBoundException("Cannot bind to an empty name (this context)");
-        }
-        addDeepBinding(name, obj, false, false);
-    }
-
-    public void rebind(String name, Object obj) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        rebind(new CompositeName(name), obj);
-    }
-
-    public void rebind(Name name, Object obj) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.isEmpty()) {
-            throw new NameAlreadyBoundException("Cannot rebind an empty name (this context)");
-        }
-        addDeepBinding(name, obj, true, false);
-    }
-
-    public void rename(String oldName, String newName) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (oldName == null) throw new NullPointerException("oldName is null");
-        if (newName == null) throw new NullPointerException("newName is null");
-        rename(new CompositeName(oldName), new CompositeName(newName));
-    }
-
-    public void rename(Name oldName, Name newName) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (oldName == null || newName == null) {
-            throw new NullPointerException("name is null");
-        } else if (oldName.isEmpty() || newName.isEmpty()) {
-            throw new NameAlreadyBoundException("Name cannot be empty");
-        }
-        this.bind(newName, this.lookup(oldName));
-        this.unbind(oldName);
-    }
-
-    public void unbind(String name) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        unbind(new CompositeName(name));
-    }
-
-    public void unbind(Name name) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.isEmpty()) {
-            throw new InvalidNameException("Cannot unbind empty name");
-        }
-        removeDeepBinding(name, false);
-    }
-
-    //
-    // List
-    //
-
-    protected NamingEnumeration<NameClassPair> list() throws NamingException {
-        Map<String, Object> bindings = getBindings();
-        return new ContextUtil.ListEnumeration(bindings);
-    }
-
-    protected NamingEnumeration<Binding> listBindings() throws NamingException {
-        Map<String, Object> bindings = getBindings();
-        return new ContextUtil.ListBindingEnumeration(bindings, this);
-    }
-
-    public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-
-        // if the name is empty, list the current context
-        if (name.length() == 0) {
-            return list();
-        }
-
-        // lookup the target context
-        Object target;
-        try {
-            target = lookup(name);
-        } catch (NamingException e) {
-            throw new NotContextException(name);
-        }
-
-        if (target == this) {
-            return list();
-        } else if (target instanceof Context) {
-            return ((Context) target).list("");
-        } else {
-            throw new NotContextException("The name " + name + " cannot be listed");
-        }
-    }
-
-    public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-
-        // if the name is empty, list the current context
-        if (name.isEmpty()) {
-            return list();
-        }
-
-        // lookup the target context
-        Object target;
-        try {
-            target = lookup(name);
-        } catch (NamingException e) {
-            throw new NotContextException(name.toString());
-        }
-
-        if (target == this) {
-            return list();
-        } else if (target instanceof Context) {
-            return ((Context) target).list("");
-        } else {
-            throw new NotContextException("The name " + name + " cannot be listed");
-        }
-    }
-
-    public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-
-        // if the name is empty, list the current context
-        if (name.length() == 0) {
-            return listBindings();
-        }
-
-        // lookup the target context
-        Object target;
-        try {
-            target = lookup(name);
-        } catch (NamingException e) {
-            throw new NotContextException(name);
-        }
-
-        if (target == this) {
-            return listBindings();
-        } else if (target instanceof Context) {
-            return ((Context) target).listBindings("");
-        } else {
-            throw new NotContextException("The name " + name + " cannot be listed");
-        }
-    }
-
-    public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
-        if (name == null) throw new NullPointerException("name is null");
-
-        // if the name is empty, list the current context
-        if (name.isEmpty()) {
-            return listBindings();
-        }
-
-        // lookup the target context
-        Object target;
-        try {
-            target = lookup(name);
-        } catch (NamingException e) {
-            throw new NotContextException(name.toString());
-        }
-
-        if (target == this) {
-            return listBindings();
-        } else if (target instanceof Context) {
-            return ((Context) target).listBindings("");
-        } else {
-            throw new NotContextException("The name " + name + " cannot be listed");
-        }
-    }
-
-    //
-    // Subcontexts
-    //
-
-    public Context createSubcontext(String name) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        return createSubcontext(new CompositeName(name));
-    }
-
-    public Context createSubcontext(Name name) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.isEmpty()) {
-            throw new NameAlreadyBoundException("Cannot create a subcontext if the name is empty");
-        }
-        Context abstractContext = createNestedSubcontext(name.toString(), Collections.EMPTY_MAP);
-        addDeepBinding(name, abstractContext, false, false);
-        return abstractContext;
-    }
-
-    public void destroySubcontext(String name) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        destroySubcontext(new CompositeName(name));
-    }
-
-    public void destroySubcontext(Name name) throws NamingException {
-        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
-        if (name == null) throw new NullPointerException("name is null");
-        if (name.isEmpty()) {
-            throw new InvalidNameException("Cannot destroy subcontext with empty name");
-        }
-        unbind(name);
-    }
-}
+/**
+ * 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.xbean.naming.context;
+
+import javax.naming.CompositeName;
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NotContextException;
+import javax.naming.LinkRef;
+import javax.naming.NameNotFoundException;
+import javax.naming.InitialContext;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.NameClassPair;
+import javax.naming.Binding;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Map;
+
+public abstract class AbstractContext implements Context, NestedContextFactory, Serializable {
+    private static final long serialVersionUID = 6481918425692261483L;
+    private final String nameInNamespace;
+    private final Name parsedNameInNamespace;
+    private final ContextAccess contextAccess;
+    private final boolean modifiable;
+    private final ThreadLocal<Name> inCall = new ThreadLocal<Name>();
+
+    protected AbstractContext(String nameInNamespace) {
+        this(nameInNamespace, ContextAccess.MODIFIABLE);
+    }
+
+    public AbstractContext(String nameInNamespace, ContextAccess contextAccess) {
+        this.nameInNamespace = nameInNamespace;
+        try {
+            this.parsedNameInNamespace = getNameParser().parse(nameInNamespace);
+        } catch (NamingException e) {
+            throw new RuntimeException(e);
+        }
+        this.contextAccess = contextAccess;
+        this.modifiable = contextAccess.isModifiable(getParsedNameInNamespace());
+    }
+
+    public void close() throws NamingException {
+        //Ignore. Explicitly do not close the context
+    }
+
+    protected ContextAccess getContextAccess() {
+        return contextAccess;
+    }
+
+    //
+    //  Lookup Binding
+    //
+
+    /**
+     * Gets the object bound to the name.  The name may contain slashes.
+     * @param name the name
+     * @return the object bound to the name, or null if not found
+     */
+    protected Object getDeepBinding(String name) {
+        return null;
+    }
+
+    /**
+     * Gets the object bound to the name.  The name will not contain slashes.
+     * @param name the name
+     * @return the object bound to the name, or null if not found
+     * @throws javax.naming.NamingException on error
+     */
+    protected Object getBinding(String name) throws NamingException {
+        Map<String, Object> bindings = getBindings();
+        return bindings.get(name);
+    }
+
+    /**
+     * Finds the specified entry.  Normally there is no need to override this method; instead you should
+     * simply implement the getDeepBindings(String) and getBindings(String) method.
+     *
+     * This method will follow links except for the final element which is always just returned without
+     * inspection.  This means this method can be used to implement lookupLink.
+     *
+     * @param stringName the string version of the name; maybe null
+     * @param parsedName the parsed name; may be null
+     * @return the value bound to the name
+     * @throws NamingException if no value is bound to that name or if a problem occurs during the lookup
+     */
+    protected Object lookup(String stringName, Name parsedName) throws NamingException {
+        if (stringName == null && parsedName == null) {
+            throw new IllegalArgumentException("Both stringName and parsedName are null");
+        }
+        if (stringName == null) stringName = parsedName.toString();
+
+        // try to look up the name directly (this is the fastest path)
+        Object directLookup = getDeepBinding(stringName);
+        if (directLookup != null) {
+            return ContextUtil.resolve(directLookup, stringName, parsedName, this);
+        }
+
+        // if the parsed name has no parts, they are asking for the current context
+        if (parsedName == null) parsedName = getNameParser().parse(stringName);
+        if (parsedName.isEmpty()) {
+            return this;
+        }
+
+        // we didn't find an entry, pop the first element off the parsed name and attempt to
+        // get a context from the bindings and delegate to that context
+        Object localValue;
+        String firstNameElement = parsedName.get(0);
+        if (firstNameElement.length() == 0) {
+            // the element is null... this is normally caused by looking up with a trailing '/' character
+            localValue = this;
+        } else {
+            localValue = getBinding(firstNameElement);
+        }
+
+        if (localValue != null) {
+
+            // if the name only had one part, we've looked up everything
+            if (parsedName.size() == 1) {
+                localValue = ContextUtil.resolve(localValue, stringName, parsedName, this);
+                return localValue;
+            }
+
+            // if we have a link ref, follow it
+            if (localValue instanceof LinkRef) {
+                LinkRef linkRef = (LinkRef) localValue;
+                localValue = lookup(linkRef.getLinkName());
+            }
+
+            // we have more to lookup so we better have a context object
+            if (!(localValue instanceof Context)) {
+                throw new NameNotFoundException(stringName);
+            }
+
+            // delegate to the sub-context
+            return ((Context) localValue).lookup(parsedName.getSuffix(1));
+        }
+
+        // if we didn't find an entry, it may be an absolute name
+        Object value = faultLookup(stringName, parsedName);
+        if (value != null) {
+            return value;
+        }
+        if (parsedName.size() > 1) {
+            throw new NotContextException(stringName);
+        } else {
+            throw new NameNotFoundException(stringName);
+        }
+    }
+
+    /**
+     * When a value can not be found within this context, this method is called as a last ditch effort befrore
+     * thowing a null pointer exception.
+     * @param stringName the string version of the name; will not be null
+     * @param parsedName the parsed name; will not be null
+     * @return the value or null if no fault value could be found
+     */
+    protected Object faultLookup(String stringName, Name parsedName) {
+        if (!stringName.startsWith(nameInNamespace) && stringName.indexOf(':') > 0 && inCall.get() == null) {
+            inCall.set(parsedName);
+            try {
+                Context ctx = new InitialContext();
+                return ctx.lookup(parsedName);
+            } catch (NamingException ignored) {
+                // thrown below
+            } finally {
+                inCall.set(null);                
+            }
+        }
+        return null;
+    }
+
+    protected Context lookupFinalContext(Name name) throws NamingException {
+        Object value;
+        try {
+            value = lookup(name.getPrefix(name.size() - 1));
+        } catch (NamingException e) {
+            throw new NotContextException("The intermediate context " + name.get(name.size() - 1) + " does not exist");
+        }
+
+        if (value == null) {
+            throw new NotContextException("The intermediate context " + name.get(name.size() - 1) + " does not exist");
+        } else if (!(value instanceof Context)) {
+            throw new NotContextException("The intermediate context " + name.get(name.size() - 1) + " is not a context");
+        } else {
+            return (Context) value;
+        }
+    }
+
+    //
+    //  List Bindings
+    //
+
+    /**
+     * Gets a map of the bindings for the current node (i.e., no names with slashes).
+     * This method must not return null.
+     *
+     * @return a Map from binding name to binding value
+     * @throws NamingException if a problem occurs while getting the bindigns
+     */
+    protected abstract Map<String, Object> getBindings() throws NamingException;
+
+    //
+    //  Add Binding
+    //
+
+    protected void addDeepBinding(Name name, Object value, boolean rebind, boolean createIntermediateContexts) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+        if (value == null) throw new NullPointerException("value is null for name: " + name);
+
+        if (name.isEmpty()) {
+            throw new InvalidNameException("Name is empty");
+        }
+
+        if (name.size() == 1) {
+            addBinding(name.get(0), value, rebind);
+            return;
+        }
+
+        if (!createIntermediateContexts) {
+            Context context = lookupFinalContext(name);
+
+            String lastSegment = name.get(name.size() - 1);
+            addBinding(context, lastSegment, value, rebind);
+        } else {
+            Context currentContext = this;
+            for (int i = 0; i < name.size(); i++) {
+                String part = name.get(i);
+
+                // empty path parts are not allowed
+                if (part.length() == 0) {
+                    // this could be supported but it would be tricky
+                    throw new InvalidNameException("Name part " + i + " is empty: " + name);
+                }
+
+                // Is this the last element in the name?
+                if (i == name.size() - 1) {
+                    // we're at the end... (re)bind the value into the parent context
+                    addBinding(currentContext, part, value, rebind);
+
+                    // all done... this is redundant but makes the code more readable
+                    break;
+                } else {
+                    Object currentValue = getBinding(currentContext, part);
+                    if (currentValue == null) {
+                        // the next step in the tree is not present, so create everything down
+                        // and add it to the current bindings
+                        Context subcontext = createSubcontextTree(name.getPrefix(i).toString(), name.getSuffix(i), value);
+                        addBinding(currentContext, part, subcontext, rebind);
+
+                        // all done
+                        break;
+                    } else {
+                        // the current value must be a nested subcontext
+                        if (!(currentValue instanceof Context)) {
+                            throw new NotContextException("Expected an instance of context to be bound at " +
+                                    part + " but found an instance of " + currentValue.getClass().getName());
+                        }
+                        currentContext = (Context) currentValue;
+                        // now we recurse into the current context
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the value bound to the specified name within the specified context.  If the specified context is an
+     * AbstractContext this method will call the faster getBinding method, otherwise it will call lookup.
+     *
+     * @param context the context to get the binding from
+     * @param name the binding name
+     * @return the bound value or null if no value was bound
+     */
+    private static Object getBinding(Context context, String name) {
+        try {
+            if (context instanceof AbstractContext) {
+                AbstractContext abstractContext = (AbstractContext) context;
+                return abstractContext.getBinding(name);
+            } else {
+                return context.lookup(name);
+            }
+        } catch (NamingException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Binds the specified value to the specified name within the specified context.  If the specified context is an
+     * AbstractContext and is a nested subcontext, this method will call the direct addBinding method, otherwise it
+     * will call public (re)bind method.
+     *
+     * @param context the context to add the binding to
+     * @param name the binding name
+     * @param value the value to bind
+     * @param rebind if true, this method will replace any exsiting binding, otherwise a NamingException will be thrown
+     * @throws NamingException if a problem occurs while (re)binding
+     */
+    protected void addBinding(Context context, String name, Object value, boolean rebind) throws NamingException {
+        if (context == this || (context instanceof AbstractContext && isNestedSubcontext(context))) {
+            AbstractContext abstractContext = (AbstractContext) context;
+            abstractContext.addBinding(name, value, rebind);
+        } else {
+            if (rebind) {
+                context.rebind(name, value);
+            } else {
+                context.bind(name, value);
+            }
+        }
+    }
+
+    protected abstract boolean addBinding(String name, Object value, boolean rebind) throws NamingException;
+
+    /**
+     * Creates a context tree which will be rooted at the specified path and contain a single entry located down
+     * a path specified by the name.  All necessary intermediate contexts will be created using the createContext method.
+     * @param path the path to the context that will contains this context
+     * @param name the name under which the value should be bound
+     * @param value the value
+     * @return a context with the value bound at the specified name
+     * @throws NamingException if a problem occurs while creating the subcontext tree
+     */
+    protected Context createSubcontextTree(String path, Name name, Object value) throws NamingException {
+        if (path == null) throw new NullPointerException("path is null");
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.size() < 2) throw new InvalidNameException("name must have at least 2 parts " + name);
+
+        if (path.length() > 0 && !path.endsWith("/")) path += "/";
+
+        for (int i = name.size() - 1; i > 0; i--) {
+            String fullPath = path + name.getPrefix(i);
+            String key = name.get(i);
+            value = createNestedSubcontext(fullPath, Collections.singletonMap(key, value));
+        }
+        return (Context) value;
+    }
+
+
+    //
+    //  Remove Binding
+    //
+
+    /**
+     * Removes the binding from the context.  The name will not contain a path and the value will not
+     * be a nested context although it may be a foreign context.
+     * @param name name under which the value should be bound
+     * @param removeNotEmptyContext ??? TODO figure this out
+     * @return whether removal was successful
+     * @throws NamingException if a problem occurs during the bind such as a value already being bound
+     */
+    protected abstract boolean removeBinding(String name, boolean removeNotEmptyContext) throws NamingException;
+
+    protected void removeDeepBinding(Name name, boolean pruneEmptyContexts) throws NamingException {
+        removeDeepBinding(name, pruneEmptyContexts, false);
+    }
+
+    protected void removeDeepBinding(Name name, boolean pruneEmptyContexts, boolean removeNotEmptyContext) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.isEmpty()) {
+            throw new InvalidNameException("Name is empty");
+        }
+
+        if (name.size() == 1) {
+            removeBinding(name.get(0), removeNotEmptyContext);
+            return;
+        }
+
+        if (!pruneEmptyContexts) {
+            Context context = lookupFinalContext(name);
+            context.unbind(name.getSuffix(name.size() - 1));
+        } else {
+            // we serch the tree for a target context and name to remove
+            // this is normally the last context in the tree and the final name part, but
+            // it may be farther up the path if the intervening nodes are empty
+            Context targetContext = this;
+            String targetName = name.get(0);
+
+            Context currentContext = this;
+            for (int i = 0; i < name.size(); i++) {
+                String part = name.get(i);
+
+                // empty path parts are not allowed
+                if (part.length() == 0) {
+                    throw new InvalidNameException("Name part " + i + " is empty: " + name);
+                }
+
+                // update targets
+                if (getSize(currentContext) > 1) {
+                    targetContext = currentContext;
+                    targetName = part;
+                }
+
+
+                // Is this the last element in the name?
+                if (i == name.size() - 1) {
+                    // we're at the end... unbind value
+                    unbind(targetContext, targetName, true);
+
+                    // all done... this is redundant but makes the code more readable
+                    break;
+                } else {
+                    Object currentValue = getBinding(currentContext, part);
+                    if (currentValue == null) {
+                        // path not found we are done, but first prune the empty contexts
+                        if (targetContext != currentContext) {
+                            unbind(targetContext, targetName, false);
+                        }
+                        break;
+                    } else {
+                        // the current value must be a context
+                        if (!(currentValue instanceof Context)) {
+                            throw new NotContextException("Expected an instance of context to be bound at " +
+                                    part + " but found an instance of " + currentValue.getClass().getName());
+                        }
+                        currentContext = (Context) currentValue;
+                        // now we recurse into the current context
+                    }
+                }
+            }
+        }
+    }
+
+    protected static boolean isEmpty(Context context) throws NamingException {
+        if (context instanceof AbstractContext) {
+            AbstractContext abstractContext = (AbstractContext) context;
+            Map<String, Object> currentBindings = abstractContext.getBindings();
+            return currentBindings.isEmpty();
+        } else {
+            NamingEnumeration namingEnumeration = context.list("");
+            return namingEnumeration.hasMore();
+        }
+    }
+
+    protected static int getSize(Context context) throws NamingException {
+        if (context instanceof AbstractContext) {
+            AbstractContext abstractContext = (AbstractContext) context;
+            Map<String, Object> currentBindings = abstractContext.getBindings();
+            return currentBindings.size();
+        } else {
+            NamingEnumeration namingEnumeration = context.list("");
+            int size = 0;
+            while (namingEnumeration.hasMore()) size++;
+            return size;
+        }
+    }
+
+    /**
+     * Unbinds any value bound to the specified name within the specified context.  If the specified context is an
+     * AbstractContext and is a nested context, this method will call the direct removeBinding method, otherwise it
+     * will call public unbind.
+     *
+     * @param context the context to remove the binding from
+     * @param name the binding name
+     * @param removeNotEmptyContext ??? TODO figure this out
+     * @throws NamingException if a problem occurs while unbinding
+     */
+    private void unbind(Context context, String name, boolean removeNotEmptyContext) throws NamingException {
+        if (context == this || (context instanceof AbstractContext && isNestedSubcontext(context))) {
+            AbstractContext abstractContext = (AbstractContext) context;
+            abstractContext.removeBinding(name, removeNotEmptyContext);
+        } else {
+            context.unbind(name);
+        }
+    }
+
+    //
+    // Environment
+    //
+
+    /**
+     * Always returns a new (empty) Hashtable.
+     * @return a new (empty) Hashtable
+     */
+    public Hashtable getEnvironment() {
+        return new Hashtable();
+    }
+
+    public Object addToEnvironment(String propName, Object propVal) throws NamingException {
+        if (propName == null) throw new NullPointerException("propName is null");
+        if (propVal == null) throw new NullPointerException("propVal is null");
+
+        Map env = getEnvironment();
+        return env.put(propName, propVal);
+    }
+
+    public Object removeFromEnvironment(String propName) throws NamingException {
+        if (propName == null) throw new NullPointerException("propName is null");
+
+        Map env = getEnvironment();
+        return env.remove(propName);
+    }
+
+    //
+    // Name handling
+    //
+
+    /**
+     * Gets the name of this context withing the global namespace.  This method may return null
+     * if the location of the node in the global namespace is not known
+     * @return the name of this context within the global namespace or null if unknown.
+     */
+    public String getNameInNamespace() {
+        return nameInNamespace;
+    }
+
+    /**
+     * Gets the name of this context withing the global namespace.  This method may return null
+     * if the location of the node in the global namespace is not known
+     * @return the name of this context within the global namespace or null if unknown.
+     */
+    protected Name getParsedNameInNamespace() {
+        return parsedNameInNamespace;
+    }
+
+    /**
+     * Gets the name of a path withing the global namespace context.
+     * @param path path to extend
+     * @return full path in namespace
+     */
+    protected String getNameInNamespace(String path) {
+        String nameInNamespace = getNameInNamespace();
+        if (nameInNamespace == null || nameInNamespace.length() == 0) {
+            return path;
+        } else {
+            return nameInNamespace + "/" + path;
+        }
+    }
+
+    /**
+     * Gets the name of a path withing the global namespace context.
+     * @param path path to extend
+     * @return full path in namespace
+     * @throws javax.naming.NamingException on error
+     */
+    protected Name getNameInNamespace(Name path) throws NamingException {
+        Name nameInNamespace = getParsedNameInNamespace();
+        if (nameInNamespace == null || nameInNamespace.size() == 0) {
+            return path;
+        } else {
+            return composeName(nameInNamespace, path);
+        }
+    }
+
+    /**
+     * A parser that can turn Strings into javax.naming.Name objects.
+     * @return ContextUtil.NAME_PARSER
+     */
+    protected NameParser getNameParser() {
+        return ContextUtil.NAME_PARSER;
+    }
+
+    public NameParser getNameParser(Name name) {
+        return getNameParser();
+    }
+
+    public NameParser getNameParser(String name) {
+        return getNameParser();
+    }
+
+    public Name composeName(Name name, Name prefix) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+        if (prefix == null) throw new NullPointerException("prefix is null");
+
+        Name result = (Name) prefix.clone();
+        result.addAll(name);
+        return result;
+    }
+
+    public String composeName(String name, String prefix) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+        if (prefix == null) throw new NullPointerException("prefix is null");
+
+        CompositeName result = new CompositeName(prefix);
+        result.addAll(new CompositeName(name));
+        return result.toString();
+    }
+
+    //
+    // Lookup
+    //
+
+    public Object lookup(String name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+
+        Object value = lookup(name, null);
+
+        // if we got a link back we need to resolve it
+        if (value instanceof LinkRef) {
+            LinkRef linkRef = (LinkRef) value;
+            value = lookup(linkRef.getLinkName());
+        }
+
+        return value;
+    }
+
+    public Object lookup(Name name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+
+        Object value = lookup(null, name);
+
+
+        // if we got a link back we need to resolve it
+        if (value instanceof LinkRef) {
+            LinkRef linkRef = (LinkRef) value;
+            value = lookup(linkRef.getLinkName());
+        }
+
+        return value;
+    }
+
+    public Object lookupLink(String name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+        return lookup(name, null);
+    }
+
+    public Object lookupLink(Name name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+        return lookup(null, name);
+    }
+
+    //
+    // Bind, rebind, rename and unbind
+    //
+
+    public void bind(String name, Object obj) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.length() == 0) {
+            throw new NameAlreadyBoundException("Cannot bind to an empty name (this context)");
+        }
+        bind(new CompositeName(name), obj);
+    }
+
+    public void bind(Name name, Object obj) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.isEmpty()) {
+            throw new NameAlreadyBoundException("Cannot bind to an empty name (this context)");
+        }
+        addDeepBinding(name, obj, false, false);
+    }
+
+    public void rebind(String name, Object obj) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        rebind(new CompositeName(name), obj);
+    }
+
+    public void rebind(Name name, Object obj) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.isEmpty()) {
+            throw new NameAlreadyBoundException("Cannot rebind an empty name (this context)");
+        }
+        addDeepBinding(name, obj, true, false);
+    }
+
+    public void rename(String oldName, String newName) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (oldName == null) throw new NullPointerException("oldName is null");
+        if (newName == null) throw new NullPointerException("newName is null");
+        rename(new CompositeName(oldName), new CompositeName(newName));
+    }
+
+    public void rename(Name oldName, Name newName) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (oldName == null || newName == null) {
+            throw new NullPointerException("name is null");
+        } else if (oldName.isEmpty() || newName.isEmpty()) {
+            throw new NameAlreadyBoundException("Name cannot be empty");
+        }
+        this.bind(newName, this.lookup(oldName));
+        this.unbind(oldName);
+    }
+
+    public void unbind(String name) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        unbind(new CompositeName(name));
+    }
+
+    public void unbind(Name name) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.isEmpty()) {
+            throw new InvalidNameException("Cannot unbind empty name");
+        }
+        removeDeepBinding(name, false);
+    }
+
+    //
+    // List
+    //
+
+    protected NamingEnumeration<NameClassPair> list() throws NamingException {
+        Map<String, Object> bindings = getBindings();
+        return new ContextUtil.ListEnumeration(bindings);
+    }
+
+    protected NamingEnumeration<Binding> listBindings() throws NamingException {
+        Map<String, Object> bindings = getBindings();
+        return new ContextUtil.ListBindingEnumeration(bindings, this);
+    }
+
+    public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+
+        // if the name is empty, list the current context
+        if (name.length() == 0) {
+            return list();
+        }
+
+        // lookup the target context
+        Object target;
+        try {
+            target = lookup(name);
+        } catch (NamingException e) {
+            throw new NotContextException(name);
+        }
+
+        if (target == this) {
+            return list();
+        } else if (target instanceof Context) {
+            return ((Context) target).list("");
+        } else {
+            throw new NotContextException("The name " + name + " cannot be listed");
+        }
+    }
+
+    public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+
+        // if the name is empty, list the current context
+        if (name.isEmpty()) {
+            return list();
+        }
+
+        // lookup the target context
+        Object target;
+        try {
+            target = lookup(name);
+        } catch (NamingException e) {
+            throw new NotContextException(name.toString());
+        }
+
+        if (target == this) {
+            return list();
+        } else if (target instanceof Context) {
+            return ((Context) target).list("");
+        } else {
+            throw new NotContextException("The name " + name + " cannot be listed");
+        }
+    }
+
+    public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+
+        // if the name is empty, list the current context
+        if (name.length() == 0) {
+            return listBindings();
+        }
+
+        // lookup the target context
+        Object target;
+        try {
+            target = lookup(name);
+        } catch (NamingException e) {
+            throw new NotContextException(name);
+        }
+
+        if (target == this) {
+            return listBindings();
+        } else if (target instanceof Context) {
+            return ((Context) target).listBindings("");
+        } else {
+            throw new NotContextException("The name " + name + " cannot be listed");
+        }
+    }
+
+    public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
+        if (name == null) throw new NullPointerException("name is null");
+
+        // if the name is empty, list the current context
+        if (name.isEmpty()) {
+            return listBindings();
+        }
+
+        // lookup the target context
+        Object target;
+        try {
+            target = lookup(name);
+        } catch (NamingException e) {
+            throw new NotContextException(name.toString());
+        }
+
+        if (target == this) {
+            return listBindings();
+        } else if (target instanceof Context) {
+            return ((Context) target).listBindings("");
+        } else {
+            throw new NotContextException("The name " + name + " cannot be listed");
+        }
+    }
+
+    //
+    // Subcontexts
+    //
+
+    public Context createSubcontext(String name) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        return createSubcontext(new CompositeName(name));
+    }
+
+    public Context createSubcontext(Name name) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.isEmpty()) {
+            throw new NameAlreadyBoundException("Cannot create a subcontext if the name is empty");
+        }
+        Context abstractContext = createNestedSubcontext(name.toString(), Collections.EMPTY_MAP);
+        addDeepBinding(name, abstractContext, false, false);
+        return abstractContext;
+    }
+
+    public void destroySubcontext(String name) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        destroySubcontext(new CompositeName(name));
+    }
+
+    public void destroySubcontext(Name name) throws NamingException {
+        if (!modifiable) throw new OperationNotSupportedException("Context is read only");
+        if (name == null) throw new NullPointerException("name is null");
+        if (name.isEmpty()) {
+            throw new InvalidNameException("Cannot destroy subcontext with empty name");
+        }
+        unbind(name);
+    }
+}

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/AbstractFederatedContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextAccess.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextAccessControlList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextFederation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextFlyweight.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/ContextUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/ImmutableContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/NestedContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/VirtualSubcontext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/context/WritableContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/global/GlobalContextManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/java/javaURLContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/reference/CachingReference.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/main/java/org/apache/xbean/naming/reference/SimpleReference.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/test/java/org/apache/xbean/naming/context/AbstractContextTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/test/java/org/apache/xbean/naming/context/ContextAccessControlListTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/test/java/org/apache/xbean/naming/context/FederationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/test/java/org/apache/xbean/naming/context/ImmutableContextTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/test/java/org/apache/xbean/naming/context/UnmodifiableContextTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/test/java/org/apache/xbean/naming/context/WritableContextTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-naming/src/test/java/org/apache/xbean/naming/global/GlobalContextManagerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/AbstractCollectionConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/AbstractConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/AbstractMapConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ArrayConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ArrayListEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/BigDecimalEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/BigIntegerEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/BooleanEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ByteEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/CharacterEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ClassEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/CollectionUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/CommonsLoggingConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/Converter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/DateEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/DoubleEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/EnumConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/FileEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/FloatEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/GenericCollectionConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/GenericMapConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/HashMapEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/HashtableEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/IdentityHashMapEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/Inet4AddressEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/Inet6AddressEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/InetAddressEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/IntegerEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/JndiConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/LinkedHashMapEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/LinkedHashSetEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/LinkedListEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ListEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/Log4jConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/LoggerConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/LongEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/MapEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ObjectNameEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/PatternConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/PropertiesEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/PropertyEditorException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/PropertyEditors.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ReferenceIdentityMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/SetEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/ShortEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/SortedMapEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/SortedSetEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/StringEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/TreeMapEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/TreeSetEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/URIEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/URLEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/VectorEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/propertyeditor/WeakHashMapEditor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AllPropertiesRecipe.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AsmParameterNameLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/CircularDependencyException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/CollectionRecipe.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ConstructionException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/DefaultExecutionContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/DefaultRepository.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExecutionContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/MapRecipe.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/MissingAccessorException.java
------------------------------------------------------------------------------
    svn:eol-style = native