diff --git a/framework/src/main/java/org/eclipse/gemini/naming/Activator.java b/framework/src/main/java/org/eclipse/gemini/naming/Activator.java
index 357f100..1efdc77 100644
--- a/framework/src/main/java/org/eclipse/gemini/naming/Activator.java
+++ b/framework/src/main/java/org/eclipse/gemini/naming/Activator.java
@@ -1,267 +1,288 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 Oracle.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *     http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *     http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.
- *
- * Contributors:
- *     Bob Nettleton (Oracle) - Initial Reference Implementation
- ******************************************************************************/
-
-package org.eclipse.gemini.naming;
-
-import java.lang.reflect.Field;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.naming.NamingException;
-import javax.naming.spi.InitialContextFactoryBuilder;
-import javax.naming.spi.NamingManager;
-import javax.naming.spi.ObjectFactory;
-import javax.naming.spi.ObjectFactoryBuilder;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.jndi.JNDIConstants;
-import org.osgi.service.jndi.JNDIContextManager;
-import org.osgi.service.jndi.JNDIProviderAdmin;
-
-/**
- * Activator implementation for the Gemini Naming Bundle.
- * 
- * This activator's main purpose is to register the JNDI Builder singleton
- * implementations that allow the Factory Manager to override the default JNDI
- * framework.
- * 
- * 
- */
-public class Activator implements BundleActivator {
-
-	private static final String					OSGI_URL_SCHEME					= "osgi";
-	
-	private static Logger logger = Logger.getLogger(Activator.class.getName());
-
-	private BundleContext						m_bundleContext					= null;
-	private final List                          m_listOfServiceRegistrations = new LinkedList();
-
-	private CloseableProviderAdmin	m_providerAdminService;
-	private ContextManagerServiceFactoryImpl m_contextManagerServiceFactory;
-	
-	/*
-	 * Create the Factory Manager's builder implementation, and register it with
-	 * the JNDI NamingManager.
-	 * 
-	 * @see
-	 * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
-	 * )
-	 */
-	public void start(BundleContext context) throws Exception {
-		logger.info("Initializing Gemini Naming Factory Manager Bundle");
-		
-		m_bundleContext = context;
-
-		// register static singletons with the JNDI framework
-		logger.info("Installing Static Singletons");
-		registerInitialContextFactoryBuilderSingleton();
-		registerObjectFactoryBuilderSingleton();
-
-		logger.info("Registering URL Context Factory for 'osgi' URL scheme");
-		registerOSGiURLContextFactory();
-		
-		logger.info("Registering Default Runtime Builder for JRE-provided factories");
-		registerDefaultRuntimeBuilder();
-		
-		logger.info("Registering ContextManager service");
-		// register the JNDIContextManager service once all Factory
-		// Manager initialization is complete
-		registerContextManager();
-		
-		logger.info("Registering ProviderAdmin service");
-		// register the JNDIProviderAdmin interface, used by OSGi-aware
-		// context implementations to resolve JNDI references
-		registerProviderAdmin();
-	}
-	
-
-	/*
-	 * Allow the Builder implementation to clean up any
-	 * ServiceListener/ServiceTracker instances.
-	 * 
-	 * @see
-	 * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
-	 */
-	public void stop(BundleContext context) throws Exception {
-		logger.info("Shutting down Gemini Naming Factory Manager Bundle");
-		
-		// close all known Contexts associated with the JNDIContextManager service
-		m_contextManagerServiceFactory.closeAll();
-		
-		// close the JNDIProviderAdmin service
-		m_providerAdminService.close();
-
-		// unregister all the JNDI services registered by this Activator
-		Iterator iterator = m_listOfServiceRegistrations.iterator();
-		while(iterator.hasNext()) {
-			ServiceRegistration serviceRegistration = 
-				(ServiceRegistration)iterator.next();
-			serviceRegistration.unregister();
-		}
-		
-		unregisterSingletons();
-	}
-
-
-	/**
-	 * Registers the InitialContextFactoryBuilder static singleton
-	 * @throws NamingException on any error that occurs during the setting
-	 *         of the builder.  
-	 */
-	private static void registerInitialContextFactoryBuilderSingleton() throws NamingException {
-		try {
-			NamingManager.setInitialContextFactoryBuilder(new TraditionalInitialContextFactoryBuilder());
-		}
-		catch (IllegalStateException illegalStateException) {
-			logger.log(Level.SEVERE, 
-			           "Gemini Naming Implementation cannot set the InitialContextFactoryBuilder - another builder was already installed",
-			           illegalStateException);
-			NamingException namingException = 
-				new NamingException("Error occurred while attempting to set the IntialContextFactoryBuilder.");
-			namingException.setRootCause(illegalStateException);
-			throw namingException;
-		} 
-		catch(SecurityException securityException) {
-			logger.log(Level.SEVERE, 
-					   "Gemini Naming Implementation did not have the proper security permissions to install the InitialContextFactoryBuilder",
-					   securityException);
-			NamingException namingException = 
-				new NamingException("Error occurred while attempting to set the IntialContextFactoryBuilder.");
-			namingException.setRootCause(securityException);
-			throw namingException;
-		}
-	}
-	
-	
-	/**
-	 * Registers the ObjectFactoryBuilder static singleton
-	 * @throws NamingException on any error that occurs during the setting
-	 *         of the builder.  
-	 */
-	private static void registerObjectFactoryBuilderSingleton() throws NamingException {
-		try {
-			NamingManager.setObjectFactoryBuilder(new TraditionalObjectFactoryBuilder());
-		}
-		catch (IllegalStateException illegalStateException) {
-			logger.log(Level.SEVERE, 
-			           "Gemini Naming Implementation cannot set the ObjectFactoryBuilder - another builder was already installed",
-			           illegalStateException);
-			NamingException namingException = 
-				new NamingException("Error occurred while attempting to set the ObjectFactoryBuilder.");
-			namingException.setRootCause(illegalStateException);
-			throw namingException;
-		} 
-		catch(SecurityException securityException) {
-			logger.log(Level.SEVERE, 
-					   "Gemini Naming Implementation did not have the proper security permissions to install the ObjectFactoryBuilder",
-					   securityException);
-			NamingException namingException = 
-				new NamingException("Error occurred while attempting to set the ObjectFactoryBuilder.");
-			namingException.setRootCause(securityException);
-			throw namingException;
-		}
-	}
-		
-	/**
-	 * Unregisters the InitialContextFactoryBuilder static singleton
-	 * and the ObjectFactoryBuilder static singleton.
-	 */
-	private static void unregisterSingletons() {
-		Field[] fields = NamingManager.class.getDeclaredFields();
-		if (fields != null && fields.length > 0) {
-			for (Field field: fields) {
-				if (InitialContextFactoryBuilder.class.equals(field.getType()) 
-						|| ObjectFactoryBuilder.class.equals(field.getType())){
-					field.setAccessible(true);
-					try {
-						field.set(null, null);
-					} catch (IllegalArgumentException e) {
-						logger.log(Level.SEVERE,
-								   "Unable to reset NamingManager static singleton " + field.getType(),
-								   e);
-					} catch (IllegalAccessException e) {
-						logger.log(Level.SEVERE,
-								   "Unable to reset NamingManager static singleton " + field.getType(),
-								   e);
-					}
-				}
-			}
-		}
-	}
-	
-	
-	
-	
-	/**
-	 * Registers the OSGi URL Context Factory.
-	 * 
-	 */
-	private void registerOSGiURLContextFactory() {
-		Hashtable serviceProperties = new Hashtable();
-		serviceProperties.put(JNDIConstants.JNDI_URLSCHEME, OSGI_URL_SCHEME);
-
-		ServiceRegistration serviceRegistration = 
-			m_bundleContext.registerService(ObjectFactory.class.getName(), 
-										    new OSGiURLContextFactoryServiceFactory(), 
-										    serviceProperties);
-		m_listOfServiceRegistrations.add(serviceRegistration);
-	}
-	
-	
-	/**
-	 * Registers the InitialContextFactoryBuilder implementation that 
-	 * is responsible for loading the JDK-defined providers that must be
-	 * loaded from the boot classpath.  
-	 * 
-	 */
-	private void registerDefaultRuntimeBuilder() {
-		ServiceRegistration serviceRegistration = 
-			m_bundleContext.registerService(InitialContextFactoryBuilder.class.getName(), 
-					                        new DefaultRuntimeInitialContextFactoryBuilder(), 
-					                        null);
-		m_listOfServiceRegistrations.add(serviceRegistration);
-	}
-	
-	
-	private void registerContextManager() {
-		m_contextManagerServiceFactory = 
-			new ContextManagerServiceFactoryImpl(m_bundleContext);
-		ServiceRegistration serviceRegistration = 
-			m_bundleContext.registerService(JNDIContextManager.class.getName(),
-											m_contextManagerServiceFactory,
-					                        null);
-		m_listOfServiceRegistrations.add(serviceRegistration);
-	}
-	
-
-	private void registerProviderAdmin() {
-		m_providerAdminService = 
-			new SecurityAwareProviderAdminImpl(new ProviderAdminImpl(m_bundleContext));
-		
-		
-		ServiceRegistration serviceRegistration =  
-			m_bundleContext.registerService(JNDIProviderAdmin.class.getName(),
-					                        m_providerAdminService,
-					                        null);
-		m_listOfServiceRegistrations.add(serviceRegistration);
-	}
-
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Oracle.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution. 
+ * The Eclipse Public License is available at
+ *     http://www.eclipse.org/legal/epl-v10.html
+ * and the Apache License v2.0 is available at 
+ *     http://www.opensource.org/licenses/apache2.0.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ *     Bob Nettleton (Oracle) - Initial Reference Implementation
+ ******************************************************************************/
+
+package org.eclipse.gemini.naming;
+
+import java.lang.reflect.Field;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactoryBuilder;
+import javax.naming.spi.NamingManager;
+import javax.naming.spi.ObjectFactory;
+import javax.naming.spi.ObjectFactoryBuilder;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.jndi.JNDIConstants;
+import org.osgi.service.jndi.JNDIContextManager;
+import org.osgi.service.jndi.JNDIProviderAdmin;
+
+/**
+ * Activator implementation for the Gemini Naming Bundle.
+ * 
+ * This activator's main purpose is to register the JNDI Builder singleton
+ * implementations that allow the Factory Manager to override the default JNDI
+ * framework.
+ * 
+ * 
+ */
+public class Activator implements BundleActivator {
+
+	private static final String					OSGI_URL_SCHEME					= "osgi";
+	private static final String					RMI_URL_SCHEME					= "rmi";
+	private static final String					RMI_URL_CONTEXT_FACTORY			= "com.sun.jndi.url.rmi.rmiURLContextFactory";
+	
+	private static Logger logger = Logger.getLogger(Activator.class.getName());
+
+	private BundleContext						m_bundleContext					= null;
+	private final List<ServiceRegistration>        m_listOfServiceRegistrations = new LinkedList<ServiceRegistration>();
+
+	private CloseableProviderAdmin	m_providerAdminService;
+	private ContextManagerServiceFactoryImpl m_contextManagerServiceFactory;
+	
+	/*
+	 * Create the Factory Manager's builder implementation, and register it with
+	 * the JNDI NamingManager.
+	 * 
+	 * @see
+	 * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
+	 * )
+	 */
+	public void start(BundleContext context) throws Exception {
+		logger.info("Initializing Gemini Naming Factory Manager Bundle");
+		
+		m_bundleContext = context;
+
+		// register static singletons with the JNDI framework
+		logger.info("Installing Static Singletons");
+		registerInitialContextFactoryBuilderSingleton();
+		registerObjectFactoryBuilderSingleton();
+
+		logger.info("Registering URL Context Factory for 'osgi' URL scheme");
+		registerOSGiURLContextFactory();
+		
+		logger.info("Registering Default Runtime Builder for JRE-provided factories");
+		registerDefaultRuntimeBuilder();
+		
+		logger.info("Registering ContextManager service");
+		// register the JNDIContextManager service once all Factory
+		// Manager initialization is complete
+		registerContextManager();
+		
+		logger.info("Registering ProviderAdmin service");
+		// register the JNDIProviderAdmin interface, used by OSGi-aware
+		// context implementations to resolve JNDI references
+		registerProviderAdmin();
+	}
+	
+
+	/*
+	 * Allow the Builder implementation to clean up any
+	 * ServiceListener/ServiceTracker instances.
+	 * 
+	 * @see
+	 * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		logger.info("Shutting down Gemini Naming Factory Manager Bundle");
+		
+		// close all known Contexts associated with the JNDIContextManager service
+		m_contextManagerServiceFactory.closeAll();
+		
+		// close the JNDIProviderAdmin service
+		m_providerAdminService.close();
+
+		// unregister all the JNDI services registered by this Activator
+		Iterator<ServiceRegistration> iterator = m_listOfServiceRegistrations.iterator();
+		while(iterator.hasNext()) {
+			ServiceRegistration serviceRegistration = 
+				(ServiceRegistration)iterator.next();
+			serviceRegistration.unregister();
+		}
+		
+		unregisterSingletons();
+	}
+
+
+	/**
+	 * Registers the InitialContextFactoryBuilder static singleton
+	 * @throws NamingException on any error that occurs during the setting
+	 *         of the builder.  
+	 */
+	private static void registerInitialContextFactoryBuilderSingleton() throws NamingException {
+		try {
+			NamingManager.setInitialContextFactoryBuilder(new TraditionalInitialContextFactoryBuilder());
+		}
+		catch (IllegalStateException illegalStateException) {
+			logger.log(Level.SEVERE, 
+			           "Gemini Naming Implementation cannot set the InitialContextFactoryBuilder - another builder was already installed",
+			           illegalStateException);
+			NamingException namingException = 
+				new NamingException("Error occurred while attempting to set the IntialContextFactoryBuilder.");
+			namingException.setRootCause(illegalStateException);
+			throw namingException;
+		} 
+		catch(SecurityException securityException) {
+			logger.log(Level.SEVERE, 
+					   "Gemini Naming Implementation did not have the proper security permissions to install the InitialContextFactoryBuilder",
+					   securityException);
+			NamingException namingException = 
+				new NamingException("Error occurred while attempting to set the IntialContextFactoryBuilder.");
+			namingException.setRootCause(securityException);
+			throw namingException;
+		}
+	}
+	
+	
+	/**
+	 * Registers the ObjectFactoryBuilder static singleton
+	 * @throws NamingException on any error that occurs during the setting
+	 *         of the builder.  
+	 */
+	private static void registerObjectFactoryBuilderSingleton() throws NamingException {
+		try {
+			NamingManager.setObjectFactoryBuilder(new TraditionalObjectFactoryBuilder());
+		}
+		catch (IllegalStateException illegalStateException) {
+			logger.log(Level.SEVERE, 
+			           "Gemini Naming Implementation cannot set the ObjectFactoryBuilder - another builder was already installed",
+			           illegalStateException);
+			NamingException namingException = 
+				new NamingException("Error occurred while attempting to set the ObjectFactoryBuilder.");
+			namingException.setRootCause(illegalStateException);
+			throw namingException;
+		} 
+		catch(SecurityException securityException) {
+			logger.log(Level.SEVERE, 
+					   "Gemini Naming Implementation did not have the proper security permissions to install the ObjectFactoryBuilder",
+					   securityException);
+			NamingException namingException = 
+				new NamingException("Error occurred while attempting to set the ObjectFactoryBuilder.");
+			namingException.setRootCause(securityException);
+			throw namingException;
+		}
+	}
+		
+	/**
+	 * Unregisters the InitialContextFactoryBuilder static singleton
+	 * and the ObjectFactoryBuilder static singleton.
+	 */
+	private static void unregisterSingletons() {
+		Field[] fields = NamingManager.class.getDeclaredFields();
+		if (fields != null && fields.length > 0) {
+			for (Field field: fields) {
+				if (InitialContextFactoryBuilder.class.equals(field.getType()) 
+						|| ObjectFactoryBuilder.class.equals(field.getType())){
+					field.setAccessible(true);
+					try {
+						field.set(null, null);
+					} catch (IllegalArgumentException e) {
+						logger.log(Level.SEVERE,
+								   "Unable to reset NamingManager static singleton " + field.getType(),
+								   e);
+					} catch (IllegalAccessException e) {
+						logger.log(Level.SEVERE,
+								   "Unable to reset NamingManager static singleton " + field.getType(),
+								   e);
+					}
+				}
+			}
+		}
+	}
+	
+	
+	
+	
+	/**
+	 * Registers the OSGi URL Context Factory.
+	 * 
+	 */
+	private void registerOSGiURLContextFactory() {
+		Hashtable<Object, Object> serviceProperties = new Hashtable<Object, Object>();
+		serviceProperties.put(JNDIConstants.JNDI_URLSCHEME, OSGI_URL_SCHEME);
+
+		ServiceRegistration serviceRegistration = 
+			m_bundleContext.registerService(ObjectFactory.class.getName(), 
+										    new OSGiURLContextFactoryServiceFactory(), 
+										    serviceProperties);
+		m_listOfServiceRegistrations.add(serviceRegistration);
+	}
+	
+	
+	/**
+	 * Registers the InitialContextFactoryBuilder implementation that 
+	 * is responsible for loading the JDK-defined providers that must be
+	 * loaded from the boot classpath.  
+	 * 
+	 */
+	private void registerDefaultRuntimeBuilder() {
+		ServiceRegistration serviceRegistration = 
+			m_bundleContext.registerService(InitialContextFactoryBuilder.class.getName(), 
+					                        new DefaultRuntimeInitialContextFactoryBuilder(), 
+					                        null);
+		m_listOfServiceRegistrations.add(serviceRegistration);
+		
+		Hashtable<Object, Object> props = new Hashtable<Object, Object>();
+        props.put(JNDIConstants.JNDI_URLSCHEME, RMI_URL_SCHEME);
+		try {
+			ServiceRegistration rmiRegistration = 
+				m_bundleContext.registerService(ObjectFactory.class.getName(),
+												ClassLoader.getSystemClassLoader().loadClass(RMI_URL_CONTEXT_FACTORY).newInstance(),
+												props);
+			m_listOfServiceRegistrations.add(rmiRegistration);
+		}
+		catch(ClassNotFoundException e) {
+			logger.log(Level.SEVERE, RMI_URL_CONTEXT_FACTORY + " cannot be found through the system classloader.", e);
+		}
+		catch(InstantiationException e) {
+			logger.log(Level.SEVERE, "Exception occurred while instantiating " + RMI_URL_CONTEXT_FACTORY, e);
+		}
+		catch(IllegalAccessException e) {
+			logger.log(Level.SEVERE, "Exception occured while instantiating " + RMI_URL_CONTEXT_FACTORY, e);
+		}
+	}
+	
+	
+	private void registerContextManager() {
+		m_contextManagerServiceFactory = 
+			new ContextManagerServiceFactoryImpl(m_bundleContext);
+		ServiceRegistration serviceRegistration = 
+			m_bundleContext.registerService(JNDIContextManager.class.getName(),
+											m_contextManagerServiceFactory,
+					                        null);
+		m_listOfServiceRegistrations.add(serviceRegistration);
+	}
+	
+
+	private void registerProviderAdmin() {
+		m_providerAdminService = 
+			new SecurityAwareProviderAdminImpl(new ProviderAdminImpl(m_bundleContext));
+		
+		
+		ServiceRegistration serviceRegistration =  
+			m_bundleContext.registerService(JNDIProviderAdmin.class.getName(),
+					                        m_providerAdminService,
+					                        null);
+		m_listOfServiceRegistrations.add(serviceRegistration);
+	}
+
 }
\ No newline at end of file
diff --git a/org.eclipse.gemini.naming.utests/src/test/java/org/eclipse/gemini/naming/ActivatorTestCase.java b/org.eclipse.gemini.naming.utests/src/test/java/org/eclipse/gemini/naming/ActivatorTestCase.java
index 4f1c6fd..9bc20d9 100644
--- a/org.eclipse.gemini.naming.utests/src/test/java/org/eclipse/gemini/naming/ActivatorTestCase.java
+++ b/org.eclipse.gemini.naming.utests/src/test/java/org/eclipse/gemini/naming/ActivatorTestCase.java
@@ -1,255 +1,261 @@
-/*******************************************************************************
- * Copyright (c) 2010 Oracle.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution. 
- * The Eclipse Public License is available at
- *     http://www.eclipse.org/legal/epl-v10.html
- * and the Apache License v2.0 is available at 
- *     http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.
- *
- * Contributors:
- *     Bob Nettleton (Oracle) - Initial Reference Implementation Unit Tests
- ******************************************************************************/
-
-package org.eclipse.gemini.naming;
-
-import java.lang.reflect.Field;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import javax.naming.NamingException;
-import javax.naming.spi.DirObjectFactory;
-import javax.naming.spi.InitialContextFactory;
-import javax.naming.spi.InitialContextFactoryBuilder;
-import javax.naming.spi.NamingManager;
-import javax.naming.spi.ObjectFactory;
-import javax.naming.spi.ObjectFactoryBuilder;
-
-import org.easymock.EasyMockSupport;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.jndi.JNDIConstants;
-import org.osgi.service.jndi.JNDIContextManager;
-import org.osgi.service.jndi.JNDIProviderAdmin;
-
-import static org.easymock.EasyMock.*;
-
-import junit.framework.TestCase;
-
-public class ActivatorTestCase extends TestCase {
-
-	public void setUp() {
-		setNamingManagerStaticFieldToNull("initctx_factory_builder");
-		setNamingManagerStaticFieldToNull("object_factory_builder");
-	}
-
-	public void tearDown() {
-		setNamingManagerStaticFieldToNull("initctx_factory_builder");
-		setNamingManagerStaticFieldToNull("object_factory_builder");
-	}
-	
-	
-	/**
-	 * Verify the basic startup of the Gemini Naming Activator.  
-	 *  
-	 * This test method verifies that all the expected services are 
-	 * registered using the correct interface, actual type, and service
-	 * properties.  
-	 */
-	public void testStart() throws Exception {
-		EasyMockSupport mockSupport = new EasyMockSupport();
-		BundleContext bundleContextMock = 
-			mockSupport.createMock(BundleContext.class);
-		
-		setupBundleContextMock(mockSupport, bundleContextMock);
-		// expect OSGi URLContextFactory 
-		Hashtable<String, Object> serviceProperties = new Hashtable<String, Object>();
-		serviceProperties.put(JNDIConstants.JNDI_URLSCHEME, "osgi");
-		setServiceRegistrationExpectation(mockSupport, bundleContextMock,
-				                          ObjectFactory.class.getName(), 
-				                          OSGiURLContextFactoryServiceFactory.class, 
-				                          serviceProperties);
-
-		// expect the "default" InitialContextFactoryBuilder
-		setServiceRegistrationExpectation(mockSupport, bundleContextMock,
-				                          InitialContextFactoryBuilder.class.getName(),
-				                          DefaultRuntimeInitialContextFactoryBuilder.class,
-				                          null);
-		
-		// expect the JNDIContextManager service registration
-		setServiceRegistrationExpectation(mockSupport, bundleContextMock, 
-				                          JNDIContextManager.class.getName(),
-				                          ContextManagerServiceFactoryImpl.class, 
-                						  null);
-		// expect the JNDIProviderAdmin service registration
-		setServiceRegistrationExpectation(mockSupport, bundleContextMock, 
-                						  JNDIProviderAdmin.class.getName(),
-                						  SecurityAwareProviderAdminImpl.class, 
-                						  null);
-				
-		
-		mockSupport.replayAll();
-		
-		// begin test
-		Activator activator = new Activator();
-		activator.start(bundleContextMock);
-		
-		// verify that the static singletons are set as expected
-		assertTrue("Activator did not set the InitialContextFactoryBuilder singleton correctly",
-				    getPrivateStaticField(NamingManager.class, "initctx_factory_builder") instanceof TraditionalInitialContextFactoryBuilder);
-		assertTrue("Activator did not set the ObjectFactoryBuilder singleton correctly",
-			       getPrivateStaticField(NamingManager.class, "object_factory_builder") instanceof TraditionalObjectFactoryBuilder);
-		
-		// stop() should complete without any exceptions
-		activator.stop(bundleContextMock);
-		
-		mockSupport.verifyAll();
-	}
-	
-	public void testRegistrationOfContextBuilderError() throws Exception {
-		// setup test mocks
-		EasyMockSupport mockSupport = new EasyMockSupport();
-		InitialContextFactoryBuilder builderMock = 
-			mockSupport.createMock(InitialContextFactoryBuilder.class);
-		if(!NamingManager.hasInitialContextFactoryBuilder()) {
-			NamingManager.setInitialContextFactoryBuilder(builderMock);
-		}
-		
-		BundleContext bundleContextMock = 
-			mockSupport.createMock(BundleContext.class);
-		mockSupport.replayAll();
-		
-		// begin test
-		Activator activator = new Activator();
-		try {
-			activator.start(bundleContextMock);
-			fail("NamingException should have been thrown");
-		} catch (NamingException namingException) {
-			// expected exception
-		}
-		
-		mockSupport.verifyAll();
-		
-	}
-	
-	
-	public void testRegistrationOfObjectFactoryBuilderError() throws Exception {
-		// setup test mocks
-		EasyMockSupport mockSupport = new EasyMockSupport();
-		ObjectFactoryBuilder builderMock = 
-			mockSupport.createMock(ObjectFactoryBuilder.class);
-		
-		try {
-			// try to set builder, to guarantee
-			// that Activator's attempt to set this will fail
-			NamingManager.setObjectFactoryBuilder(builderMock);
-		} catch (Throwable throwable) {
-			// if already set, test can continue
-		}
-		
-		BundleContext bundleContextMock = 
-			mockSupport.createMock(BundleContext.class);
-		mockSupport.replayAll();
-		
-		// begin test
-		Activator activator = new Activator();
-		try {
-			activator.start(bundleContextMock);
-			fail("NamingException should have been thrown");
-		} catch (NamingException namingException) {
-			// expected exception
-		}
-		
-		mockSupport.verifyAll();
-		
-	}
-
-	/* test utility methods/classes */
-	
-	private static void setupBundleContextMock(EasyMockSupport mockSupport, BundleContext bundleContextMock) throws InvalidSyntaxException {
-		Filter filterMock = 
-			mockSupport.createMock(Filter.class);
-		expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactory.class.getName() + ")")).andReturn(filterMock);
-		expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
-		expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactory.class.getName() + ")")).andReturn(filterMock).anyTimes();
-		expect(bundleContextMock.createFilter("(objectClass=" + DirObjectFactory.class.getName() + ")")).andReturn(filterMock);
-		expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
-		
-		bundleContextMock.addServiceListener(isA(ServiceListener.class), isA(String.class));
-		expectLastCall().anyTimes();
-		
-		bundleContextMock.removeServiceListener(isA(ServiceListener.class));
-		expectLastCall().anyTimes();
-		
-		expect(bundleContextMock.getServiceReferences(isA(String.class), isA(String.class))).andReturn(new ServiceReference[0]).anyTimes();
-		expect(bundleContextMock.getServiceReferences(isA(String.class), (String)isNull())).andReturn(new ServiceReference[0]).anyTimes();
-	}
-
-	private static <T> void setServiceRegistrationExpectation(EasyMockSupport mockSupport, BundleContext bundleContextMock, String serviceName, Class<T> serviceType, Dictionary<String, Object> serviceProperties) {
-		ServiceRegistration serviceRegistrationMock = 
-			mockSupport.createMock(ServiceRegistration.class);
-		// required for stop() method
-		serviceRegistrationMock.unregister();
-		if(serviceProperties != null) {
-			expect(bundleContextMock.registerService(eq(serviceName),
-	                isA(serviceType), eq(serviceProperties))).andReturn(serviceRegistrationMock);
-		} else {
-			expect(bundleContextMock.registerService(eq(serviceName),
-	                isA(serviceType), (Dictionary)isNull())).andReturn(serviceRegistrationMock);
-		}
-		
-	}
-	
-	/**
-	 * This method should be used only for unit testing the Gemini Naming Activator.  
-	 * 
-	 * This method sets the static singleton fields on the NamingManger class to null.  This facilitates
-	 * simpler unit-testing of the Activator, which attempts to set these singletons.  The NamingManager usually
-	 * throws and Exception on the set() methods for these singletons after they've been set once.  
-	 * 
-	 * This utility method is meant to make unit testing simpler, but should not be used in production code. 
-	 * 
-	 * This utility method will probably not work properly if a security manager is enabled.  
-	 * 
-	 * @param fieldName the name of the static field to set to null.
-	 */
-	private static void setNamingManagerStaticFieldToNull(String fieldName) {
-		try {
-			final Field field = NamingManager.class.getDeclaredField(fieldName);
-			if(field != null) {
-				field.setAccessible(true);
-				// reset this static field to null
-				field.set(null, null);
-			}
-		} catch (Throwable throwable) {
-			throwable.printStackTrace();
-		}
-	}
-	
-	/*
-	 * Utility method used to access the private static singletons on the NamingManager class.  
-	 * 
-	 * This method should only be used for unit-testing the Gemini Naming code.  
-	 *
-	 * This utility method will probably not work properly if a security manager is enabled.
-	 * 
-	 * @param type the Class type that contains the field
-	 * @param fieldName a String name that identifies the field
-	 */
-	private static Object getPrivateStaticField(Class type, String fieldName) throws Exception {
-		Field field = type.getDeclaredField(fieldName);
-		if(field != null) {
-			field.setAccessible(true);
-			return field.get(null);
-		}
-		
-		return null;
-	}
-	
-}
+/*******************************************************************************
+ * Copyright (c) 2010 Oracle.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution. 
+ * The Eclipse Public License is available at
+ *     http://www.eclipse.org/legal/epl-v10.html
+ * and the Apache License v2.0 is available at 
+ *     http://www.opensource.org/licenses/apache2.0.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ *     Bob Nettleton (Oracle) - Initial Reference Implementation Unit Tests
+ ******************************************************************************/
+
+package org.eclipse.gemini.naming;
+
+import java.lang.reflect.Field;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.naming.NamingException;
+import javax.naming.spi.DirObjectFactory;
+import javax.naming.spi.InitialContextFactory;
+import javax.naming.spi.InitialContextFactoryBuilder;
+import javax.naming.spi.NamingManager;
+import javax.naming.spi.ObjectFactory;
+import javax.naming.spi.ObjectFactoryBuilder;
+
+import org.easymock.EasyMockSupport;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.jndi.JNDIConstants;
+import org.osgi.service.jndi.JNDIContextManager;
+import org.osgi.service.jndi.JNDIProviderAdmin;
+
+import static org.easymock.EasyMock.*;
+
+import junit.framework.TestCase;
+
+public class ActivatorTestCase extends TestCase {
+
+	public void setUp() {
+		setNamingManagerStaticFieldToNull("initctx_factory_builder");
+		setNamingManagerStaticFieldToNull("object_factory_builder");
+	}
+
+	public void tearDown() {
+		setNamingManagerStaticFieldToNull("initctx_factory_builder");
+		setNamingManagerStaticFieldToNull("object_factory_builder");
+	}
+	
+	
+	/**
+	 * Verify the basic startup of the Gemini Naming Activator.  
+	 *  
+	 * This test method verifies that all the expected services are 
+	 * registered using the correct interface, actual type, and service
+	 * properties.  
+	 */
+	public void testStart() throws Exception {
+		EasyMockSupport mockSupport = new EasyMockSupport();
+		BundleContext bundleContextMock = 
+			mockSupport.createMock(BundleContext.class);
+		
+		setupBundleContextMock(mockSupport, bundleContextMock);
+		// expect OSGi URLContextFactory 
+		Hashtable<String, Object> serviceProperties = new Hashtable<String, Object>();
+		serviceProperties.put(JNDIConstants.JNDI_URLSCHEME, "osgi");
+		setServiceRegistrationExpectation(mockSupport, bundleContextMock,
+				                          ObjectFactory.class.getName(), 
+				                          OSGiURLContextFactoryServiceFactory.class, 
+				                          serviceProperties);
+
+		// expect the "default" InitialContextFactoryBuilder
+		setServiceRegistrationExpectation(mockSupport, bundleContextMock,
+				                          InitialContextFactoryBuilder.class.getName(),
+				                          DefaultRuntimeInitialContextFactoryBuilder.class,
+				                          null);
+		
+		// expect the JNDIContextManager service registration
+		setServiceRegistrationExpectation(mockSupport, bundleContextMock, 
+				                          JNDIContextManager.class.getName(),
+				                          ContextManagerServiceFactoryImpl.class, 
+                						  null);
+		// expect the JNDIProviderAdmin service registration
+		setServiceRegistrationExpectation(mockSupport, bundleContextMock, 
+                						  JNDIProviderAdmin.class.getName(),
+                						  SecurityAwareProviderAdminImpl.class, 
+                						  null);
+		// expect the rmiURLContextFactory service registration
+		Hashtable<String, Object> props = new Hashtable<String, Object>();
+        props.put(JNDIConstants.JNDI_URLSCHEME, "rmi");
+		setServiceRegistrationExpectation(mockSupport, bundleContextMock, 
+										  ObjectFactory.class.getName(),
+										  ClassLoader.getSystemClassLoader().loadClass("com.sun.jndi.url.rmi.rmiURLContextFactory"), 
+                						  props);				
+		
+		mockSupport.replayAll();
+		
+		// begin test
+		Activator activator = new Activator();
+		activator.start(bundleContextMock);
+		
+		// verify that the static singletons are set as expected
+		assertTrue("Activator did not set the InitialContextFactoryBuilder singleton correctly",
+				    getPrivateStaticField(NamingManager.class, "initctx_factory_builder") instanceof TraditionalInitialContextFactoryBuilder);
+		assertTrue("Activator did not set the ObjectFactoryBuilder singleton correctly",
+			       getPrivateStaticField(NamingManager.class, "object_factory_builder") instanceof TraditionalObjectFactoryBuilder);
+		
+		// stop() should complete without any exceptions
+		activator.stop(bundleContextMock);
+		
+		mockSupport.verifyAll();
+	}
+	
+	public void testRegistrationOfContextBuilderError() throws Exception {
+		// setup test mocks
+		EasyMockSupport mockSupport = new EasyMockSupport();
+		InitialContextFactoryBuilder builderMock = 
+			mockSupport.createMock(InitialContextFactoryBuilder.class);
+		if(!NamingManager.hasInitialContextFactoryBuilder()) {
+			NamingManager.setInitialContextFactoryBuilder(builderMock);
+		}
+		
+		BundleContext bundleContextMock = 
+			mockSupport.createMock(BundleContext.class);
+		mockSupport.replayAll();
+		
+		// begin test
+		Activator activator = new Activator();
+		try {
+			activator.start(bundleContextMock);
+			fail("NamingException should have been thrown");
+		} catch (NamingException namingException) {
+			// expected exception
+		}
+		
+		mockSupport.verifyAll();
+		
+	}
+	
+	
+	public void testRegistrationOfObjectFactoryBuilderError() throws Exception {
+		// setup test mocks
+		EasyMockSupport mockSupport = new EasyMockSupport();
+		ObjectFactoryBuilder builderMock = 
+			mockSupport.createMock(ObjectFactoryBuilder.class);
+		
+		try {
+			// try to set builder, to guarantee
+			// that Activator's attempt to set this will fail
+			NamingManager.setObjectFactoryBuilder(builderMock);
+		} catch (Throwable throwable) {
+			// if already set, test can continue
+		}
+		
+		BundleContext bundleContextMock = 
+			mockSupport.createMock(BundleContext.class);
+		mockSupport.replayAll();
+		
+		// begin test
+		Activator activator = new Activator();
+		try {
+			activator.start(bundleContextMock);
+			fail("NamingException should have been thrown");
+		} catch (NamingException namingException) {
+			// expected exception
+		}
+		
+		mockSupport.verifyAll();
+		
+	}
+
+	/* test utility methods/classes */
+	
+	private static void setupBundleContextMock(EasyMockSupport mockSupport, BundleContext bundleContextMock) throws InvalidSyntaxException {
+		Filter filterMock = 
+			mockSupport.createMock(Filter.class);
+		expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactory.class.getName() + ")")).andReturn(filterMock);
+		expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
+		expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactory.class.getName() + ")")).andReturn(filterMock).anyTimes();
+		expect(bundleContextMock.createFilter("(objectClass=" + DirObjectFactory.class.getName() + ")")).andReturn(filterMock);
+		expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
+		
+		bundleContextMock.addServiceListener(isA(ServiceListener.class), isA(String.class));
+		expectLastCall().anyTimes();
+		
+		bundleContextMock.removeServiceListener(isA(ServiceListener.class));
+		expectLastCall().anyTimes();
+		
+		expect(bundleContextMock.getServiceReferences(isA(String.class), isA(String.class))).andReturn(new ServiceReference[0]).anyTimes();
+		expect(bundleContextMock.getServiceReferences(isA(String.class), (String)isNull())).andReturn(new ServiceReference[0]).anyTimes();
+	}
+
+	private static <T> void setServiceRegistrationExpectation(EasyMockSupport mockSupport, BundleContext bundleContextMock, String serviceName, Class<T> serviceType, Dictionary<String, Object> serviceProperties) {
+		ServiceRegistration serviceRegistrationMock = 
+			mockSupport.createMock(ServiceRegistration.class);
+		// required for stop() method
+		serviceRegistrationMock.unregister();
+		if(serviceProperties != null) {
+			expect(bundleContextMock.registerService(eq(serviceName),
+	                isA(serviceType), eq(serviceProperties))).andReturn(serviceRegistrationMock);
+		} else {
+			expect(bundleContextMock.registerService(eq(serviceName),
+	                isA(serviceType), (Dictionary)isNull())).andReturn(serviceRegistrationMock);
+		}
+		
+	}
+	
+	/**
+	 * This method should be used only for unit testing the Gemini Naming Activator.  
+	 * 
+	 * This method sets the static singleton fields on the NamingManger class to null.  This facilitates
+	 * simpler unit-testing of the Activator, which attempts to set these singletons.  The NamingManager usually
+	 * throws and Exception on the set() methods for these singletons after they've been set once.  
+	 * 
+	 * This utility method is meant to make unit testing simpler, but should not be used in production code. 
+	 * 
+	 * This utility method will probably not work properly if a security manager is enabled.  
+	 * 
+	 * @param fieldName the name of the static field to set to null.
+	 */
+	private static void setNamingManagerStaticFieldToNull(String fieldName) {
+		try {
+			final Field field = NamingManager.class.getDeclaredField(fieldName);
+			if(field != null) {
+				field.setAccessible(true);
+				// reset this static field to null
+				field.set(null, null);
+			}
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+	}
+	
+	/*
+	 * Utility method used to access the private static singletons on the NamingManager class.  
+	 * 
+	 * This method should only be used for unit-testing the Gemini Naming code.  
+	 *
+	 * This utility method will probably not work properly if a security manager is enabled.
+	 * 
+	 * @param type the Class type that contains the field
+	 * @param fieldName a String name that identifies the field
+	 */
+	private static Object getPrivateStaticField(Class type, String fieldName) throws Exception {
+		Field field = type.getDeclaredField(fieldName);
+		if(field != null) {
+			field.setAccessible(true);
+			return field.get(null);
+		}
+		
+		return null;
+	}
+	
+}
