Author: rickhall
Date: Tue Aug 25 14:31:32 2009
New Revision: 807651

URL: http://svn.apache.org/viewvc?rev=807651&view=rev
Log:
More OSGi API updates. (FELIX-1205)

Modified:
    
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/AdminPermission.java
    
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/FrameworkUtil.java
    
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/PackagePermission.java
    
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java
    
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/EventHook.java
    
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/FindHook.java
    
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java

Modified: 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/AdminPermission.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/AdminPermission.java?rev=807651&r1=807650&r2=807651&view=diff
==============================================================================
--- 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/AdminPermission.java 
(original)
+++ 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/AdminPermission.java 
Tue Aug 25 14:31:32 2009
@@ -87,7 +87,7 @@
  * Filter attribute names are processed in a case sensitive manner.
  * 
  * @ThreadSafe
- * @version $Revision: 6867 $
+ * @version $Revision: 7743 $
  */
 
 public final class AdminPermission extends BasicPermission {
@@ -213,6 +213,12 @@
        private transient volatile Dictionary   properties;
 
        /**
+        * ThreadLocal used to determine if we have recursively called
+        * getProperties.
+        */
+       private static final ThreadLocal                recurse                 
                        = new ThreadLocal();
+
+       /**
         * Creates a new <code>AdminPermission</code> object that matches all
         * bundles and has all actions. Equivalent to AdminPermission("*","*");
         */
@@ -647,7 +653,17 @@
                if (requested.bundle == null) {
                        return false;
                }
-               return f.matchCase(requested.getProperties());
+               Dictionary requestedProperties = requested.getProperties();
+               if (requestedProperties == null) {
+                       /*
+                        * If the requested properties are null, then we have 
detected a
+                        * recursion getting the bundle location. So we return 
true to
+                        * permit the bundle location request in the 
AdminPermission check
+                        * up the stack to succeed.
+                        */
+                       return true;
+               }
+               return f.matchCase(requestedProperties);
        }
 
        /**
@@ -808,10 +824,10 @@
        }
 
        /**
-        * Called by <code><@link AdminPermission#implies(Permission)></code> 
on an
-        * AdminPermission which was constructed with a Bundle. This method 
loads a
-        * dictionary with the filter-matchable properties of this bundle. The
-        * dictionary is cached so this lookup only happens once.
+        * Called by <code>implies0</code> on an AdminPermission which was
+        * constructed with a Bundle. This method loads a dictionary with the
+        * filter-matchable properties of this bundle. The dictionary is cached 
so
+        * this lookup only happens once.
         * 
         * This method should only be called on an AdminPermission which was
         * constructed with a bundle
@@ -823,23 +839,38 @@
                if (result != null) {
                        return result;
                }
-               final Dictionary dict = new Hashtable(4);
-               AccessController.doPrivileged(new PrivilegedAction() {
-                       public Object run() {
-                               dict.put("id", new Long(bundle.getBundleId()));
-                               dict.put("location", bundle.getLocation());
-                               String name = bundle.getSymbolicName();
-                               if (name != null) {
-                                       dict.put("name", name);
-                               }
-                               SignerProperty signer = new 
SignerProperty(bundle);
-                               if (signer.isBundleSigned()) {
-                                       dict.put("signer", signer); 
+               /*
+                * We may have recursed here due to the Bundle.getLocation call 
in the
+                * doPrivileged below. If this is the case, return null to 
allow implies
+                * to return true.
+                */
+               final Object mark = recurse.get();
+               if (mark == bundle) {
+                       return null;
+               }
+               recurse.set(bundle);
+               try {
+                       final Dictionary dict = new Hashtable(4);
+                       AccessController.doPrivileged(new PrivilegedAction() {
+                               public Object run() {
+                                       dict.put("id", new 
Long(bundle.getBundleId()));
+                                       dict.put("location", 
bundle.getLocation());
+                                       String name = bundle.getSymbolicName();
+                                       if (name != null) {
+                                               dict.put("name", name);
+                                       }
+                                       SignerProperty signer = new 
SignerProperty(bundle);
+                                       if (signer.isBundleSigned()) {
+                                               dict.put("signer", signer);
+                                       }
+                                       return null;
                                }
-                               return null;
-                       }
-               });
-               return properties = dict;
+                       });
+                       return properties = dict;
+               }
+               finally {
+                       recurse.set(null);
+               }
        }
 }
 

Modified: 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/FrameworkUtil.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/FrameworkUtil.java?rev=807651&r1=807650&r2=807651&view=diff
==============================================================================
--- 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/FrameworkUtil.java 
(original)
+++ 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/FrameworkUtil.java 
Tue Aug 25 14:31:32 2009
@@ -39,7 +39,7 @@
  * 
  * @since 1.3
  * @ThreadSafe
- * @version $Revision: 6888 $
+ * @version $Revision: 7761 $
  */
 public class FrameworkUtil {
        /**
@@ -186,7 +186,7 @@
         */
        public static boolean matchDistinguishedNameChain(String matchPattern,
                        List /* <String> */dnChain) {
-               return DNChainMatching.match(matchPattern, new 
ArrayList(dnChain));
+               return DNChainMatching.match(matchPattern, dnChain);
        }
 
        /**
@@ -1704,11 +1704,11 @@
                /**
                 * Check the name/value pairs of the rdn against the pattern.
                 * 
-                * @param rdn ArrayList of name value pairs for a given RDN.
-                * @param rdnPattern ArrayList of name value pattern pairs.
+                * @param rdn List of name value pairs for a given RDN.
+                * @param rdnPattern List of name value pattern pairs.
                 * @return true if the list of name value pairs match the 
pattern.
                 */
-               private static boolean rdnmatch(ArrayList rdn, ArrayList 
rdnPattern) {
+               private static boolean rdnmatch(List rdn, List rdnPattern) {
                        if (rdn.size() != rdnPattern.size()) {
                                return false;
                        }
@@ -1732,7 +1732,7 @@
                        return true;
                }
 
-               private static boolean dnmatch(ArrayList dn, ArrayList 
dnPattern) {
+               private static boolean dnmatch(List dn, List dnPattern) {
                        int dnStart = 0;
                        int patStart = 0;
                        int patLen = dnPattern.size();
@@ -1750,8 +1750,7 @@
                                if (dn.size() > patLen) {
                                        if 
(!dnPattern.get(0).equals(STAR_WILDCARD)) {
                                                // If the number of rdns do not 
match we must have a
-                                               // prefix
-                                               // map
+                                               // prefix map
                                                return false;
                                        }
                                        // The rdnPattern and rdn must have the 
same number of
@@ -1760,8 +1759,8 @@
                                }
                        }
                        for (int i = 0; i < patLen; i++) {
-                               if (!rdnmatch((ArrayList) dn.get(i + dnStart),
-                                               (ArrayList) dnPattern.get(i + 
patStart))) {
+                               if (!rdnmatch((List) dn.get(i + dnStart), 
(List) dnPattern
+                                               .get(i + patStart))) {
                                        return false;
                                }
                        }
@@ -1769,24 +1768,24 @@
                }
 
                /**
-                * Parses a distinguished name chain pattern and returns an 
ArrayList
-                * where each element represents a distinguished name (DN) in 
the chain
-                * of DNs. Each element will be either a String, if the element
-                * represents a wildcard ("*" or "-"), or an ArrayList 
representing an
-                * RDN. Each element in the RDN ArrayList will be a String, if 
the
-                * element represents a wildcard ("*"), or an ArrayList of 
Strings, each
-                * String representing a name/value pair in the RDN.
+                * Parses a distinguished name chain pattern and returns a List 
where
+                * each element represents a distinguished name (DN) in the 
chain of
+                * DNs. Each element will be either a String, if the element 
represents
+                * a wildcard ("*" or "-"), or a List representing an RDN. Each 
element
+                * in the RDN List will be a String, if the element represents a
+                * wildcard ("*"), or a List of Strings, each String 
representing a
+                * name/value pair in the RDN.
                 * 
                 * @param dnChain
                 * @return a list of DNs.
                 * @throws IllegalArgumentException
                 */
-               private static ArrayList parseDNchainPattern(String dnChain) {
+               private static List parseDNchainPattern(String dnChain) {
                        if (dnChain == null) {
                                throw new IllegalArgumentException(
                                                "The DN chain must not be 
null.");
                        }
-                       ArrayList parsed = new ArrayList();
+                       List parsed = new ArrayList();
                        int startIndex = 0;
                        startIndex = skipSpaces(dnChain, startIndex);
                        while (startIndex < dnChain.length()) {
@@ -1814,23 +1813,22 @@
                                startIndex = endIndex + 1;
                                startIndex = skipSpaces(dnChain, startIndex);
                        }
-                       parseDNchain(parsed);
-                       return parsed;
+                       return parseDNchain(parsed);
                }
 
                private static List parseDNchain(List chain) {
                        if (chain == null) {
                                throw new IllegalArgumentException("DN chain 
must not be null.");
                        }
-                       // Now we parse is a list of strings, lets make 
ArrayList of rdn out
-                       // of
-                       // them
+                       chain = new ArrayList(chain);
+                       // Now we parse is a list of strings, lets make List of 
rdn out
+                       // of them
                        for (int i = 0; i < chain.size(); i++) {
                                String dn = (String) chain.get(i);
                                if (dn.equals(STAR_WILDCARD) || 
dn.equals(MINUS_WILDCARD)) {
                                        continue;
                                }
-                               ArrayList rdns = new ArrayList();
+                               List rdns = new ArrayList();
                                if (dn.charAt(0) == '*') {
                                        if (dn.charAt(1) != ',') {
                                                throw new 
IllegalArgumentException(
@@ -1870,13 +1868,13 @@
                 * rdnArray with the extracted RDNs.
                 * 
                 * @param dn the distinguished name in canonical form.
-                * @param rdnArray the array to fill in with RDNs extracted 
from the dn
+                * @param rdn the list to fill in with RDNs extracted from the 
dn
                 * @throws IllegalArgumentException if a formatting error is 
found.
                 */
-               private static void parseDN(String dn, ArrayList rdnArray) {
+               private static void parseDN(String dn, List rdn) {
                        int startIndex = 0;
                        char c = '\0';
-                       ArrayList nameValues = new ArrayList();
+                       List nameValues = new ArrayList();
                        while (startIndex < dn.length()) {
                                int endIndex;
                                for (endIndex = startIndex; endIndex < 
dn.length(); endIndex++) {
@@ -1894,7 +1892,7 @@
                                }
                                nameValues.add(dn.substring(startIndex, 
endIndex));
                                if (c != '+') {
-                                       rdnArray.add(nameValues);
+                                       rdn.add(nameValues);
                                        if (endIndex != dn.length()) {
                                                nameValues = new ArrayList();
                                        }
@@ -1912,7 +1910,7 @@
 
                /**
                 * This method will return an 'index' which points to a 
non-wildcard DN
-                * or the end-of-arraylist.
+                * or the end-of-list.
                 */
                private static int skipWildCards(List dnChainPattern,
                                int dnChainPatternIndex) {
@@ -1928,22 +1926,19 @@
                                        // otherwise continue skipping over 
wild cards
                                }
                                else {
-                                       if (dnPattern instanceof ArrayList) {
-                                               // if its an arraylist then we 
have our 'non-wildcard'
-                                               // DN
+                                       if (dnPattern instanceof List) {
+                                               // if its a list then we have 
our 'non-wildcard' DN
                                                break;
                                        }
                                        else {
                                                // unknown member of the 
DNChainPattern
                                                throw new 
IllegalArgumentException(
-                                                               "expected 
String or Arraylist in DN Pattern");
+                                                               "expected 
String or List in DN Pattern");
                                        }
                                }
                        }
-                       // i either points to end-of-arraylist, or to the first
-                       // non-wildcard
-                       // pattern
-                       // after dnChainPatternIndex
+                       // i either points to end-of-list, or to the first
+                       // non-wildcard pattern after dnChainPatternIndex
                        return i;
                }
 
@@ -1986,9 +1981,8 @@
                                }
                                //
                                // we will now recursively call to see if the 
rest of the
-                               // DNChainPattern
-                               // matches increasingly smaller portions of the 
rest of the
-                               // DNChain
+                               // DNChainPattern matches increasingly smaller 
portions of the
+                               // rest of the DNChain
                                //
                                if (dnPattern.equals(STAR_WILDCARD)) {
                                        // '*' option: only wildcard on 0 or 1
@@ -2008,13 +2002,12 @@
                                // failure
                        }
                        else {
-                               if (dnPattern instanceof ArrayList) {
+                               if (dnPattern instanceof List) {
                                        // here we have to do a deeper check 
for each DN in the
-                                       // pattern
-                                       // until we hit a wild card
+                                       // pattern until we hit a wild card
                                        do {
-                                               if (!dnmatch((ArrayList) 
dnChain.get(dnChainIndex),
-                                                               (ArrayList) 
dnPattern)) {
+                                               if (!dnmatch((List) 
dnChain.get(dnChainIndex),
+                                                               (List) 
dnPattern)) {
                                                        return false;
                                                }
                                                // go to the next set of DN's 
in both chains
@@ -2027,24 +2020,18 @@
                                                        return true;
                                                }
                                                // if the DN Chain is finished, 
but the pattern isn't
-                                               // finished
-                                               // then if the rest of the 
pattern is not wildcard then
-                                               // we
-                                               // are
-                                               // done
+                                               // finished then if the rest of 
the pattern is not
+                                               // wildcard then we are done
                                                if (dnChainIndex >= 
dnChain.size()) {
                                                        dnChainPatternIndex = 
skipWildCards(dnChainPattern,
                                                                        
dnChainPatternIndex);
                                                        // return TRUE iff the 
pattern index moved past the
-                                                       // array-size
-                                                       // (implying that the 
rest of the pattern is all
-                                                       // wildcards)
+                                                       // list-size (implying 
that the rest of the pattern
+                                                       // is all wildcards)
                                                        return 
dnChainPatternIndex >= dnChainPattern.size();
                                                }
                                                // if the pattern finished, but 
the chain continues then
-                                               // we
-                                               // have
-                                               // a mis-match
+                                               // we have a mis-match
                                                if (dnChainPatternIndex >= 
dnChainPattern.size()) {
                                                        return false;
                                                }
@@ -2062,23 +2049,20 @@
                                                                        
dnChainPattern, dnChainPatternIndex);
                                                }
                                                else {
-                                                       if (!(dnPattern 
instanceof ArrayList)) {
+                                                       if (!(dnPattern 
instanceof List)) {
                                                                throw new 
IllegalArgumentException(
-                                                                               
"expected String or Arraylist in DN Pattern");
+                                                                               
"expected String or List in DN Pattern");
                                                        }
                                                }
                                                // if we are here, then we will 
just continue to the
-                                               // match
-                                               // the
-                                               // next set of DN's from the 
DNChain, and the
-                                               // DNChainPattern
-                                               // since both are array-lists
+                                               // match the next set of DN's 
from the DNChain, and the
+                                               // DNChainPattern since both 
are lists
                                        } while (true);
                                        // should never reach here?
                                }
                                else {
                                        throw new IllegalArgumentException(
-                                                       "expected String or 
Arraylist in DN Pattern");
+                                                       "expected String or 
List in DN Pattern");
                                }
                        }
                        // if we get here, the the default return is 'mis-match'
@@ -2124,16 +2108,20 @@
                        try {
                                parsedDNChain = parseDNchain(dnChain);
                        }
-                       catch (IllegalArgumentException e) {
-                               throw (IllegalArgumentException) new 
IllegalArgumentException(
-                                               "Invalid DN chain: " + 
toString(dnChain)).initCause(e);
+                       catch (RuntimeException e) {
+                               IllegalArgumentException iae = new 
IllegalArgumentException(
+                                               "Invalid DN chain: " + 
toString(dnChain));
+                               iae.initCause(e);
+                               throw iae;
                        }
                        try {
                                parsedDNPattern = parseDNchainPattern(pattern);
                        }
-                       catch (IllegalArgumentException e) {
-                               throw (IllegalArgumentException) new 
IllegalArgumentException(
-                                               "Invalid match pattern: " + 
pattern).initCause(e);
+                       catch (RuntimeException e) {
+                               IllegalArgumentException iae = new 
IllegalArgumentException(
+                                               "Invalid match pattern: " + 
pattern);
+                               iae.initCause(e);
+                               throw iae;
                        }
                        return dnChainMatch(parsedDNChain, 0, parsedDNPattern, 
0);
                }

Modified: 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/PackagePermission.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/PackagePermission.java?rev=807651&r1=807650&r2=807651&view=diff
==============================================================================
--- 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/PackagePermission.java
 (original)
+++ 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/PackagePermission.java
 Tue Aug 25 14:31:32 2009
@@ -56,7 +56,7 @@
  * which is deprecated, implies the <code>import</code> action.
  * 
  * @ThreadSafe
- * @version $Revision: 6530 $
+ * @version $Revision: 7189 $
  */
 
 public final class PackagePermission extends BasicPermission {
@@ -165,9 +165,9 @@
         *        only be specified if the specified action is 
<code>import</code>.
         * @param actions <code>exportonly</code>,<code>import</code> (canonical
         *        order).
-        * @throw IllegalArgumentException If the specified name is a filter
-        *        expression and either the specified action is not
-        *        <code>import</code> or the filter has an invalid syntax.
+        * @throws IllegalArgumentException If the specified name is a filter
+        *         expression and either the specified action is not
+        *         <code>import</code> or the filter has an invalid syntax.
         */
        public PackagePermission(String name, String actions) {
                this(name, parseActions(actions));
@@ -188,8 +188,8 @@
         * @param name The name of the requested package to import.
         * @param exportingBundle The bundle exporting the requested package.
         * @param actions The action <code>import</code>.
-        * @throw IllegalArgumentException If the specified action is not
-        *        <code>import</code> or the name is a filter expression.
+        * @throws IllegalArgumentException If the specified action is not
+        *         <code>import</code> or the name is a filter expression.
         * @since 1.5
         */
        public PackagePermission(String name, Bundle exportingBundle, String 
actions) {

Modified: 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java?rev=807651&r1=807650&r2=807651&view=diff
==============================================================================
--- 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java
 (original)
+++ 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/ServicePermission.java
 Tue Aug 25 14:31:32 2009
@@ -51,7 +51,7 @@
  * <code>ServicePermission</code> to get the specific service.
  * 
  * @ThreadSafe
- * @version $Revision: 6530 $
+ * @version $Revision: 7189 $
  */
 
 public final class ServicePermission extends BasicPermission {
@@ -166,9 +166,9 @@
         * 
         * @param name The service class name
         * @param actions <code>get</code>,<code>register</code> (canonical 
order)
-        * @throw IllegalArgumentException If the specified name is a filter
-        *        expression and either the specified action is not 
<code>get</code>
-        *        or the filter has an invalid syntax.
+        * @throws IllegalArgumentException If the specified name is a filter
+        *         expression and either the specified action is not
+        *         <code>get</code> or the filter has an invalid syntax.
         */
        public ServicePermission(String name, String actions) {
                this(name, parseActions(actions));
@@ -188,8 +188,8 @@
         * 
         * @param reference The requested service.
         * @param actions The action <code>get</code>.
-        * @throw IllegalArgumentException If the specified action is not
-        *        <code>get</code> or reference is <code>null</code>.
+        * @throws IllegalArgumentException If the specified action is not
+        *         <code>get</code> or reference is <code>null</code>.
         * @since 1.5
         */
        public ServicePermission(ServiceReference reference, String actions) {

Modified: 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/EventHook.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/EventHook.java?rev=807651&r1=807650&r2=807651&view=diff
==============================================================================
--- 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/EventHook.java
 (original)
+++ 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/EventHook.java
 Tue Aug 25 14:31:32 2009
@@ -28,7 +28,7 @@
  * (register, modify, and unregister service) operations.
  * 
  * @ThreadSafe
- * @version $Revision: 6860 $
+ * @version $Revision: 6967 $
  */
 
 public interface EventHook {
@@ -50,5 +50,5 @@
         *        synchronized.
         */
        void event(ServiceEvent event,
-                       Collection/* <? extends BundleContext> */contexts);
+                       Collection/* <BundleContext> */contexts);
 }

Modified: 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/FindHook.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/FindHook.java?rev=807651&r1=807650&r2=807651&view=diff
==============================================================================
--- 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/FindHook.java
 (original)
+++ 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/FindHook.java
 Tue Aug 25 14:31:32 2009
@@ -28,7 +28,7 @@
  * (get service references) operations.
  * 
  * @ThreadSafe
- * @version $Revision: 6860 $
+ * @version $Revision: 6967 $
  */
 
 public interface FindHook {
@@ -59,5 +59,5 @@
         */
        void find(BundleContext context, String name, String filter,
                        boolean allServices,
-                       Collection/* <? extends ServiceReference> */references);
+                       Collection/* <ServiceReference> */references);
 }

Modified: 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java?rev=807651&r1=807650&r2=807651&view=diff
==============================================================================
--- 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
 (original)
+++ 
felix/trunk/org.osgi.core/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
 Tue Aug 25 14:31:32 2009
@@ -28,7 +28,7 @@
  * addition and removal.
  * 
  * @ThreadSafe
- * @version $Revision: 6906 $
+ * @version $Revision: 6967 $
  */
 
 public interface ListenerHook {
@@ -46,7 +46,7 @@
         *        result in an <code>UnsupportedOperationException</code>. The
         *        collection is not synchronized.
         */
-       void added(Collection/* <? extends ListenerInfo> */listeners);
+       void added(Collection/* <ListenerInfo> */listeners);
 
        /**
         * Removed listeners hook method. This method is called to provide the 
hook
@@ -60,7 +60,7 @@
         *        will result in an <code>UnsupportedOperationException</code>. 
The
         *        collection is not synchronized.
         */
-       void removed(Collection/* <? extends ListenerInfo> */listeners);
+       void removed(Collection/* <ListenerInfo> */listeners);
 
        /**
         * Information about a Service Listener. This interface describes the 
bundle


Reply via email to