/*******************************************************************************
 * Copyright (c) 2011, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Raymond Augé - bug fixes and enhancements
 *     Juan Gonzalez <juan.gonzalez@liferay.com> - Bug 486412
 *     Peter Nehrer <pnehrer@eclipticalsoftware.com> - Bug 515912
 *******************************************************************************/
package org.eclipse.equinox.http.servlet.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestListener;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
import javax.servlet.http.Part;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
import org.eclipse.equinox.http.servlet.RangeAwareServletContextHelper;
import org.eclipse.equinox.http.servlet.context.ContextPathCustomizer;
import org.eclipse.equinox.http.servlet.session.HttpSessionInvalidator;
import org.eclipse.equinox.http.servlet.testbase.BaseTest;
import org.eclipse.equinox.http.servlet.tests.util.AsyncOutputServlet;
import org.eclipse.equinox.http.servlet.tests.util.BaseAsyncServlet;
import org.eclipse.equinox.http.servlet.tests.util.BaseChangeSessionIdServlet;
import org.eclipse.equinox.http.servlet.tests.util.BaseHttpContext;
import org.eclipse.equinox.http.servlet.tests.util.BaseHttpSessionAttributeListener;
import org.eclipse.equinox.http.servlet.tests.util.BaseHttpSessionIdListener;
import org.eclipse.equinox.http.servlet.tests.util.BaseServlet;
import org.eclipse.equinox.http.servlet.tests.util.BaseServletContextAttributeListener;
import org.eclipse.equinox.http.servlet.tests.util.BaseServletContextListener;
import org.eclipse.equinox.http.servlet.tests.util.BaseServletRequestAttributeListener;
import org.eclipse.equinox.http.servlet.tests.util.BaseServletRequestListener;
import org.eclipse.equinox.http.servlet.tests.util.BufferedServlet;
import org.eclipse.equinox.http.servlet.tests.util.TestServletPrototype;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.service.FindHook;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.service.http.context.ServletContextHelper;
import org.osgi.service.http.runtime.HttpServiceRuntime;
import org.osgi.service.http.runtime.dto.ResourceDTO;
import org.osgi.service.http.runtime.dto.RuntimeDTO;
import org.osgi.service.http.runtime.dto.ServletContextDTO;
import org.osgi.service.http.runtime.dto.ServletDTO;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
import org.osgi.util.tracker.ServiceTracker;

public class ServletTest extends BaseTest {
	@Rule
	public TestName testName = new TestName();

	@Override
	protected void startBundles() throws BundleException {
		for (String bundle : BUNDLES) {
			advisor.startBundle(bundle);
		}
	}

	@Override
	protected void stopBundles() throws BundleException {
		for (int i = BUNDLES.length - 1; i >= 0; i--) {
			String bundle = BUNDLES[i];
			advisor.stopBundle(bundle);
		}
	}

	@Test
	public void test_ErrorPage1() throws Exception {
		String expected = "403 ERROR :";
		String actual = null;
		Map<String, List<String>> response = Collections.emptyMap();
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			response = requestAdvisor.request("TestErrorPage1/a", null);
		}
		finally {
			uninstallBundle(bundle);
		}
		String responseCode = response.get("responseCode").get(0);
		actual = response.get("responseBody").get(0);

		Assert.assertEquals("403", responseCode);
		Assert.assertTrue(
			"Expected <" + expected + "*> but got <" + actual + ">", actual.startsWith(expected));
	}

	@Test
	public void test_ErrorPage2() throws Exception {
		String expected = "org.eclipse.equinox.http.servlet.tests.tb1.TestErrorPage2$MyException ERROR :";
		String actual = null;
		Map<String, List<String>> response = Collections.emptyMap();
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			response = requestAdvisor.request("TestErrorPage2/a", null);
		}
		finally {
			uninstallBundle(bundle);
		}
		String responseCode = response.get("responseCode").get(0);
		actual = response.get("responseBody").get(0);

		Assert.assertEquals("500", responseCode);
		Assert.assertTrue(
			"Expected <" + expected + "*> but got <" + actual + ">", actual.startsWith(expected));
	}

	@Test
	public void test_ErrorPage3() throws Exception {
		String expected = "400 ERROR :";
		String actual = null;
		Map<String, List<String>> response = Collections.emptyMap();
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			response = requestAdvisor.request("TestErrorPage3/a", null);
		}
		finally {
			uninstallBundle(bundle);
		}
		String responseCode = response.get("responseCode").get(0);
		actual = response.get("responseBody").get(0);

		Assert.assertEquals("400", responseCode);
		Assert.assertTrue(
			"Expected <" + expected + "*> but got <" + actual + ">", actual.startsWith(expected));
	}

	/**
	 * This case should NOT hit the error servlet because the response is already
	 * committed. However, setting the response code is perfectly allowed.
	 */
	@Test
	public void test_ErrorPage4() throws Exception {
		String actual = null;
		Map<String, List<String>> response = Collections.emptyMap();
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			response = requestAdvisor.request("TestErrorPage4/a", null);
		}
		finally {
			uninstallBundle(bundle);
		}
		String responseCode = response.get("responseCode").get(0);
		actual = response.get("responseBody").get(0);

		Assert.assertEquals("401", responseCode);
		Assert.assertEquals("", actual);
	}

	@Test
	public void test_ErrorPage5() throws Exception {
		BundleContext bundleContext = getBundleContext();
		Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
		serviceProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/prototype/*");
		TestServletPrototype testDriver = new TestServletPrototype(bundleContext);
		registrations.add(bundleContext.registerService(Servlet.class, testDriver, serviceProps));

		Dictionary<String, Object> errorProps = new Hashtable<String, Object>();
		errorProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E5.4xx");
		errorProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, "4xx");
		registrations.add(getBundleContext().registerService(Servlet.class, new ErrorServlet("4xx"), errorProps));
		errorProps = new Hashtable<String, Object>();
		errorProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E5.5xx");
		errorProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, "5xx");
		registrations.add(getBundleContext().registerService(Servlet.class, new ErrorServlet("5xx"), errorProps));
		for(String expectedCode: Arrays.asList("400", "450", "499", "500", "550", "599")) {
			Map<String, List<String>> response = doRequestGetResponse(ERROR, Collections.singletonMap(TEST_ERROR_CODE, expectedCode));
			String expectedResponse = expectedCode.charAt(0) + "xx : " + expectedCode + " : ERROR";
			String actualCode = response.get("responseCode").get(0);
			String actualResponse = response.get("responseBody").get(0);

			Assert.assertEquals(expectedCode, actualCode);
			Assert.assertTrue(
				"Expected <" + expectedResponse + "*> but got <" + actualResponse + ">", actualResponse.startsWith(expectedResponse));
		}
	}

	/**
	 * This test should also not hit the error servlet as we've only set the
	 * status. As per the Servlet spec this should not trigger error handling.
	 */
	@Test
	public void test_ErrorPage6() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(
				HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				response.getWriter().write("Hello!");
				response.setStatus(444);
			}

		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E6");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/TestErrorPage6/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));
		props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E6.error");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, "444");
		registrations.add(getBundleContext().registerService(Servlet.class, new ErrorServlet("444"), props));

		Map<String, List<String>> response = requestAdvisor.request("TestErrorPage6/a", null);

		String responseCode = response.get("responseCode").get(0);
		String responseBody = response.get("responseBody").get(0);

		Assert.assertEquals("444", responseCode);
		Assert.assertNotEquals("444 : 444 : ERROR : /TestErrorPage6/a", responseBody);
	}

	/**
	 * This test should also not hit the error servlet as we've only set the
	 * status. As per the Servlet spec this should not trigger error handling.
	 */
	@Test
	public void test_ErrorPage7() throws Exception {
		final int status = 422;

		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				resp.setStatus(status);

				PrintWriter printWriter = new PrintWriter(
					resp.getOutputStream());

				printWriter.println("{");
				printWriter.println("error: 'An error message',");
				printWriter.println("code: 'An error code'");
				printWriter.println("}");

				printWriter.flush();
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E7");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/TestErrorPage7/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));
		props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E7.error");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, String.valueOf(status));
		registrations.add(getBundleContext().registerService(Servlet.class, new ErrorServlet(String.valueOf(status)), props));

		Map<String, List<String>> response = requestAdvisor.request("TestErrorPage7/a", null);

		String responseCode = response.get("responseCode").get(0);
		String responseBody = response.get("responseBody").get(0);

		Assert.assertEquals(String.valueOf(status), responseCode);
		Assert.assertNotEquals(status + " : " + status + " : ERROR : /TestErrorPage7/a", responseBody);
	}

	@Test
	public void test_ErrorPage8() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				throw new RuntimeException();
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E8");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/TestErrorPage8/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));
		props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E8.error");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, RuntimeException.class.getName());
		registrations.add(getBundleContext().registerService(Servlet.class, new ErrorServlet("500"), props));

		Map<String, List<String>> response = requestAdvisor.request("TestErrorPage8/a", null);

		String responseCode = response.get("responseCode").get(0);
		String responseBody = response.get("responseBody").get(0);

		Assert.assertEquals("500", responseCode);
		Assert.assertEquals("500 : 500 : ERROR : /TestErrorPage8/a", responseBody);
	}

	@Test
	public void test_ErrorPage9() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				throw new IOException();
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E9");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/TestErrorPage9/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));
		props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E9.error");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, IOException.class.getName());
		registrations.add(getBundleContext().registerService(Servlet.class, new ErrorServlet("500"), props));

		Map<String, List<String>> response = requestAdvisor.request("TestErrorPage9/a", null);

		String responseCode = response.get("responseCode").get(0);
		String responseBody = response.get("responseBody").get(0);

		Assert.assertEquals("500", responseCode);
		Assert.assertEquals("500 : 500 : ERROR : /TestErrorPage9/a", responseBody);
	}

	@Test
	public void test_ErrorPage10() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				resp.getWriter().write("some output");
				resp.flushBuffer();

				throw new IOException();
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E10");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/TestErrorPage10/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		try {
			requestAdvisor.request("TestErrorPage10/a");
		}
		catch (Exception e) {
			Assert.assertTrue(e instanceof IOException);

			return;
		}

		Assert.fail("Expecting java.io.IOException: Premature EOF");
	}

	@Test
	public void test_ErrorPage11() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				resp.sendError(403);
				resp.getOutputStream().flush();
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "E10");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/TestErrorPage11/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		try {
			requestAdvisor.request("TestErrorPage11/a");
		} catch (IOException e) {
			// This is expected because of old behavior
			// TODO is this really the correct behavior though
		}
	}

	@Test
	public void test_Filter1() throws Exception {
		String expected = "bab";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter1/bab");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter2() throws Exception {
		String expected = "cbabc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter2/cbabc");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter3() throws Exception {
		String expected = "cbdadbc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter3/cbdadbc");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter4() throws Exception {
		String expected = "dcbabcd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter4/dcbabcd");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter5() throws Exception {
		String expected = "bab";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/bab.TestFilter5");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter6() throws Exception {
		String expected = "cbabc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/cbabc.TestFilter6");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter7() throws Exception {
		String expected = "cbdadbc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/cbdadbc.TestFilter7");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter8() throws Exception {
		String expected = "dcbabcd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/dcbabcd.TestFilter8");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter9() throws Exception {
		String expected = "bab";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter9/bab");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter10() throws Exception {
		String expected = "cbabc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter10/cbabc");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter11() throws Exception {
		String expected = "cbdadbc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter11/cbdadbc");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter12() throws Exception {
		String expected = "dcbabcd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter12/dcbabcd");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter13() throws Exception {
		String expected = "bab";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/a.TestFilter13");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter14() throws Exception {
		String expected = "cbabc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/a.TestFilter14");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter15() throws Exception {
		String expected = "cbdadbc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/a.TestFilter15");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter16() throws Exception {
		String expected = "dcbabcd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/a.TestFilter16");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter17() throws Exception {
		String expected = "ebcdadcbe";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter17/foo/bar/baz");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter18() throws Exception {
		String expected = "dbcacbd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter18/foo/bar/baz");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter19() throws Exception {
		String expected = "dfbcacbfd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestFilter18/foo/bar/baz/with/path/info");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Filter20() throws Exception {
		// Make sure legacy filter registrations match against all controllers that are for legacy HttpContext
		// Make sure legacy filter registrations match as if they are prefix matching with wildcards
		String expected = "a";
		TestFilter testFilter1 = new TestFilter();
		TestFilter testFilter2 = new TestFilter();
		Servlet testServlet = new BaseServlet(expected);
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		extendedHttpService.registerFilter("/hello", testFilter1, null, extendedHttpService.createDefaultHttpContext());
		extendedHttpService.registerFilter("/hello/*", testFilter2, null, extendedHttpService.createDefaultHttpContext());
		extendedHttpService.registerServlet("/hello", testServlet, null, extendedHttpService.createDefaultHttpContext());

		String actual = requestAdvisor.request("hello");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertTrue("testFilter2 did not get called.", testFilter2.getCalled());

		testFilter1.clear();
		testFilter2.clear();
		actual = requestAdvisor.request("hello/test");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertTrue("testFilter2 did not get called.", testFilter2.getCalled());
	}

	@Test
	public void test_Filter21() throws Exception {
		// Make sure exact path matching is honored by filters registrations
		String expected = "a";
		TestFilter testFilter1 = new TestFilter();
		TestFilter testFilter2 = new TestFilter();
		Servlet testServlet = new BaseServlet(expected);

		Dictionary<String, String> props = new Hashtable<String, String>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME, "F1");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/hello");
		registrations.add(getBundleContext().registerService(Filter.class, testFilter1, props));

		props = new Hashtable<String, String>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME, "F2");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/hello/*");
		registrations.add(getBundleContext().registerService(Filter.class, testFilter2, props));

		props = new Hashtable<String, String>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/hello/*");
		registrations.add(getBundleContext().registerService(Servlet.class, testServlet, props));

		String actual = requestAdvisor.request("hello");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertTrue("testFilter2 did not get called.", testFilter2.getCalled());

		testFilter1.clear();
		testFilter2.clear();
		actual = requestAdvisor.request("hello/test");
		Assert.assertEquals(expected, actual);
		Assert.assertFalse("testFilter1 got called.", testFilter1.getCalled());
		Assert.assertTrue("testFilter2 did not get called.", testFilter2.getCalled());
	}

	public void basicFilterTest22( String servlet1Pattern, String servlet2Pattern, String filterPattern, String expected, String[] dispatchers ) throws Exception {
		final AtomicReference<HttpServletRequestWrapper> httpServletRequestWrapper = new AtomicReference<HttpServletRequestWrapper>();
		final AtomicReference<HttpServletResponseWrapper> httpServletResponseWrapper = new AtomicReference<HttpServletResponseWrapper>();

		Servlet servlet1 = new BaseServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response)
					throws ServletException, IOException {
				request.getRequestDispatcher("index.jsp").forward(request, response);
			}
		};

		Servlet servlet2 = new BaseServlet("a") {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(
				HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				if ((httpServletRequestWrapper.get() != null) && !request.equals(httpServletRequestWrapper.get())) {
					throw new ServletException("not the same request");
				}
				if ((httpServletResponseWrapper.get() != null) && !response.equals(httpServletResponseWrapper.get())) {
					throw new ServletException("not the same response");
				}

				response.getWriter().print(content);
			}

		};

		Filter filter = new TestFilter() {

			@Override
			public void doFilter(
					ServletRequest request, ServletResponse response, FilterChain chain)
				throws IOException, ServletException {

				response.getWriter().write('b');

				httpServletRequestWrapper.set(new HttpServletRequestWrapper((HttpServletRequest) request));
				httpServletResponseWrapper.set(new HttpServletResponseWrapper((HttpServletResponse) response));

				chain.doFilter(httpServletRequestWrapper.get(), httpServletResponseWrapper.get());

				response.getWriter().write('b');
			}

		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, servlet1Pattern);
		registrations.add(getBundleContext().registerService(Servlet.class, servlet1, props));

		props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, servlet2Pattern);
		registrations.add(getBundleContext().registerService(Servlet.class, servlet2, props));

		props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME, "F22");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_DISPATCHER, dispatchers);
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, filterPattern);
		registrations.add(getBundleContext().registerService(Filter.class, filter, props));

		String response = requestAdvisor.request("f22/a");

		Assert.assertEquals(expected, response);
	}

	@Test
	public void test_Filter22a() throws Exception {
		basicFilterTest22 ( "/f22/*", "*.jsp", "/f22/*", "a", new String[] {"REQUEST"} );
	}

	@Test
	public void test_Filter22b() throws Exception {
		basicFilterTest22 ( "/*", "*.jsp", "/*", "a", new String[] {"REQUEST"} );
	}

	@Test
	public void test_Filter22c() throws Exception {
		basicFilterTest22 ( "/f22/*", "*.jsp", "*.jsp", "a", new String[] {"REQUEST"} );
	}

	@Test
	public void test_Filter22d() throws Exception {
		basicFilterTest22 ( "/f22/*", "*.jsp", "/f22/*", "bab", new String[] {"FORWARD"} );
	}

	@Test
	public void test_Filter22e() throws Exception {
		basicFilterTest22 ( "/*", "*.jsp", "/*", "bab", new String[] {"FORWARD"} );
	}

	@Test
	public void test_Filter22f() throws Exception {
		basicFilterTest22 ( "/f22/*", "*.jsp", "*.jsp", "bab", new String[] {"FORWARD"} );
	}

	@Test
	public void test_Filter22g() throws Exception {
		basicFilterTest22 ( "/f22/*", "*.jsp", "/f22/*", "bab", new String[] {"REQUEST", "FORWARD"} );
	}

	@Test
	public void test_Filter22h() throws Exception {
		basicFilterTest22 ( "/*", "*.jsp", "/*", "bab", new String[] {"REQUEST", "FORWARD"} );
	}

	@Test
	public void test_Filter22i() throws Exception {
		basicFilterTest22 ( "/f22/*", "*.jsp", "*.jsp", "bab", new String[] {"REQUEST", "FORWARD"} );
	}

	@Test
	public void test_Filter23a() throws Exception {
		// Make sure legacy filter registrations match as if they are prefix matching with extension matching
		String expected = "a";
		TestFilter testFilter1 = new TestFilter();
		TestFilter testFilter2 = new TestFilter();
		TestFilter testFilter3 = new TestFilter();
		Servlet testServlet = new BaseServlet(expected);
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		extendedHttpService.registerFilter("*.ext", testFilter1, null, extendedHttpService.createDefaultHttpContext());
		extendedHttpService.registerFilter("/hello/*.ext", testFilter2, null, extendedHttpService.createDefaultHttpContext());
		extendedHttpService.registerFilter("/hello/test/*.ext", testFilter3, null, extendedHttpService.createDefaultHttpContext());
		extendedHttpService.registerServlet("/hello", testServlet, null, extendedHttpService.createDefaultHttpContext());

		String actual = requestAdvisor.request("hello/test/request");
		Assert.assertEquals(expected, actual);
		Assert.assertFalse("testFilter1 did get called.", testFilter1.getCalled());
		Assert.assertFalse("testFilter2 did get called.", testFilter2.getCalled());
		Assert.assertFalse("testFilter3 did get called.", testFilter3.getCalled());

		testFilter1.clear();
		testFilter2.clear();
		testFilter3.clear();
		actual = requestAdvisor.request("hello/test/request.ext");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertTrue("testFilter2 did not get called.", testFilter2.getCalled());
		Assert.assertTrue("testFilter3 did not get called.", testFilter3.getCalled());
	}

	@Test
	public void test_Filter23b() throws Exception {
		// Make sure legacy filter registrations match as if they are prefix matching wildcard, but make sure the prefix is checked
		String expected = "a";
		TestFilter testFilter1 = new TestFilter();
		TestFilter testFilter2 = new TestFilter();
		Servlet testServlet = new BaseServlet(expected);
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		extendedHttpService.registerFilter("/", testFilter1, null, extendedHttpService.createDefaultHttpContext());
		extendedHttpService.registerFilter("/hello", testFilter2, null, extendedHttpService.createDefaultHttpContext());
		extendedHttpService.registerServlet("/", testServlet, null, extendedHttpService.createDefaultHttpContext());

		String actual = requestAdvisor.request("hello_test/request");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertFalse("testFilter2 did get called.", testFilter2.getCalled());

		actual = requestAdvisor.request("hello/request");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertTrue("testFilter2 did not get called.", testFilter2.getCalled());
	}

	@Test
	public void test_Filter23c() throws Exception {
		// Test WB servlet with default servlet pattern "/" and filter matching against it.
		String expected = "a";
		TestFilter testFilter1 = new TestFilter();
		TestFilter testFilter2 = new TestFilter();
		Servlet testServlet = new BaseServlet(expected);

		registrations.add(getBundleContext().registerService(Filter.class, testFilter1, new Hashtable<String, String>(Collections.singletonMap(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/*"))));
		registrations.add(getBundleContext().registerService(Filter.class, testFilter2, new Hashtable<String, String>(Collections.singletonMap(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/hello/*"))));
		registrations.add(getBundleContext().registerService(Servlet.class, testServlet, new Hashtable<String, String>(Collections.singletonMap(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/"))));

		String actual = requestAdvisor.request("hello_test/request");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertFalse("testFilter2 did get called.", testFilter2.getCalled());

		actual = requestAdvisor.request("hello/request");
		Assert.assertEquals(expected, actual);
		Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());
		Assert.assertTrue("testFilter2 did not get called.", testFilter2.getCalled());
	}

	@Test
	public void test_Filter24() throws Exception {
		// Test WB servlet and WB testfilter matching against it.
		// Test filter gets called.
		// Unregister WB filter.
		// test filter is NOT called
		String expected = "a";
		TestFilter testFilter1 = new TestFilter();
		Servlet testServlet = new BaseServlet(expected);

		ServiceRegistration<Filter> filterReg = getBundleContext().registerService(Filter.class, testFilter1, new Hashtable<String, String>(Collections.singletonMap(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/hello/*")));
		try {
			registrations.add(getBundleContext().registerService(Servlet.class, testServlet, new Hashtable<String, String>(Collections.singletonMap(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/hello/*"))));

			String actual = requestAdvisor.request("hello/request");
			Assert.assertEquals(expected, actual);
			Assert.assertTrue("testFilter1 did not get called.", testFilter1.getCalled());

			filterReg.unregister();
			filterReg = null;
			testFilter1.clear();

			actual = requestAdvisor.request("hello/request");
			Assert.assertEquals(expected, actual);
			Assert.assertFalse("testFilter1 did get called.", testFilter1.getCalled());
		} finally {
			if (filterReg != null) {
				filterReg.unregister();
			}
		}
	}

	@Test
	public void test_Registration1() throws Exception {
		String expected = "Alias cannot be null";
		try {
			ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

			extendedHttpService.registerServlet(
				null, new BaseServlet(), null, null);
		}
		catch(IllegalArgumentException iae) {
			Assert.assertEquals(expected, iae.getMessage());

			return;
		}

		Assert.fail();
	}

	@Test
	public void test_Registration2() throws Exception {
		String pattern = "blah";
		String expected = "Invalid pattern '" + pattern + "'";
		try {
			ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

			extendedHttpService.registerServlet(
				pattern, new BaseServlet(), null, null);
		}
		catch(IllegalArgumentException iae) {
			Assert.assertEquals(expected, iae.getMessage());

			return;
		}

		Assert.fail();
	}

	@Test
	public void test_Registration3() throws Exception {
		String pattern = "/blah/";
		String expected = "Invalid pattern '" + pattern + "'";
		try {
			ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

			extendedHttpService.registerServlet(
				pattern, new BaseServlet(), null, null);
		}
		catch(IllegalArgumentException iae) {
			Assert.assertEquals(expected, iae.getMessage());

			return;
		}

		Assert.fail();
	}

	@Test
	public void test_Registration4() throws Exception {
		String pattern = "/blah";
		String expected = "Pattern already in use: " + pattern;
		try {
			ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

			extendedHttpService.registerServlet(
				pattern, new BaseServlet(), null, null);
			extendedHttpService.registerServlet(
				pattern, new BaseServlet(), null, null);
		}
		catch(NamespaceException ne) {
			Assert.assertEquals(expected, ne.getMessage());

			return;
		}

		Assert.fail();
	}

	@Test
	public void test_Registration5() throws Exception {
		String alias = "/blah";
		String expected = "Servlet cannot be null";
		try {
			ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

			extendedHttpService.registerServlet(
				alias, null, null, null);
		}
		catch(IllegalArgumentException iae) {
			Assert.assertEquals(expected, iae.getMessage());

			return;
		}

		Assert.fail();
	}

	@Test
	public void test_Registration6() throws Exception {
		String expected = "Servlet has already been registered:";
		try {
			ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

			Servlet servlet = new BaseServlet();

			extendedHttpService.registerServlet("/blah1", servlet, null, null);
			extendedHttpService.registerServlet("/blah2", servlet, null, null);
		}
		catch(ServletException se) {
			Assert.assertTrue(se.getMessage().startsWith(expected));

			return;
		}

		Assert.fail();
	}

	@Test
	public void test_unregister() throws Exception {
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

		Servlet servlet = new BaseServlet();
		Filter filter = new TestFilter();

		extendedHttpService.registerServlet("/s1", servlet, null, null);
		extendedHttpService.registerFilter("/f1", filter, null, null);
		extendedHttpService.registerResources("/r1", "/resources", null);

		extendedHttpService.unregister("/s1");
		extendedHttpService.unregisterFilter(filter);
		extendedHttpService.unregister("/r1");
	}

	@Test
	public void test_Registration11() throws Exception {
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

		Servlet servlet = new BaseServlet();

		extendedHttpService.registerServlet("/blah1", servlet, null, null);

		BundleContext bundleContext = getBundleContext();

		ServiceReference<HttpServiceRuntime> serviceReference =
			bundleContext.getServiceReference(HttpServiceRuntime.class);
		HttpServiceRuntime runtime = bundleContext.getService(serviceReference);

		RuntimeDTO runtimeDTO = runtime.getRuntimeDTO();

		ServletContextDTO[] servletContextDTOs = runtimeDTO.servletContextDTOs;

		for (ServletContextDTO servletContextDTO : servletContextDTOs) {
			if (servletContextDTO.name.startsWith("org.eclipse.equinox.http.servlet.internal.HttpServiceImpl$")) {
				ServletDTO servletDTO = servletContextDTO.servletDTOs[0];

				Assert.assertFalse(servletDTO.asyncSupported);
				Assert.assertEquals(servlet.getClass().getName(), servletDTO.name);
				Assert.assertEquals("/blah1", servletDTO.patterns[0]);
				Assert.assertTrue(servletDTO.serviceId < 0);
			}
		}
	}

	@Test
	public void test_Registration12() throws Exception {
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			BundleContext bundleContext = getBundleContext();

			ServiceReference<HttpServiceRuntime> serviceReference =
				bundleContext.getServiceReference(HttpServiceRuntime.class);
			HttpServiceRuntime runtime = bundleContext.getService(serviceReference);

			RuntimeDTO runtimeDTO = runtime.getRuntimeDTO();

			ServletContextDTO[] servletContextDTOs = runtimeDTO.servletContextDTOs;

			ServletContextDTO servletContextDTO = servletContextDTOs[0];

			Assert.assertNotNull(servletContextDTO.name);
		}
		finally {
			uninstallBundle(bundle);
		}
	}

	@Test
	public void test_Registration13() throws Exception {
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

		extendedHttpService.registerResources("/blah1", "/foo", null);

		BundleContext bundleContext = getBundleContext();

		ServiceReference<HttpServiceRuntime> serviceReference =
			bundleContext.getServiceReference(HttpServiceRuntime.class);
		HttpServiceRuntime runtime = bundleContext.getService(serviceReference);

		RuntimeDTO runtimeDTO = runtime.getRuntimeDTO();

		ServletContextDTO[] servletContextDTOs = runtimeDTO.servletContextDTOs;

		for (ServletContextDTO servletContextDTO : servletContextDTOs) {
			if (servletContextDTO.name.startsWith("org.eclipse.equinox.http.servlet.internal.HttpServiceImpl$")) {
				ResourceDTO resourceDTO = servletContextDTO.resourceDTOs[0];

				Assert.assertEquals("/blah1/*", resourceDTO.patterns[0]);
				Assert.assertEquals("/foo", resourceDTO.prefix);
				Assert.assertTrue(resourceDTO.serviceId < 0);
			}
		}
	}

	@Test
	public void test_Registration14() throws Exception {
		Servlet initError = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			public void init(ServletConfig config) throws ServletException {
				throw new ServletException("Init error.");
			}

		};
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		try {
			extendedHttpService.registerServlet("/foo", initError, null, null);
			fail("Expected an init failure.");
		} catch (ServletException e) {
			//expected
			assertEquals("Wrong exception message.", "Init error.", e.getMessage());
		}
	}

	@Test
	public void test_Registration15() throws Exception {
		Servlet initError = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			public void init(ServletConfig config) throws ServletException {
				throw new IllegalStateException("Init error.");
			}

		};
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		try {
			extendedHttpService.registerServlet("/foo", initError, null, null);
			fail("Expected an init failure.");
		} catch (IllegalStateException e) {
			//expected
			assertEquals("Wrong exception message.", "Init error.", e.getMessage());
		}
	}

	@Test
	public void test_Registration16() throws Exception {
		Filter initError = new Filter() {

			@Override
			public void init(FilterConfig filterConfig) throws ServletException {
				throw new IllegalStateException("Init error.");
			}

			@Override
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
					ServletException {
				// nothing
			}

			@Override
			public void destroy() {
				// nothing
			}
		};
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		try {
			extendedHttpService.registerFilter("/foo", initError, null, null);
			fail("Expected an init failure.");
		} catch (IllegalStateException e) {
			//expected
			assertEquals("Wrong exception message.", "Init error.", e.getMessage());
		}
	}

	@Test
	public void test_Registration17() throws Exception {
		Filter initError = new Filter() {

			@Override
			public void init(FilterConfig filterConfig) throws ServletException {
				throw new ServletException("Init error.");
			}

			@Override
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
					ServletException {
				// nothing
			}

			@Override
			public void destroy() {
				// nothing
			}
		};
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		try {
			extendedHttpService.registerFilter("/foo", initError, null, null);
			fail("Expected an init failure.");
		} catch (ServletException e) {
			//expected
			assertEquals("Wrong exception message.", "Init error.", e.getMessage());
		}
	}

	@Test
	public void test_Registration18_WhiteboardServletByNameOnly() throws Exception {
		String expected = "a";
		final String servletName = "hello_servlet";
		Servlet namedServlet = new BaseServlet(expected);
		Servlet targetServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				request.getServletContext().getNamedDispatcher(servletName).forward(request, response);
			}

		};

		Hashtable<String, String> props = new Hashtable<String, String>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, servletName);
		registrations.add(getBundleContext().registerService(Servlet.class, namedServlet, props));

		props = new Hashtable<String, String>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
		registrations.add(getBundleContext().registerService(Servlet.class, targetServlet, props));

		String actual = requestAdvisor.request("s");
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_RegistrationTCCL1() {
		final Set<String> filterTCCL = Collections.synchronizedSet(new HashSet<String>());
		final Set<String> servletTCCL = Collections.synchronizedSet(new HashSet<String>());
		Filter tcclFilter = new Filter() {

			@Override
			public void init(FilterConfig filterConfig) throws ServletException {
				filterTCCL.add(Thread.currentThread().getContextClassLoader().getClass().getName());
			}

			@Override
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
					ServletException {
				filterTCCL.add(Thread.currentThread().getContextClassLoader().getClass().getName());
				chain.doFilter(request, response);
			}

			@Override
			public void destroy() {
				filterTCCL.add(Thread.currentThread().getContextClassLoader().getClass().getName());
			}
		};
		HttpServlet tcclServlet = new HttpServlet() {

			@Override
			public void destroy() {
				super.destroy();
				servletTCCL.add(Thread.currentThread().getContextClassLoader().getClass().getName());
			}

			@Override
			public void init(ServletConfig config) throws ServletException {
				super.init(config);
				servletTCCL.add(Thread.currentThread().getContextClassLoader().getClass().getName());
			}

			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
					IOException {
				servletTCCL.add(Thread.currentThread().getContextClassLoader().getClass().getName());
				response.getWriter().print(Thread.currentThread().getContextClassLoader().getClass().getName());
			}

		};

		ClassLoader originalTCCL = Thread.currentThread().getContextClassLoader();
		ClassLoader dummy = new ClassLoader() {
		};
		Thread.currentThread().setContextClassLoader(dummy);
		String expected = dummy.getClass().getName();
		String actual = null;
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();
		try {
			extendedHttpService.registerFilter("/tccl", tcclFilter, null, null);
			extendedHttpService.registerServlet("/tccl", tcclServlet, null, null);
			actual = requestAdvisor.request("tccl");
		} catch (Exception e) {
			fail("Unexpected exception: " + e);
		} finally {
			Thread.currentThread().setContextClassLoader(originalTCCL);
			try {
				extendedHttpService.unregister("/tccl");
				extendedHttpService.unregisterFilter(tcclFilter);
			} catch (IllegalArgumentException e) {
				// ignore
			}
		}
		assertEquals(expected, actual);
		assertEquals("Wrong filterTCCL size: " + filterTCCL, 1, filterTCCL.size());
		assertTrue("Wrong filterTCCL: " + filterTCCL, filterTCCL.contains(expected));
		assertEquals("Wrong httpTCCL size: " + servletTCCL, 1, servletTCCL.size());
		assertTrue("Wrong servletTCCL: " + servletTCCL, servletTCCL.contains(expected));

	}

	@Test
	public void test_Sessions01() {
		final AtomicBoolean valueBound = new AtomicBoolean(false);
		final AtomicBoolean valueUnbound = new AtomicBoolean(false);
		final HttpSessionBindingListener bindingListener = new HttpSessionBindingListener() {

			@Override
			public void valueUnbound(HttpSessionBindingEvent event) {
				valueUnbound.set(true);
			}

			@Override
			public void valueBound(HttpSessionBindingEvent event) {
				valueBound.set(true);
			}
		};
		final AtomicBoolean sessionCreated = new AtomicBoolean(false);
		final AtomicBoolean sessionDestroyed = new AtomicBoolean(false);
		HttpSessionListener sessionListener = new HttpSessionListener() {

			@Override
			public void sessionDestroyed(HttpSessionEvent se) {
				sessionDestroyed.set(true);
			}

			@Override
			public void sessionCreated(HttpSessionEvent se) {
				sessionCreated.set(true);
			}
		};
		HttpServlet sessionServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
					IOException {
				HttpSession session = request.getSession();
				if (session.getAttribute("test.attribute") == null) {
					session.setAttribute("test.attribute", bindingListener);
					response.getWriter().print("created");
				} else {
					session.invalidate();
					response.getWriter().print("invalidated");
				}
			}

		};
		ServiceRegistration<Servlet> servletReg = null;
		ServiceRegistration<HttpSessionListener> sessionListenerReg = null;
		Dictionary<String, Object> servletProps = new Hashtable<String, Object>();
		servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/sessions");
		String actual = null;
		CookieHandler previous = CookieHandler.getDefault();
		CookieHandler.setDefault(new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );
		try {
			servletReg = getBundleContext().registerService(Servlet.class, sessionServlet, servletProps);
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			sessionListenerReg = getBundleContext().registerService(HttpSessionListener.class, sessionListener, listenerProps);

			sessionCreated.set(false);
			valueBound.set(false);
			sessionDestroyed.set(false);
			valueUnbound.set(false);
			// first call will create the session
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "created", actual);
			assertTrue("No sessionCreated called", sessionCreated.get());
			assertTrue("No valueBound called", valueBound.get());
			assertFalse("sessionDestroyed was called", sessionDestroyed.get());
			assertFalse("valueUnbound was called", valueUnbound.get());

			sessionCreated.set(false);
			valueBound.set(false);
			sessionDestroyed.set(false);
			valueUnbound.set(false);
			// second call will invalidate the session
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "invalidated", actual);
			assertFalse("sessionCreated was called", sessionCreated.get());
			assertFalse("valueBound was called", valueBound.get());
			assertTrue("No sessionDestroyed called", sessionDestroyed.get());
			assertTrue("No valueUnbound called", valueUnbound.get());

			sessionCreated.set(false);
			sessionDestroyed.set(false);
			valueBound.set(false);
			valueUnbound.set(false);
			// calling again should create the session again
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "created", actual);
			assertTrue("No sessionCreated called", sessionCreated.get());
			assertTrue("No valueBound called", valueBound.get());
		} catch (Exception e) {
			fail("Unexpected exception: " + e);
		} finally {
			if (servletReg != null) {
				servletReg.unregister();
			}
			if (sessionListenerReg != null) {
				sessionListenerReg.unregister();
			}
			CookieHandler.setDefault(previous);
		}
	}

	@Test
	public void test_Sessions02() {
		final AtomicReference<HttpSession> sessionReference = new AtomicReference<HttpSession>();

		HttpServlet sessionServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
					IOException {
				HttpSession session = request.getSession();
				sessionReference.set(session);
				if (session.getAttribute("test.attribute") == null) {
					session.setAttribute("test.attribute", "foo");
					response.getWriter().print("created");
				} else {
					session.setAttribute("test.attribute", null);
					response.getWriter().print("attribute set to null");
				}
			}
		};
		ServiceRegistration<Servlet> servletReg = null;
		Dictionary<String, Object> servletProps = new Hashtable<String, Object>();
		servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/sessions");
		String actual = null;
		CookieHandler previous = CookieHandler.getDefault();
		CookieHandler.setDefault(new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );
		try {
			servletReg = getBundleContext().registerService(Servlet.class, sessionServlet, servletProps);

			// first call will create the session
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "created", actual);

			// second call will set parameter to null
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "attribute set to null", actual);

			HttpSession httpSession = sessionReference.get();

			Enumeration<String> names = httpSession.getAttributeNames();

			boolean exist = false;

			while (names.hasMoreElements()) {
				String name = names.nextElement();
				if (name.equals("test.attribute")) {
					exist = true;
				}
			}

			assertFalse("Session atribute was not removed", exist);
		} catch (Exception e) {
			fail("Unexpected exception: " + e);
		} finally {
			if (servletReg != null) {
				servletReg.unregister();
			}
			CookieHandler.setDefault(previous);
		}
	}

	@Test
	public void test_Sessions03_HttpSessionInvalidator() throws Exception {
		ServiceTracker<HttpSessionInvalidator, HttpSessionInvalidator> sessionInvalidatorTracker =
			new ServiceTracker<>(getBundleContext(), HttpSessionInvalidator.class, null);
		sessionInvalidatorTracker.open();
		HttpSessionInvalidator invalidator = sessionInvalidatorTracker.waitForService(100);

		final AtomicBoolean valueBound = new AtomicBoolean(false);
		final AtomicBoolean valueUnbound = new AtomicBoolean(false);
		final HttpSessionBindingListener bindingListener = new HttpSessionBindingListener() {

			@Override
			public void valueUnbound(HttpSessionBindingEvent event) {
				valueUnbound.set(true);
			}

			@Override
			public void valueBound(HttpSessionBindingEvent event) {
				valueBound.set(true);
			}
		};
		final AtomicBoolean sessionCreated = new AtomicBoolean(false);
		final AtomicBoolean sessionDestroyed = new AtomicBoolean(false);
		final AtomicReference<String> sessionId = new AtomicReference<String>();
		HttpSessionListener sessionListener = new HttpSessionListener() {

			@Override
			public void sessionDestroyed(HttpSessionEvent se) {
				sessionDestroyed.set(true);
			}

			@Override
			public void sessionCreated(HttpSessionEvent se) {
				sessionCreated.set(true);
			}
		};
		HttpServlet sessionServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
					IOException {
				HttpSession session = request.getSession();
				if (session.getAttribute("test.attribute") == null) {
					session.setAttribute("test.attribute", bindingListener);
					sessionId.set(session.getId());
					response.getWriter().print("created");
				} else {
					session.invalidate();
					response.getWriter().print("invalidated");
				}
			}

		};
		ServiceRegistration<Servlet> servletReg = null;
		ServiceRegistration<HttpSessionListener> sessionListenerReg = null;
		Dictionary<String, Object> servletProps = new Hashtable<String, Object>();
		servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/sessions");
		String actual = null;
		CookieHandler previous = CookieHandler.getDefault();
		CookieHandler.setDefault(new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );
		try {
			servletReg = getBundleContext().registerService(Servlet.class, sessionServlet, servletProps);
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			sessionListenerReg = getBundleContext().registerService(HttpSessionListener.class, sessionListener, listenerProps);

			sessionCreated.set(false);
			valueBound.set(false);
			sessionDestroyed.set(false);
			valueUnbound.set(false);

			// first call will create the session
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "created", actual);
			assertTrue("No sessionCreated called", sessionCreated.get());
			assertTrue("No valueBound called", valueBound.get());
			assertFalse("sessionDestroyed was called", sessionDestroyed.get());
			assertFalse("valueUnbound was called", valueUnbound.get());

			sessionCreated.set(false);
			valueBound.set(false);
			sessionDestroyed.set(false);
			valueUnbound.set(false);

			assertNotNull(sessionId.get());

			// invalidate using the invalidator
			invalidator.invalidate(sessionId.get(), true);

			// second call should find the session invalidated, and create a new one
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "created", actual);
			assertTrue("No sessionCreated was called", sessionCreated.get());
			assertTrue("No valueBound was called", valueBound.get());
			assertTrue("No sessionDestroyed called", sessionDestroyed.get());
			assertTrue("No valueUnbound called", valueUnbound.get());

			sessionCreated.set(false);
			sessionDestroyed.set(false);
			valueBound.set(false);
			valueUnbound.set(false);

			// calling again should invalidate the session again
			actual = requestAdvisor.request("sessions");
			assertEquals("Wrong result", "invalidated", actual);
			assertFalse("sessionCreated called", sessionCreated.get());
			assertFalse("valueBound called", valueBound.get());
			assertTrue("No sessionDestroyed called", sessionDestroyed.get());
			assertTrue("No valueUnbound called", valueUnbound.get());
		} catch (Exception e) {
			fail("Unexpected exception: " + e);
		} finally {
			if (servletReg != null) {
				servletReg.unregister();
			}
			if (sessionListenerReg != null) {
				sessionListenerReg.unregister();
			}
			CookieHandler.setDefault(previous);
			sessionInvalidatorTracker.close();
		}
	}

	@Test
	public void test_Sessions04_inlineSessionId() {
		final AtomicBoolean valueBound = new AtomicBoolean(false);
		final AtomicBoolean valueUnbound = new AtomicBoolean(false);
		final HttpSessionBindingListener bindingListener = new HttpSessionBindingListener() {

			@Override
			public void valueUnbound(HttpSessionBindingEvent event) {
				valueUnbound.set(true);
			}

			@Override
			public void valueBound(HttpSessionBindingEvent event) {
				valueBound.set(true);
			}
		};
		final AtomicBoolean sessionCreated = new AtomicBoolean(false);
		final AtomicBoolean sessionDestroyed = new AtomicBoolean(false);
		HttpSessionListener sessionListener = new HttpSessionListener() {

			@Override
			public void sessionDestroyed(HttpSessionEvent se) {
				sessionDestroyed.set(true);
			}

			@Override
			public void sessionCreated(HttpSessionEvent se) {
				sessionCreated.set(true);
			}
		};
		HttpServlet sessionServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
					IOException {
				HttpSession session = request.getSession();
				if (session.getAttribute("test.attribute") == null) {
					session.setAttribute("test.attribute", bindingListener);
					response.getWriter().print(response.encodeURL(request.getRequestURI()));
				} else {
					session.invalidate();
					response.getWriter().print("invalidated");
				}
			}

		};
		ServiceRegistration<Servlet> servletReg = null;
		ServiceRegistration<HttpSessionListener> sessionListenerReg = null;
		Dictionary<String, Object> servletProps = new Hashtable<String, Object>();
		servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/sessions");
		String actual = null;

		try {
			servletReg = getBundleContext().registerService(Servlet.class, sessionServlet, servletProps);
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			sessionListenerReg = getBundleContext().registerService(HttpSessionListener.class, sessionListener, listenerProps);

			sessionCreated.set(false);
			valueBound.set(false);
			sessionDestroyed.set(false);
			valueUnbound.set(false);

			// first call will create the session
			String inlined = requestAdvisor.request("sessions");
			assertTrue("Wrong result: " + inlined, inlined.startsWith("/sessions;jsessionid="));
			assertTrue("No sessionCreated called", sessionCreated.get());
			assertTrue("No valueBound called", valueBound.get());
			assertFalse("sessionDestroyed was called", sessionDestroyed.get());
			assertFalse("valueUnbound was called", valueUnbound.get());

			sessionCreated.set(false);
			valueBound.set(false);
			sessionDestroyed.set(false);
			valueUnbound.set(false);

			// second call will invalidate the session
			actual = requestAdvisor.request(inlined.substring(1));
			assertEquals("Wrong result", "invalidated", actual);
			assertFalse("sessionCreated was called", sessionCreated.get());
			assertFalse("valueBound was called", valueBound.get());
			assertTrue("No sessionDestroyed called", sessionDestroyed.get());
			assertTrue("No valueUnbound called", valueUnbound.get());

			sessionCreated.set(false);
			sessionDestroyed.set(false);
			valueBound.set(false);
			valueUnbound.set(false);
			// calling again should create the session again
			actual = requestAdvisor.request(inlined.substring(1) + "?bar=2");
			assertTrue("Wrong result: " + actual, actual.startsWith("/sessions;jsessionid="));
			assertTrue("No sessionCreated called", sessionCreated.get());
			assertTrue("No valueBound called", valueBound.get());
		} catch (Exception e) {
			fail("Unexpected exception: " + e);
		} finally {
			if (servletReg != null) {
				servletReg.unregister();
			}
			if (sessionListenerReg != null) {
				sessionListenerReg.unregister();
			}
		}
	}

	@Test
	public void test_Sessions05_Bug541607_MemoryLeak() throws Exception {
		final List<String> sessionIds = new CopyOnWriteArrayList<>();
		HttpSessionListener sessionListener = new HttpSessionListener() {

			@Override
			public void sessionDestroyed(HttpSessionEvent se) {
				sessionIds.remove(se.getSession().getId());
			}

			@Override
			public void sessionCreated(HttpSessionEvent se) {
				sessionIds.add(se.getSession().getId());
			}
		};
		HttpServlet sessionServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
					IOException {
				HttpSession session = request.getSession();
				response.getWriter().print("created " + session.getId());
			}

		};
		ServiceRegistration<Servlet> servletReg = null;
		ServiceRegistration<HttpSessionListener> sessionListenerReg = null;
		Dictionary<String, Object> servletProps = new Hashtable<String, Object>();
		servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/sessions");

		try {
			servletReg = getBundleContext().registerService(Servlet.class, sessionServlet, servletProps);
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			sessionListenerReg = getBundleContext().registerService(HttpSessionListener.class, sessionListener, listenerProps);

			// call the servet 10 times, we should get 10 sessions
			for (int i = 0; i < 10; i++) {
				requestAdvisor.request("sessions");
			}

			assertEquals("Wrong result", 10, sessionIds.size());
			Thread.sleep(12000); // 12 seconds
			assertEquals("Wrong result", 0, sessionIds.size());
		} catch (Exception e) {
			fail("Unexpected exception: " + e);
		} finally {
			if (servletReg != null) {
				servletReg.unregister();
			}
			if (sessionListenerReg != null) {
				sessionListenerReg.unregister();
			}
		}
	}

	@Test
	public void test_Resource1() throws Exception {
		String expected = "a";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestResource1/resource1.txt");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Resource2() throws Exception {
		String expected = "cbdadbc";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestResource2/resource1.txt");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Resource3() throws Exception {
		String expected = "a";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestResource3/resource1.txt");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Resource4() throws Exception {
		String expected = "dcbabcd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestResource4/resource1.txt");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Resource5() throws Exception {
		String expected = "dcbabcd";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestResource5/resource1.txt");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_ResourceAliasNormal() throws Exception {
		HttpService extendedHttpService = getHttpService();

		extendedHttpService.registerResources("/testalias", "/org/eclipse/equinox/http/servlet/tests", null);

		String actual = requestAdvisor.request("testalias/resource2.txt");
		Assert.assertEquals("Wrong value.", "test", actual);
	}

	@Test
	public void test_ResourceAliasSlash() throws Exception {
		HttpService extendedHttpService = getHttpService();

		extendedHttpService.registerResources("/", "/org/eclipse/equinox/http/servlet/tests", null);

		String actual = requestAdvisor.request("resource2.txt");
		Assert.assertEquals("Wrong value.", "test", actual);
	}

	@Test
	public void test_ResourceRangeRequest_Complete() throws Exception {
		Bundle bundle = installBundle(TEST_BUNDLE_2);
		ServletContextHelper customSCH = new ServletContextHelper(bundle) {
			@Override
			public String getMimeType(String filename) {
				if (filename.endsWith(".mp4")) { //$NON-NLS-1$
					return "video/mp4"; //$NON-NLS-1$
				}
				return null;
			}
		};
		Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "foo");
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/foo");
		registrations.add(getBundleContext().registerService(ServletContextHelper.class, customSCH, contextProps));
		Map<String, List<String>> actual;
		Map<String, List<String>> requestHeader = new HashMap<>();
		requestHeader.put("Range", Collections.singletonList("bytes=0-"));
		try {
			bundle.start();
			actual = requestAdvisor.request("foo/TestResource1/rangerequest.mp4", requestHeader);
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals("Response Code", Collections.singletonList("206"), actual.get("responseCode"));
		Assert.assertEquals("Content-Length", Collections.singletonList("20655"), actual.get("Content-Length"));
		Assert.assertEquals("Accept-Ranges", Collections.singletonList("bytes"), actual.get("Accept-Ranges"));
		Assert.assertEquals("Content-Range", Collections.singletonList("bytes 0-20654/20655"), actual.get("Content-Range"));
	}

	@Test
	public void test_ResourceRangeRequest_WithRange() throws Exception {
		Map<String, List<String>> actual;
		Bundle bundle = installBundle(TEST_BUNDLE_2);
		ServletContextHelper customSCH = new ServletContextHelper(bundle) {
			@Override
			public String getMimeType(String filename) {
				if (filename.endsWith(".mp4")) { //$NON-NLS-1$
					return "video/mp4"; //$NON-NLS-1$
				}
				return null;
			}
		};
		Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "foo");
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/foo");
		registrations.add(getBundleContext().registerService(ServletContextHelper.class, customSCH, contextProps));
		Map<String, List<String>> requestHeader = new HashMap<>();
		requestHeader.put("Range", Collections.singletonList("bytes=1000-9999"));
		try {
			bundle.start();
			actual = requestAdvisor.request("foo/TestResource1/rangerequest.mp4", requestHeader);
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals("Response Code", Collections.singletonList("206"), actual.get("responseCode"));
		Assert.assertEquals("Content-Length", Collections.singletonList("9000"), actual.get("Content-Length"));
		Assert.assertEquals("Accept-Ranges", Collections.singletonList("bytes"), actual.get("Accept-Ranges"));
		Assert.assertEquals("Content-Range", Collections.singletonList("bytes 1000-9999/20655"), actual.get("Content-Range"));
		Assert.assertEquals("Response Body Prefix", "901", actual.get("responseBody").get(0).substring(0, 3));
		Assert.assertEquals("Response Body Suffix", "567", actual.get("responseBody").get(0).substring(8997, 9000));
	}

	@Test
	public void test_ResourceRangeRequest_WithRange_customContext() throws Exception {
		Map<String, List<String>> actual;
		Bundle bundle = installBundle(TEST_BUNDLE_2);
		RangeAwareServletContextHelper customSCH = new RangeAwareServletContextHelper(bundle) {
			@Override
			public String getMimeType(String filename) {
				if (filename.endsWith(".mp4")) { //$NON-NLS-1$
					return "video/mp4"; //$NON-NLS-1$
				}
				return null;
			}
			@Override
			public boolean rangeableContentType(String contentType, String userAgent) {
				return userAgent.contains("Foo") && contentType.startsWith("video/");
			}
		};
		Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "foo");
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/foo");
		registrations.add(getBundleContext().registerService(ServletContextHelper.class, customSCH, contextProps));

		Map<String, List<String>> requestHeader = new HashMap<>();
		requestHeader.put("User-Agent", Collections.singletonList("Foo"));
		try {
			bundle.start();
			actual = requestAdvisor.request("foo/TestResource1/rangerequest.mp4", requestHeader);
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals("Response Code", Collections.singletonList("206"), actual.get("responseCode"));
		Assert.assertEquals("Content-Length", Collections.singletonList("20655"), actual.get("Content-Length"));
		Assert.assertEquals("Accept-Ranges", Collections.singletonList("bytes"), actual.get("Accept-Ranges"));
		Assert.assertEquals("Content-Range", Collections.singletonList("bytes 0-20654/20655"), actual.get("Content-Range"));
		Assert.assertEquals("Response Body Prefix", "123", actual.get("responseBody").get(0).substring(0, 3));
		Assert.assertEquals("Response Body Suffix", "789", actual.get("responseBody").get(0).substring(8997, 9000));
	}

	@Test
	public void test_Runtime() throws Exception {
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();

			BundleContext bundleContext = getBundleContext();

			ServiceReference<HttpServiceRuntime> serviceReference = bundleContext.getServiceReference(HttpServiceRuntime.class);
			HttpServiceRuntime runtime = bundleContext.getService(serviceReference);

			Assert.assertNotNull(runtime);

			RuntimeDTO runtimeDTO = runtime.getRuntimeDTO();

			ServletContextDTO[] servletContextDTOs = runtimeDTO.servletContextDTOs;

			Assert.assertTrue(servletContextDTOs.length > 0);
		} finally {
			uninstallBundle(bundle);
		}
	}

	@Test
	public void test_Servlet1() throws Exception {
		String expected = STATUS_OK;
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet1");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet2() throws Exception {
		String expected = "3";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet2");
			Assert.assertEquals(expected, actual);
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet3() throws Exception {
		String expected = STATUS_OK;
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet3");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet4() throws Exception {
		String expected = System.getProperty(JETTY_PROPERTY_PREFIX + "context.path", "");
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet4");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet5() throws Exception {
		String expected = "Equinox Jetty-based Http Service";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet5");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet6() throws Exception {
		String expected = "a";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("something/a.TestServlet6");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet7() throws Exception {
		String expected = "a";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet7/a");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet9() throws Exception {
		String expected = "Equinox Jetty-based Http Service";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet9");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet10() throws Exception {
		String expected = "a";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet10");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet11() throws Exception {
		String expected = "a";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServlet11");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_Servlet12() throws Exception {
		Servlet sA = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				response.getWriter().write('a');
			}

		};

		Servlet sB = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				response.getWriter().write('b');
			}

		};

		HttpService httpService = getHttpService();

		HttpContext httpContext = httpService.createDefaultHttpContext();

		httpService.registerServlet("*.txt", sA, null, httpContext);
		httpService.registerServlet("/files/*.txt", sB, null, httpContext);

		Assert.assertEquals("b", requestAdvisor.request("files/help.txt"));
	}

	@Test
	public void test_Servlet13() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				PrintWriter writer = resp.getWriter();
				writer.write(req.getQueryString());
				writer.write("|");
				writer.write(req.getParameter("p"));
				writer.write("|");
				writer.write(Arrays.toString(req.getParameterValues("p")));
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S13");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet13/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		String result = requestAdvisor.request("Servlet13/a?p=1&p=2");

		Assert.assertEquals("p=1&p=2|1|[1, 2]", result);
	}

	@Test
	public void test_ServletExactMatchPrecidence() throws Exception {
		Servlet sA = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				response.getWriter().write('a');
			}

		};

		Servlet sB = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				response.getWriter().write('b');
			}

		};

		HttpService httpService = getHttpService();

		HttpContext httpContext = httpService.createDefaultHttpContext();

		httpService.registerServlet("*.txt", sA, null, httpContext);
		httpService.registerServlet("/files/help.txt", sB, null, httpContext);

		Assert.assertEquals("b", requestAdvisor.request("files/help.txt"));
	}

//	private static String getSubmittedFileName(Part part) {
//		for (String cd : part.getHeader("content-disposition").split(";")) {
//			if (cd.trim().startsWith("filename")) {
//				String fileName = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
//				return fileName.substring(fileName.lastIndexOf('/') + 1).substring(fileName.lastIndexOf('\\') + 1); // MSIE fix.
//			}
//		}
//		return null;
//	}

	/*
	 * 3.1 file uploads
	 */
	@Test
	public void test_Servlet16() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws IOException, ServletException {

				Part part = req.getPart("file");
				Assert.assertNotNull(part);

				String submittedFileName = part.getSubmittedFileName();
				String contentType = part.getContentType();
				long size = part.getSize();

				PrintWriter writer = resp.getWriter();

				writer.write(submittedFileName);
				writer.write("|");
				writer.write(contentType);
				writer.write("|" + size);
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		props.put("equinox.http.multipartSupported", Boolean.TRUE);
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

		map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt")));

		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);

		Assert.assertEquals("200", result.get("responseCode").get(0));
		Assert.assertEquals("resource1.txt|text/plain|25", result.get("responseBody").get(0));
	}

	@Test
	public void test_Servlet16_notEnabled() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws IOException, ServletException {

				req.getPart("file");
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

		map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt")));

		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);

		Assert.assertEquals("500", result.get("responseCode").get(0));
	}

	@Test
	public void test_Servlet16_fileuploadWithLocation() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws IOException, ServletException {

				Part part = req.getPart("file");
				Assert.assertNotNull(part);

				String submittedFileName = part.getSubmittedFileName();
				String contentType = part.getContentType();
				long size = part.getSize();

				File tempDir = (File)getServletContext().getAttribute(ServletContext.TEMPDIR);
				File location = new File(tempDir, "file-upload-test");

				File[] listFiles = location.listFiles();

				PrintWriter writer = resp.getWriter();

				writer.write(submittedFileName);
				writer.write("|");
				writer.write(contentType);
				writer.write("|" + size);
				writer.write("|" + listFiles.length);
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		props.put("equinox.http.multipartSupported", Boolean.TRUE);
		props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

		map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt")));

		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);

		Assert.assertEquals("200", result.get("responseCode").get(0));
		Assert.assertEquals("resource1.txt|text/plain|25|0", result.get("responseBody").get(0));
	}

	@Test
	public void test_Servlet16_fileuploadWithLocationAndThreshold() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws IOException, ServletException {

				Part part = req.getPart("file");
				Assert.assertNotNull(part);

				String submittedFileName = part.getSubmittedFileName();
				String contentType = part.getContentType();
				long size = part.getSize();

				File tempDir = (File)getServletContext().getAttribute(ServletContext.TEMPDIR);
				File location = new File(tempDir, "file-upload-test");

				File[] listFiles = location.listFiles();

				PrintWriter writer = resp.getWriter();

				writer.write(submittedFileName);
				writer.write("|");
				writer.write(contentType);
				writer.write("|" + size);
				writer.write("|" + listFiles.length);
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		props.put("equinox.http.multipartSupported", Boolean.TRUE);
		props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test");
		props.put("equinox.http.whiteboard.servlet.multipart.fileSizeThreshold", 10);
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

		map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt")));

		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);

		Assert.assertEquals("200", result.get("responseCode").get(0));
		Assert.assertEquals("resource1.txt|text/plain|25|1", result.get("responseBody").get(0));
	}

	@Test
	public void test_Servlet16_fileuploadWithLocationMaxFileSize() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws IOException, ServletException {

				req.getPart("file");
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		props.put("equinox.http.multipartSupported", Boolean.TRUE);
		props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test");
		// Note the actual uploaded file size is 25bytes
		props.put("equinox.http.whiteboard.servlet.multipart.maxFileSize", 24L);
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

		map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt")));

		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);

		Assert.assertEquals("500", result.get("responseCode").get(0));
	}

	@Test
	public void test_Servlet16_fileuploadWithLocationMaxRequestSize() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws IOException, ServletException {

				req.getPart("file");
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		props.put("equinox.http.multipartSupported", Boolean.TRUE);
		props.put("equinox.http.whiteboard.servlet.multipart.location", "file-upload-test");
		// Note the actual uploaded file size is 25bytes, but you also need room for the rest of the headers
		props.put("equinox.http.whiteboard.servlet.multipart.maxRequestSize", 26L);
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

		map.put("file", Arrays.<Object>asList(getClass().getResource("resource1.txt")));

		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);

		Assert.assertEquals("500", result.get("responseCode").get(0));
	}

	/*
	 * 3.0 file uploads
	 */
// This is commented due to a bug in commons-fileupload which was subsequently fixed in later versions.
//	@Test
//	public void test_Servlet17() throws Exception {
//		Servlet servlet = new HttpServlet() {
//			private static final long serialVersionUID = 1L;
//
//			@Override
//			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
//				throws IOException, ServletException {
//
//				Part part = req.getPart("file");
//				Assert.assertNotNull(part);
//
//				String submittedFileName = getSubmittedFileName(part);
//				String contentType = part.getContentType();
//				long size = part.getSize();
//
//				PrintWriter writer = resp.getWriter();
//
//				writer.write(submittedFileName);
//				writer.write("|");
//				writer.write(contentType);
//				writer.write("|" + size);
//			}
//		};
//
//		Dictionary<String, Object> props = new Hashtable<String, Object>();
//		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
//		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
//		props.put("equinox.http.multipartSupported", Boolean.TRUE);
//		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));
//
//		Map<String, List<Object>> map = new HashMap<String, List<Object>>();
//
//		map.put("file", Arrays.<Object>asList(getClass().getResource("blue.png")));
//
//		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);
//
//		Assert.assertEquals("200", result.get("responseCode").get(0));
//		Assert.assertEquals("blue.png|image/png|292", result.get("responseBody").get(0));
//	}

	@Test
	public void test_Servlet18() throws Exception {
		Servlet sA = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {
				// get a resource that is imported
				URL url = request.getServletContext().getResource("org/osgi/service/http/HttpService.class");
				response.getWriter().write(url == null ? "null" : url.getProtocol());
			}

		};

		HttpService httpService = getHttpService();

		HttpContext httpContext = httpService.createDefaultHttpContext();

		httpService.registerServlet("/testDefaultHttpContextResource", sA, null, httpContext);

		// just making sure bundleresource protocol is used as proof that Bundle.getResource was called
		Assert.assertEquals("bundleresource", requestAdvisor.request("testDefaultHttpContextResource"));
	}

	@Test
	public void test_commonsFileUpload() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doPost(HttpServletRequest req, HttpServletResponse resp)
				throws IOException, ServletException {

				boolean isMultipart = ServletFileUpload.isMultipartContent(req);
				Assert.assertTrue(isMultipart);

				DiskFileItemFactory factory = new DiskFileItemFactory();

				ServletContext servletContext = this.getServletConfig().getServletContext();
				File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
				factory.setRepository(repository);
				ServletFileUpload upload = new ServletFileUpload(factory);

				List<FileItem> items = null;
				try {
					List<FileItem> parseRequest = upload.parseRequest(req);
					items = parseRequest;
				} catch (FileUploadException e) {
					e.printStackTrace();
				}

				Assert.assertNotNull(items);
				Assert.assertFalse(items.isEmpty());

				FileItem fileItem = items.get(0);

				String submittedFileName = fileItem.getName();
				String contentType = fileItem.getContentType();
				long size = fileItem.getSize();

				PrintWriter writer = resp.getWriter();

				writer.write(submittedFileName);
				writer.write("|");
				writer.write(contentType);
				writer.write("|" + size);
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<Object>> map = new HashMap<String, List<Object>>();

		map.put("file", Arrays.<Object>asList(getClass().getResource("blue.png")));

		Map<String, List<String>> result = requestAdvisor.upload("Servlet16/do", map);

		Assert.assertEquals("200", result.get("responseCode").get(0));
		Assert.assertEquals("blue.png|image/png|292", result.get("responseBody").get(0));
	}

	@Test
	public void test_PathEncodings_Bug540970() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws ServletException, IOException {

				PrintWriter writer = resp.getWriter();

				writer.write(req.getRequestURI());
			}
		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S16");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/Servlet16/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<String>> map = new HashMap<String, List<String>>();

		Map<String, List<String>> result = requestAdvisor.request("Servlet16/NEEO-a5056097%2Fdevice%2Fapt-neeo_io%3Avirtual%3A6jzOoAtL%2FTemperature_GF_Living%2Fnone%2F1%2Fdirectory%2Factor/default", map);

		Assert.assertEquals("200", result.get("responseCode").get(0));
		Assert.assertEquals("/Servlet16/NEEO-a5056097%2Fdevice%2Fapt-neeo_io%3Avirtual%3A6jzOoAtL%2FTemperature_GF_Living%2Fnone%2F1%2Fdirectory%2Factor/default", result.get("responseBody").get(0));
	}

	@Test
	public void test_ServletContext1() throws Exception {
		String expected = "/org/eclipse/equinox/http/servlet/tests/tb1/resource1.txt";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServletContext1");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);

	}

	@Test
	public void test_ServletContext1_2() throws Exception {
		String expected = "/org/eclipse/equinox/http/servlet/tests/tb1/resource1.txt";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("TestServletContext1");
			Assert.assertEquals(expected, actual);
			bundle.stop();
			bundle.start();
			bundle.stop();
			bundle.start();
			actual = requestAdvisor.request("TestServletContext1");
		} finally {
			uninstallBundle(bundle);
		}

		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_ServletContext2() throws Exception {
		Servlet servlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(
				HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				getServletContext().setAttribute("name", null);
			}

		};

		Dictionary<String, Object> props = new Hashtable<String, Object>();
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
		props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/S1/*");
		registrations.add(getBundleContext().registerService(Servlet.class, servlet, props));

		Map<String, List<String>> response = requestAdvisor.request("S1/a", null);

		String responseCode = response.get("responseCode").get(0);

		Assert.assertEquals("200", responseCode);
	}

	@Test
	public void testServletContextUnsupportedOperations() {
		final AtomicReference<ServletContext> contextHolder = new AtomicReference<ServletContext>();
		Servlet unsupportedServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;
			@Override
			public void init(ServletConfig config) throws ServletException {
				contextHolder.set(config.getServletContext());
			}
		};

		ServiceRegistration<Servlet> servletReg = null;
		Dictionary<String, Object> servletProps = new Hashtable<String, Object>();
		servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/sessions");
		try {
			servletReg = getBundleContext().registerService(Servlet.class, unsupportedServlet, servletProps);
		} catch (Exception e) {
			fail("Unexpected exception: " + e);
		} finally {
			if (servletReg != null) {
				servletReg.unregister();
			}
		}
		ServletContext context = contextHolder.get();
		assertNotNull("Null context.", context);
		for(Method m : getUnsupportedMethods()) {
			checkMethod(m, context);
		}
	}

	private void checkMethod(Method m, ServletContext context) throws RuntimeException {
		Class<?>[] types = m.getParameterTypes();
		Object[] params = new Object[types.length];
		try {
			m.invoke(context, params);
			fail("Expected an exception.");
		} catch (IllegalAccessException e) {
			fail("unexpected: " + e);
		} catch (InvocationTargetException e) {
			Throwable cause = e.getTargetException();
			if (!(cause instanceof UnsupportedOperationException)) {
				fail("unexpected exception for " + m.getName() + ": " + cause);
			}
		}

	}

	static private List<Method> getUnsupportedMethods() {
		List<Method> methods = new ArrayList<Method>();
		Class<ServletContext> contextClass = ServletContext.class;
		for(Method m : contextClass.getMethods()) {
			String name = m.getName();
			if (name.equals("addFilter") || name.equals("addListener") || name.equals("addServlet") || name.equals("createFilter") || name.equals("createListener") || name.equals("createServlet") | name.equals("declareRoles")) {
				methods.add(m);
			}
		}
		return methods;
	}

	@Test
	public void test_ServletContextHelper1() throws Exception {
		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		Dictionary<String, String> contextProps = new Hashtable<String, String>();
		registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

		servletContextHelper = new ServletContextHelper(bundle){};
		contextProps = new Hashtable<String, String>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "test.sch.one");
		registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

		servletContextHelper = new ServletContextHelper(bundle){};
		contextProps = new Hashtable<String, String>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/test-sch2");
		registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

		servletContextHelper = new ServletContextHelper(bundle){};
		contextProps = new Hashtable<String, String>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "Test SCH 3!");
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/test-sch3");
		registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

		servletContextHelper = new ServletContextHelper(bundle){};
		contextProps = new Hashtable<String, String>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "test.sch.four");
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "test$sch$4");
		registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

		ServiceReference<HttpServiceRuntime> serviceReference =
			bundleContext.getServiceReference(HttpServiceRuntime.class);
		HttpServiceRuntime runtime = bundleContext.getService(serviceReference);

		RuntimeDTO runtimeDTO = runtime.getRuntimeDTO();
		Assert.assertEquals(5, runtimeDTO.failedServletContextDTOs.length);

		for (ServiceRegistration<?> registration : registrations) {
			registration.unregister();
		}
		registrations.clear();

		runtimeDTO = runtime.getRuntimeDTO();
		Assert.assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
	}

	@Test
	public void test_ServletContextHelper7() throws Exception {
		String expected = "a";

		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		Servlet s1 = new BaseServlet("a");

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			Dictionary<String, String> servletProps = new Hashtable<String, String>();
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s1");
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			registrations.add(bundleContext.registerService(Servlet.class, s1, servletProps));

			String actual = requestAdvisor.request("s1");

			Assert.assertEquals(expected, actual);
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_ServletContextHelper8() throws Exception {
		String expected = "b";

		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();
		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		Servlet s1 = new BaseServlet("b");

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			Dictionary<String, String> servletProps = new Hashtable<String, String>();
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s1");
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			registrations.add(bundleContext.registerService(Servlet.class, s1, servletProps));

			String actual = requestAdvisor.request("a/s1");

			Assert.assertEquals(expected, actual);
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_ServletContextHelper9() throws Exception {
		String expected1 = "c";
		String expected2 = "d";

		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		Servlet s1 = new BaseServlet(expected1);
		Servlet s2 = new BaseServlet(expected2);

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			registrations.add(bundleContext.registerService(Servlet.class, s1, servletProps1));

			Dictionary<String, String> servletProps2 = new Hashtable<String, String>();
			servletProps2.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps2.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			servletProps2.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			registrations.add(bundleContext.registerService(Servlet.class, s2, servletProps2));

			String actual = requestAdvisor.request("s");

			Assert.assertEquals(expected1, actual);

			actual = requestAdvisor.request("a/s");

			Assert.assertEquals(expected2, actual);
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_ServletContextHelperVisibility() throws Exception {
		String expected1 = "c";

		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		Servlet s1 = new BaseServlet(expected1);


		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			// register a hook that hides the helper from the registering bundle
			registrations.add(bundleContext.registerService(FindHook.class, new FindHook() {

				@Override
				public void find(BundleContext context, String name, String filter, boolean allServices,
						Collection<ServiceReference<?>> references) {
					if (ServletContextHelper.class.getName().equals(name) && context.getBundle().equals(getBundleContext().getBundle())) {
						references.clear();
					}
				}
			}, null));

			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			Dictionary<String, String> servletProps2 = new Hashtable<String, String>();
			servletProps2.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps2.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			servletProps2.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			registrations.add(bundleContext.registerService(Servlet.class, s1, servletProps2));

			try {
				requestAdvisor.request("a/s");
			} catch (FileNotFoundException e) {
				// expected
			}
		} finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_ServletContextHelper10() throws Exception {
		String expected = "cac";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("a/TestServletContextHelper10/a");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	private static final String HTTP_CONTEXT_TEST_ROOT = "http.context.test";

	@Test
	public void test_ServletContextHelper11() throws Exception {
		BaseHttpContext ctx1 = new BaseHttpContext(true, HTTP_CONTEXT_TEST_ROOT + "/1", getBundleContext().getBundle());
		BaseHttpContext ctx2 = new BaseHttpContext(true, HTTP_CONTEXT_TEST_ROOT + "/2", getBundleContext().getBundle());
		String actual;
		try {
			getHttpService().registerResources("/" + HTTP_CONTEXT_TEST_ROOT + "/1", "", ctx1);
			getHttpService().registerResources("/" + HTTP_CONTEXT_TEST_ROOT + "/2", "", ctx2);
			actual = requestAdvisor.request(HTTP_CONTEXT_TEST_ROOT + "/1/test");
			Assert.assertEquals("1", actual);
			actual = requestAdvisor.request(HTTP_CONTEXT_TEST_ROOT + "/2/test");
			Assert.assertEquals("2", actual);
		}
		finally {
			try {
				getHttpService().unregister("/" + HTTP_CONTEXT_TEST_ROOT + "/1");
				getHttpService().unregister("/" + HTTP_CONTEXT_TEST_ROOT + "/2");
			} catch (IllegalArgumentException e) {
				// ignore
			}
		}
	}

	@Test
	public void test_ServletContextHelper12() throws Exception {
		String expected1 = "a,b,null";

		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		Servlet s1 = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void service(
					HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException {

				StringBuilder builder = new StringBuilder();
				builder.append(request.getServletContext().getInitParameter("a")).append(',');
				builder.append(request.getServletContext().getInitParameter("b")).append(',');
				builder.append(request.getServletContext().getInitParameter("c"));
				response.getWriter().print(builder.toString());
			}
		};

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, Object> contextProps = new Hashtable<String, Object>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX + "a", "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX + "b", "b");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_INIT_PARAM_PREFIX + "c", Integer.valueOf(1));
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			registrations.add(bundleContext.registerService(Servlet.class, s1, servletProps1));

			String actual = requestAdvisor.request("a/s");

			Assert.assertEquals(expected1, actual);
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_ServletContextHelper13() throws Exception {
		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		// test that the helper handlesecurity is called before the filter by setting an attribute on the request
		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){

			@Override
			public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
				request.setAttribute(testName.getMethodName(), Boolean.TRUE);
				return super.handleSecurity(request, response);
			}

		};
		Filter f1 = new Filter() {

			@Override
			public void init(FilterConfig filterConfig) throws ServletException {
			}

			@Override
			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
					throws IOException, ServletException {
				if (request.getAttribute(testName.getMethodName()) == Boolean.TRUE) {
					request.setAttribute(testName.getMethodName() + ".fromFilter", Boolean.TRUE);
				}
				chain.doFilter(request, response);
			}

			@Override
			public void destroy() {
			}

		};
		Servlet s1 = new HttpServlet() {
			private static final long serialVersionUID = 1L;
			@Override
			public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
				res.getWriter().print(req.getAttribute(testName.getMethodName() + ".fromFilter"));
			}

		};

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			Dictionary<String, String> filterProps = new Hashtable<String, String>();
			filterProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/*");
			filterProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			registrations.add(bundleContext.registerService(Filter.class, f1, filterProps));

			Dictionary<String, String> servletProps = new Hashtable<String, String>();
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s1");
			servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			registrations.add(bundleContext.registerService(Servlet.class, s1, servletProps));

			String actual = requestAdvisor.request("s1");

			Assert.assertEquals(Boolean.TRUE.toString(), actual);
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_ServletContextHelper14_uniqueTempDirs() throws Exception {
		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelperA = new ServletContextHelper(bundle){};
		ServletContextHelper servletContextHelperB = new ServletContextHelper(bundle){};

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			final AtomicReference<File> fileA = new AtomicReference<File>();

			Servlet servletA = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					fileA.set((File)getServletContext().getAttribute(ServletContext.TEMPDIR));
					new File(fileA.get(), "test").createNewFile();
				}
			};

			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelperA, contextProps));
			Dictionary<String, Object> props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/SA");
			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));

			requestAdvisor.request("a/SA");
			Assert.assertNotNull(fileA.get());
			Assert.assertTrue(new File(fileA.get(), "test").exists());

			contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "b");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/b");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelperB, contextProps));

			Assert.assertNotNull(fileA.get());
			Assert.assertTrue(new File(fileA.get(), "test").exists());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_ServletContextHelper15_fullContextPath_include() throws Exception {
		try {
			stopJetty();
			System.setProperty("org.eclipse.equinox.http.jetty.context.path", "/foo");
		}
		finally {
			startJetty();
		}

		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelperA = new ServletContextHelper(bundle){};

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			final AtomicReference<String> path = new AtomicReference<String>();

			Servlet servletA = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					RequestDispatcher rd = req.getRequestDispatcher("/foo/a/SB");
					rd.include(req, resp);
				}
			};
			Servlet servletB = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					path.set((String)req.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH));
				}
			};

			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelperA, contextProps));
			Dictionary<String, Object> props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/SA");
			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
			props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SB");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/SB");
			registrations.add(getBundleContext().registerService(Servlet.class, servletB, props));

			requestAdvisor.request("a/SA");

			Assert.assertEquals("/foo/a", path.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
			try {
				stopJetty();
				System.setProperty("org.eclipse.equinox.http.jetty.context.path", "");
			}
			finally {
				startJetty();
			}
		}
	}

	@Test
	public void test_ServletContextHelper15_fullContextPath_forward() throws Exception {
		try {
			stopJetty();
			System.setProperty("org.eclipse.equinox.http.jetty.context.path", "/foo");
		}
		finally {
			startJetty();
		}

		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelperA = new ServletContextHelper(bundle){};

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			final AtomicReference<String> path = new AtomicReference<String>();

			Servlet servletA = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					RequestDispatcher rd = req.getRequestDispatcher("/foo/a/SB");
					rd.forward(req, resp);
				}
			};
			Servlet servletB = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					path.set((String)req.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH));
				}
			};

			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelperA, contextProps));
			Dictionary<String, Object> props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/SA");
			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
			props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SB");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/SB");
			registrations.add(getBundleContext().registerService(Servlet.class, servletB, props));

			requestAdvisor.request("a/SA");

			Assert.assertEquals("/foo/a", path.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
			try {
				stopJetty();
				System.setProperty("org.eclipse.equinox.http.jetty.context.path", "");
			}
			finally {
				startJetty();
			}
		}
	}

	@Test
	public void test_getRequestURI_trailingSlash1() throws Exception {
		try {
			stopJetty();
			System.setProperty("org.eclipse.equinox.http.jetty.context.path", "/foo");
		}
		finally {
			startJetty();
		}

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			final AtomicReference<String> getRequestURI = new AtomicReference<String>();

			Servlet servletA = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					getRequestURI.set(req.getRequestURI());
				}
			};

			Dictionary<String, Object> props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, new String[] {"/*", "/"});
			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
			props = new Hashtable<String, Object>();

			requestAdvisor.request("a/b/c/");

			Assert.assertEquals("/foo/a/b/c/", getRequestURI.get());
			requestAdvisor.request("a/b/");
			Assert.assertEquals("/foo/a/b/", getRequestURI.get());
			requestAdvisor.request("a/");
			Assert.assertEquals("/foo/a/", getRequestURI.get());
			// Note using empty string here because of the way requestAdvisor works
			// by appending a slash first.
			requestAdvisor.request("");
			Assert.assertEquals("/foo/", getRequestURI.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
			try {
				stopJetty();
				System.setProperty("org.eclipse.equinox.http.jetty.context.path", "");
			}
			finally {
				startJetty();
			}
		}
	}

	@Test
	public void test_getRequestURI_trailingSlash2() throws Exception {
		try {
			stopJetty();
			System.setProperty("org.eclipse.equinox.http.jetty.context.path", "/foo");
		}
		finally {
			startJetty();
		}

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			final AtomicReference<String> getRequestURI = new AtomicReference<String>();

			Servlet servletA = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					HttpSession session = req.getSession();
					session.setAttribute("test", req.getParameter("p1"));
					getRequestURI.set(resp.encodeURL(req.getRequestURI()));
				}
			};

			Dictionary<String, Object> props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/*");
			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
			props = new Hashtable<String, Object>();

			requestAdvisor.request("a/b/c/?p1=v1");
			// get the session
			String initialURI = getRequestURI.get();
			int sessionIdx = initialURI.indexOf(";jsessionid=");
			Assert.assertTrue("No session: " + initialURI, sessionIdx > -1);
			String sessionPostfix = initialURI.substring(sessionIdx);
			Assert.assertEquals("/foo/a/b/c/" + sessionPostfix, getRequestURI.get());
			requestAdvisor.request("a/b/" + sessionPostfix);
			Assert.assertEquals("/foo/a/b/" + sessionPostfix, getRequestURI.get());
			requestAdvisor.request("a/" + sessionPostfix);
			Assert.assertEquals("/foo/a/" + sessionPostfix, getRequestURI.get());
			// Note using empty string here because of the way requestAdvisor works
			// by appending a slash first.
			requestAdvisor.request("" + sessionPostfix);
			Assert.assertEquals("/foo/" + sessionPostfix, getRequestURI.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
			try {
				stopJetty();
				System.setProperty("org.eclipse.equinox.http.jetty.context.path", "");
			}
			finally {
				startJetty();
			}
		}
	}

	@Test
	public void test_getRequestURI_trailingSlash3() throws Exception {
		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			final AtomicReference<String> getRequestURI = new AtomicReference<String>();

			Servlet servletA = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					getRequestURI.set(req.getRequestURI());
				}
			};

			Dictionary<String, Object> props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, new String[] {"/*", "/"});
			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
			props = new Hashtable<String, Object>();

			requestAdvisor.request("a/b/c/");
			Assert.assertEquals("/a/b/c/", getRequestURI.get());
			requestAdvisor.request("a/b/");
			Assert.assertEquals("/a/b/", getRequestURI.get());
			requestAdvisor.request("a/");
			Assert.assertEquals("/a/", getRequestURI.get());
			// Note using empty string here because of the way requestAdvisor works
			// by appending a slash first.
			requestAdvisor.request("");
			Assert.assertEquals("/", getRequestURI.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_getRequestURI_trailingSlash4() throws Exception {
		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			final AtomicReference<String> getRequestURI = new AtomicReference<String>();

			Servlet servletA = new HttpServlet() {
				private static final long serialVersionUID = 1L;
				@Override
				protected void service(HttpServletRequest req, HttpServletResponse resp)
					throws IOException, ServletException {
					HttpSession session = req.getSession();
					session.setAttribute("test", req.getParameter("p1"));
					getRequestURI.set(resp.encodeURL(req.getRequestURI()));
				}
			};

			Dictionary<String, Object> props = new Hashtable<String, Object>();
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "SA");
			props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/*");
			registrations.add(getBundleContext().registerService(Servlet.class, servletA, props));
			props = new Hashtable<String, Object>();

			requestAdvisor.request("a/b/c/?p1=v1");
			// get the session
			String initialURI = getRequestURI.get();
			int sessionIdx = initialURI.indexOf(";jsessionid=");
			Assert.assertTrue("No session: " + initialURI, sessionIdx > -1);
			String sessionPostfix = initialURI.substring(sessionIdx);
			Assert.assertEquals("/a/b/c/" + sessionPostfix, getRequestURI.get());
			requestAdvisor.request("a/b/" + sessionPostfix);
			Assert.assertEquals("/a/b/" + sessionPostfix, getRequestURI.get());
			requestAdvisor.request("a/" + sessionPostfix);
			Assert.assertEquals("/a/" + sessionPostfix, getRequestURI.get());
			// Note using empty string here because of the way requestAdvisor works
			// by appending a slash first.
			requestAdvisor.request("" + sessionPostfix);
			Assert.assertEquals("/" + sessionPostfix, getRequestURI.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener1() throws Exception {
		BaseServletContextListener scl1 =
			new BaseServletContextListener();

		Dictionary<String, String> listenerProps = new Hashtable<String, String>();
		listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
		ServiceRegistration<ServletContextListener> registration = getBundleContext().registerService(ServletContextListener.class, scl1, listenerProps);
		registration.unregister();


		Assert.assertTrue(scl1.initialized.get());
		Assert.assertTrue(scl1.destroyed.get());
	}

	@Test
	public void test_Listener2() throws Exception {
		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			BaseServletContextListener scl1 =
					new BaseServletContextListener();
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			ServiceRegistration<ServletContextListener> registration = getBundleContext().registerService(ServletContextListener.class, scl1, listenerProps);
			registration.unregister();

			Assert.assertTrue(scl1.initialized.get());
			Assert.assertTrue(scl1.destroyed.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener3() throws Exception {
		BundleContext bundleContext = getBundleContext();
		Bundle bundle = bundleContext.getBundle();

		ServletContextHelper servletContextHelper = new ServletContextHelper(bundle){};
		BaseServletContextListener scl1 = new BaseServletContextListener();
		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> contextProps = new Hashtable<String, String>();
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
			contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
			registrations.add(bundleContext.registerService(ServletContextHelper.class, servletContextHelper, contextProps));

			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(bundleContext.registerService(ServletContextListener.class, scl1, listenerProps));

			Assert.assertTrue(scl1.initialized.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
			Assert.assertTrue(scl1.destroyed.get());
		}
	}

	@Test
	public void test_Listener4() throws Exception {

		BaseServletContextAttributeListener scal1 =
			new BaseServletContextAttributeListener();
		Servlet s1 = new BaseServlet("a");

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(ServletContextAttributeListener.class, scal1, listenerProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			registrations.add(getBundleContext().registerService(Servlet.class, s1, servletProps1));

			requestAdvisor.request("s");

			Assert.assertTrue(scal1.added.get());
			Assert.assertFalse(scal1.replaced.get());
			Assert.assertFalse(scal1.removed.get());

			requestAdvisor.request("s");

			Assert.assertTrue(scal1.added.get());
			Assert.assertTrue(scal1.replaced.get());
			Assert.assertFalse(scal1.removed.get());

			requestAdvisor.request("s");

			Assert.assertTrue(scal1.added.get());
			Assert.assertTrue(scal1.replaced.get());
			Assert.assertTrue(scal1.removed.get());

		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener5() throws Exception {

		BaseServletRequestListener srl1 = new BaseServletRequestListener();

		Servlet s1 = new BaseServlet("a");

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(ServletRequestListener.class, srl1, listenerProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			registrations.add(getBundleContext().registerService(Servlet.class, s1, servletProps1));

			requestAdvisor.request("s");

			Assert.assertTrue(srl1.initialized.get());
			Assert.assertTrue(srl1.destroyed.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener6() throws Exception {

		BaseServletRequestAttributeListener sral1 = new BaseServletRequestAttributeListener();

		Servlet s1 = new BaseServlet("a");

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(ServletRequestAttributeListener.class, sral1, listenerProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			registrations.add(getBundleContext().registerService(Servlet.class, s1, servletProps1));

			requestAdvisor.request("s");

			Assert.assertTrue(sral1.added.get());
			Assert.assertTrue(sral1.replaced.get());
			Assert.assertTrue(sral1.removed.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener7() throws Exception {

		BaseHttpSessionAttributeListener hsal1 =
			new BaseHttpSessionAttributeListener();

		Servlet s1 = new BaseServlet("test_Listener7");

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(HttpSessionAttributeListener.class, hsal1, listenerProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			registrations.add(getBundleContext().registerService(Servlet.class, s1, servletProps1));

			Map<String, List<String>> responseMap = requestAdvisor.request("s", null);

			Assert.assertTrue(hsal1.added.get());
			Assert.assertFalse(hsal1.replaced.get());
			Assert.assertFalse(hsal1.removed.get());

			List<String> list = responseMap.get("Set-Cookie");

			String sessionId = "";

			for (String string : list) {
				if (string.startsWith("JSESSIONID=")) {
					sessionId = string;

					int pos = sessionId.indexOf(';');
					if (pos != -1) {
						sessionId = sessionId.substring(0, pos);
					}
				}
			}

			Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
			requestHeaders.put("Cookie", Arrays.asList(sessionId));

			requestAdvisor.request("s", requestHeaders);

			Assert.assertTrue(hsal1.added.get());
			Assert.assertTrue(hsal1.replaced.get());
			Assert.assertFalse(hsal1.removed.get());

			requestAdvisor.request("s", requestHeaders);

			Assert.assertTrue(hsal1.added.get());
			Assert.assertTrue(hsal1.replaced.get());
			Assert.assertTrue(hsal1.removed.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener8() throws Exception {
		BaseHttpSessionIdListener hsil1 = new BaseHttpSessionIdListener();

		Servlet s1 = new BaseChangeSessionIdServlet("test_Listener8");

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(HttpSessionIdListener.class, hsil1, listenerProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S8");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			registrations.add(getBundleContext().registerService(Servlet.class, s1, servletProps1));

			requestAdvisor.request("s");

			Assert.assertTrue(hsil1.changed.get());
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener9() throws Exception {
		Servlet sA = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				RequestDispatcher requestDispatcher = req.getRequestDispatcher("/s9B");

				requestDispatcher.include(req, resp);
			}
		};
		Servlet sB = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				PrintWriter writer = resp.getWriter();
				writer.write("S9 included");
			}
		};

		BaseServletRequestListener srl1 = new BaseServletRequestListener();

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> listenerProps = new Hashtable<String, String>();
			listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(ServletRequestListener.class, srl1, listenerProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S9A");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s9A");
			registrations.add(getBundleContext().registerService(Servlet.class, sA, servletProps1));

			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S9B");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s9B");
			registrations.add(getBundleContext().registerService(Servlet.class, sB, servletProps1));

			String result = requestAdvisor.request("s9A");
			Assert.assertEquals("S9 included", result);

			Assert.assertEquals(0, srl1.number.get());

		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_Listener10() throws Exception {
		BaseServletContextListener scl1 = new BaseServletContextListener();
		BaseServletContextListener scl2 = new BaseServletContextListener();
		BaseServletContextListener scl3 = new BaseServletContextListener();

		Dictionary<String, String> listenerProps = new Hashtable<String, String>();
		listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
		registrations.add(getBundleContext().registerService(ServletContextListener.class, scl1, listenerProps));

		listenerProps = new Hashtable<String, String>();
		listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
		registrations.add(getBundleContext().registerService(ServletContextListener.class, scl2, listenerProps));

		Dictionary<String, String> contextProps = new Hashtable<String, String>();
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "a");
		contextProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/a");
		registrations.add(getBundleContext().registerService(ServletContextHelper.class, new ServletContextHelper(){}, contextProps));

		listenerProps = new Hashtable<String, String>();
		listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
		listenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=a)");
		registrations.add(getBundleContext().registerService(ServletContextListener.class, scl3, listenerProps));

		ServletContext servletContext1 = scl1.servletContext;
		ServletContext servletContext2 = scl2.servletContext;
		ServletContext servletContext3 = scl3.servletContext;

		Assert.assertNotNull(servletContext1);
		Assert.assertNotNull(servletContext2);
		Assert.assertNotNull(servletContext3);

		Assert.assertTrue(servletContext1.equals(servletContext1));
		Assert.assertTrue(servletContext2.equals(servletContext2));
		Assert.assertTrue(servletContext3.equals(servletContext3));

		Assert.assertTrue(servletContext1.equals(servletContext2));
		Assert.assertFalse(servletContext1.equals(servletContext3));
		Assert.assertFalse(servletContext2.equals(servletContext3));

		// Asserts two invocations return the same value
		Assert.assertEquals(servletContext1.hashCode(), servletContext1.hashCode());
		Assert.assertEquals(servletContext2.hashCode(), servletContext2.hashCode());
		Assert.assertEquals(servletContext3.hashCode(), servletContext3.hashCode());

		Assert.assertEquals(servletContext1.hashCode(), servletContext2.hashCode());
		Assert.assertNotEquals(servletContext1.hashCode(), servletContext3.hashCode());
		Assert.assertNotEquals(servletContext2.hashCode(), servletContext3.hashCode());
	}

	@Test
	public void test_Listener11() throws Exception {

		final AtomicInteger listenerBalance = new AtomicInteger(0);
		final AtomicReference<HttpSession> sessionReference = new AtomicReference<HttpSession>();

		ServletContextListener scl = new ServletContextListener() {

			@Override
			public void contextInitialized(ServletContextEvent arg0) {
			}

			@Override
			public void contextDestroyed(ServletContextEvent arg0) {
				listenerBalance.decrementAndGet();
			}
		};

		HttpSessionListener sl = new HttpSessionListener() {

			@Override
			public void sessionDestroyed(HttpSessionEvent se) {
				listenerBalance.incrementAndGet();
			}

			@Override
			public void sessionCreated(HttpSessionEvent se) {
			}
		};

		Servlet sA = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(
				HttpServletRequest req, HttpServletResponse resp)
				throws ServletException, IOException {

				HttpSession session = req.getSession();
				sessionReference.set(session);

				session.setAttribute("testAttribute", "testValue");
				PrintWriter writer = resp.getWriter();
				writer.write("S11 requested");
			}
		};

		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> scListenerProps = new Hashtable<String, String>();
			scListenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(ServletContextListener.class, scl, scListenerProps));

			Dictionary<String, String> sListenerProps = new Hashtable<String, String>();
			sListenerProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true");
			registrations.add(getBundleContext().registerService(HttpSessionListener.class, sl, sListenerProps));

			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S11");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s11");
			registrations.add(getBundleContext().registerService(Servlet.class, sA, servletProps1));

			String result = requestAdvisor.request("s11");
			Assert.assertEquals("S11 requested", result);
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}

		//Emulate session expiration to check sessionListener
		//is only called once (when unregister)
		HttpSession session = sessionReference.get();

		session.invalidate();

		Assert.assertEquals(0, listenerBalance.get());
	}

	@Test
	public void test_Async1() throws Exception {

		Servlet s1 = new BaseAsyncServlet("test_Listener8");
		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, Object> servletProps1 = new Hashtable<String, Object>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S1");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED, true);
			registrations.add(getBundleContext().registerService(Servlet.class, s1, servletProps1));

			String output1 = requestAdvisor.request("s");

			Assert.assertTrue(output1, output1.endsWith("test_Listener8"));
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_AsyncOutput1() throws Exception {
		Servlet s1 = new AsyncOutputServlet();
		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, Object> servletProps1 = new Hashtable<String, Object>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "AsyncOutputServlet");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/asyncOutput");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED, true);
			registrations.add(getBundleContext().registerService(Servlet.class, s1, servletProps1));

			String output1 = requestAdvisor.request("asyncOutput?iterations=2");

			Assert.assertEquals("write(int)", "01234567890123456789", output1);

			String output2 = requestAdvisor.request("asyncOutput?bytes=true&iterations=4");

			Assert.assertEquals("write(byte[], int, int)", "0123456789012345678901234567890123456789", output2);
		} finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void test_WBServlet1() throws Exception {
		String expected = "a";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("WBServlet1/a");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_WBServlet2() throws Exception {
		String expected = "bab";
		String actual;
		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();
			actual = requestAdvisor.request("WBServlet2/a");
		} finally {
			uninstallBundle(bundle);
		}
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void test_BufferedOutput() throws Exception {
		Collection<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
		try {
			Dictionary<String, String> servletProps1 = new Hashtable<String, String>();
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME, "S9");
			servletProps1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/s9");
			registrations.add(getBundleContext().registerService(Servlet.class, new BufferedServlet(), servletProps1));

			Map<String, List<String>> response = requestAdvisor.request(
				"s9", Collections.<String, List<String>>emptyMap());

			String responseCode = response.get("responseCode").get(0);
			Assert.assertEquals("200", responseCode);
		}
		finally {
			for (ServiceRegistration<?> registration : registrations) {
				registration.unregister();
			}
		}
	}

	@Test
	public void testWBServletChangeInitParams() throws Exception{
		BundleContext bundleContext = getBundleContext();
		Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
		serviceProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/prototype/*");
		TestServletPrototype testDriver = new TestServletPrototype(bundleContext);
		registrations.add(bundleContext.registerService(Servlet.class, testDriver, serviceProps));

			String actual;

			Map<String, String> params = new HashMap<String, String>();
			params.put(TEST_PROTOTYPE_NAME, testName.getMethodName());
			params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, '/' + testName.getMethodName());
			params.put(STATUS_PARAM, testName.getMethodName());
			actual = doRequest(CONFIGURE, params);
			Assert.assertEquals(testName.getMethodName(), actual);
			actual = requestAdvisor.request(testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);

			// change the init param
			params.put(STATUS_PARAM, "changed");
			doRequest(CONFIGURE, params);
			actual = requestAdvisor.request(testName.getMethodName());
			Assert.assertEquals("changed", actual);
	}

	@Test
	public void testWBServletChangePattern() throws Exception{
		BundleContext bundleContext = getBundleContext();
		Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
		serviceProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/prototype/*");
		TestServletPrototype testDriver = new TestServletPrototype(bundleContext);
		registrations.add(bundleContext.registerService(Servlet.class, testDriver, serviceProps));

		String actual;

		Map<String, String> params = new HashMap<String, String>();
		params.put(TEST_PROTOTYPE_NAME, testName.getMethodName());
		params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, '/' + testName.getMethodName());
		params.put(STATUS_PARAM, testName.getMethodName());
		actual = doRequest(CONFIGURE, params);
		Assert.assertEquals(testName.getMethodName(), actual);
		actual = requestAdvisor.request(testName.getMethodName());
		Assert.assertEquals(testName.getMethodName(), actual);

		// change the pattern
		params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/changed");
		doRequest(CONFIGURE, params);
		actual = requestAdvisor.request("changed");
		Assert.assertEquals(testName.getMethodName(), actual);
	}

	@Test
	public void testWBServletChangeRanking() throws Exception{
		BundleContext bundleContext = getBundleContext();
		Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
		serviceProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/prototype/*");
		TestServletPrototype testDriver = new TestServletPrototype(bundleContext);
		registrations.add(bundleContext.registerService(Servlet.class, testDriver, serviceProps));

		String actual;

		// Configure two servlets with the second one registered ranking higher
		Map<String, String> params1 = new HashMap<String, String>();
		params1.put(TEST_PROTOTYPE_NAME, testName.getMethodName() + 1);
		params1.put(Constants.SERVICE_RANKING, "1");
		params1.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, '/' + testName.getMethodName());
		params1.put(STATUS_PARAM, testName.getMethodName() + 1);
		actual = doRequest(CONFIGURE, params1);
		Assert.assertEquals(testName.getMethodName() + 1, actual);

		Map<String, String> params2 = new HashMap<String, String>();
		params2.put(TEST_PROTOTYPE_NAME, testName.getMethodName() + 2);
		params2.put(Constants.SERVICE_RANKING, "2");
		params2.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, '/' + testName.getMethodName());
		params2.put(STATUS_PARAM, testName.getMethodName() + 2);
		actual = doRequest(CONFIGURE, params2);
		Assert.assertEquals(testName.getMethodName() + 2, actual);

		// Confirm the second registered (higher ranked) gets used
		actual = requestAdvisor.request(testName.getMethodName());
		Assert.assertEquals(testName.getMethodName() + 2, actual);

		// change the ranking to use the first servlet registered
		params2.put(Constants.SERVICE_RANKING, "0");
		doRequest(CONFIGURE, params2);
		actual = requestAdvisor.request(testName.getMethodName());
		Assert.assertEquals(testName.getMethodName() + 1, actual);

		// Unregister the first servlet should cause the second servlet to be used
		actual = doRequest(UNREGISTER, Collections.singletonMap(TEST_PROTOTYPE_NAME, testName.getMethodName() + 1));
		Assert.assertEquals(testName.getMethodName() + 1, actual);

		// Confirm the second registered is used
		actual = requestAdvisor.request(testName.getMethodName());
		Assert.assertEquals(testName.getMethodName() + 2, actual);
	}

	@Test
	public void testWBServletDefaultContextAdaptor1() throws Exception{
		BundleContext bundleContext = getBundleContext();
		Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
		serviceProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/prototype/*");
		TestServletPrototype testDriver = new TestServletPrototype(bundleContext);
		registrations.add(bundleContext.registerService(Servlet.class, testDriver, serviceProps));

		Dictionary<String, String> helperProps = new Hashtable<String, String>();
		helperProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "testContext" + testName.getMethodName());
		helperProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/testContext");
		helperProps.put(TEST_PATH_CUSTOMIZER_NAME, testName.getMethodName());
		ServiceRegistration<ServletContextHelper> helperReg = getBundleContext().registerService(ServletContextHelper.class, new TestServletContextHelperFactory(), helperProps);

		ServiceRegistration<ContextPathCustomizer> pathAdaptorReg = null;
		try {
			Map<String, String> params = new HashMap<String, String>();
			params.put(TEST_PROTOTYPE_NAME, testName.getMethodName());
			params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, '/' + testName.getMethodName());
			params.put(STATUS_PARAM, testName.getMethodName());
			params.put("servlet.init." + TEST_PATH_CUSTOMIZER_NAME, testName.getMethodName());
			String actual = doRequest(CONFIGURE, params);
			Assert.assertEquals(testName.getMethodName(), actual);

			actual = requestAdvisor.request(testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);

			ContextPathCustomizer pathAdaptor = new TestContextPathAdaptor("(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" + "testContext" + testName.getMethodName() + ")", null, testName.getMethodName());
			pathAdaptorReg = getBundleContext().registerService(ContextPathCustomizer.class, pathAdaptor, null);

			actual = requestAdvisor.request("testContext/" + testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);

			pathAdaptorReg.unregister();
			pathAdaptorReg = null;

			actual = requestAdvisor.request(testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);
			doRequest(UNREGISTER, params);
		} finally {
			helperReg.unregister();
			if (pathAdaptorReg != null) {
				pathAdaptorReg.unregister();
			}
		}
	}

	@Test
	public void testWBServletDefaultContextAdaptor2() throws Exception{
		BundleContext bundleContext = getBundleContext();
		Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
		serviceProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/prototype/*");
		TestServletPrototype testDriver = new TestServletPrototype(bundleContext);
		registrations.add(bundleContext.registerService(Servlet.class, testDriver, serviceProps));

		Dictionary<String, String> helperProps = new Hashtable<String, String>();
		helperProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "testContext" + testName.getMethodName());
		helperProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/testContext");
		helperProps.put(TEST_PATH_CUSTOMIZER_NAME, testName.getMethodName());
		ServiceRegistration<ServletContextHelper> helperReg = getBundleContext().registerService(ServletContextHelper.class, new TestServletContextHelperFactory(), helperProps);

		ServiceRegistration<ContextPathCustomizer> pathAdaptorReg = null;
		try {
			Map<String, String> params = new HashMap<String, String>();
			params.put(TEST_PROTOTYPE_NAME, testName.getMethodName());
			params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, '/' + testName.getMethodName());
			params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" + "testContext" + testName.getMethodName() + ")");
			params.put(STATUS_PARAM, testName.getMethodName());
			params.put("servlet.init." + TEST_PATH_CUSTOMIZER_NAME, testName.getMethodName());
			String actual = doRequest(CONFIGURE, params);
			Assert.assertEquals(testName.getMethodName(), actual);

			actual = requestAdvisor.request("testContext/" + testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);

			ContextPathCustomizer pathAdaptor = new TestContextPathAdaptor(null, "testPrefix", testName.getMethodName());
			pathAdaptorReg = getBundleContext().registerService(ContextPathCustomizer.class, pathAdaptor, null);

			actual = requestAdvisor.request("testPrefix/testContext/" + testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);

			pathAdaptorReg.unregister();
			pathAdaptorReg = null;

			actual = requestAdvisor.request("testContext/" + testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);
			doRequest(UNREGISTER, params);
		} finally {
			helperReg.unregister();
			if (pathAdaptorReg != null) {
				pathAdaptorReg.unregister();
			}
		}
	}

	@Test
	public void testWBServletDefaultContextAdaptor3() throws Exception{
		BundleContext bundleContext = getBundleContext();
		Dictionary<String, Object> serviceProps = new Hashtable<String, Object>();
		serviceProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/prototype/*");
		TestServletPrototype testDriver = new TestServletPrototype(bundleContext);
		registrations.add(bundleContext.registerService(Servlet.class, testDriver, serviceProps));

		// test the ContextPathCustomizer with a ServletContextHelper that has a '/' context path
		Dictionary<String, String> helperProps = new Hashtable<String, String>();
		helperProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, "testContext" + testName.getMethodName());
		helperProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/");
		helperProps.put(TEST_PATH_CUSTOMIZER_NAME, testName.getMethodName());
		ServiceRegistration<ServletContextHelper> helperReg = getBundleContext().registerService(ServletContextHelper.class, new TestServletContextHelperFactory(), helperProps);

		ServiceRegistration<ContextPathCustomizer> pathAdaptorReg = null;
		try {
			Map<String, String> params = new HashMap<String, String>();
			params.put(TEST_PROTOTYPE_NAME, testName.getMethodName());
			params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, '/' + testName.getMethodName());
			params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" + "testContext" + testName.getMethodName() + ")");
			params.put(STATUS_PARAM, testName.getMethodName());
			params.put("servlet.init." + TEST_PATH_CUSTOMIZER_NAME, testName.getMethodName());
			String actual = doRequest(CONFIGURE, params);
			Assert.assertEquals(testName.getMethodName(), actual);

			actual = requestAdvisor.request(testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);

			ContextPathCustomizer pathAdaptor = new TestContextPathAdaptor(null, "testPrefix", testName.getMethodName());
			pathAdaptorReg = getBundleContext().registerService(ContextPathCustomizer.class, pathAdaptor, null);

			actual = requestAdvisor.request("testPrefix/" + testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);

			pathAdaptorReg.unregister();
			pathAdaptorReg = null;

			actual = requestAdvisor.request(testName.getMethodName());
			Assert.assertEquals(testName.getMethodName(), actual);
			doRequest(UNREGISTER, params);
		} finally {
			helperReg.unregister();
			if (pathAdaptorReg != null) {
				pathAdaptorReg.unregister();
			}
		}
	}

	@Test
	public void testHttpContextSetUser() throws ServletException, NamespaceException, IOException {
		ExtendedHttpService extendedHttpService = (ExtendedHttpService)getHttpService();

		HttpContext testContext = new HttpContext() {

			@Override
			public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
				request.setAttribute(HttpContext.REMOTE_USER, "TEST");
				request.setAttribute(HttpContext.AUTHENTICATION_TYPE, "Basic");
				return true;
			}

			@Override
			public URL getResource(String name) {
				return null;
			}

			@Override
			public String getMimeType(String name) {
				return null;
			}
		};
		HttpServlet testServlet = new HttpServlet() {
			private static final long serialVersionUID = 1L;

			@Override
			protected void doGet(HttpServletRequest req, HttpServletResponse resp)
					throws ServletException, IOException {
				resp.setContentType("text/html");
				PrintWriter out = resp.getWriter();
				out.print("USER: " + req.getRemoteUser() + " AUTH_TYPE: " + req.getAuthType());
			}

		};
		extendedHttpService.registerServlet("/" + testName.getMethodName(), testServlet, null, testContext);

		String expected = "USER: TEST AUTH_TYPE: Basic";
		String actual = requestAdvisor.request(testName.getMethodName());
		Assert.assertEquals(expected, actual);
	}

	@Test
	public void testHTTPSEndpoint() throws Exception {
		stopJetty();
		File keyStoreFile = getBundleContext().getDataFile("server-keystore.jks");
		URL keyStoreURL = getClass().getResource("server-keystore.jks");
		if (!keyStoreFile.exists()) {
			Files.copy(keyStoreURL.openStream(), keyStoreFile.toPath());
		}

		startJettyWithSSL("8443", keyStoreFile.getAbsolutePath(), "secret", "secret");

		Bundle bundle = installBundle(TEST_BUNDLE_1);
		try {
			bundle.start();

			String actual = requestAdvisor.requestHttps("TestServlet10");
			assertEquals("Expected output not found", "a", actual);
		} finally {
			uninstallBundle(bundle);
			stopJettyWithSSL();
		}
	}
}
