/*******************************************************************************
 * 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 - Initial Developer tests for Reference Implementation
 ******************************************************************************/

package org.eclipse.gemini.naming.test;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Set;

import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoInitialContextException;
import javax.naming.OperationNotSupportedException;
import javax.naming.directory.DirContext;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;

import org.osgi.framework.Constants;
import org.osgi.framework.ServiceException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.jndi.JNDIContextManager;


/**
 * Class used to verify the behavior of the JNDIContextManager service.  
 *
 * @author Bob Nettleton
 * 
 */
public class ContextManagerTestCase extends NamingTestCase {
	/**
	 * Verifies that if a specific InitialContextFactory is requested by 
	 * a client, and that factory is not available, the Factory Manager will query the 
	 * list of known InitialContextFactoryBuilder implementations to try 
	 * and create a suitable context.  
	 * 
	 * Please see section 5.2.1.1 of RFC 142 for more details. 
	 * 
	 * @throws Exception
	 */
	public void testSpecificFactoryResolvedByBuilder() throws Exception {
		final String expectedBindingName = "test-binding-one";
		final String expectedBindingValue = "this is only a test";
		
		// setup a test context
		Context testContext = new FactoryResolutionTestCase.TestContext() {
			public Object lookup(String name) throws NamingException {
				if (name.equals(expectedBindingName)) {
					return expectedBindingValue;
				}
				
				throw new NameNotFoundException("Error in JNDI test");
			}
			
		};
		
		// register a builder service
		registerService(InitialContextFactoryBuilder.class.getName(), 
                		new FactoryResolutionTestCase.TestContextFactoryBuilder(testContext), null);
		
		Hashtable environment = new Hashtable();
		environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.test.factory.FactoryDoesNotExist");
		environment.put("osgi.service.jndi.bundleContext", bundleContext);
		// builder should provide an InitialContextFactory implementation
		InitialContext initialContext = null;
		try {
			initialContext = new InitialContext(environment);
			// verify that the expected value is returned
			assertEquals("Factory Manager did not return the expected factory", 
						 expectedBindingValue, initialContext.lookup(expectedBindingName));
		} finally {
			initialContext.close();
		}
		
		// attempt the same test from the context manager service
		
		ServiceReference serviceRef =  
			getContext().getServiceReference(JNDIContextManager.class.getName());
		JNDIContextManager contextManager = 
			(JNDIContextManager)getContext().getService(serviceRef);
		assertNotNull("Context Manager service not available", contextManager);
		Context serviceInitialContext = contextManager.newInitialContext(environment);
		// verify that context returned from manager behaves the same 
		assertEquals("Factory Manager did not return the expected factory", 
				 expectedBindingValue, serviceInitialContext.lookup(expectedBindingName));
		
		getContext().ungetService(serviceRef);
	}
	
	
	/**
	 * Verifies that the Gemini Naming bundle provides an implementation 
	 * of the JNDIContextManager service interface.  
	 */
	public void testJNDIContextManagerServiceAvailable() throws Exception {
		ServiceReference serviceReference = null;
			try {
				serviceReference = getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
				assertNotNull("JNDIContextManager was not published as expected", serviceReference);
			} finally {
				if(serviceReference != null) {
					getContext().ungetService(serviceReference);
				}
			}
	}
	
	/**
	 * Verifies that the implementation of JNDIContextManager.newInitialContext() will
	 * query the available InitialContextFactoryBuilder services to create a "default" context, 
	 * if the JNDI client has not specified which factory to use to create the Context.
	 */
	public void testJNDIContextManagerCreateDefaultContextWithBuilder() throws Exception {
		final String expectedName = "test-one";
		final String expectedValue = "this is only a test";
		// test setup
		final Context testContext = new ExpectedValueTestContext(expectedName, expectedValue);
		InitialContextFactoryBuilder builder = 
			new FactoryResolutionTestCase.TestContextFactoryBuilder(testContext);
		registerService(InitialContextFactoryBuilder.class.getName(), builder, null);
		
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		// create a context with the default environment setup
		Context initialContext = contextManager.newInitialContext();
		assertNotNull("JNDIContextManager did not create a new default context", initialContext);
		assertEquals("JNDIContextManager did not return the correct context", 
				     expectedValue, initialContext.lookup(expectedName));
		getContext().ungetService(serviceReference);
	}
	
	
	/**
	 * Verify that if a Builder service is un-registered, that the JNDI Context 
	 * created by this Builder will throw the appropriate exception.  If the service
	 * is re-registered, the Context should function properly as before the service
	 * was un-registered.  
	 */
	public void testJNDIContextManagerCreateDefaultContextWithBuilderThenRemoveBuilder() throws Exception {
		final String expectedName = "test-one";
		final String expectedValue = "this is only a test";
		// test setup
		final Context testContext = new ExpectedValueTestContext(expectedName, expectedValue);
		InitialContextFactoryBuilder builder = 
			new FactoryResolutionTestCase.TestContextFactoryBuilder(testContext);
		registerService(InitialContextFactoryBuilder.class.getName(), builder, null);
		
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		// create a context with the default environment setup
		Context initialContext = contextManager.newInitialContext();
		assertNotNull("JNDIContextManager did not create a new default context", initialContext);
		assertEquals("JNDIContextManager did not return the correct context", 
				     expectedValue, initialContext.lookup(expectedName));
		
		unregisterService(builder);
		// try lookup again, without builder being available
		try {
			initialContext.lookup(expectedName);
			fail("NoInitialContextException should have been thrown");
		} catch (NoInitialContextException e) {
			// expected exception
		}
		
		// re-register Builder service
		registerService(InitialContextFactoryBuilder.class.getName(), 
		        builder, null);
		
		assertEquals("JNDIContextManager did not return the correct context after re-bind of Builder service", 
			     expectedValue, initialContext.lookup(expectedName));
		
		getContext().ungetService(serviceReference);
	}
	
	
	/**
	 * Verify that when all references to the JNDIContextManager service 
	 * are released (with an ungetService() call), the JNDIContextManager service
	 * implementation will call Context.close() on all Contexts created for the client
	 * by this service.  
	 */
	public void testJNDIContextManagerContextClose() throws Exception {
		final String expectedName = "test-one";
		final String expectedValue = "this is only a test";
		// test setup
		final ExpectedValueTestContext testContext = 
			new ExpectedValueTestContext(expectedName, expectedValue);
		InitialContextFactoryBuilder builder = 
			new FactoryResolutionTestCase.TestContextFactoryBuilder(testContext);
		registerService(InitialContextFactoryBuilder.class.getName(), builder, null);
		
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		try {
			// create a context with the default environment setup
			Context initialContext = contextManager.newInitialContext();
			assertNotNull("JNDIContextManager did not create a new default context", initialContext);
			assertEquals("JNDIContextManager did not return the correct context", 
					     expectedValue, initialContext.lookup(expectedName));
			
			// remove reference to service, this should trigger a close() call
			// on the context instance.  
			assertEquals("JNDIContextManager service should not have closed the context yet", 
					     0, testContext.getNumCloseCalls());
			getContext().ungetService(serviceReference);
			assertEquals("JNDIContextManager service did not properly close the created context",
					     1, testContext.getNumCloseCalls());
		} finally {
			getContext().ungetService(serviceReference);
		}
		
	}
	
	
	/**
	 * Verify that if no factories or builders exist to create a Context, the 
	 * "default" Context instance returned will not support bind() calls.  
	 */
	public void testJNDIContextManagerCreateDefaultContextWithoutBuilder() throws Exception {
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		// create a context with the default environment setup
		try {
			// this should fail
			Context initialContext = contextManager.newInitialContext();
			initialContext.bind("this is just a test", "test object one");
			fail("NoInitialContextException should have been thrown");
		}
		catch (NoInitialContextException namingException) {
			// expected exception
		}
		
		getContext().ungetService(serviceReference);
	}
	
	
	
	/**
	 * Verify basic creation of DirContexts.  
	 */
	public void testCreateDirContext() throws Exception {
		// setup test InitialContextFactory service
		String[] serviceInterfaceNames = {InitialContextFactory.class.getName(), 
				                          TestInitialDirContextFactory.class.getName()};
		ServiceRegistration serviceRegistration = 
			getContext().registerService(serviceInterfaceNames, 
					                     new TestInitialDirContextFactory(), null);
		
		try {
			ServiceReference serviceReference = 
				getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
			JNDIContextManager contextManager = (JNDIContextManager)
			    getContext().getService(serviceReference);
			
			Hashtable environment = new Hashtable();
			environment.put(Context.INITIAL_CONTEXT_FACTORY, 
					        TestInitialDirContextFactory.class.getName());
			
			DirContext dirContext = 
				contextManager.newInitialDirContext(environment);
			assertNotNull("JNDIContextManager did not create a DirContext as expected", 
					      dirContext);
			
			getContext().ungetService(serviceReference);
		}
		finally {
			if(serviceRegistration != null) {
				serviceRegistration.unregister();
			}
		}
	}
	
	
	/**
	 * Verify creation of DirContext using an InitialContextFactoryBuilder.  
	 */
	public void testJNDIContextManagerCreateDefaultDirContextWithBuilder() throws Exception {
		// test setup
		InitialContextFactoryBuilder builder = 
			new InitialContextFactoryBuilder() {
				public InitialContextFactory createInitialContextFactory(
						Hashtable var0) throws NamingException {
					return new TestInitialDirContextFactory();
				}
		};

		registerService(InitialContextFactoryBuilder.class.getName(), 
				        builder, null);
		
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		// create a context with the default environment setup
		DirContext initialDirContext = contextManager.newInitialDirContext();
		assertNotNull("JNDIContextManager did not create a new default context", initialDirContext);
		
		getContext().ungetService(serviceReference);
	}
	
	
	/**
	 * Verify that the methods to create a DirContext on the JNDIContextManager
	 * interface check the type of the created Context.  If the object is not an 
	 * instanceof DirContext, a NoInitialContextException should be thrown.  
	 * 
	 */
	public void testJNDIContextManagerCreateDirContextWithBuilderWrongType() throws Exception {
		// test setup
		registerService(InitialContextFactoryBuilder.class.getName(), 
				        new FactoryResolutionTestCase.TestContextFactoryBuilder(new FactoryResolutionTestCase.TestContext()), null);
		
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		// create a context with an environment config
		try {
			contextManager.newInitialDirContext(new Hashtable());
			fail("NoInitialContextException should have been thrown");
		}
		catch (NoInitialContextException e) {
			// expected exception
		}
		
		// create a context with the default environment config
		try {
			contextManager.newInitialDirContext();
			fail("NoInitialContextException should have been thrown");
		} 
		catch (NoInitialContextException e) {
			// expected exception
		}
		
		getContext().ungetService(serviceReference);
	}

	/**
	 * Verify that if no builders or factories exist to create the DirContext,
	 * then a NoInitialContextException should be thrown.  
	 * 
	 */
	public void testJNDIContextManagerCreateDefaultDirContextWithoutBuilder() throws Exception {
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		// create a context with the default environment setup
		try {
			// this should fail
			contextManager.newInitialDirContext();
			fail("NoInitialContextException should have been thrown");
		}
		catch (NoInitialContextException namingException) {
			// expected exception
		}
		
		getContext().ungetService(serviceReference);
	}
	
	
	/**
	 * Verify the basic behavior of an "osgi:servicelist" lookup, including
	 * the basic operations of the NamingEnumeration associated with this type
	 * of lookup (Context.list()).  
	 */
	public void testJNDIServiceListNamingEnumeration() throws Exception {
		final String expectedBindingName = "test-binding-one";
		final String expectedBindingValue = "this is only a test";
		
		// setup a test context
		Context testContext = 
			new ExpectedValueTestContext(expectedBindingName, expectedBindingValue);
		
		// register a builder service
		registerService(InitialContextFactoryBuilder.class.getName(), 
                		new FactoryResolutionTestCase.TestContextFactoryBuilder(testContext), null);
		
		registerService(Closeable.class.getName(), new NoOpCloseable(), null);
		registerService(Closeable.class.getName(), new NoOpCloseable(), null);
		
		ServiceReference[] builderReferences = 
			getContext().getServiceReferences(Closeable.class.getName(), null);
		
		final Set setOfIds = new HashSet();
		for(int i = 0; i < builderReferences.length; i++) {
			setOfIds.add(builderReferences[i].getProperty(Constants.SERVICE_ID).toString());
		}
		
		assertEquals("Initial set of services is not the expected number", 
				      2, setOfIds.size());
		
		
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		
		try {
			Context initialContext = contextManager.newInitialContext(new Hashtable());
			Context serviceListContext = (Context)initialContext.lookup("osgi:servicelist/" + Closeable.class.getName());
		
			final int originalNumberOfServicesInUse = 
				getContext().getBundle().getServicesInUse().length;
			
			assertNotNull("JNDI implementation did not return the expected context type for a servicelist URL", 
					       serviceListContext);
			NamingEnumeration namingEnum = serviceListContext.list("");
			assertTrue("NamingEnumeration did not contain any elements", 
					    namingEnum.hasMoreElements());
			
			Object result = namingEnum.next();
			assertNotNull("NamingEnumeration did not contain the expected service",
					       result);
			assertTrue("NamingEnumeration returned an unexpected type", 
					    result instanceof NameClassPair);

			NameClassPair nameClassPair = (NameClassPair)result;
			assertEquals("NameClassPair did not contain the expected type", 
					     Closeable.class.getName(), 
					     nameClassPair.getClassName());
			assertTrue("NameClassPair did not contain an expected ID", 
					    setOfIds.contains(nameClassPair.getName()));
			
			assertTrue("NamingEnumeration should contain one more element", 
				     namingEnum.hasMoreElements());
			
			NameClassPair nameClassPairTwo = (NameClassPair)namingEnum.next();
			assertEquals("NameClassPair did not contain the expected type", 
					     Closeable.class.getName(),
					     nameClassPairTwo.getClassName());
			assertTrue("NameClassPair did not contain an expected ID", 
				        setOfIds.contains(nameClassPairTwo.getName()));
			
			assertFalse("NamingEnumeration should not contain any more elements", 
				        namingEnum.hasMoreElements());
			
			// verify exception handling
			try {
				namingEnum.nextElement();
				fail("NoSuchElementException should have been thrown");
			} catch (NoSuchElementException e) {
				// expected exception
			}
			
			// verify exception handling
			try {
				namingEnum.next();
				fail("NoSuchElementException should have been thrown");
			} catch (NoSuchElementException e) {
				// expected exception
			}

			assertEquals("NamingEnumeration returned from Context.list() call incorrectly increased the service count for this calling bundle", 
					     originalNumberOfServicesInUse, getContext().getBundle().getServicesInUse().length);
			
			
			NamingEnumeration namingEnumTwo = 
				serviceListContext.list("");
			assertNotSame("ServiceList context should have returned a new enumeration",
					       namingEnum, namingEnumTwo);
			
			// close first enumeration, verify that service count does not change
			namingEnum.close();
			assertEquals("NamingEnumeration returned from Context.list() call incorrectly decreased the service count for this calling bundle", 
				     originalNumberOfServicesInUse, getContext().getBundle().getServicesInUse().length);
			
			
			 assertTrue("NamingEnum should have contained elements", 
					    namingEnumTwo.hasMoreElements());
			 namingEnumTwo.close();
			 
			 try {
				 namingEnumTwo.next();
				 fail("NamingException should have been thrown");
			 } catch (NamingException e) {
				 // expected exception
			 }
			 
			// verify that only empty string context lists are supported
			try {
				serviceListContext.list("someName");
				fail("OperationNotSupportedException should have been thrown");
			} catch (OperationNotSupportedException e) {
				// expected exception
			}
			
		} finally {
			getContext().ungetService(serviceReference);
		}
	}
	
	/**
	 * Verifies the behavior of the NamingEnumeration returned as the result 
	 * of a Context.listBindings() call on a Context that supports the "osgi:servicelist" 
	 * lookup.  
	 */
	public void testJNDIServiceListBindingsNamingEnumeration() throws Exception {
		final String expectedBindingName = "test-binding-one";
		final String expectedBindingValue = "this is only a test";
		
		// setup a test context
		Context testContext = 
			new ExpectedValueTestContext(expectedBindingName, expectedBindingValue);
		
		// register a builder service
		registerService(InitialContextFactoryBuilder.class.getName(), 
                		new FactoryResolutionTestCase.TestContextFactoryBuilder(testContext), null);
		
		registerService(Closeable.class.getName(), new NoOpCloseable(), null);
		
		registerService(Closeable.class.getName(), new NoOpCloseable(), null);
		
		ServiceReference[] builderReferences = 
			getContext().getServiceReferences(Closeable.class.getName(), null);
		
		final Set setOfIds = new HashSet();
		for(int i = 0; i < builderReferences.length; i++) {
			setOfIds.add(builderReferences[i].getProperty(Constants.SERVICE_ID).toString());
		}
		
		assertEquals("Initial set of services is not the expected number", 
				      2, setOfIds.size());
		
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		
		try {
			Context initialContext = contextManager.newInitialContext(new Hashtable());
			Context serviceListContext = (Context)initialContext.lookup("osgi:servicelist/" + Closeable.class.getName());
			
			final int originalNumOfServices =  
				getContext().getBundle().getServicesInUse().length;
			
			assertNotNull("JNDI implementation did not return the expected context type for a servicelist URL", 
					       serviceListContext);
			
			NamingEnumeration namingEnum = serviceListContext.listBindings("");
			
			// verify that the number of services in use by this bundle 
			// has increased due to the call to listBindings
			// this test verifies that the NamingEnumeration is using the 
			// caller's bundle context to obtain the services
			assertEquals("Context.listBindings() call should have increased the service count for this bundle",
					      originalNumOfServices + setOfIds.size(), getContext().getBundle().getServicesInUse().length);
			
			assertTrue("NamingEnumeration did not contain any elements", 
				    namingEnum.hasMoreElements());
		
			Object result = namingEnum.next();
			assertNotNull("NamingEnumeration did not contain the expected service",
				          result);
			assertTrue("NamingEnumeration returned an unexpected type", 
				        result instanceof Binding);
			
			Binding bindingOne = (Binding)result;
			assertEquals("Incorrect Binding type", 
					      Closeable.class.getName(), 
					      bindingOne.getClassName());
			assertTrue("Binding's service ID was not expected",
					    setOfIds.contains(bindingOne.getName()));
			assertNotNull("Binding's service object was not included", 
					       bindingOne.getObject());
			assertTrue("Binding's service object was not the correct type",
					    bindingOne.getObject() instanceof Closeable);
			
			
			assertTrue("NamingEnumeration should contain one more element", 
				     namingEnum.hasMoreElements());
			
			Binding bindingTwo = (Binding)namingEnum.next();
			assertEquals("NameClassPair did not contain the expected type", 
					     Closeable.class.getName(),
					     bindingTwo.getClassName());
			assertTrue("NameClassPair did not contain an expected ID", 
				        setOfIds.contains(bindingTwo.getName()));
			assertNotNull("Binding's service object was not included", 
				          bindingTwo.getObject());
			assertTrue("Binding's service object was not the correct type",
				        bindingTwo.getObject() instanceof Closeable);
			
			assertFalse("NamingEnumeration should not contain any more elements", 
				        namingEnum.hasMoreElements());
			
			
			
			NamingEnumeration namingEnumTwo = 
				serviceListContext.listBindings("");
			assertNotSame("ServiceList context should have returned a new enumeration",
					       namingEnum, namingEnumTwo);
			
			 assertTrue("NamingEnum should have contained elements", 
					    namingEnumTwo.hasMoreElements());
			 namingEnumTwo.close();
			 
			 try {
				 namingEnumTwo.next();
				 fail("NamingException should have been thrown");
			 } catch (NamingException e) {
				 // expected exception
			 }
			
			
			// verify exception handling
			try {
				namingEnum.nextElement();
				fail("NoSuchElementException should have been thrown");
			} catch (NoSuchElementException e) {
				// expected exception
			}
			
			// verify exception handling
			try {
				namingEnum.next();
				fail("NoSuchElementException should have been thrown");
			} catch (NoSuchElementException e) {
				// expected exception
			}
			
			// verify that only empty string context lists are supported
			try {
				serviceListContext.listBindings("someName");
				fail("OperationNotSupportedException should have been thrown");
			} catch (OperationNotSupportedException e) {
				// expected exception
			}
			
			namingEnum.close();

			assertEquals("namingEnum.close() call should have decreased the service count for this bundle",
				          originalNumOfServices, getContext().getBundle().getServicesInUse().length);
			
		} finally {
			getContext().ungetService(serviceReference);
		}
	}
	
	
	/**
	 * Verify that an OSGi service returned from a JNDI lookup is proxied
	 * according to the requirements of the OSGi Enterprise Spec, JNDI Services
	 * Chapter.  
	 */
	public void testOSGiServiceProxyWithInterface() throws Exception {
		// test setup
		Hello testService = new Hello() {
			public String sayHello(String name) {
				return "Hello " + name;
			}
		};
		
		registerService(Hello.class.getName(), testService, null);
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		try {
			Context initialContext = contextManager.newInitialContext();
			Hello helloService = 
				(Hello) initialContext.lookup("osgi:service/" + Hello.class.getName());
			assertNotNull("OSGi URL Context did not return the expected service value", helloService);
			assertEquals("OSGi URL Context did not return the correct service", 
					     "Hello Bob", helloService.sayHello("Bob"));
			
			// verify that service un-binds are handled correctly
			unregisterService(testService);
			
			try {
				helloService.sayHello("OSGi");
				fail("ServiceException should have been thrown");
			} catch(ServiceException serviceUnavailable) {
				// expected exception
				assertEquals("ServiceException was thrown with incorrect type code", 
						      ServiceException.UNREGISTERED, serviceUnavailable.getType());
			}
			
			// verify that service re-binds are handled correctly
			registerService(Hello.class.getName(), testService, null);
			
			assertEquals("OSGi URL Context did not return the correct service", 
				     "Hello Todd", helloService.sayHello("Todd"));
		} finally {
			getContext().ungetService(serviceReference);
		}
		
	}
	
	
	/**
	 * Verify that the Gemini Naming bundle properly handles the case of 
	 * a private interface being used as an OSGi service interface.  An exception
	 * should be thrown back to the JNDI client, indicating the error.  
	 */
	public void testOSGiServiceProxyWithPrivateInterface() throws Exception {
		// test setup
		Thanks testService = new Thanks() {
			public String sayThankYou(String name) {
				return "Thank You " + name;
			}
		};
		
		registerService(Thanks.class.getName(), testService, null);
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		try {
			Context initialContext = contextManager.newInitialContext();
			Thanks thanksService = 
				(Thanks) initialContext.lookup("osgi:service/" + Thanks.class.getName());
			assertNotNull("OSGi URL Context did not return the expected service value", thanksService);
			
			try {
				thanksService.sayThankYou("Connie");
				fail("ServiceException should have been thrown");
			}
			catch (ServiceException serviceException) {
				// expected exception
				assertTrue("ServiceException did not contain expected cause", 
						    serviceException.getCause() instanceof IllegalAccessException);
			}
		} finally {
			getContext().ungetService(serviceReference);
		}
	}
	
	/**
	 * Verify the behavior of service proxies that are returned 
	 * as part of a NamingEnumeration from a Context.listBindings() call on 
	 * a Context returned from an "osgi:servicelist/" lookup.  
	 */
	public void testServiceProxyWithListBindingsNamingEnumeration() throws Exception {


	/*******************************************************/
        /* Comment out this test. It seems to spuriously fail. */
	/*******************************************************/

/* 

		// test setup
		Hello testService = new Hello() {
			public String sayHello(String name) {
				return "Hello " + name;
			}
		};
		
		registerService(Hello.class.getName(), testService, null);
		// obtain JNDIContextManager service
		ServiceReference serviceReference = 
			getContext().getServiceReference("org.osgi.service.jndi.JNDIContextManager");
		JNDIContextManager contextManager = (JNDIContextManager)
		    getContext().getService(serviceReference);
		
		try {
			final int originalNumberOfServices = 
				getContext().getBundle().getServicesInUse().length;
			
			Context initialContext = contextManager.newInitialContext();
			Context serviceListContext = 
				(Context) initialContext.lookup("osgi:servicelist/" + Hello.class.getName());
			assertNotNull("JNDIContextManager did not return expected context", serviceListContext);
			
			NamingEnumeration namingEnumeration = 
				serviceListContext.listBindings("");
			
			Binding binding = (Binding)namingEnumeration.next();
			Hello serviceFromEnum = 
				(Hello)binding.getObject();
			
			assertNotNull("ServiceListContext did not return expected service in enum", 
					       serviceFromEnum);
			assertEquals("Returned service did not return correct result", 
					      "Hello Bob", serviceFromEnum.sayHello("Bob"));
			
			unregisterService(testService);
			// verify that proxy handles un-bind correctly
			try {
				serviceFromEnum.sayHello("Joe");
				fail("ServiceException should have been thrown");
			} catch (ServiceException serviceException) {
				// expected exception
				assertEquals("ServiceException was thrown with incorrect type code", 
						      ServiceException.UNREGISTERED, serviceException.getType());
			}
			
			registerService(Hello.class.getName(), testService, null);
			// verify that proxy does not attempt to rebind the service
			try {
				serviceFromEnum.sayHello("Cole");
				fail("ServiceException should have been thrown");
			} catch (ServiceException serviceException) {
				// expected exception
				assertEquals("ServiceException was thrown with incorrect type code", 
						      ServiceException.UNREGISTERED, serviceException.getType());
			}
			
			// clean up enumeration
			namingEnumeration.close();

			// verify service tracking
			assertEquals("JNDI Implementation did not correctly manage service references", 
					     originalNumberOfServices, getContext().getBundle().getServicesInUse().length);
		} finally {
			getContext().ungetService(serviceReference);
		}
*/
		
	}

    /* test classes */	
	private static final class ExpectedValueTestContext extends FactoryResolutionTestCase.TestContext {
		private final String expectedValue;
		private final String expectedName;

		private ExpectedValueTestContext(String expectedName, String expectedValue) {
			this.expectedName = expectedName;
			this.expectedValue = expectedValue;
		}

		public Object lookup(String name) throws NamingException {
			if(name.equals(expectedName)) {
				return expectedValue;
			}
			throw new NameNotFoundException("name not found - test error");
		}
	}

	private static final class NoOpCloseable implements Closeable {
		public void close() throws IOException {
			// no-op for testing
		}
	}

	private static class TestInitialDirContextFactory implements InitialContextFactory {

		public Context getInitialContext(Hashtable var0)
				throws NamingException {
			
			return (Context)Proxy.newProxyInstance(this.getClass().getClassLoader(), 
					                      new Class[] {DirContext.class}, 
					                      new TestInvocationHandler());
			
		}
		
		private static class TestInvocationHandler implements InvocationHandler {

			public Object invoke(Object var0, Method var1, Object[] var2)
					throws Throwable {
				return null;
			}
			
		}
			
	}
	
	public interface Hello {
		String sayHello(String name);
	}
	
	private interface Thanks {
		String sayThankYou(String name);
	}
	
}
