Split integration tests into separate classes for easier maintenance

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@805802 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java
index 28d4b9d..aa589cd 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentConfigurationTest.java
@@ -19,114 +19,21 @@
 package org.apache.felix.scr.integration;
 
 
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.provision;
-import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanDir;
-import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.withBnd;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
 import junit.framework.TestCase;
 
 import org.apache.felix.scr.Component;
-import org.apache.felix.scr.ScrService;
-import org.apache.felix.scr.integration.components.MyTinyBundle;
 import org.apache.felix.scr.integration.components.SimpleComponent;
-import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Inject;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.Configuration;
 import org.ops4j.pax.exam.junit.JUnit4TestRunner;
-import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.util.tracker.ServiceTracker;
 
 
 @RunWith(JUnit4TestRunner.class)
-public class ComponentConfigurationTest
+public class ComponentConfigurationTest extends ComponentTestBase
 {
 
-    @Inject
-    private BundleContext bundleContext;
-
-    private Bundle bundle;
-
-    private ServiceTracker scrTracker;
-
-    private ServiceTracker configAdminTracker;
-
-    private static final String PROP_NAME = "theValue";
-    private static final Dictionary<String, String> theConfig;
-
-    static
-    {
-        theConfig = new Hashtable<String, String>();
-        theConfig.put( PROP_NAME, PROP_NAME );
-    }
-
-
-    @Configuration
-    public static Option[] configuration()
-    {
-        return options( provision( scanDir( "target" ).filter( "*.jar" ), mavenBundle( "org.ops4j.pax.swissbox",
-            "pax-swissbox-tinybundles", "1.0.0" ), mavenBundle( "org.apache.felix", "org.apache.felix.configadmin",
-            "1.0.10" ) )
-//                    , PaxRunnerOptions.vmOption( "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=30303" )
-        //            PaxRunnerOptions.timeout( 0 )
-
-        );
-    }
-
-
-    @Before
-    public void setUp() throws BundleException
-    {
-        scrTracker = new ServiceTracker( bundleContext, ScrService.class.getName(), null );
-        scrTracker.open();
-        configAdminTracker = new ServiceTracker( bundleContext, ConfigurationAdmin.class.getName(), null );
-        configAdminTracker.open();
-
-        //        final InputStream bundleStream = newBundle()
-        final InputStream bundleStream = new MyTinyBundle().addResource( "OSGI-INF/components.xml",
-            getClass().getResource( "/integration_test_simple_components.xml" ) ).prepare(
-            withBnd().set( Constants.BUNDLE_SYMBOLICNAME, "simplecomponent" ).set( Constants.BUNDLE_VERSION, "0.0.11" )
-                .set( Constants.IMPORT_PACKAGE, "org.apache.felix.scr.integration.components" ).set(
-                    "Service-Component", "OSGI-INF/components.xml" ) ).build( TinyBundles.asStream() );
-
-        bundle = bundleContext.installBundle( "test:SimpleComponent", bundleStream );
-
-        bundle.start();
-    }
-
-
-    @After
-    public void tearDown() throws BundleException
-    {
-        bundle.stop();
-        bundle.uninstall();
-
-        configAdminTracker.close();
-        configAdminTracker = null;
-        scrTracker.close();
-        scrTracker = null;
-    }
-
-
     @Test
     public void test_SimpleComponent_configuration_ignore()
     {
@@ -162,13 +69,6 @@
     }
 
 
-    @Test
-    public void test_SimpleComponent_service()
-    {
-        test_service( "ServiceComponent" );
-    }
-
-
     private void test_configuration_ignore( final String componentName )
     {
         final String pid = componentName + ".configuration.ignore";
@@ -242,7 +142,6 @@
         TestCase.assertNotNull( secondInstance );
         TestCase.assertEquals( PROP_NAME, secondInstance.getProperty( PROP_NAME ) );
 
-
         deleteConfig( pid );
         delay();
 
@@ -252,8 +151,10 @@
         TestCase.assertNull( thirdInstance.getProperty( PROP_NAME ) );
 
         TestCase.assertNotSame( "Expect new instance object after reconfiguration", firstInstance, secondInstance );
-        TestCase.assertNotSame( "Expect new instance object after configuration deletion (1)", firstInstance, thirdInstance);
-        TestCase.assertNotSame( "Expect new instance object after configuration deletion (2)", secondInstance, thirdInstance);
+        TestCase.assertNotSame( "Expect new instance object after configuration deletion (1)", firstInstance,
+            thirdInstance );
+        TestCase.assertNotSame( "Expect new instance object after configuration deletion (2)", secondInstance,
+            thirdInstance );
 
         component.disable();
         delay();
@@ -388,8 +289,8 @@
         TestCase.assertEquals( Component.STATE_ACTIVE, twoConfigs[0].getState() );
         TestCase.assertEquals( Component.STATE_DISABLED, twoConfigs[1].getState() );
         TestCase.assertEquals( 1, SimpleComponent.INSTANCES.size() );
-        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( pid0 ) );
-        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( pid1 ) );
+        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( twoConfigs[0].getId() ) );
+        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( twoConfigs[1].getId() ) );
 
         // enable second component
         twoConfigs[1].enable();
@@ -399,8 +300,8 @@
         TestCase.assertEquals( Component.STATE_ACTIVE, twoConfigs[0].getState() );
         TestCase.assertEquals( Component.STATE_ACTIVE, twoConfigs[1].getState() );
         TestCase.assertEquals( 2, SimpleComponent.INSTANCES.size() );
-        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( pid0 ) );
-        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( pid1 ) );
+        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( twoConfigs[0].getId() ) );
+        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( twoConfigs[1].getId() ) );
 
         // delete a configuration
         deleteConfig( pid0 );
@@ -412,8 +313,8 @@
         TestCase.assertEquals( 1, oneConfig.length );
         TestCase.assertEquals( Component.STATE_ACTIVE, oneConfig[0].getState() );
         TestCase.assertEquals( 1, SimpleComponent.INSTANCES.size() );
-        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( pid0 ) );
-        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( pid1 ) );
+        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( twoConfigs[0].getId() ) );
+        TestCase.assertTrue( SimpleComponent.INSTANCES.containsKey( twoConfigs[1].getId() ) );
 
         // delete second configuration
         deleteConfig( pid1 );
@@ -425,8 +326,8 @@
         TestCase.assertEquals( 1, configsDeleted.length );
         TestCase.assertEquals( Component.STATE_UNSATISFIED, configsDeleted[0].getState() );
         TestCase.assertEquals( 0, SimpleComponent.INSTANCES.size() );
-        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( pid0 ) );
-        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( pid1 ) );
+        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( twoConfigs[0].getId() ) );
+        TestCase.assertFalse( SimpleComponent.INSTANCES.containsKey( twoConfigs[1].getId() ) );
 
     }
 
@@ -475,151 +376,4 @@
                 && !propKey.startsWith( "." ) );
         }
     }
-
-
-    private Component findComponentByName( String name )
-    {
-        ScrService scr = ( ScrService ) scrTracker.getService();
-        if ( scr != null )
-        {
-            Component[] components = scr.getComponents();
-            if ( components != null )
-            {
-                for ( Component component : components )
-                {
-                    if ( name.equals( component.getName() ) )
-                    {
-                        return component;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-
-    private Component[] findComponentsByName( String name )
-    {
-        ScrService scr = ( ScrService ) scrTracker.getService();
-        if ( scr != null )
-        {
-            List<Component> cList = new ArrayList<Component>();
-            Component[] components = scr.getComponents();
-            if ( components != null )
-            {
-                for ( Component component : components )
-                {
-                    if ( name.equals( component.getName() ) )
-                    {
-                        cList.add( component );
-                    }
-                }
-            }
-
-            if ( !cList.isEmpty() )
-            {
-                return cList.toArray( new Component[cList.size()] );
-            }
-        }
-
-        return null;
-    }
-
-
-    private static void delay()
-    {
-        try
-        {
-            Thread.sleep( 300 );
-        }
-        catch ( InterruptedException ie )
-        {
-            // dont care
-        }
-    }
-
-
-    private ConfigurationAdmin getConfigurationAdmin()
-    {
-        ConfigurationAdmin ca = ( ConfigurationAdmin ) configAdminTracker.getService();
-        if ( ca == null )
-        {
-            TestCase.fail( "Missing ConfigurationAdmin service" );
-        }
-        return ca;
-    }
-
-
-    private void configure( String pid )
-    {
-        ConfigurationAdmin ca = getConfigurationAdmin();
-        try
-        {
-            org.osgi.service.cm.Configuration config = ca.getConfiguration( pid, null );
-            config.update( theConfig );
-        }
-        catch ( IOException ioe )
-        {
-            TestCase.fail( "Failed updating configuration " + pid + ": " + ioe.toString() );
-        }
-    }
-
-
-    private void deleteConfig( String pid )
-    {
-        ConfigurationAdmin ca = getConfigurationAdmin();
-        try
-        {
-            org.osgi.service.cm.Configuration config = ca.getConfiguration( pid );
-            config.delete();
-        }
-        catch ( IOException ioe )
-        {
-            TestCase.fail( "Failed deleting configuration " + pid + ": " + ioe.toString() );
-        }
-    }
-
-
-    private String createFactoryConfiguration( String factoryPid )
-    {
-        ConfigurationAdmin ca = getConfigurationAdmin();
-        try
-        {
-            org.osgi.service.cm.Configuration config = ca.createFactoryConfiguration( factoryPid, null );
-            config.update( theConfig );
-            return config.getPid();
-        }
-        catch ( IOException ioe )
-        {
-            TestCase.fail( "Failed updating factory configuration " + factoryPid + ": " + ioe.toString() );
-            return null;
-        }
-    }
-
-
-    private void deleteFactoryConfigurations( String factoryPid )
-    {
-        ConfigurationAdmin ca = getConfigurationAdmin();
-        try
-        {
-            final String filter = "(service.factoryPid=" + factoryPid + ")";
-            org.osgi.service.cm.Configuration[] configs = ca.listConfigurations( filter );
-            if ( configs != null )
-            {
-                for ( org.osgi.service.cm.Configuration configuration : configs )
-                {
-                    configuration.delete();
-                }
-            }
-        }
-        catch ( InvalidSyntaxException ise )
-        {
-            // unexpected
-        }
-        catch ( IOException ioe )
-        {
-            TestCase.fail( "Failed deleting configurations " + factoryPid + ": " + ioe.toString() );
-        }
-    }
 }
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
new file mode 100644
index 0000000..6448a94
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.integration;
+
+
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanDir;
+import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.withBnd;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import junit.framework.TestCase;
+
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.ScrService;
+import org.apache.felix.scr.integration.components.MyTinyBundle;
+import org.junit.After;
+import org.junit.Before;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+
+public abstract class ComponentTestBase
+{
+
+    @Inject
+    protected BundleContext bundleContext;
+
+    protected Bundle bundle;
+
+    protected ServiceTracker scrTracker;
+
+    protected ServiceTracker configAdminTracker;
+
+    protected static final String PROP_NAME = "theValue";
+    protected static final Dictionary<String, String> theConfig;
+
+    static
+    {
+        theConfig = new Hashtable<String, String>();
+        theConfig.put( PROP_NAME, PROP_NAME );
+    }
+
+
+    @Configuration
+    public static Option[] configuration()
+    {
+        return options(
+            provision(
+                scanDir( "target" ).filter( "*.jar" ),
+                mavenBundle( "org.ops4j.pax.swissbox", "pax-swissbox-tinybundles", "1.0.0" ),
+                mavenBundle( "org.apache.felix", "org.apache.felix.configadmin", "1.0.10" )
+             )
+//             , PaxRunnerOptions.vmOption( "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=30303" )
+        );
+    }
+
+
+    @Before
+    public void setUp() throws BundleException
+    {
+        scrTracker = new ServiceTracker( bundleContext, ScrService.class.getName(), null );
+        scrTracker.open();
+        configAdminTracker = new ServiceTracker( bundleContext, ConfigurationAdmin.class.getName(), null );
+        configAdminTracker.open();
+
+        //        final InputStream bundleStream = newBundle()
+        final InputStream bundleStream = new MyTinyBundle().addResource( "OSGI-INF/components.xml",
+            getClass().getResource( "/integration_test_simple_components.xml" ) ).prepare(
+            withBnd().set( Constants.BUNDLE_SYMBOLICNAME, "simplecomponent" ).set( Constants.BUNDLE_VERSION, "0.0.11" )
+                .set( Constants.IMPORT_PACKAGE, "org.apache.felix.scr.integration.components" ).set(
+                    "Service-Component", "OSGI-INF/components.xml" ) ).build( TinyBundles.asStream() );
+
+        bundle = bundleContext.installBundle( "test:SimpleComponent", bundleStream );
+
+        bundle.start();
+    }
+
+
+    @After
+    public void tearDown() throws BundleException
+    {
+        bundle.stop();
+        bundle.uninstall();
+
+        configAdminTracker.close();
+        configAdminTracker = null;
+        scrTracker.close();
+        scrTracker = null;
+    }
+
+
+    protected Component findComponentByName( String name )
+    {
+        ScrService scr = ( ScrService ) scrTracker.getService();
+        if ( scr != null )
+        {
+            Component[] components = scr.getComponents();
+            if ( components != null )
+            {
+                for ( Component component : components )
+                {
+                    if ( name.equals( component.getName() ) )
+                    {
+                        return component;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+
+    protected Component[] findComponentsByName( String name )
+    {
+        ScrService scr = ( ScrService ) scrTracker.getService();
+        if ( scr != null )
+        {
+            List<Component> cList = new ArrayList<Component>();
+            Component[] components = scr.getComponents();
+            if ( components != null )
+            {
+                for ( Component component : components )
+                {
+                    if ( name.equals( component.getName() ) )
+                    {
+                        cList.add( component );
+                    }
+                }
+            }
+
+            if ( !cList.isEmpty() )
+            {
+                return cList.toArray( new Component[cList.size()] );
+            }
+        }
+
+        return null;
+    }
+
+
+    protected static void delay()
+    {
+        try
+        {
+            Thread.sleep( 300 );
+        }
+        catch ( InterruptedException ie )
+        {
+            // dont care
+        }
+    }
+
+
+    protected ConfigurationAdmin getConfigurationAdmin()
+    {
+        ConfigurationAdmin ca = ( ConfigurationAdmin ) configAdminTracker.getService();
+        if ( ca == null )
+        {
+            TestCase.fail( "Missing ConfigurationAdmin service" );
+        }
+        return ca;
+    }
+
+
+    protected void configure( String pid )
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            org.osgi.service.cm.Configuration config = ca.getConfiguration( pid, null );
+            config.update( theConfig );
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed updating configuration " + pid + ": " + ioe.toString() );
+        }
+    }
+
+
+    protected void deleteConfig( String pid )
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            org.osgi.service.cm.Configuration config = ca.getConfiguration( pid );
+            config.delete();
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed deleting configuration " + pid + ": " + ioe.toString() );
+        }
+    }
+
+
+    protected String createFactoryConfiguration( String factoryPid )
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            org.osgi.service.cm.Configuration config = ca.createFactoryConfiguration( factoryPid, null );
+            config.update( theConfig );
+            return config.getPid();
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed updating factory configuration " + factoryPid + ": " + ioe.toString() );
+            return null;
+        }
+    }
+
+
+    protected void deleteFactoryConfigurations( String factoryPid )
+    {
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        try
+        {
+            final String filter = "(service.factoryPid=" + factoryPid + ")";
+            org.osgi.service.cm.Configuration[] configs = ca.listConfigurations( filter );
+            if ( configs != null )
+            {
+                for ( org.osgi.service.cm.Configuration configuration : configs )
+                {
+                    configuration.delete();
+                }
+            }
+        }
+        catch ( InvalidSyntaxException ise )
+        {
+            // unexpected
+        }
+        catch ( IOException ioe )
+        {
+            TestCase.fail( "Failed deleting configurations " + factoryPid + ": " + ioe.toString() );
+        }
+    }
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ServiceComponentTest.java b/scr/src/test/java/org/apache/felix/scr/integration/ServiceComponentTest.java
new file mode 100644
index 0000000..94d4dc8
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ServiceComponentTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.integration;
+
+
+import junit.framework.TestCase;
+
+import org.apache.felix.scr.Component;
+import org.apache.felix.scr.integration.components.SimpleComponent;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.ServiceReference;
+
+
+@RunWith(JUnit4TestRunner.class)
+public class ServiceComponentTest extends ComponentTestBase
+{
+
+    @Test
+    public void test_SimpleComponent_service()
+    {
+        final String pid = "ServiceComponent";
+
+        // one single component exists without configuration
+        final Component component = findComponentByName( pid );
+        TestCase.assertNotNull( component );
+        TestCase.assertEquals( Component.STATE_DISABLED, component.getState() );
+
+        component.enable();
+        delay();
+
+        final SimpleComponent instance = SimpleComponent.INSTANCE;
+        TestCase.assertEquals( Component.STATE_ACTIVE, component.getState() );
+        TestCase.assertNotNull( instance );
+
+        // assert component properties (all !)
+        TestCase.assertEquals( "required", instance.getProperty( "prop.public" ) );
+        TestCase.assertEquals( "private", instance.getProperty( ".prop.private" ) );
+
+        // get the service
+        ServiceReference reference = bundleContext.getServiceReference( "java.lang.Object" );
+        TestCase.assertNotNull( reference );
+        try
+        {
+            TestCase.assertEquals( instance, bundleContext.getService( reference ) );
+        }
+        finally
+        {
+            bundleContext.ungetService( reference );
+        }
+
+        // check service properties
+        TestCase.assertEquals( "required", reference.getProperty( "prop.public" ) );
+        TestCase.assertNull( reference.getProperty( ".prop.private" ) );
+
+        // check property keys do not contain private keys
+        for ( String propKey : reference.getPropertyKeys() )
+        {
+            TestCase.assertTrue( "Property key [" + propKey
+                + "] must have at least one character and not start with a dot", propKey.length() > 0
+                && !propKey.startsWith( "." ) );
+        }
+    }
+}