bug 414746: Introduce LdapContextWrapperImpl which will be used when LdapContext is requested.
diff --git a/framework/META-INF/MANIFEST.MF b/framework/META-INF/MANIFEST.MF
index ccbca98..5f21a46 100644
--- a/framework/META-INF/MANIFEST.MF
+++ b/framework/META-INF/MANIFEST.MF
@@ -12,6 +12,7 @@
 Import-Package: javax.naming,
  javax.naming.directory,
  javax.naming.spi,
+ javax.naming.ldap,
  org.osgi.framework,
  org.osgi.service.jndi,
  org.osgi.util.tracker
diff --git a/framework/src/main/java/org/eclipse/gemini/naming/BuilderUtils.java b/framework/src/main/java/org/eclipse/gemini/naming/BuilderUtils.java
index b530d81..3808dbf 100644
--- a/framework/src/main/java/org/eclipse/gemini/naming/BuilderUtils.java
+++ b/framework/src/main/java/org/eclipse/gemini/naming/BuilderUtils.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2010 Oracle.

+ * Copyright (c) 2010, 2013 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. 

diff --git a/framework/src/main/java/org/eclipse/gemini/naming/InitialContextFactoryWrapper.java b/framework/src/main/java/org/eclipse/gemini/naming/InitialContextFactoryWrapper.java
index 4ea2a29..f14b62f 100644
--- a/framework/src/main/java/org/eclipse/gemini/naming/InitialContextFactoryWrapper.java
+++ b/framework/src/main/java/org/eclipse/gemini/naming/InitialContextFactoryWrapper.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2010 Oracle.

+ * Copyright (c) 2010, 2013 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. 

@@ -18,6 +18,7 @@
 import javax.naming.Context;

 import javax.naming.NamingException;

 import javax.naming.directory.DirContext;

+import javax.naming.ldap.LdapContext;

 import javax.naming.spi.InitialContextFactory;

 import java.util.Hashtable;

 

@@ -39,7 +40,11 @@
 		final Context contextToReturn = 

 			m_initialContextFactory.getInitialContext(environment);

 

-		if(contextToReturn instanceof DirContext) {

+		if (contextToReturn instanceof LdapContext) {

+			final LdapContextWrapperImpl ldapContextWrapper = new LdapContextWrapperImpl((LdapContext)contextToReturn, m_factoryManager);

+			setupFactoryAssociation(ldapContextWrapper);

+			return ServiceAwareContextFactory.createServiceAwareLdapContextWrapper(m_initialContextFactory, ldapContextWrapper, m_factoryManager);

+		} else if(contextToReturn instanceof DirContext) {

 			final DirContextWrapperImpl dirContextWrapper = new DirContextWrapperImpl((DirContext)contextToReturn, m_factoryManager);

 			setupFactoryAssociation(dirContextWrapper);

 			return ServiceAwareContextFactory.createServiceAwareDirContextWrapper(m_initialContextFactory, dirContextWrapper, m_factoryManager);

diff --git a/framework/src/main/java/org/eclipse/gemini/naming/LdapContextWrapperImpl.java b/framework/src/main/java/org/eclipse/gemini/naming/LdapContextWrapperImpl.java
new file mode 100755
index 0000000..5581df9
--- /dev/null
+++ b/framework/src/main/java/org/eclipse/gemini/naming/LdapContextWrapperImpl.java
@@ -0,0 +1,63 @@
+/*******************************************************************************

+ * Copyright (c) 2013 SAP AG.

+ * 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:

+ *     Violeta Georgieva (SAP AG) - Initial Contribution

+ ******************************************************************************/

+package org.eclipse.gemini.naming;

+

+import javax.naming.NamingException;

+import javax.naming.ldap.Control;

+import javax.naming.ldap.ExtendedRequest;

+import javax.naming.ldap.ExtendedResponse;

+import javax.naming.ldap.LdapContext;

+

+public class LdapContextWrapperImpl extends DirContextWrapperImpl implements LdapContext {

+

+	private final LdapContext m_ldapContext;

+

+	LdapContextWrapperImpl(LdapContext ldapContext, FactoryManager factoryManager) {

+		super(ldapContext, factoryManager);

+		m_ldapContext = ldapContext;

+	}

+

+	public ExtendedResponse extendedOperation(ExtendedRequest request)

+			throws NamingException {

+		return m_ldapContext.extendedOperation(request);

+	}

+

+	public LdapContext newInstance(Control[] requestControls)

+			throws NamingException {

+		return m_ldapContext.newInstance(requestControls);

+	}

+

+	public void reconnect(Control[] connCtls) throws NamingException {

+		m_ldapContext.reconnect(connCtls);

+	}

+

+	public Control[] getConnectControls() throws NamingException {

+		return m_ldapContext.getConnectControls();

+	}

+

+	public void setRequestControls(Control[] requestControls)

+			throws NamingException {

+		m_ldapContext.setRequestControls(requestControls);

+	}

+

+	public Control[] getRequestControls() throws NamingException {

+		return m_ldapContext.getRequestControls();

+	}

+

+	public Control[] getResponseControls() throws NamingException {

+		return m_ldapContext.getResponseControls();

+	}

+

+}

diff --git a/framework/src/main/java/org/eclipse/gemini/naming/ServiceAwareContextFactory.java b/framework/src/main/java/org/eclipse/gemini/naming/ServiceAwareContextFactory.java
index 0a5624e..a911351 100644
--- a/framework/src/main/java/org/eclipse/gemini/naming/ServiceAwareContextFactory.java
+++ b/framework/src/main/java/org/eclipse/gemini/naming/ServiceAwareContextFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2010 Oracle.

+ * Copyright (c) 2010, 2013 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. 

@@ -27,6 +27,7 @@
 import javax.naming.NamingException;

 import javax.naming.NoInitialContextException;

 import javax.naming.directory.DirContext;

+import javax.naming.ldap.LdapContext;

 import javax.naming.spi.InitialContextFactory;

 

 class ServiceAwareContextFactory {

@@ -44,8 +45,14 @@
 	

 	static DirContext createServiceAwareDirContextWrapper(InitialContextFactory factory, DirContext internalContext, FactoryManager manager) {

 		return (DirContext) Proxy.newProxyInstance(ServiceAwareContextFactory.class.getClassLoader(),

-												   new Class[] {DirContext.class}, 

-												   new DefaultServiceAwareInvocationHandler(factory, internalContext, manager));

+												new Class[] {DirContext.class},

+												new DefaultServiceAwareInvocationHandler(factory, internalContext, manager));

+	}

+

+	static LdapContext createServiceAwareLdapContextWrapper(InitialContextFactory factory, LdapContext internalContext, FactoryManager manager) {

+		return (LdapContext) Proxy.newProxyInstance(ServiceAwareContextFactory.class.getClassLoader(),

+												new Class[] {LdapContext.class},

+												new DefaultServiceAwareInvocationHandler(factory, internalContext, manager));

 	}

 

 	private static class DefaultServiceAwareInvocationHandler implements InvocationHandler {

diff --git a/framework/src/main/java/org/eclipse/gemini/naming/TraditionalInitialContextFactoryBuilder.java b/framework/src/main/java/org/eclipse/gemini/naming/TraditionalInitialContextFactoryBuilder.java
index 29bbe67..a14932a 100644
--- a/framework/src/main/java/org/eclipse/gemini/naming/TraditionalInitialContextFactoryBuilder.java
+++ b/framework/src/main/java/org/eclipse/gemini/naming/TraditionalInitialContextFactoryBuilder.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2010 Oracle.

+ * Copyright (c) 2010, 2013 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. 

@@ -26,6 +26,7 @@
 import javax.naming.NoInitialContextException;

 import javax.naming.directory.DirContext;

 import javax.naming.directory.InitialDirContext;

+import javax.naming.ldap.LdapContext;

 import javax.naming.spi.InitialContextFactory;

 import javax.naming.spi.InitialContextFactoryBuilder;

 

@@ -98,7 +99,9 @@
 							final TraditionalContextInvocationHandler handler = 

 								new TraditionalContextInvocationHandler(serviceRef, newInitialContext, clientBundleContext);

 							// create the correct proxy

-							if(newInitialContext instanceof DirContext) {

+							if (newInitialContext instanceof LdapContext) {

+								return (LdapContext)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {LdapContext.class}, handler);

+							} else if(newInitialContext instanceof DirContext) {

 								return (DirContext)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {DirContext.class}, handler);

 							} else {

 								return (Context)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {Context.class}, handler);

diff --git a/integration-testing/src/test/java/org/eclipse/gemini/naming/test/FactoryResolutionTestCase.java b/integration-testing/src/test/java/org/eclipse/gemini/naming/test/FactoryResolutionTestCase.java
index 15ef4e9..bea202d 100644
--- a/integration-testing/src/test/java/org/eclipse/gemini/naming/test/FactoryResolutionTestCase.java
+++ b/integration-testing/src/test/java/org/eclipse/gemini/naming/test/FactoryResolutionTestCase.java
@@ -43,16 +43,26 @@
 import javax.naming.NamingEnumeration;

 import javax.naming.NamingException;

 import javax.naming.NoInitialContextException;

+import javax.naming.NotContextException;

 import javax.naming.Reference;

 import javax.naming.Referenceable;

 import javax.naming.StringRefAddr;

+import javax.naming.directory.Attributes;

 import javax.naming.directory.DirContext;

 import javax.naming.directory.InitialDirContext;

+import javax.naming.directory.ModificationItem;

+import javax.naming.directory.SearchControls;

+import javax.naming.directory.SearchResult;

 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 javax.naming.ldap.Control;

+import javax.naming.ldap.ExtendedRequest;

+import javax.naming.ldap.ExtendedResponse;

+import javax.naming.ldap.InitialLdapContext;

+import javax.naming.ldap.LdapContext;

 

 import org.osgi.framework.*;

 

@@ -433,11 +443,46 @@
 				fail("NoInitialContextException should not happen.");

 			}

 		} finally {

-			context.close();

+			if (context != null) {

+				context.close();

+			}

 			Thread.currentThread().setContextClassLoader(oldClassLoader);

 		}

 	}

 

+	/**

+	 * Verifies access to the LDAP context factory provided by the

+	 * JDK.  This test does not verify any LDAP connectivity, it merely

+	 * ensures that the JDK-provided implementation is available in an OSGi

+	 * environment.

+	 *

+	 * @throws Exception

+	 */

+	public void testAccessToJDK_InitialLDAPContext() throws Exception {

+		InitialContextFactory initialContextFactory = new TestContextFactory(new TestLdapContext());

+		String[] interfaceNames = { InitialContextFactory.class.getName(), TestContextFactory.class.getName() };

+

+		// register context factory

+		ServiceRegistration serviceRegistration =

+			bundleContext.registerService(interfaceNames, initialContextFactory, null);

+

+		Hashtable environment = new Hashtable();

+		environment.put(Context.INITIAL_CONTEXT_FACTORY,

+				        "org.eclipse.gemini.naming.test.FactoryResolutionTestCase$TestContextFactory");

+		InitialLdapContext ldapContext = null;

+		try {

+			ldapContext = new InitialLdapContext(environment, new Control[0]);

+			ldapContext.getRequestControls();

+		} catch (NotContextException e) {

+			fail("NotContextException should not happen.");

+		} finally {

+			if (ldapContext != null) {

+				ldapContext.close();

+			}

+			serviceRegistration.unregister();

+		}

+	}

+

 	// Stub implementations of JNDI factories used for simpler unit testing

 	static class TestContextFactoryBuilder implements InitialContextFactoryBuilder {

 		private final Context m_context;

@@ -692,6 +737,158 @@
 		}

 			

 	}

-	

-	

+

+	private static class TestLdapContext extends TestContext implements LdapContext {

+

+		public Attributes getAttributes(Name name) throws NamingException {

+			return null;

+		}

+

+		public Attributes getAttributes(String name) throws NamingException {

+			return null;

+		}

+

+		public Attributes getAttributes(Name name, String[] attrIds)

+				throws NamingException {

+			return null;

+		}

+

+		public Attributes getAttributes(String name, String[] attrIds)

+				throws NamingException {

+			return null;

+		}

+

+		public void modifyAttributes(Name name, int mod_op, Attributes attrs)

+				throws NamingException {

+		}

+

+		public void modifyAttributes(String name, int mod_op, Attributes attrs)

+				throws NamingException {

+		}

+

+		public void modifyAttributes(Name name, ModificationItem[] mods)

+				throws NamingException {

+		}

+

+		public void modifyAttributes(String name, ModificationItem[] mods)

+				throws NamingException {

+		}

+

+		public void bind(Name name, Object obj, Attributes attrs)

+				throws NamingException {

+		}

+

+		public void bind(String name, Object obj, Attributes attrs)

+				throws NamingException {

+		}

+

+		public void rebind(Name name, Object obj, Attributes attrs)

+				throws NamingException {

+		}

+

+		public void rebind(String name, Object obj, Attributes attrs)

+				throws NamingException {

+		}

+

+		public DirContext createSubcontext(Name name, Attributes attrs)

+				throws NamingException {

+			return null;

+		}

+

+		public DirContext createSubcontext(String name, Attributes attrs)

+				throws NamingException {

+			return null;

+		}

+

+		public DirContext getSchema(Name name) throws NamingException {

+			return null;

+		}

+

+		public DirContext getSchema(String name) throws NamingException {

+			return null;

+		}

+

+		public DirContext getSchemaClassDefinition(Name name)

+				throws NamingException {

+			return null;

+		}

+

+		public DirContext getSchemaClassDefinition(String name)

+				throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(Name name,

+				Attributes matchingAttributes, String[] attributesToReturn)

+				throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(String name,

+				Attributes matchingAttributes, String[] attributesToReturn)

+				throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(Name name,

+				Attributes matchingAttributes) throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(String name,

+				Attributes matchingAttributes) throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(Name name, String filter,

+				SearchControls cons) throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(String name,

+				String filter, SearchControls cons) throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(Name name,

+				String filterExpr, Object[] filterArgs, SearchControls cons)

+				throws NamingException {

+			return null;

+		}

+

+		public NamingEnumeration<SearchResult> search(String name,

+				String filterExpr, Object[] filterArgs, SearchControls cons)

+				throws NamingException {

+			return null;

+		}

+

+		public ExtendedResponse extendedOperation(ExtendedRequest request)

+				throws NamingException {

+			return null;

+		}

+

+		public LdapContext newInstance(Control[] requestControls)

+				throws NamingException {

+			return null;

+		}

+

+		public void reconnect(Control[] connCtls) throws NamingException {

+		}

+

+		public Control[] getConnectControls() throws NamingException {

+			return null;

+		}

+

+		public void setRequestControls(Control[] requestControls)

+				throws NamingException {

+		}

+

+		public Control[] getRequestControls() throws NamingException {

+			return null;

+		}

+

+		public Control[] getResponseControls() throws NamingException {

+			return null;

+		}

+	}

 }

diff --git a/org.eclipse.gemini.naming.utests/src/test/java/org/eclipse/gemini/naming/LdapContextWrapperImplTestCase.java b/org.eclipse.gemini.naming.utests/src/test/java/org/eclipse/gemini/naming/LdapContextWrapperImplTestCase.java
new file mode 100755
index 0000000..fd45ed8
--- /dev/null
+++ b/org.eclipse.gemini.naming.utests/src/test/java/org/eclipse/gemini/naming/LdapContextWrapperImplTestCase.java
@@ -0,0 +1,99 @@
+/*******************************************************************************

+ * Copyright (c) 2013 SAP AG.

+ * 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:

+ *     Violeta Georgieva (SAP AG) - Initial Contribution

+ ******************************************************************************/

+package org.eclipse.gemini.naming;

+

+import javax.naming.ldap.Control;

+import javax.naming.ldap.ExtendedRequest;

+import javax.naming.ldap.ExtendedResponse;

+import javax.naming.ldap.LdapContext;

+

+import org.easymock.EasyMockSupport;

+

+import junit.framework.TestCase;

+

+import static org.easymock.EasyMock.*;

+

+public class LdapContextWrapperImplTestCase extends TestCase {

+

+	public void testCreate() throws Exception {

+		// setup mocks

+		EasyMockSupport mockSupport = new EasyMockSupport();

+		LdapContext ldapContextMock =

+			mockSupport.createMock(LdapContext.class);

+		FactoryManager factoryManagerMock =

+			mockSupport.createMock(FactoryManager.class);

+

+		mockSupport.replayAll();

+		// begin test

+		new LdapContextWrapperImpl(ldapContextMock, factoryManagerMock);

+

+		mockSupport.verifyAll();

+	}

+

+

+	/**

+	 * This test verifies that all of the methods on the wrapper for the LdapContext interface

+	 * will delegate to the internal LdapContext implementation.  The test also verifies that the

+	 * parameters passed into the wrapper are passed unchanged to the internal

+	 * implementation.

+	 *

+	 */

+	public void testDelegatedMethods() throws Exception {

+		// mock setup

+		EasyMockSupport mockSupport = new EasyMockSupport();

+		LdapContext ldapContextMock =

+			mockSupport.createMock(LdapContext.class);

+		LdapContext subContextMock =

+			mockSupport.createMock(LdapContext.class);

+		FactoryManager factoryManagerMock =

+			mockSupport.createMock(FactoryManager.class);

+		ExtendedResponse extendedResponseMock =

+			mockSupport.createMock(ExtendedResponse.class);

+		ExtendedRequest extendedRequestMock =

+			mockSupport.createMock(ExtendedRequest.class);

+		Control[] controls = new Control[0];

+		//setup of expected method calls on internal LdapContext

+		expect(ldapContextMock.extendedOperation(extendedRequestMock)).andReturn(extendedResponseMock);

+		expect(ldapContextMock.newInstance(controls)).andReturn(subContextMock);

+		ldapContextMock.reconnect(controls);

+		expect(ldapContextMock.getConnectControls()).andReturn(controls);

+		ldapContextMock.setRequestControls(controls);

+		expect(ldapContextMock.getRequestControls()).andReturn(controls);

+		expect(ldapContextMock.getResponseControls()).andReturn(controls);

+

+

+		mockSupport.replayAll();

+

+		// begin test

+		LdapContext testDirContext =

+			new LdapContextWrapperImpl(ldapContextMock, factoryManagerMock);

+

+		assertSame("LdapContextWrapperImpl did not return expected ExtendedResponse",

+				extendedResponseMock, testDirContext.extendedOperation(extendedRequestMock));

+		assertSame("LdapContextWrapperImpl did not return expected subContext",

+				subContextMock, testDirContext.newInstance(controls));

+		testDirContext.reconnect(controls);

+		assertSame("LdapContextWrapperImpl did not return expected controls",

+				controls, testDirContext.getConnectControls());

+		testDirContext.setRequestControls(controls);

+		assertSame("LdapContextWrapperImpl did not return expected controls",

+				controls, testDirContext.getRequestControls());

+		assertSame("LdapContextWrapperImpl did not return expected controls",

+				controls, testDirContext.getResponseControls());

+

+		mockSupport.verifyAll();

+	}

+

+}