[CVS spice] increase coverage to 80%

tanderson-yCVjj/[email protected] 30 Jun 2005 04:22:16 -0000
Newsgroups gmane.comp.java.spice.cvs
Message-ID <[email protected]>
<html>
<head>
<style><!--
  body {background-color:#ffffff;}
  .file {border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;}
  .pathname {font-family:monospace; float:right;}
  .fileheader {margin-bottom:.5em;}
  .diff {margin:0;}
  .tasklist {padding:4px;border:1px dashed #000000;margin-top:1em;}
  .tasklist ul {margin-top:0;margin-bottom:0;}
  tr.alt {background-color:#eeeeee}
  #added {background-color:#ddffdd;}
  #addedchars {background-color:#99ff99;font-weight:bolder;}
  tr.alt #added {background-color:#ccf7cc;}
  #removed {background-color:#ffdddd;}
  #removedchars {background-color:#ff9999;font-weight:bolder;}
  tr.alt #removed {background-color:#f7cccc;}
  #info {color:#888888;}
  #context {background-color:#eeeeee;}
  td {padding-left:.3em;padding-right:.3em;}
  tr.head {border-bottom-width:1px;border-bottom-style:solid;}
  tr.head td {padding:0;padding-top:.2em;}
  .task {background-color:#ffff00;}
  .comment {padding:4px;border:1px dashed #000000;background-color:#ffffdd}
  .error {color:red;}
  hr {border-width:0px;height:2px;background:black;}
--></style>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head"><td colspan="4">Commit in <b><tt>spice/components/jndikit/src/test/org/codehaus/spice/jndikit</tt></b><span id="info"> on MAIN</span></td></tr>
<tr><td><tt>memory/test/<a href="#file1"><span id="added">AbstractMemoryContextTestCase.java</span></a></tt></td><td align="right" id="added">+43</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file2"><span id="added">MemoryContextDefaultNamespaceTestCase.java</span></a></tt></td><td align="right" id="added">+36</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file3">MemoryContextTestCase.java</a></tt></td><td align="right" id="added">+20</td><td align="right" id="removed">-15</td><td nowrap="nowrap" align="center">1.1 -&gt; 1.2</td></tr>
<tr class="alt"><td><tt>rmi/test/<a href="#file4"><span id="added">AbstractRMIContextTestCase.java</span></a></tt></td><td align="right" id="added">+83</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file5"><span id="added">RMIContextDefaultNamespaceTestCase.java</span></a></tt></td><td align="right" id="added">+48</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file6"><span id="added">RMITestSetup.java</span></a></tt></td><td align="right" id="added">+96</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file7">RMIContextTestCase.java</a></tt></td><td align="right" id="added">+45</td><td align="right" id="removed">-53</td><td nowrap="nowrap" align="center">1.1 -&gt; 1.2</td></tr>
<tr class="alt"><td><tt>test/<a href="#file8"><span id="added">ExceptionReferenceable.java</span></a></tt></td><td align="right" id="added">+37</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file9"><span id="added">TestData.java</span></a></tt></td><td align="right" id="added">+65</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file10"><span id="added">TestDataReferenceable.java</span></a></tt></td><td align="right" id="added">+69</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file11"><span id="added">TestObjectFactory.java</span></a></tt></td><td align="right" id="added">+72</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file12"><span id="added">TestStateFactory.java</span></a></tt></td><td align="right" id="added">+61</td><td></td><td nowrap="nowrap" align="right">added 1.1</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file13">AbstractContextTestCase.java</a></tt></td><td align="right" id="added">+597</td><td align="right" id="removed">-154</td><td nowrap="nowrap" align="center">1.2 -&gt; 1.3</td></tr>
<tr><td></td><td align="right" id="added">+1272</td><td align="right" id="removed">-222</td><td></td></tr>
</table>
<small id="info">10 added + 3 modified, total 13 files</small><br />
<pre class="comment">
increase coverage to 80%
</pre>
<hr /><a name="file1" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/memory/test<br /></span>
<div class="fileheader" id="added"><big><b>AbstractMemoryContextTestCase.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N AbstractMemoryContextTestCase.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ AbstractMemoryContextTestCase.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,43 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.memory.test;
+
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+
+import junit.framework.AssertionFailedError;
+import org.codehaus.spice.jndikit.StandardNamespace;
+import org.codehaus.spice.jndikit.test.AbstractContextTestCase;
+
+/**
+ * Unit test for Memory context, using the {@link StandardNamespace}. ,
+ *
+ * @author Tim Anderson
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractMemoryContextTestCase
+    extends AbstractContextTestCase
+{
+
+    public void testGetNameInNamespace() throws AssertionFailedError
+    {
+        try
+        {
+            String name = m_context.getNameInNamespace();
+            fail( "Expected getNameInNamespace to throw OperationNotSupportedException but returned "
+                  + name );
+        }
+        catch( final OperationNotSupportedException expected )
+        {
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.getMessage() );
+        }
+    }
+}
</pre></div>
<hr /><a name="file2" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/memory/test<br /></span>
<div class="fileheader" id="added"><big><b>MemoryContextDefaultNamespaceTestCase.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N MemoryContextDefaultNamespaceTestCase.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ MemoryContextDefaultNamespaceTestCase.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,36 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.memory.test;
+
+import javax.naming.Context;
+
+import org.codehaus.spice.jndikit.DefaultNameParser;
+import org.codehaus.spice.jndikit.DefaultNamespace;
+import org.codehaus.spice.jndikit.memory.MemoryContext;
+import org.codehaus.spice.jndikit.test.TestObjectFactory;
+import org.codehaus.spice.jndikit.test.TestStateFactory;
+
+/**
+ * Unit test for Memory context, using the {@link DefaultNamespace}.
+ *
+ * @author Tim Anderson
+ * @version $Revision: 1.1 $
+ */
+public class MemoryContextDefaultNamespaceTestCase
+    extends AbstractMemoryContextTestCase
+{
+
+    protected Context getRoot() throws Exception
+    {
+        final DefaultNameParser parser = new DefaultNameParser();
+        final DefaultNamespace namespace = new DefaultNamespace( parser );
+        namespace.addObjectFactory( new TestObjectFactory() );
+        namespace.addStateFactory( new TestStateFactory() );
+        return new MemoryContext( namespace, null, null );
+    }
+}
</pre></div>
<hr /><a name="file3" /><div class="file">
<span class="pathname">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/memory/test<br /></span>
<div class="fileheader"><big><b>MemoryContextTestCase.java</b></big> <small id="info">1.1 -&gt; 1.2</small></div>
<pre class="diff"><small id="info">diff -u -r1.1 -r1.2
--- MemoryContextTestCase.java	27 Nov 2003 00:50:48 -0000	1.1
+++ MemoryContextTestCase.java	30 Jun 2005 04:22:16 -0000	1.2
@@ -9,28 +9,33 @@
</small></pre><pre class="diff" id="context"> 
 import java.util.Hashtable;
 import javax.naming.Context;
</pre><pre class="diff" id="removed">-import org.codehaus.spice.jndikit.memory.MemoryInitialContextFactory;
-import org.codehaus.spice.jndikit.test.AbstractContextTestCase;
</pre><pre class="diff" id="added">+
+import org.codehaus.spice.jndikit.DefaultNameParser;
+import org.codehaus.spice.jndikit.Namespace;
+import org.codehaus.spice.jndikit.StandardNamespace;
+import org.codehaus.spice.jndikit.memory.MemoryContext;
+import org.codehaus.spice.jndikit.test.TestStateFactory;
</pre><pre class="diff" id="context"> 
 /**
</pre><pre class="diff" id="removed">- * Unit test for Memory context
</pre><pre class="diff" id="added">+ * Unit test for Memory context, using the {@link StandardNamespace}. ,
</pre><pre class="diff" id="context">  *
  * @author Peter Donald
</pre><pre class="diff" id="removed">- * @version $Revision: 1.1 $
</pre><pre class="diff" id="added">+ * @author Tim Anderson
+ * @version $Revision: 1.2 $
</pre><pre class="diff" id="context">  */
</pre><pre class="diff" id="removed">- public class MemoryContextTestCase
-    extends AbstractContextTestCase
</pre><pre class="diff" id="added">+public class MemoryContextTestCase
+    extends AbstractMemoryContextTestCase
</pre><pre class="diff" id="context"> {
</pre><pre class="diff" id="removed">-    /**
-     * Contter used to create contexts for tests.
-     */
-    private static int c_id = 0;
</pre><pre class="diff" id="context"> 
</pre><pre class="diff" id="removed">-    protected <span id="removedchars">void&nbsp;setUp</span>() throws Exception
</pre><pre class="diff" id="added">+    protected <span id="addedchars">Context&nbsp;getRoot</span>() throws Exception
</pre><pre class="diff" id="context">     {
</pre><pre class="diff" id="removed">-        final MemoryInitialContextFactory factory = new MemoryInitialContextFactory();
-        final Context root = factory.getInitialContext( new Hashtable() );
-        setRoot( root );
-        setContext( root.createSubcontext( "test" + c_id++ ) );
</pre><pre class="diff" id="added">+        final DefaultNameParser parser = new DefaultNameParser();
+        final Namespace namespace = new StandardNamespace( parser );
+
+        Hashtable environment = new Hashtable();
+        environment.put( Context.STATE_FACTORIES,
+                         TestStateFactory.class.getName() );
+
+        return new MemoryContext( namespace, environment, null );
</pre><pre class="diff" id="context">     }
 }
</pre></div>
<hr /><a name="file4" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/rmi/test<br /></span>
<div class="fileheader" id="added"><big><b>AbstractRMIContextTestCase.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N AbstractRMIContextTestCase.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ AbstractRMIContextTestCase.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,83 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.rmi.test;
+
+import javax.naming.Context;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.NamingException;
+
+import org.codehaus.spice.jndikit.rmi.RMIInitialContextFactory;
+import org.codehaus.spice.jndikit.test.AbstractContextTestCase;
+import junit.framework.AssertionFailedError;
+
+/**
+ * Unit test for RMI context.
+ *
+ * @author Tim Anderson
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractRMIContextTestCase
+    extends AbstractContextTestCase
+{
+
+    private final RMITestSetup _helper;
+
+    public AbstractRMIContextTestCase( RMIInitialContextFactory factory )
+    {
+        _helper = new RMITestSetup( factory );
+    }
+
+    public void testGetNameInNamespace() throws AssertionFailedError
+    {
+        try
+        {
+            Context sub1 = m_root.createSubcontext( "sub1");
+            Context sub2 = sub1.createSubcontext( "sub2");
+            Context sub3 = sub2.createSubcontext( "sub3");
+            Context sub4 = sub3.createSubcontext( "sub4");
+            assertEquals("sub1/sub2/sub3/sub4", sub4.getNameInNamespace());
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.getMessage() );
+        }
+    }
+
+    /**
+     * Verifies that non-Serializable and non-Referenceable objects cannot be
+     * bound.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testInvalidBind() throws AssertionFailedError {
+        try
+        {
+            m_context.bind("invalid", new Object());
+            fail("Expected bind of non-Serializable, non-Referenceable object to throw NamingException");
+        } catch (final NamingException expected) {
+        }
+    }
+
+    protected void setUp() throws Exception
+    {
+        _helper.setUp();
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception
+    {
+        _helper.tearDown();
+        super.tearDown();
+    }
+
+    protected Context getRoot() throws Exception
+    {
+        return _helper.getRoot();
+    }
+
+}
</pre></div>
<hr /><a name="file5" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/rmi/test<br /></span>
<div class="fileheader" id="added"><big><b>RMIContextDefaultNamespaceTestCase.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N RMIContextDefaultNamespaceTestCase.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ RMIContextDefaultNamespaceTestCase.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,48 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.rmi.test;
+
+import java.util.Hashtable;
+import javax.naming.NamingException;
+
+import org.codehaus.spice.jndikit.DefaultNamespace;
+import org.codehaus.spice.jndikit.Namespace;
+import org.codehaus.spice.jndikit.rmi.RMIInitialContextFactory;
+import org.codehaus.spice.jndikit.test.TestObjectFactory;
+import org.codehaus.spice.jndikit.test.TestStateFactory;
+
+/**
+ * Unit test for RMI context, using the {@link DefaultNamespace}.
+ *
+ * @author Tim Anderson
+ * @version $Revision: 1.1 $
+ */
+public class RMIContextDefaultNamespaceTestCase
+    extends AbstractRMIContextTestCase
+{
+
+    public RMIContextDefaultNamespaceTestCase()
+    {
+        super( new DefaultNamespaceICF() );
+    }
+
+    static class DefaultNamespaceICF
+        extends RMIInitialContextFactory
+    {
+
+        protected Namespace newNamespace( final Hashtable environment )
+            throws NamingException
+        {
+            final DefaultNamespace namespace = ( DefaultNamespace ) super.newNamespace(
+                environment );
+            namespace.addObjectFactory( new TestObjectFactory() );
+            namespace.addStateFactory( new TestStateFactory() );
+            return namespace;
+        }
+    }
+}
</pre></div>
<hr /><a name="file6" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/rmi/test<br /></span>
<div class="fileheader" id="added"><big><b>RMITestSetup.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N RMITestSetup.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ RMITestSetup.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,96 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.rmi.test;
+
+import java.util.Hashtable;
+import java.util.Random;
+import javax.naming.Context;
+import javax.naming.spi.InitialContextFactory;
+
+import org.codehaus.spice.jndikit.rmi.RMIInitialContextFactory;
+import org.codehaus.spice.jndikit.rmi.server.Main;
+
+/**
+ * Helper for setting up and tearing down the RMI naming provider.
+ *
+ * @author Peter Donald
+ * @author Tim Anderson
+ * @version $Revision: 1.1 $ $Date: 2005/06/30 04:22:16 $
+ */
+public class RMITestSetup
+{
+
+    private Main m_server;
+    private Thread m_serverThread;
+    private static final Random RANDOM = new Random();
+    private int m_port;
+    private final InitialContextFactory m_factory;
+
+    public RMITestSetup()
+    {
+        this( new RMIInitialContextFactory() );
+    }
+
+    public RMITestSetup( RMIInitialContextFactory factory )
+    {
+        m_factory = factory;
+
+    }
+
+    public void setUp() throws Exception
+    {
+        m_port = 1500 + Math.abs( RANDOM.nextInt() % 1000 );
+
+        startServer();
+    }
+
+    public Context getRoot() throws Exception
+    {
+        final Hashtable environment = new Hashtable();
+        environment.put( Context.PROVIDER_URL, "rmi://localhost:" + m_port );
+        final Context root = m_factory.getInitialContext( environment );
+        return root;
+    }
+
+    public void tearDown()
+        throws Exception
+    {
+        try
+        {
+            stopServer();
+        }
+        catch( Exception e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+    private void startServer()
+        throws Exception
+    {
+        m_server = new Main( true, m_port );
+        m_server.start();
+
+        m_serverThread = new Thread( m_server );
+        m_serverThread.start();
+        while( !m_server.isRunning() )
+        {
+            Thread.yield();
+        }
+    }
+
+    private void stopServer()
+        throws Exception
+    {
+        m_server.stop();
+        m_server.dispose();
+        m_serverThread.interrupt();
+    }
+
+
+}
</pre></div>
<hr /><a name="file7" /><div class="file">
<span class="pathname">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/rmi/test<br /></span>
<div class="fileheader"><big><b>RMIContextTestCase.java</b></big> <small id="info">1.1 -&gt; 1.2</small></div>
<pre class="diff"><small id="info">diff -u -r1.1 -r1.2
--- RMIContextTestCase.java	27 Nov 2003 00:50:48 -0000	1.1
+++ RMIContextTestCase.java	30 Jun 2005 04:22:16 -0000	1.2
@@ -8,75 +8,67 @@
</small></pre><pre class="diff" id="context"> package org.codehaus.spice.jndikit.rmi.test;
 
 import java.util.Hashtable;
</pre><pre class="diff" id="removed">-import java.util.Random;
</pre><pre class="diff" id="context"> import javax.naming.Context;
</pre><pre class="diff" id="added">+import javax.naming.NamingException;
+import javax.naming.ServiceUnavailableException;
+
+import org.codehaus.spice.jndikit.Namespace;
+import org.codehaus.spice.jndikit.NamingProvider;
+import org.codehaus.spice.jndikit.RemoteContext;
+import org.codehaus.spice.jndikit.StandardNamespace;
</pre><pre class="diff" id="context"> import org.codehaus.spice.jndikit.rmi.RMIInitialContextFactory;
</pre><pre class="diff" id="removed">-import org.codehaus.spice.jndikit.rmi.server.Main;
-import org.codehaus.spice.jndikit.test.AbstractContextTestCase;
</pre><pre class="diff" id="added">+import org.codehaus.spice.jndikit.test.TestStateFactory;
</pre><pre class="diff" id="context"> 
 /**
</pre><pre class="diff" id="removed">- * Unit test for RMI context
</pre><pre class="diff" id="added">+ * Unit test for RMI context<span id="addedchars">.</span>
</pre><pre class="diff" id="context">  *
</pre><pre class="diff" id="removed">- * @author Peter Donald
- * @version $Revision: 1.1 $
</pre><pre class="diff" id="added">+ * @author Tim Anderson
+ * @version $Revision: 1.2 $
</pre><pre class="diff" id="context">  */
 public class RMIContextTestCase
</pre><pre class="diff" id="removed">-    extends AbstractContextTestCase
</pre><pre class="diff" id="added">+    extends Abstract<span id="addedchars">RMI</span>ContextTestCase
</pre><pre class="diff" id="context"> {
</pre><pre class="diff" id="removed">-    private static int c_id = 0;
-    private Main m_server;
-    private Thread m_serverThread;
-    private static final Random RANDOM = new Random();
-    private int m_port;
-
-    public void setUp()
-        throws Exception
</pre><pre class="diff" id="added">+    public RMIContextTestCase()
</pre><pre class="diff" id="context">     {
</pre><pre class="diff" id="removed">-        m_port = 1500 + Math.abs( RANDOM.nextInt() % 1000 );
-
-        startServer();
-
-        final RMIInitialContextFactory factory = new RMIInitialContextFactory();
-        final Hashtable environment = new Hashtable();
-        environment.put( Context.PROVIDER_URL, "rmi://localhost:" + m_port );
-        final Context root = factory.getInitialContext( environment );
-        setRoot( root );
-
-        setContext( root.createSubcontext( "test" + c_id++ ) );
</pre><pre class="diff" id="added">+        super( new StandardNamespaceICF() );
</pre><pre class="diff" id="context">     }
 
</pre><pre class="diff" id="removed">-    public void tearDown()
-        throws Exception
</pre><pre class="diff" id="added">+    static class StandardNamespaceICF extends RMIInitialContextFactory
</pre><pre class="diff" id="context">     {
</pre><pre class="diff" id="removed">-        try
-        {
-            stopServer();
-        }
-        catch( Exception e )
</pre><pre class="diff" id="added">+
+        public Context getInitialContext( Hashtable environment )
+            throws NamingException
</pre><pre class="diff" id="context">         {
</pre><pre class="diff" id="removed">-            e.printStackTrace();
</pre><pre class="diff" id="added">+            environment.put( Context.STATE_FACTORIES,
+                             TestStateFactory.class.getName() );
+            return super.getInitialContext( environment );
</pre><pre class="diff" id="context">         }
</pre><pre class="diff" id="removed">-    }
-
-    private void startServer()
-        throws Exception
-    {
-        m_server = new Main( true, m_port );
-        m_server.start();
</pre><pre class="diff" id="context"> 
</pre><pre class="diff" id="removed">-        m_serverThread = new Thread( m_server );
-        m_serverThread.start();
-        while( !m_server.isRunning() )
</pre><pre class="diff" id="added">+        protected Namespace newNamespace( final Hashtable environment )
+            throws NamingException
</pre><pre class="diff" id="context">         {
</pre><pre class="diff" id="removed">-            Thread.yield();
</pre><pre class="diff" id="added">+            try
+            {
+                final NamingProvider provider =
+                    ( NamingProvider ) environment.get(
+                        RemoteContext.NAMING_PROVIDER );
+
+                return new StandardNamespace( provider.getNameParser() );
+            }
+            catch( final Exception e )
+            {
+                if( e instanceof NamingException )
+                {
+                    throw ( NamingException ) e;
+                }
+                else
+                {
+                    final ServiceUnavailableException sue =
+                        new ServiceUnavailableException( e.getMessage() );
+                    sue.setRootCause( e );
+                    throw sue;
+                }
+            }
</pre><pre class="diff" id="context">         }
</pre><pre class="diff" id="removed">-    }
-
-    private void stopServer()
-        throws Exception
-    {
-        m_server.stop();
-        m_server.dispose();
-        m_serverThread.interrupt();
</pre><pre class="diff" id="context">     }
 }
</pre></div>
<hr /><a name="file8" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/test<br /></span>
<div class="fileheader" id="added"><big><b>ExceptionReferenceable.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N ExceptionReferenceable.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ExceptionReferenceable.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,37 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.test;
+
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+
+/**
+ * Implementation of {@link Referenceable}, for testing purposes. When {@link
+ * TestObjectFactory} encounters a {@link Reference} to this, it throws an
+ * exception.
+ *
+ * @author &lt;a href="mailto:[email protected]"&gt;Tim Anderson&lt;/a&gt;
+ * @version $Revision: 1.1 $ $Date: 2005/06/30 04:22:16 $
+ * @see TestObjectFactory
+ */
+public class ExceptionReferenceable implements Referenceable
+{
+
+    /**
+     * Retrieves the Reference of this object.
+     *
+     * @return the non-null Reference of this object.
+     */
+    public Reference getReference()
+    {
+        return new Reference( getClass().getName(),
+                              TestObjectFactory.class.getName(),
+                              null );
+    }
+
+}
</pre></div>
<hr /><a name="file9" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/test<br /></span>
<div class="fileheader" id="added"><big><b>TestData.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N TestData.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ TestData.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,65 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.test;
+
+import java.io.Serializable;
+import javax.naming.Context;
+
+/**
+ * Helper class for testing behaviour of {@link Context#bind} operations.
+ *
+ * @author &lt;a href="mailto:[email protected]"&gt;Tim Anderson&lt;/a&gt;
+ * @version $Revision: 1.1 $ $Date: 2005/06/30 04:22:16 $
+ */
+public class TestData implements Serializable
+{
+
+    /**
+     * Arbitrary test value.
+     */
+    private String _value;
+
+
+    /**
+     * Default ctor for serialization.
+     */
+    public TestData()
+    {
+    }
+
+    /**
+     * Construct a new &lt;code&gt;TestData&lt;/code&gt;.
+     *
+     * @param value test data
+     */
+    public TestData( String value )
+    {
+        _value = value;
+    }
+
+    /**
+     * Sets the value of this.
+     *
+     * @param value the value
+     */
+    public void setValue( String value )
+    {
+        _value = value;
+    }
+
+    /**
+     * Returns the value of this.
+     *
+     * @return the value of this, assigned during construction
+     */
+    public String getValue()
+    {
+        return _value;
+    }
+
+}
</pre></div>
<hr /><a name="file10" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/test<br /></span>
<div class="fileheader" id="added"><big><b>TestDataReferenceable.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N TestDataReferenceable.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ TestDataReferenceable.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,69 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.test;
+
+import java.io.IOException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+import javax.naming.StringRefAddr;
+
+
+/**
+ * Implementation of {@link Referenceable}, for testing purposes.
+ *
+ * @author &lt;a href="mailto:[email protected]"&gt;Tim Anderson&lt;/a&gt;
+ * @version $Revision: 1.1 $ $Date: 2005/06/30 04:22:16 $
+ * @see TestObjectFactory
+ */
+public class TestDataReferenceable extends TestData implements Referenceable
+{
+
+
+    /**
+     * Default ctor for serialization.
+     */
+    public TestDataReferenceable()
+    {
+    }
+
+    /**
+     * Construct a new &lt;code&gt;TestDataReferenceable&lt;/code&gt;.
+     *
+     * @param value test data
+     */
+    public TestDataReferenceable( String value )
+    {
+        super( value );
+    }
+
+    /**
+     * Retrieves the Reference of this object.
+     *
+     * @return the non-null Reference of this object.
+     */
+    public Reference getReference()
+    {
+        return new Reference( getClass().getName(),
+                              new StringRefAddr( "value", getValue() ),
+                              TestObjectFactory.class.getName(),
+                              null );
+    }
+
+    private void writeObject( java.io.ObjectOutputStream out )
+        throws IOException
+    {
+        throw new IOException( "Cannot serialize. Use getReference() instead" );
+    }
+
+    private void readObject( java.io.ObjectInputStream in )
+        throws IOException
+    {
+        throw new IOException( "Cannot serialize. Use getReference() instead" );
+    }
+
+}
</pre></div>
<hr /><a name="file11" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/test<br /></span>
<div class="fileheader" id="added"><big><b>TestObjectFactory.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N TestObjectFactory.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ TestObjectFactory.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,72 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.test;
+
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import javax.naming.spi.ObjectFactory;
+
+
+/**
+ * Implementation of {@link ObjectFactory}, for testing purposes.
+ *
+ * @author &lt;a href="mailto:[email protected]"&gt;Tim Anderson&lt;/a&gt;
+ * @version $Revision: 1.1 $ $Date: 2005/06/30 04:22:16 $
+ * @see TestDataReferenceable
+ */
+public class TestObjectFactory implements ObjectFactory
+{
+
+    /**
+     * Creates an object using the location or reference information specified.
+     *
+     * @param obj         The possibly null object containing location or
+     *                    reference information that can be used in creating an
+     *                    object.
+     * @param name        The name of this object relative to &lt;code&gt;nameCtx&lt;/code&gt;,
+     *                    or null if no name is specified.
+     * @param nameCtx     The context relative to which the &lt;code&gt;name&lt;/code&gt;
+     *                    parameter is specified, or null if &lt;code&gt;name&lt;/code&gt;
+     *                    is relative to the default initial context.
+     * @param environment The possibly null environment that is used in creating
+     *                    the object.
+     * @return The object created; null if an object cannot be created.
+     * @throws Exception if this object factory encountered an exception while
+     *                   attempting to create an object, and no other object
+     *                   factories are to be tried.
+     */
+    public Object getObjectInstance( Object obj, Name name, Context nameCtx,
+                                     Hashtable environment ) throws Exception
+    {
+        Object result = null;
+        if( obj instanceof Reference )
+        {
+            Reference ref = ( Reference ) obj;
+            String clazz = ref.getClassName();
+            if( clazz.equals( TestDataReferenceable.class.getName() ) )
+            {
+                String value = null;
+                StringRefAddr str = ( StringRefAddr ) ref.get( "value" );
+                if( str != null )
+                {
+                    value = ( String ) str.getContent();
+                }
+                result = new TestDataReferenceable( value );
+            }
+            else if( clazz.equals( ExceptionReferenceable.class.getName() ) )
+            {
+                throw new Exception( "Encountered " + clazz );
+            }
+        }
+        return result;
+    }
+
+}
</pre></div>
<hr /><a name="file12" /><div class="file">
<span class="pathname" id="added">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/test<br /></span>
<div class="fileheader" id="added"><big><b>TestStateFactory.java</b></big> <small id="info">added at 1.1</small></div>
<pre class="diff"><small id="info">diff -N TestStateFactory.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ TestStateFactory.java	30 Jun 2005 04:22:16 -0000	1.1
@@ -0,0 +1,61 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (C) The Spice Group. All rights reserved.
+ *
+ * This software is published under the terms of the Spice
+ * Software License version 1.1, a copy of which has been included
+ * with this distribution in the LICENSE.txt file.
+ */
+package org.codehaus.spice.jndikit.test;
+
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.spi.DirectoryManager;
+import javax.naming.spi.NamingManager;
+import javax.naming.spi.StateFactory;
+
+
+/**
+ * Implementation of  {@link StateFactory} for testing purposes.
+ *
+ * @author Tim Anderson
+ * @version $Revision: 1.1 $ $Date: 2005/06/30 04:22:16 $
+ */
+public class TestStateFactory implements StateFactory
+{
+
+    /**
+     * Retrieves the state of an object for binding.
+     *
+     * @param obj         A non-null object whose state is to be retrieved.
+     * @param name        The name of this object relative to &lt;code&gt;nameCtx&lt;/code&gt;,
+     *                    or null if no name is specified.
+     * @param nameCtx     The context relative to which the &lt;code&gt;name&lt;/code&gt;
+     *                    parameter is specified, or null if &lt;code&gt;name&lt;/code&gt;
+     *                    is relative to the default initial context.
+     * @param environment The possibly null environment to be used in the
+     *                    creation of the object's state.
+     * @return The object's state for binding; null if the factory is not
+     *         returning any changes.
+     * @throws NamingException if this factory encountered an exception while
+     *                         attempting to get the object's state, and no
+     *                         other factories are to be tried.
+     * @see NamingManager#getStateToBind
+     * @see DirectoryManager#getStateToBind
+     */
+    public Object getStateToBind( Object obj, Name name, Context nameCtx,
+                                  Hashtable environment )
+        throws NamingException
+    {
+        Object result = null;
+        if( obj instanceof TestData )
+        {
+            TestData data = ( TestData ) obj;
+            TestDataReferenceable ref = new TestDataReferenceable(
+                data.getValue() );
+            result = ref.getReference();
+        }
+        return result;
+    }
+}
</pre></div>
<hr /><a name="file13" /><div class="file">
<span class="pathname">spice/components/jndikit/src/test/org/codehaus/spice/jndikit/test<br /></span>
<div class="fileheader"><big><b>AbstractContextTestCase.java</b></big> <small id="info">1.2 -&gt; 1.3</small></div>
<pre class="diff"><small id="info">diff -u -r1.2 -r1.3
--- AbstractContextTestCase.java	24 Jun 2005 15:13:52 -0000	1.2
+++ AbstractContextTestCase.java	30 Jun 2005 04:22:16 -0000	1.3
@@ -12,13 +12,19 @@
</small></pre><pre class="diff" id="context"> import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
</pre><pre class="diff" id="added">+import java.util.NoSuchElementException;
</pre><pre class="diff" id="context"> import java.util.Set;
 import javax.naming.Binding;
 import javax.naming.Context;
</pre><pre class="diff" id="added">+import javax.naming.ContextNotEmptyException;
</pre><pre class="diff" id="context"> import javax.naming.NameClassPair;
 import javax.naming.NameNotFoundException;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
</pre><pre class="diff" id="added">+import javax.naming.NotContextException;
+import javax.naming.Reference;
+import javax.naming.Referenceable;
+
</pre><pre class="diff" id="context"> import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
</pre><pre class="diff"><small id="info">@@ -26,7 +32,7 @@
</small></pre><pre class="diff" id="context">  * Unit testing for JNDI system
  *
  * @author Peter Donald
</pre><pre class="diff" id="removed">- * @version $Revision: 1.<span id="removedchars">2</span> $
</pre><pre class="diff" id="added">+ * @version $Revision: 1.<span id="addedchars">3</span> $
</pre><pre class="diff" id="context">  */
 public abstract class AbstractContextTestCase
     extends TestCase
</pre><pre class="diff"><small id="info">@@ -40,20 +46,10 @@
</small></pre><pre class="diff" id="context">     protected static final Object O7 = "iO7";
     protected static final Object O8 = "iO8";
 
</pre><pre class="diff" id="removed">-    private Context m_context;
-    private Context m_root;
</pre><pre class="diff" id="added">+    protected Context m_context;
+    protected Context m_root;
+    private static int c_id = 0;
</pre><pre class="diff" id="context"> 
</pre><pre class="diff" id="removed">-    protected void tearDown() throws Exception
-    {
-        if( null != m_context )
-        {
-            m_context.close();
-        }
-        if( null != m_root )
-        {
-            m_root.close();
-        }
-    }
</pre><pre class="diff" id="context"> 
     public void testBindToDirectContext()
         throws AssertionFailedError
</pre><pre class="diff"><small id="info">@@ -109,13 +105,22 @@
</small></pre><pre class="diff" id="context">             m_context.unbind( "O7" );
             m_context.unbind( "O8" );
 
</pre><pre class="diff" id="removed">-            final Enumeration enum = m_context.list( "" );
</pre><pre class="diff" id="added">+            final <span id="addedchars">Naming</span>Enumeration enum = m_context.list( "" );
</pre><pre class="diff" id="context"> 
             if( enum.hasMoreElements() )
             {
                 fail( "Failed to unbind all test elements: ie " +
                       enum.nextElement() );
             }
</pre><pre class="diff" id="added">+
+            try
+            {
+                enum.nextElement();
+                fail( "Expected nextElement() to throw NoSuchElementException" );
+            }
+            catch( final NoSuchElementException nsee )
+            {
+            }
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -178,6 +183,15 @@
</small></pre><pre class="diff" id="context">                       enum.nextElement() );
             }
 
</pre><pre class="diff" id="added">+            try
+            {
+                enum.nextElement();
+                fail( "Expected nextElement() to throw NoSuchElementException" );
+            }
+            catch( final NoSuchElementException nsee )
+            {
+            }
+
</pre><pre class="diff" id="context">             //unbind a unbound name - OK
             m_context.unbind( "a" );
             m_context.unbind( "x/a" );
</pre><pre class="diff"><small id="info">@@ -250,6 +264,19 @@
</small></pre><pre class="diff" id="context">             catch( final NamingException ne )
             {
             }
</pre><pre class="diff" id="added">+
+            m_context.bind( "O1", O1 );
+            try
+            {
+                // could potentially throw NotContextException (for O1) or
+                // NameNotFoundException (for O2)
+                m_context.bind( "O1/O2/O3", O3 );
+                fail( "Expected bind to non-context to throw NamingException" );
+            }
+            catch( final NamingException expected )
+            {
+            }
+
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -270,6 +297,7 @@
</small></pre><pre class="diff" id="context">             m_context.unbind( "x/O2" );
             m_context.unbind( "x/O3" );
 
</pre><pre class="diff" id="added">+
</pre><pre class="diff" id="context">             final Enumeration enum = m_context.list( "x/y" );
 
             if( enum.hasMoreElements() )
</pre><pre class="diff"><small id="info">@@ -278,6 +306,15 @@
</small></pre><pre class="diff" id="context">                       enum.nextElement() );
             }
 
</pre><pre class="diff" id="added">+            try
+            {
+                enum.nextElement();
+                fail( "Expected nextElement() to throw NoSuchElementException" );
+            }
+            catch( final NoSuchElementException nsee )
+            {
+            }
+
</pre><pre class="diff" id="context">             //Not sure if the next is legal????
             /*
             try
</pre><pre class="diff"><small id="info">@@ -291,6 +328,17 @@
</small></pre><pre class="diff" id="context">             //unbind a unbound name - OK
             m_context.unbind( "a" );
             m_context.unbind( "x/a" );
</pre><pre class="diff" id="added">+
+            m_context.bind( "x/y/O2", O2 );
+            try
+            {
+                m_context.unbind( "x/y/O2/bogus" );
+                fail(
+                    "Expected unbind from non-context to throw NamingException" );
+            }
+            catch( final NamingException ne )
+            {
+            }
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -298,6 +346,42 @@
</small></pre><pre class="diff" id="context">         }
     }
 
</pre><pre class="diff" id="added">+    /**
+     * Verifies that attempting to bind to self throws NamingException.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testBindSelf()
+        throws AssertionFailedError
+    {
+        try
+        {
+            m_context.bind( "", O1 );
+            fail( "Expected bind to self to throw NamingException" );
+        }
+        catch( NamingException ne )
+        {
+        }
+    }
+
+    /**
+     * Verifies that attempting to unbind self throws NamingException.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testUnbindSelf()
+        throws AssertionFailedError
+    {
+        try
+        {
+            m_context.unbind( "" );
+            fail( "Expected unbind of self to throw NamingException" );
+        }
+        catch( NamingException ne )
+        {
+        }
+    }
+
</pre><pre class="diff" id="context">     public void testCreateSubContext()
         throws AssertionFailedError
     {
</pre><pre class="diff"><small id="info">@@ -327,6 +411,15 @@
</small></pre><pre class="diff" id="context">             catch( final NamingException ne )
             {
             }
</pre><pre class="diff" id="added">+
+            try
+            {
+                m_context.createSubcontext( "" );
+                fail( "Created a subcontext with empty name" );
+            }
+            catch( final NamingException ne )
+            {
+            }
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -346,8 +439,12 @@
</small></pre><pre class="diff" id="context">                 m_context.destroySubcontext( "x" );
                 assertTrue( "destroySubContext with existing subContexts.", false );
             }
</pre><pre class="diff" id="added">+            catch( final ContextNotEmptyException ne )
+            {
+            }
</pre><pre class="diff" id="context">             catch( final NamingException ne )
             {
</pre><pre class="diff" id="added">+                fail( "Expected ContextNotEmptyException but got " + ne );
</pre><pre class="diff" id="context">             }
 
             try
</pre><pre class="diff"><small id="info">@@ -359,17 +456,59 @@
</small></pre><pre class="diff" id="context">             {
             }
 
</pre><pre class="diff" id="added">+            try
+            {
+                m_context.destroySubcontext( "x/a/y" );
+                fail(
+                    "destroySubcontext suceeded for non-existent intermediary subcontext" );
+            }
+            catch( final NameNotFoundException nnf )
+            {
+            }
+            catch( final NamingException ne )
+            {
+                fail( "Expected NameNotFoundException but got " + ne );
+            }
+
+            m_context.destroySubcontext( "x/y" );
+
+            // destroy non-existent context - OK
</pre><pre class="diff" id="context">             m_context.destroySubcontext( "x/y" );
</pre><pre class="diff" id="added">+
+
</pre><pre class="diff" id="context">             m_context.destroySubcontext( "x" );
 
             try
             {
</pre><pre class="diff" id="removed">-                m_context.lookup( "<span id="removedchars">z</span>" );
</pre><pre class="diff" id="added">+                m_context.lookup( "<span id="addedchars">x</span>" );
</pre><pre class="diff" id="context">                 assertTrue( "subContext exists after delete.", false );
             }
             catch( final NamingException ne )
             {
             }
</pre><pre class="diff" id="added">+
+            // destroy non-existent context - OK
+            m_context.destroySubcontext( "x" );
+
+
+            try
+            {
+                m_context.destroySubcontext( "" );
+                fail( "destroySubcontext destroyed self" );
+            }
+            catch( final NamingException ne )
+            {
+            }
+
+            try
+            {
+                m_context.bind( "x", O1 );
+                m_context.destroySubcontext( "x" );
+                fail( "destroySubcontext destroyed non-context" );
+            }
+            catch( final NotContextException nce )
+            {
+            }
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -444,6 +583,41 @@
</small></pre><pre class="diff" id="context">             catch( final NameNotFoundException nnfe )
             {
             }
</pre><pre class="diff" id="added">+
+            m_context.bind( "05", O5 );
+            try
+            {
+                m_context.rename( "O5", "O5" );
+            }
+            catch( final NamingException ne )
+            {
+            }
+
+            try
+            {
+                // rename self invalid
+                m_context.rename( "", "" );
+            }
+            catch( final NamingException ne )
+            {
+            }
+
+            try
+            {
+                m_context.rename( "", "O5" );
+            }
+            catch( final NamingException ne )
+            {
+            }
+
+            try
+            {
+                m_context.rename( "O5", "" );
+            }
+            catch( final NamingException ne )
+            {
+            }
+
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -466,7 +640,8 @@
</small></pre><pre class="diff" id="context">             m_context.bind( "O5", O5 );
             m_context.bind( "O6", O6 );
             m_context.bind( "O7", O7 );
</pre><pre class="diff" id="removed">-            m_context.bind( "O8", O8 );
</pre><pre class="diff" id="added">+            m_context.createSubcontext( "x" );
+            m_context.bind( "x/O8", O8 );
</pre><pre class="diff" id="context">             assertTrue( "Make sure lookup O2 returns correct object",
                         m_context.lookup( "O2" ).equals( O2 ) );
             assertTrue( "Make sure lookup O3 returns correct object",
</pre><pre class="diff"><small id="info">@@ -479,8 +654,8 @@
</small></pre><pre class="diff" id="context">                         m_context.lookup( "O6" ).equals( O6 ) );
             assertTrue( "Make sure lookup O7 returns correct object",
                         m_context.lookup( "O7" ).equals( O7 ) );
</pre><pre class="diff" id="removed">-            assertTrue( "Make sure lookup O8 returns correct object",
-                        m_context.lookup( "O8" ).equals( O8 ) );
</pre><pre class="diff" id="added">+            assertTrue( "Make sure lookup x/O8 returns correct object",
+                        m_context.lookup( "x/O8" ).equals( O8 ) );
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -499,7 +674,7 @@
</small></pre><pre class="diff" id="context">             m_context.rebind( "O5", O6 );
             m_context.rebind( "O6", O7 );
             m_context.rebind( "O7", O8 );
</pre><pre class="diff" id="removed">-            m_context.rebind( "O8", O1 );
</pre><pre class="diff" id="added">+            m_context.rebind( "<span id="addedchars">x/</span>O8", O1 );
</pre><pre class="diff" id="context">             assertTrue( "Rebind of O2 returns correct object",
                         m_context.lookup( "O2" ).equals( O3 ) );
             assertTrue( "Rebind of O3 returns correct object",
</pre><pre class="diff"><small id="info">@@ -512,15 +687,15 @@
</small></pre><pre class="diff" id="context">                         m_context.lookup( "O6" ).equals( O7 ) );
             assertTrue( "Rebind of O7 returns correct object",
                         m_context.lookup( "O7" ).equals( O8 ) );
</pre><pre class="diff" id="removed">-            assertTrue( "Rebind of O8 returns correct object",
-                        m_context.lookup( "O8" ).equals( O1 ) );
</pre><pre class="diff" id="added">+            assertTrue( "Rebind of x/O8 returns correct object",
+                        m_context.lookup( "x/O8" ).equals( O1 ) );
</pre><pre class="diff" id="context"> 
</pre><pre class="diff" id="removed">-            m_context.bind( "<span id="removedchars">x</span>", O1 );
</pre><pre class="diff" id="added">+            m_context.bind( "<span id="addedchars">y</span>", O1 );
</pre><pre class="diff" id="context">             assertTrue( "Make sure lookup x returns correct object",
</pre><pre class="diff" id="removed">-                        m_context.lookup( "x" ).equals( O1 ) );
-            m_context.rebind( "x", O8 );
-            assertTrue( "Rebind of x returns correct object",
-                        m_context.lookup( "x" ).equals( O8 ) );
</pre><pre class="diff" id="added">+                        m_context.lookup( "y" ).equals( O1 ) );
+            m_context.rebind( "y", O8 );
+            assertTrue( "Rebind of y returns correct object",
+                        m_context.lookup( "y" ).equals( O8 ) );
</pre><pre class="diff" id="context">         }
         catch( final NamingException ne )
         {
</pre><pre class="diff"><small id="info">@@ -542,194 +717,462 @@
</small></pre><pre class="diff" id="context">      * Create a subcontext, bind to it, and verify that the objects
      * can be looked up from it
      */
</pre><pre class="diff" id="removed">-    public void testSubcontextBindAndLookup() throws AssertionFailedError {
-        try {
-            m_context.createSubcontext("x");
-            Context context = (Context) m_context.lookup("x");
-            
-            context.bind("o1", O1);
-            
-            assertTrue("Make sure lookup o1 returns correct object",
-                       context.lookup("o1").equals(O1));
-            assertTrue("Make sure lookup o1 from root returns correct object",
-                        m_context.lookup("x/o1").equals(O1));
-        } catch (final NamingException ne) {
-            throw new AssertionFailedError( ne.toString());
</pre><pre class="diff" id="added">+    public void testSubcontextBindAndLookup() throws AssertionFailedError
+    {
+        try
+        {
+            m_context.createSubcontext( "x" );
+            Context context = ( Context ) m_context.lookup( "x" );
+
+            context.bind( "o1", O1 );
+
+            assertTrue( "Make sure lookup o1 returns correct object",
+                        context.lookup( "o1" ).equals( O1 ) );
+            assertTrue( "Make sure lookup o1 from root returns correct object",
+                        m_context.lookup( "x/o1" ).equals( O1 ) );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
</pre><pre class="diff" id="context">         }
     }
 
     /**
</pre><pre class="diff" id="removed">-     * Create a subcontext, bind to it, and verify that:
-     * &lt;ul&gt;
-     *   &lt;li&gt;can list the binding names from the root context&lt;/li&gt;
-     *   &lt;li&gt;can list the binding names from the subcontext&lt;/li&gt;
-     * &lt;/ul&gt; 
</pre><pre class="diff" id="added">+     * Create a subcontext, bind to it, and verify that: &lt;ul&gt; &lt;li&gt;can list the
+     * binding names from the root context&lt;/li&gt; &lt;li&gt;can list the binding names
+     * from the subcontext&lt;/li&gt; &lt;/ul&gt;
</pre><pre class="diff" id="context">      */
</pre><pre class="diff" id="removed">-    public void testSubcontextBindAndList1() throws AssertionFailedError<span id="removedchars">&nbsp;{</span>
</pre><pre class="diff" id="added">+    public void testSubcontextBindAndList1() throws AssertionFailedError
+    {
</pre><pre class="diff" id="context">         Map map = new HashMap();
</pre><pre class="diff" id="removed">-        map.put("o1", O1);
-        map.put("o2", O2);
-        map.put("o3", O3);
</pre><pre class="diff" id="added">+        map.put( "o1", O1 );
+        map.put( "o2", O2 );
+        map.put( "o3", O3 );
</pre><pre class="diff" id="context">         Set names;
 
</pre><pre class="diff" id="removed">-        try {
-            m_context.createSubcontext("x");
-            Context context = (Context) m_context.lookup("x");
-            
</pre><pre class="diff" id="added">+        try
+        {
+            m_context.createSubcontext( "x" );
+            Context context = ( Context ) m_context.lookup( "x" );
+
</pre><pre class="diff" id="context">             Iterator entries = map.entrySet().iterator();
</pre><pre class="diff" id="removed">-            while (entries.hasNext()) {
-                Map.Entry entry = (Map.Entry) entries.next();
-                context.bind((String) entry.getKey(), entry.getValue());
-            }
-            names = listNames(m_context, "x");
-            assertEquals("Make sure can list subcontext names from root",
-                         map.keySet(), names);
-
-            names = listNames(context, "");
-            assertEquals("Make sure can list subcontext names",
-                         map.keySet(), names);
-        } catch (final NamingException ne) {
-            throw new AssertionFailedError( ne.toString());
</pre><pre class="diff" id="added">+            while( entries.hasNext() )
+            {
+                Map.Entry entry = ( Map.Entry ) entries.next();
+                context.bind( ( String ) entry.getKey(), entry.getValue() );
+            }
+            names = listNames( m_context, "x" );
+            assertEquals( "Make sure can list subcontext names from root",
+                          map.keySet(), names );
+
+            names = listNames( context, "" );
+            assertEquals( "Make sure can list subcontext names",
+                          map.keySet(), names );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
</pre><pre class="diff" id="context">         }
     }
 
     /**
      * Create a subcontext, bind to it via the root context, and verify that:
</pre><pre class="diff" id="removed">-     * &lt;ul&gt;
-     *   &lt;li&gt;can list the binding names from the root context&lt;/li&gt;
-     *   &lt;li&gt;can list the binding names from the subcontext&lt;/li&gt;
-     * &lt;/ul&gt;
</pre><pre class="diff" id="added">+     * &lt;ul&gt; &lt;li&gt;can list the binding names from the root context&lt;/li&gt; &lt;li&gt;can
+     * list the binding names from the subcontext&lt;/li&gt; &lt;/ul&gt;
</pre><pre class="diff" id="context">      */
</pre><pre class="diff" id="removed">-    public void testSubcontextBindAndList2() throws AssertionFailedError<span id="removedchars">&nbsp;{</span>
</pre><pre class="diff" id="added">+    public void testSubcontextBindAndList2() throws AssertionFailedError
+    {
</pre><pre class="diff" id="context">         Map map = new HashMap();
</pre><pre class="diff" id="removed">-        map.put("o1", O1);
-        map.put("o2", O2);
-        map.put("o3", O3);
</pre><pre class="diff" id="added">+        map.put( "o1", O1 );
+        map.put( "o2", O2 );
+        map.put( "o3", O3 );
</pre><pre class="diff" id="context">         Set names;
 
</pre><pre class="diff" id="removed">-        try {
-            m_context.createSubcontext("x");
</pre><pre class="diff" id="added">+        try
+        {
+            m_context.createSubcontext( "x" );
</pre><pre class="diff" id="context"> 
             Iterator entries = map.entrySet().iterator();
</pre><pre class="diff" id="removed">-            while (entries.hasNext()) {
-                Map.Entry entry = (Map.Entry) entries.next();
</pre><pre class="diff" id="added">+            while( entries.hasNext() )
+            {
+                Map.Entry entry = ( Map.Entry ) entries.next();
</pre><pre class="diff" id="context">                 String name = "x/" + entry.getKey();
</pre><pre class="diff" id="removed">-                m_context.bind(name, entry.getValue());
</pre><pre class="diff" id="added">+                m_context.bind( name, entry.getValue() );
</pre><pre class="diff" id="context">             }
</pre><pre class="diff" id="removed">-            names = listNames(m_context, "x");
-            assertEquals("Make sure can list subcontext names from root",
-                         map.keySet(), names);
-            
-            Context context = (Context) m_context.lookup("x");
-            names = listNames(context, "");
-            assertEquals("Make sure can list subcontext names",
-                         map.keySet(), names);
-        } catch (final NamingException ne) {
-            throw new AssertionFailedError( ne.toString());
</pre><pre class="diff" id="added">+            names = listNames( m_context, "x" );
+            assertEquals( "Make sure can list subcontext names from root",
+                          map.keySet(), names );
+
+            Context context = ( Context ) m_context.lookup( "x" );
+            names = listNames( context, "" );
+            assertEquals( "Make sure can list subcontext names",
+                          map.keySet(), names );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
</pre><pre class="diff" id="context">         }
     }
 
</pre><pre class="diff" id="removed">-    public void testSubcontextListBindings() throws AssertionFailedError<span id="removedchars">&nbsp;{</span>
</pre><pre class="diff" id="added">+    public void testSubcontextListBindings() throws AssertionFailedError
+    {
</pre><pre class="diff" id="context">         Map map = new HashMap();
</pre><pre class="diff" id="removed">-        map.put("o1", O1);
-        map.put("o2", O2);
-        map.put("o3", O3);
</pre><pre class="diff" id="added">+        map.put( "o1", O1 );
+        map.put( "o2", O2 );
+        map.put( "o3", O3 );
</pre><pre class="diff" id="context">         Set names = new HashSet();
 
</pre><pre class="diff" id="removed">-        try<span id="removedchars">&nbsp;{</span>
</pre><pre class="diff" id="added">+        try
+        {
</pre><pre class="diff" id="context">             m_context.createSubcontext( "x" );
</pre><pre class="diff" id="removed">-            Context context = (Context) m_context.lookup("x");
</pre><pre class="diff" id="added">+            Context context = ( Context ) m_context.lookup( "x" );
</pre><pre class="diff" id="context">             Iterator entries = map.entrySet().iterator();
</pre><pre class="diff" id="removed">-            while (entries.hasNext()) {
-                Map.Entry entry = (Map.Entry) entries.next();
-                context.bind((String) entry.getKey(), entry.getValue());
-            }
-            NamingEnumeration bindings = context.listBindings("");
-            while (bindings.hasMore()) {
-                Binding binding = (Binding) bindings.next();
</pre><pre class="diff" id="added">+            while( entries.hasNext() )
+            {
+                Map.Entry entry = ( Map.Entry ) entries.next();
+                context.bind( ( String ) entry.getKey(), entry.getValue() );
+            }
+            NamingEnumeration bindings = context.listBindings( "" );
+            while( bindings.hasMore() )
+            {
+                Binding binding = ( Binding ) bindings.nextElement();
</pre><pre class="diff" id="context">                 String name = binding.getName();
</pre><pre class="diff" id="removed">-                Object expected = map.get(name);
-                if (expected == null) {
-                    throw new AssertionFailedError(
-                        "Invalid binding: name=" + name + ", classname="
-                        + binding.getClassName() + ", object="
-                        + binding.getObject());
</pre><pre class="diff" id="added">+                Object expected = map.get( name );
+                if( expected == null )
+                {
+                    throw new AssertionFailedError( "Invalid binding: name="
+                                                    + name
+                                                    + ", classname="
+                                                    + binding.getClassName()
+                                                    + ", object="
+                                                    + binding.getObject() );
</pre><pre class="diff" id="context">                 }
</pre><pre class="diff" id="removed">-                assertEquals(expected, binding.getObject());
-                names.add(name);
</pre><pre class="diff" id="added">+                assertEquals( expected, binding.getObject() );
+                names.add( name );
+            }
+
+            try
+            {
+                bindings.nextElement();
+                fail( "Expected nextElement() to throw NoSuchElementException" );
</pre><pre class="diff" id="context">             }
</pre><pre class="diff" id="removed">-        } catch (final NamingException ne) {
-            throw new AssertionFailedError( ne.toString());
</pre><pre class="diff" id="added">+            catch( final NoSuchElementException nsee )
+            {
+            }
+
+            bindings.close();
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
</pre><pre class="diff" id="context">         }
 
</pre><pre class="diff" id="removed">-        assertEquals(map.keySet(), names);
</pre><pre class="diff" id="added">+        assertEquals( map.keySet(), names );
</pre><pre class="diff" id="context">     }
 
     /**
      * Bind a tree of subcontexts, and ensure they can be listed
</pre><pre class="diff" id="added">+     *
</pre><pre class="diff" id="context">      * @throws AssertionFailedError
      */
</pre><pre class="diff" id="removed">-    public void testRecursiveListBindings() throws AssertionFailedError<span id="removedchars">&nbsp;{</span>
</pre><pre class="diff" id="added">+    public void testRecursiveListBindings() throws AssertionFailedError
+    {
</pre><pre class="diff" id="context">         Map expected = new HashMap();
</pre><pre class="diff" id="removed">-        expected.put("o1", O1);
-        expected.put("o2", O2);
-        expected.put("x/o3", O3);
-        expected.put("x/o4", O4);
-        expected.put("x/y/o5", O5);
</pre><pre class="diff" id="added">+        expected.put( "o1", O1 );
+        expected.put( "o2", O2 );
+        expected.put( "x/o3", O3 );
+        expected.put( "x/o4", O4 );
+        expected.put( "x/y/o5", O5 );
</pre><pre class="diff" id="context">         Map result = new HashMap();
 
</pre><pre class="diff" id="removed">-        try {
-            m_context.bind("o1", O1);
-            m_context.bind("o2", O2);
</pre><pre class="diff" id="added">+        try
+        {
+            m_context.bind( "o1", O1 );
+            m_context.bind( "o2", O2 );
</pre><pre class="diff" id="context">             m_context.createSubcontext( "x" );
</pre><pre class="diff" id="removed">-            Context context = (Context) m_context.lookup("x");
-            context.bind("o3", O3);
-            context.bind("o4", O4);
</pre><pre class="diff" id="added">+            Context context = ( Context ) m_context.lookup( "x" );
+            context.bind( "o3", O3 );
+            context.bind( "o4", O4 );
</pre><pre class="diff" id="context">             m_context.createSubcontext( "x/y" );
</pre><pre class="diff" id="removed">-            context = (Context) m_context.lookup("x/y");
-            context.bind("o5", O5);
</pre><pre class="diff" id="added">+            context = ( Context ) m_context.lookup( "x/y" );
+            context.bind( "o5", O5 );
</pre><pre class="diff" id="context"> 
</pre><pre class="diff" id="removed">-            listRecursive("", m_context, result);
-        } catch (final NamingException ne) {
-            throw new AssertionFailedError( ne.toString());
</pre><pre class="diff" id="added">+            listRecursive( "", m_context, result );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
</pre><pre class="diff" id="context">         }
 
</pre><pre class="diff" id="removed">-        assertEquals(expected, result);
</pre><pre class="diff" id="added">+        assertEquals( expected, result );
</pre><pre class="diff" id="context">     }
 
</pre><pre class="diff" id="removed">-    private Set listNames(Context context, String name)
-        throws NamingException {
-        Set result = new HashSet();
-        NamingEnumeration names = context.list(name);
-        while (names.hasMore()) {
-            NameClassPair pair = (NameClassPair) names.next();
-            result.add(pair.getName());
</pre><pre class="diff" id="added">+    /**
+     * Tests the {@link Context#addToEnvironment(String, Object)} and {@link
+     * Context#removeFromEnvironment(String)} methods.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testEnvironment() throws AssertionFailedError
+    {
+        final String key = "key";
+        Object value = null;
+        Object previous = null;
+
+        try
+        {
+            value = m_context.getEnvironment().get( key );
+            assertNull( value );
+
+            previous = m_context.addToEnvironment( key, O1 );
+            assertNull( previous );
+
+            previous = m_context.addToEnvironment( key, O2 );
+            assertEquals( O1, previous );
+
+            previous = m_context.removeFromEnvironment( key );
+            assertEquals( O2, previous );
+
+            previous = m_context.removeFromEnvironment( key );
+            assertNull( previous );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
</pre><pre class="diff" id="context">         }
</pre><pre class="diff" id="removed">-        return result;
</pre><pre class="diff" id="context">     }
 
</pre><pre class="diff" id="removed">-    private void listRecursive(String name, Context context, Map result) throws NamingException {
-        NamingEnumeration bindings = context.listBindings("");
-        while (bindings.hasMore()) {
-            Binding binding = (Binding) bindings.next();
-            Object object = binding.getObject();
-            String subName = (name.length() == 0) ? binding.getName() :
-                    name + "/" + binding.getName();
-            if (object instanceof Context) {
-                listRecursive(subName, (Context) object, result);
-            } else {
-                result.put(subName, object);
</pre><pre class="diff" id="added">+    public void testComposeName() throws AssertionFailedError
+    {
+        try
+        {
+            assertEquals( "a", m_context.composeName( "", "a" ) );
+            assertEquals( "a/b", m_context.composeName( "b", "a" ) );
+            assertEquals( "a/b/c", m_context.composeName( "c", "a/b" ) );
+            assertEquals( "a/b/c", m_context.composeName( "b/c", "a" ) );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
+        }
+    }
+
+    /**
+     * Bind a {@link Referenceable}, and ensure that its reference is used.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testReferenceable()
+        throws AssertionFailedError
+    {
+        try
+        {
+            TestDataReferenceable initial = new TestDataReferenceable(
+                "value1" );
+
+            m_context.bind( "o1", initial );
+            initial.setValue( "value2" );
+
+            Object obj = m_context.lookup( "o1" );
+            assertTrue( obj instanceof TestDataReferenceable );
+            assertEquals( "value1", ((TestData) obj).getValue() );
+
+            // ensure listBindings resolves the reference
+            final NamingEnumeration bindings = m_context.listBindings( "" );
+            assertTrue( bindings.hasMore() );
+            Binding binding = ( Binding ) bindings.nextElement();
+            obj = binding.getObject();
+            assertTrue( obj instanceof TestDataReferenceable );
+            assertEquals( "value1", ( ( TestData ) obj ).getValue() );
+            assertFalse( bindings.hasMore() );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
+        }
+    }
+
+    /**
+     * Bind a {@link Reference} and ensure that the class it refers to is
+     * returned on subsequent lookup.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testReference()
+        throws AssertionFailedError
+    {
+        final String expected = "foo";
+        try
+        {
+            TestDataReferenceable value = new TestDataReferenceable( expected );
+            Reference reference = value.getReference();
+            m_context.bind( "o2", reference );
+
+            Object obj = m_context.lookup( "o2" );
+            assertTrue( obj instanceof TestDataReferenceable );
+            assertEquals( expected, ( ( TestData ) obj ).getValue() );
+
+            // ensure listBindings resolves the reference
+            final NamingEnumeration bindings = m_context.listBindings( "" );
+            assertTrue( bindings.hasMore() );
+            Binding binding = ( Binding ) bindings.nextElement();
+            obj = binding.getObject();
+            assertTrue( obj instanceof TestDataReferenceable );
+            assertEquals( expected, ( ( TestData ) obj ).getValue() );
+            assertFalse( bindings.hasMore() );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
+        }
+    }
+
+    /**
+     * Bind a {@link TestData} and ensure that {@link TestStateFactory} is
+     * invoked to convert it to a {@link Reference}.
+     *
+     * @throws AssertionFailedError if the test fails.
+     */
+    public void testStateFactory() throws AssertionFailedError
+    {
+        final String expected = "bar";
+        try
+        {
+            TestData value = new TestData( expected );
+            m_context.bind( "o3", value );
+
+
+            Object obj = m_context.lookup( "o3" );
+            assertTrue( obj instanceof TestDataReferenceable );
+
+            TestDataReferenceable current = ( TestDataReferenceable ) obj;
+            assertEquals( expected, current.getValue() );
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
+        }
+    }
+
+    /**
+     * Verify that {@link NamingEnumeration#next()} throws {@link
+     * NamingException} when a reference can't be resolved.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testNextForBadReference()
+        throws AssertionFailedError
+    {
+        try
+        {
+            ExceptionReferenceable trigger = new ExceptionReferenceable();
+            m_context.bind( "o4", trigger );
+
+            NamingEnumeration enum = m_context.listBindings( "" );
+            assertTrue( enum.hasMore() );
+            try
+            {
+                Object result = enum.next();
+                fail( "Expected nextElement to throw NamingExceptionn, but returned "
+                      + result );
+            }
+            catch( final NamingException expected )
+            {
</pre><pre class="diff" id="context">             }
         }
</pre><pre class="diff" id="added">+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
+        }
</pre><pre class="diff" id="context">     }
 
</pre><pre class="diff" id="removed">-    protected void setRoot( Context root )
</pre><pre class="diff" id="added">+    /**
+     * Verify that {@link NamingEnumeration#nextElement()} throws {@link
+     * NoSuchElementException} when a reference can't be resolved.
+     *
+     * @throws AssertionFailedError if the test fails
+     */
+    public void testNextElementForBadReference()
+        throws AssertionFailedError
</pre><pre class="diff" id="context">     {
</pre><pre class="diff" id="removed">-        m_root = root;
</pre><pre class="diff" id="added">+        try
+        {
+            ExceptionReferenceable trigger = new ExceptionReferenceable();
+            m_context.bind( "o5", trigger );
+
+            NamingEnumeration enum = m_context.listBindings( "" );
+            assertTrue( enum.hasMoreElements() );
+            try
+            {
+                Object result = enum.nextElement();
+                fail( "Expected nextElement to throw NoSuchElementException, but returned "
+                      + result );
+            }
+            catch( NoSuchElementException expected )
+            {
+            }
+        }
+        catch( final NamingException ne )
+        {
+            throw new AssertionFailedError( ne.toString() );
+        }
+    }
+
+    protected void setUp() throws Exception
+    {
+        m_root = getRoot();
+        m_context = m_root.createSubcontext( "test" + c_id++ );
+    }
+
+    protected void tearDown() throws Exception
+    {
+        if( null != m_context )
+        {
+            m_context.close();
+        }
+        if( null != m_root )
+        {
+            m_root.close();
+        }
+    }
+
+    protected abstract Context getRoot() throws Exception;
+
+
+    private Set listNames( Context context, String name )
+        throws NamingException
+    {
+        Set result = new HashSet();
+        NamingEnumeration names = context.list( name );
+        while( names.hasMore() )
+        {
+            NameClassPair pair = ( NameClassPair ) names.next();
+            result.add( pair.getName() );
+        }
+        names.close();
+        return result;
</pre><pre class="diff" id="context">     }
 
</pre><pre class="diff" id="removed">-    protected void setContext( Context context )
</pre><pre class="diff" id="added">+    private void listRecursive( String name, Context context, Map result )
+        throws NamingException
</pre><pre class="diff" id="context">     {
</pre><pre class="diff" id="removed">-        m_context = context;
</pre><pre class="diff" id="added">+        NamingEnumeration bindings = context.listBindings( "" );
+        while( bindings.hasMore() )
+        {
+            Binding binding = ( Binding ) bindings.next();
+            Object object = binding.getObject();
+            String subName = ( name.length() == 0 ) ? binding.getName() :
+                name + "/" + binding.getName();
+            if( object instanceof Context )
+            {
+                listRecursive( subName, ( Context ) object, result );
+            }
+            else
+            {
+                result.put( subName, object );
+            }
+        }
+        bindings.close();
</pre><pre class="diff" id="context">     }
</pre><pre class="diff" id="added">+
</pre><pre class="diff" id="context"> }
</pre></div>
<center><small><a href="http://www.badgers-in-foil.co.uk/projects/cvsspam/" title="commit -&gt; email">CVSspam</a> 0.2.8</small></center>
</body></html>