Merge pull request #113 from chackoj/ARIES-2000

[jndi][ARIES-2000] Swallow exceptions when trying every ObjectFactory…
diff --git a/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java b/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
index bda5f69..4d195ee 100644
--- a/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
+++ b/jndi/jndi-core/src/main/java/org/apache/aries/jndi/startup/Activator.java
@@ -148,14 +148,14 @@
         icfBuilders = new CachingServiceTracker<>(trackerBundleContext, InitialContextFactoryBuilder.class);
         urlObjectFactoryFinders = new CachingServiceTracker<>(trackerBundleContext, URLObjectFactoryFinder.class);
 
-        if (!disableBuilder(context)) {
+        if (!isPropertyEnabled(context, DISABLE_BUILDER)) {
             try {
                 OSGiInitialContextFactoryBuilder builder = new OSGiInitialContextFactoryBuilder();
                 try {
                     NamingManager.setInitialContextFactoryBuilder(builder);
                 } catch (IllegalStateException e) {
                     // use reflection to force the builder to be used
-                    if (forceBuilder(context)) {
+                    if (isPropertyEnabled(context, FORCE_BUILDER)) {
                         originalICFBuilder = swapStaticField(InitialContextFactoryBuilder.class, builder);
                     }
                 }
@@ -178,7 +178,7 @@
                     NamingManager.setObjectFactoryBuilder(builder);
                 } catch (IllegalStateException e) {
                     // use reflection to force the builder to be used
-                    if (forceBuilder(context)) {
+                    if (isPropertyEnabled(context, FORCE_BUILDER)) {
                         originalOFBuilder = swapStaticField(ObjectFactoryBuilder.class, builder);
                     }
                 }
@@ -196,21 +196,10 @@
             }
         }
 
-        context.registerService(JNDIProviderAdmin.class.getName(),
-                new ProviderAdminServiceFactory(context),
-                null);
-
-        context.registerService(InitialContextFactoryBuilder.class.getName(),
-                new JREInitialContextFactoryBuilder(),
-                null);
-
-        context.registerService(JNDIContextManager.class.getName(),
-                new ContextManagerServiceFactory(),
-                null);
-
-        context.registerService(AugmenterInvoker.class.getName(),
-                augmenterInvoker = new AugmenterInvokerImpl(context),
-                null);
+        context.registerService(JNDIProviderAdmin.class.getName(), new ProviderAdminServiceFactory(context), null);
+        context.registerService(InitialContextFactoryBuilder.class.getName(), new JREInitialContextFactoryBuilder(), null);
+        context.registerService(JNDIContextManager.class.getName(), new ContextManagerServiceFactory(), null);
+        context.registerService(AugmenterInvoker.class.getName(), augmenterInvoker = new AugmenterInvokerImpl(context), null);
     }
 
     public void stop(BundleContext context) {
@@ -235,22 +224,16 @@
         instance = null;
     }
 
-    private boolean forceBuilder(BundleContext context) {
-        String forceBuilderProp = context.getProperty(FORCE_BUILDER);
-        if (forceBuilderProp != null) {
-            return !"false".equals(forceBuilderProp) && !"no".equals(forceBuilderProp);
-        }
-        BundleRevision revision = context.getBundle().adapt(BundleRevision.class);
-        return !(revision.getDeclaredCapabilities(FORCE_BUILDER).isEmpty());
-    }
-
-    private boolean disableBuilder(BundleContext context) {
-        String disableBuilder = context.getProperty(DISABLE_BUILDER);
-        if (disableBuilder != null) {
-            return !"false".equals(disableBuilder) && !"no".equals(disableBuilder);
-        }
-        BundleRevision revision = context.getBundle().adapt(BundleRevision.class);
-        return !(revision.getDeclaredCapabilities(DISABLE_BUILDER).isEmpty());
+    private boolean isPropertyEnabled(BundleContext context, String key) {
+        String value = context.getProperty(key);
+        if ("false".equals(value)) return false;
+        if ("no".equals(value)) return false;
+        if (null != value) return true;
+        Object revision = context.getBundle().adapt(BundleRevision.class);
+        // in a unit test adapt() may return an incompatible object
+        if (!!! (revision instanceof BundleRevision)) return false;
+        final BundleRevision bundleRevision = (BundleRevision) revision;
+        return bundleRevision.getDeclaredCapabilities(key).size() > 0;
     }
 
     private String getClassName(Class<?> expectedType) {
diff --git a/jndi/jndi-url/pom.xml b/jndi/jndi-url/pom.xml
index a8baca3..7a316bd 100644
--- a/jndi/jndi-url/pom.xml
+++ b/jndi/jndi-url/pom.xml
@@ -63,8 +63,8 @@
         </aries.osgi.import.service>
         <lastReleaseVersion>1.0.0</lastReleaseVersion>
 
-        <jndi-api.version>1.1.0</jndi-api.version>
-        <jndi-core.version>1.0.0</jndi-core.version>
+        <jndi-api.version>1.1.1-SNAPSHOT</jndi-api.version>
+        <jndi-core.version>1.1.0-SNAPSHOT</jndi-core.version>
     </properties>
 
     <profiles>
diff --git a/jndi/parent/pom.xml b/jndi/parent/pom.xml
index 39408b8..2634b60 100644
--- a/jndi/parent/pom.xml
+++ b/jndi/parent/pom.xml
@@ -47,7 +47,7 @@
     <properties>
         <jndi-api.dev-version>1.1.1-SNAPSHOT</jndi-api.dev-version>
         <jndi-core.dev-version>1.1.0-SNAPSHOT</jndi-core.dev-version>
-        <jndi-bundle.dev-version>1.0.1-SNAPSHOT</jndi-bundle.dev-version>
+        <jndi-bundle.dev-version>1.1.0-SNAPSHOT</jndi-bundle.dev-version>
         <jndi-url.dev-version>1.1.1-SNAPSHOT</jndi-url.dev-version>
         <jndi-rmi.dev-version>1.0.1-SNAPSHOT</jndi-rmi.dev-version>
         <jndi-url-itest-web.dev-version>1.0.1-SNAPSHOT</jndi-url-itest-web.dev-version>
@@ -108,7 +108,7 @@
             <dependency>
                 <groupId>org.apache.aries.testsupport</groupId>
                 <artifactId>org.apache.aries.testsupport.unit</artifactId>
-                <version>1.0.0</version>
+                <version>2.0.0-SNAPSHOT</version>
                 <scope>test</scope>
                 <exclusions>
                     <exclusion>
diff --git a/spi-fly/spi-fly-core/pom.xml b/spi-fly/spi-fly-core/pom.xml
index 156fbd3..becfe1b 100644
--- a/spi-fly/spi-fly-core/pom.xml
+++ b/spi-fly/spi-fly-core/pom.xml
@@ -47,8 +47,8 @@
     </scm>
 
     <properties>
-        <maven.bundle.plugin.version>4.2.0</maven.bundle.plugin.version>
-        <bnd.version>5.0.1</bnd.version>
+        <maven.bundle.plugin.version>5.1.1</maven.bundle.plugin.version>
+        <bnd.version>5.1.2</bnd.version>
     </properties>
 
     <dependencies>
diff --git a/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java b/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java
index 071f6b9..3b65715 100644
--- a/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java
+++ b/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/BaseActivator.java
@@ -91,7 +91,7 @@
             ).map(Parameters::new);
         }
         catch (Throwable t) {
-            logger.log(Level.SEVERE, t.getMessage(), t);
+            log(Level.FINE, t.getMessage(), t);
         }
 
         providerBundleTracker = new BundleTracker(context,
@@ -239,7 +239,9 @@
     }
 
     public void log(Level level, String message, Throwable th) {
-        logger.log(level, message, th);
+        if (logger.isLoggable(level)) {
+            logger.log(level, message, th);
+        }
     }
 
     public Set<WeavingData> getWeavingData(Bundle b) {
diff --git a/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java b/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
index 5de77f3..178ec99 100644
--- a/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
+++ b/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/ProviderBundleTrackerCustomizer.java
@@ -92,7 +92,7 @@
             try {

                 providedServices = readServiceLoaderMediatorCapabilityMetadata(bundle, customAttributes);

             } catch (InvalidSyntaxException e) {

-                log(Level.SEVERE, "Unable to read capabilities from bundle " + bundle, e);

+                log(Level.FINE, "Unable to read capabilities from bundle " + bundle, e);

             }

         }

 

@@ -121,7 +121,7 @@
                     + bundle.getSymbolicName());

             return null;

         } else {

-            log(Level.INFO, "Examining bundle for SPI provider: "

+            log(Level.FINE, "Examining bundle for SPI provider: "

                     + bundle.getSymbolicName());

         }

 

@@ -141,7 +141,7 @@
 

             try {

                 final Class<?> cls = bundle.loadClass(details.instanceType);

-                log(Level.INFO, "Loaded SPI provider: " + cls);

+                log(Level.FINE, "Loaded SPI provider: " + cls);

 

                 if (details.properties != null) {

                     ServiceRegistration reg = null;

@@ -157,7 +157,7 @@
                             reg = bundle.getBundleContext().registerService(

                                     details.serviceType, instance, details.properties);

                         } else {

-                            log(Level.INFO, "Bundle " + bundle + " does not have the permission to register services of type: " + details.serviceType);

+                            log(Level.FINE, "Bundle " + bundle + " does not have the permission to register services of type: " + details.serviceType);

                         }

                     } else {

                         reg = bundle.getBundleContext().registerService(

@@ -166,14 +166,14 @@
 

                     if (reg != null) {

                         registrations.add(reg);

-                        log(Level.INFO, "Registered service: " + reg);

+                        log(Level.FINE, "Registered service: " + reg);

                     }

                 }

 

                 activator.registerProviderBundle(details.serviceType, bundle, details.properties);

                 log(Level.INFO, "Registered provider " + details.instanceType + " of service " + details.serviceType + " in bundle " + bundle.getSymbolicName());

             } catch (Exception e) {

-                log(Level.WARNING,

+                log(Level.FINE,

                     "Could not load provider " + details.instanceType + " of service " + details.serviceType, e);

             }

         }

@@ -185,7 +185,7 @@
         List<ServiceDetails> serviceDetails = new ArrayList<>();

 

         for (URL serviceFileURL : serviceFileURLs) {

-            log(Level.INFO, "Found SPI resource: " + serviceFileURL);

+            log(Level.FINE, "Found SPI resource: " + serviceFileURL);

 

             try {

                 BufferedReader reader = new BufferedReader(

@@ -233,12 +233,12 @@
 

                         serviceDetails.add(new ServiceDetails(registrationClassName, className, properties));

                     } catch (Exception e) {

-                        log(Level.WARNING,

+                        log(Level.FINE,

                                 "Could not load SPI implementation referred from " + serviceFileURL, e);

                     }

                 }

             } catch (IOException e) {

-                log(Level.WARNING, "Could not read SPI metadata from " + serviceFileURL, e);

+                log(Level.FINE, "Could not read SPI metadata from " + serviceFileURL, e);

             }

         }

 

@@ -434,15 +434,14 @@
                 }

             }

         } catch (IOException e) {

-            log(Level.SEVERE, "Problem opening embedded jar file: " + url, e);

+            log(Level.FINE, "Problem opening embedded jar file: " + url, e);

         }

         return urls;

     }

 

     @Override

     public void modifiedBundle(Bundle bundle, BundleEvent event, Object registrations) {

-        removedBundle(bundle, event, registrations);

-        addingBundle(bundle, event);

+        // implementation is unnecessary for this use case

     }

 

     @Override

@@ -454,8 +453,16 @@
             return;

 

         for (ServiceRegistration reg : (List<ServiceRegistration>) registrations) {

-            reg.unregister();

-            log(Level.INFO, "Unregistered: " + reg);

+            try {

+                reg.unregister();

+                log(Level.FINE, "Unregistered: " + reg);

+            } catch (IllegalStateException ise) {

+                // Ignore the exception but do not remove the try/catch.

+                // There are some bundle context races on cleanup which

+                // are safe to ignore but unsafe not to perform our own

+                // cleanup. In an ideal world ServiceRegistration.unregister()

+                // would have been idempotent and never throw an exception.

+            }

         }

     }

 

diff --git a/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/Util.java b/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/Util.java
index 603dd60..1bed947 100644
--- a/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/Util.java
+++ b/spi-fly/spi-fly-core/src/main/java/org/apache/aries/spifly/Util.java
@@ -87,7 +87,7 @@
         );

 

         if (!(bundleLoader instanceof BundleReference)) {

-            BaseActivator.activator.log(Level.WARNING, "Classloader of consuming bundle doesn't implement BundleReference: " + bundleLoader);

+            BaseActivator.activator.log(Level.FINE, "Classloader of consuming bundle doesn't implement BundleReference: " + bundleLoader);

             return ServiceLoader.load(service);

         }

 

@@ -140,7 +140,7 @@
         );

 

         if (!(bundleLoader instanceof BundleReference)) {

-            BaseActivator.activator.log(Level.WARNING, "Classloader of consuming bundle doesn't implement BundleReference: " + bundleLoader);

+            BaseActivator.activator.log(Level.FINE, "Classloader of consuming bundle doesn't implement BundleReference: " + bundleLoader);

             return ServiceLoader.load(service, specifiedClassLoader);

         }

 

@@ -165,7 +165,7 @@
 

         final ClassLoader cl = findContextClassloader(br.getBundle(), cls, method, clsArg);

         if (cl != null) {

-            BaseActivator.activator.log(Level.INFO, "Temporarily setting Thread Context Classloader to: " + cl);

+            BaseActivator.activator.log(Level.FINE, "Temporarily setting Thread Context Classloader to: " + cl);

             AccessController.doPrivileged(new PrivilegedAction<Void>() {

                 @Override

                 public Void run() {

@@ -174,7 +174,7 @@
                 }

             });

         } else {

-            BaseActivator.activator.log(Level.WARNING, "No classloader found for " + cls + ":" + method + "(" + clsArg + ")");

+            BaseActivator.activator.log(Level.FINE, "No classloader found for " + cls + ":" + method + "(" + clsArg + ")");

         }

     }

 

@@ -194,7 +194,7 @@
                     sm.checkPermission(new ServicePermission(requestedClass, ServicePermission.GET));

                 } catch (AccessControlException ace) {

                     // access denied

-                    activator.log(Level.INFO, "No permission to obtain service of type: " + requestedClass);

+                    activator.log(Level.FINE, "No permission to obtain service of type: " + requestedClass);

                     return null;

                 }

             }

@@ -320,7 +320,7 @@
         }

 

         if (!(bundleLoader instanceof BundleReference)) {

-            BaseActivator.activator.log(Level.WARNING, "Classloader of consuming bundle doesn't implement BundleReference: " + bundleLoader);

+            BaseActivator.activator.log(Level.FINE, "Classloader of consuming bundle doesn't implement BundleReference: " + bundleLoader);

             return null;

         }

 

@@ -347,7 +347,7 @@
                     jis.close();

             }

         } catch (IOException e) {

-            BaseActivator.activator.log(Level.SEVERE, "Problem loading class from embedded jar file: " + url +

+            BaseActivator.activator.log(Level.FINE, "Problem loading class from embedded jar file: " + url +

                 " in bundle " + b.getSymbolicName(), e);

         }

         return null;

diff --git a/spi-fly/spi-fly-dynamic-bundle/pom.xml b/spi-fly/spi-fly-dynamic-bundle/pom.xml
index c78cda8..18179e9 100644
--- a/spi-fly/spi-fly-dynamic-bundle/pom.xml
+++ b/spi-fly/spi-fly-dynamic-bundle/pom.xml
@@ -47,9 +47,9 @@
     </scm>
 
     <properties>
-        <asm.version>8.0.1</asm.version>
-        <maven.bundle.plugin.version>4.2.0</maven.bundle.plugin.version>
-        <bnd.version>5.0.1</bnd.version>
+        <asm.version>9.0</asm.version>
+        <maven.bundle.plugin.version>5.1.1</maven.bundle.plugin.version>
+        <bnd.version>5.1.2</bnd.version>
     </properties>
 
     <dependencies>
@@ -211,6 +211,10 @@
                     <bndruns>
                         <bndrun>resolve.bndrun</bndrun>
                     </bndruns>
+                    <bundles>
+                        <bundle>target/${project.build.finalName}.jar</bundle>
+                    </bundles>
+                    <writeOnChanges>false</writeOnChanges>
                 </configuration>
                 <executions>
                     <execution>
diff --git a/spi-fly/spi-fly-dynamic-bundle/resolve.bndrun b/spi-fly/spi-fly-dynamic-bundle/resolve.bndrun
index 154e97f..938bb24 100644
--- a/spi-fly/spi-fly-dynamic-bundle/resolve.bndrun
+++ b/spi-fly/spi-fly-dynamic-bundle/resolve.bndrun
@@ -10,15 +10,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
--standalone: true
--resolve.effective: resolve, active
--runee: JavaSE-1.8
 -runfw: org.apache.felix.framework
--runrequires: osgi.identity;filter:='(osgi.identity=${project.artifactId})'
--runbundles: \
-	org.apache.aries.spifly.dynamic.bundle;version='[1.3.0,1.3.1)',\
-	org.objectweb.asm;version='[8.0.1,8.0.2)',\
-	org.objectweb.asm.commons;version='[8.0.1,8.0.2)',\
-	org.objectweb.asm.tree;version='[8.0.1,8.0.2)',\
-	org.objectweb.asm.tree.analysis;version='[8.0.1,8.0.2)',\
-	org.objectweb.asm.util;version='[8.0.1,8.0.2)'
diff --git a/spi-fly/spi-fly-dynamic-framework-extension/pom.xml b/spi-fly/spi-fly-dynamic-framework-extension/pom.xml
index 6bbca6a..3c9b7ab 100644
--- a/spi-fly/spi-fly-dynamic-framework-extension/pom.xml
+++ b/spi-fly/spi-fly-dynamic-framework-extension/pom.xml
@@ -47,9 +47,9 @@
     </scm>
 
     <properties>
-        <asm.version>8.0.1</asm.version>
-        <maven.bundle.plugin.version>4.2.0</maven.bundle.plugin.version>
-        <bnd.version>5.0.1</bnd.version>
+        <asm.version>9.0</asm.version>
+        <maven.bundle.plugin.version>5.1.1</maven.bundle.plugin.version>
+        <bnd.version>5.1.2</bnd.version>
     </properties>
 
     <dependencies>
@@ -210,6 +210,10 @@
                     <bndruns>
                         <bndrun>resolve.bndrun</bndrun>
                     </bndruns>
+                    <bundles>
+                        <bundle>target/${project.build.finalName}.jar</bundle>
+                    </bundles>
+                    <writeOnChanges>false</writeOnChanges>
                 </configuration>
                 <executions>
                     <execution>
diff --git a/spi-fly/spi-fly-dynamic-framework-extension/resolve.bndrun b/spi-fly/spi-fly-dynamic-framework-extension/resolve.bndrun
index 4a7b3c0..938bb24 100644
--- a/spi-fly/spi-fly-dynamic-framework-extension/resolve.bndrun
+++ b/spi-fly/spi-fly-dynamic-framework-extension/resolve.bndrun
@@ -10,9 +10,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
--standalone: true
--resolve.effective: resolve, active
--runee: JavaSE-1.8
 -runfw: org.apache.felix.framework
--runrequires: osgi.identity;filter:='(osgi.identity=${project.artifactId})'
--runbundles: org.apache.aries.spifly.dynamic.framework.extension;version='[1.3.0,1.3.1)'
diff --git a/spi-fly/spi-fly-static-bundle/pom.xml b/spi-fly/spi-fly-static-bundle/pom.xml
index 0954bc0..4889d7d 100644
--- a/spi-fly/spi-fly-static-bundle/pom.xml
+++ b/spi-fly/spi-fly-static-bundle/pom.xml
@@ -47,8 +47,8 @@
     </scm>
 
     <properties>
-        <maven.bundle.plugin.version>4.2.0</maven.bundle.plugin.version>
-        <bnd.version>5.0.1</bnd.version>
+        <maven.bundle.plugin.version>5.1.1</maven.bundle.plugin.version>
+        <bnd.version>5.1.2</bnd.version>
     </properties>
 
     <dependencies>
@@ -170,6 +170,10 @@
                     <bndruns>
                         <bndrun>resolve.bndrun</bndrun>
                     </bndruns>
+                    <bundles>
+                        <bundle>target/${project.build.finalName}.jar</bundle>
+                    </bundles>
+                    <writeOnChanges>false</writeOnChanges>
                 </configuration>
                 <executions>
                     <execution>
diff --git a/spi-fly/spi-fly-static-bundle/resolve.bndrun b/spi-fly/spi-fly-static-bundle/resolve.bndrun
index 3917f05..938bb24 100644
--- a/spi-fly/spi-fly-static-bundle/resolve.bndrun
+++ b/spi-fly/spi-fly-static-bundle/resolve.bndrun
@@ -10,9 +10,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
--standalone: true
--resolve.effective: resolve, active
--runee: JavaSE-1.8
 -runfw: org.apache.felix.framework
--runrequires: osgi.identity;filter:='(osgi.identity=${project.artifactId})'
--runbundles: org.apache.aries.spifly.static.bundle;version='[1.3.0,1.3.1)'
diff --git a/spi-fly/spi-fly-static-tool/pom.xml b/spi-fly/spi-fly-static-tool/pom.xml
index 6bcb4bf..5a1cfba 100644
--- a/spi-fly/spi-fly-static-tool/pom.xml
+++ b/spi-fly/spi-fly-static-tool/pom.xml
@@ -45,8 +45,8 @@
     </scm>
 
     <properties>
-        <maven.bundle.plugin.version>4.2.0</maven.bundle.plugin.version>
-        <bnd.version>5.0.1</bnd.version>
+        <maven.bundle.plugin.version>5.1.1</maven.bundle.plugin.version>
+        <bnd.version>5.1.2</bnd.version>
     </properties>
 
     <dependencies>
diff --git a/spi-fly/spi-fly-weaver/pom.xml b/spi-fly/spi-fly-weaver/pom.xml
index 52502ee..0025a67 100644
--- a/spi-fly/spi-fly-weaver/pom.xml
+++ b/spi-fly/spi-fly-weaver/pom.xml
@@ -42,9 +42,9 @@
     </scm>
 
     <properties>
-        <asm.version>8.0.1</asm.version>
-        <maven.bundle.plugin.version>4.2.0</maven.bundle.plugin.version>
-        <bnd.version>5.0.1</bnd.version>
+        <asm.version>9.0</asm.version>
+        <maven.bundle.plugin.version>5.1.1</maven.bundle.plugin.version>
+        <bnd.version>5.1.2</bnd.version>
     </properties>
 
     <dependencies>
diff --git a/testsupport/testsupport-unit/src/main/java/org/apache/aries/mocks/BundleContextMock.java b/testsupport/testsupport-unit/src/main/java/org/apache/aries/mocks/BundleContextMock.java
index 1c5f5aa..c6955b7 100644
--- a/testsupport/testsupport-unit/src/main/java/org/apache/aries/mocks/BundleContextMock.java
+++ b/testsupport/testsupport-unit/src/main/java/org/apache/aries/mocks/BundleContextMock.java
@@ -724,11 +724,7 @@
      * This allows tests to emulate different properties being set on the
      * context, helpful for the feature pack launcher/kernel relationship
      */
-    else if (System.getProperty(name) != null){
-      return System.getProperty(name);
-    }
-    
-    return "";
+    return System.getProperty(name);
   }
   
   /**