Readd support for application extension
diff --git a/jax-rs.itests/src/main/java/test/JaxrsTest.java b/jax-rs.itests/src/main/java/test/JaxrsTest.java
index 3fc9c52..f5b434b 100644
--- a/jax-rs.itests/src/main/java/test/JaxrsTest.java
+++ b/jax-rs.itests/src/main/java/test/JaxrsTest.java
@@ -105,6 +105,180 @@
     }
 
     @Test
+    public void testApplicationEndpointExtension() {
+        Client client = createClient();
+
+        WebTarget webTarget = client.
+            target("http://localhost:8080").
+            path("/test-application").
+            path("extended");
+
+        ServiceRegistration<?> applicationRegistration = null;
+
+        ServiceRegistration<?> serviceRegistration = null;
+
+        try {
+            applicationRegistration = registerApplication();
+
+            serviceRegistration = registerAddon(
+                "osgi.jaxrs.application.select",
+                "(osgi.jaxrs.application.base=/test-application)");
+
+            assertEquals(
+                "Hello extended",
+                webTarget.request().get().readEntity(String.class));
+        }
+        finally {
+            if (applicationRegistration != null) {
+                applicationRegistration.unregister();
+            }
+            if (serviceRegistration != null) {
+                serviceRegistration.unregister();
+            }
+        }
+    }
+
+    @Test
+    public void testApplicationEndpointExtensionReadd() {
+        Client client = createClient();
+
+        WebTarget webTarget = client.
+            target("http://localhost:8080").
+            path("/test-application").
+            path("extended");
+
+        ServiceRegistration<?> applicationRegistration = null;
+
+        try {
+            applicationRegistration = registerApplication();
+
+            Runnable testCase = () -> {
+                assertEquals(webTarget.request().get().getStatus(), 404);
+
+                ServiceRegistration<?> serviceRegistration = null;
+
+                try {
+                    serviceRegistration = registerAddon(
+                        "osgi.jaxrs.application.select",
+                        "(osgi.jaxrs.application.base=/test-application)");
+
+                    assertEquals(
+                        "Hello extended",
+                        webTarget.request().get().readEntity(String.class));
+                }
+                finally {
+                    if (serviceRegistration != null) {
+                        serviceRegistration.unregister();
+                    }
+                }
+            };
+
+            testCase.run();
+
+            testCase.run();
+        }
+        finally {
+            if (applicationRegistration != null) {
+                applicationRegistration.unregister();
+            }
+
+        }
+    }
+
+    @Test
+    public void testApplicationProviderExtension() {
+        Client client = createClient();
+
+        WebTarget webTarget = client.
+            target("http://localhost:8080").
+            path("/test-application");
+
+        ServiceRegistration<?> applicationRegistration = null;
+
+        ServiceRegistration<?> filterRegistration = null;
+
+        try {
+            applicationRegistration = registerApplication();
+
+            filterRegistration = registerFilter(
+                "osgi.jaxrs.application.select",
+                "(osgi.jaxrs.application.base=/test-application)");
+
+            Response response = webTarget.request().get();
+
+            assertEquals(
+                "Hello application",
+                response.readEntity(String.class));
+
+            assertEquals(
+                response.getHeaders().getFirst("Filtered"),
+                "true");
+        }
+        finally {
+            if (applicationRegistration != null) {
+                applicationRegistration.unregister();
+            }
+            if (filterRegistration != null) {
+                filterRegistration.unregister();
+            }
+        }
+    }
+
+    @Test
+    public void testApplicationProviderExtensionReadd() {
+        Client client = createClient();
+
+        WebTarget webTarget = client.
+            target("http://localhost:8080").
+            path("/test-application");
+
+        ServiceRegistration<?> applicationRegistration = null;
+
+        try {
+            applicationRegistration = registerApplication();
+
+            assertEquals(
+                "Hello application",
+                webTarget.request().get().readEntity(String.class));
+
+            Runnable testCase = () ->  {
+                Response response = webTarget.request().get();
+
+                assertNull(response.getHeaders().getFirst("Filtered"));
+
+                ServiceRegistration<?> filterRegistration = null;
+
+                try {
+                    filterRegistration = registerFilter(
+                        "osgi.jaxrs.application.select",
+                        "(osgi.jaxrs.application.base=/test-application)");
+
+                    response = webTarget.request().get();
+
+                    assertEquals(
+                        response.getHeaders().getFirst("Filtered"),
+                        "true");
+                }
+                finally {
+                    if (filterRegistration != null) {
+                        filterRegistration.unregister();
+                    }
+                }
+            };
+
+            testCase.run();
+
+            testCase.run();
+
+        }
+        finally {
+            if (applicationRegistration != null) {
+                applicationRegistration.unregister();
+            }
+        }
+    }
+
+    @Test
     public void testStandaloneEndPoint() {
         Client client = createClient();
 
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
index 4260db0..7ca04f5 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
@@ -49,6 +49,7 @@
 import static org.apache.aries.osgi.functional.OSGi.onClose;
 import static org.apache.aries.osgi.functional.OSGi.register;
 import static org.apache.aries.osgi.functional.OSGi.serviceReferences;
+import static org.apache.aries.osgi.functional.OSGi.services;
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME;
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
 import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME;
@@ -60,6 +61,7 @@
     private OSGiResult<?> _applicationsResult;
     private OSGiResult<?> _singletonsResult;
     private OSGiResult<?> _extensionsResult;
+    private OSGiResult<?> _applicationSingletonsResult;
 
     private static <T> OSGi<T> service(ServiceReference<T> serviceReference) {
         return
@@ -135,6 +137,18 @@
         );
 
         _extensionsResult = extensions.run(bundleContext);
+
+        OSGi<?> applicationSingletons =
+            serviceReferences("(osgi.jaxrs.application.select=*)").
+                flatMap(ref ->
+            just(ref.getProperty("osgi.jaxrs.application.select").toString()).
+                flatMap(applicationFilter ->
+            services(CXFJaxRsServiceRegistrator.class, applicationFilter).
+                flatMap(registrator ->
+            safeRegisterEndpoint(ref, registrator)
+        )));
+
+        _applicationSingletonsResult = applicationSingletons.run(bundleContext);
     }
 
     /**
@@ -261,6 +275,7 @@
     
     @Override
     public void stop(BundleContext context) throws Exception {
+        _applicationSingletonsResult.close();
         _applicationsResult.close();
         _extensionsResult.close();
         _singletonsResult.close();