You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2014/05/09 09:03:19 UTC

svn commit: r1593493 [6/24] - in /river/jtsk/skunk/qa_refactor/trunk: qa/ qa/src/com/sun/jini/test/impl/end2end/jssewrapper/ qa/src/com/sun/jini/test/impl/joinmanager/ qa/src/com/sun/jini/test/impl/mahalo/ qa/src/com/sun/jini/test/impl/outrigger/matchi...

Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/lookupservice/QATestUtils.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/lookupservice/QATestUtils.java?rev=1593493&r1=1593492&r2=1593493&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/lookupservice/QATestUtils.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/lookupservice/QATestUtils.java Fri May  9 07:03:18 2014
@@ -1,1810 +1,1813 @@
-/*
- * 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 com.sun.jini.test.spec.lookupservice;
-
-import com.sun.jini.test.spec.lookupservice.attribute.Attr;
-import com.sun.jini.test.spec.lookupservice.ServiceLeaseOverrideProvider;
-import net.jini.core.lookup.ServiceEvent;
-import net.jini.core.lookup.ServiceRegistrar;
-import net.jini.core.lookup.ServiceRegistration;
-import net.jini.core.lookup.ServiceID;
-import net.jini.core.lookup.ServiceItem;
-import net.jini.core.lookup.ServiceMatches;
-import net.jini.core.lookup.ServiceTemplate;
-import net.jini.core.entry.Entry;
-import net.jini.lookup.entry.ServiceType;
-import net.jini.core.lease.*;
-import java.rmi.RemoteException;
-import java.io.Serializable;
-import java.io.IOException;
-import java.util.Vector;
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-
-import com.sun.jini.qa.harness.QAConfig;
-import com.sun.jini.qa.harness.TestException;
-import com.sun.jini.qa.harness.QATestEnvironment;
-import java.util.Collections;
-import java.util.List;
-
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-/** Provides useful constants and utility methods and classes for all 
- *  classes of the Lookup component of the Jini System. Each field and 
- *  member class, and most methods, contained in this class is public 
- *  and static; this class does not need to be instantiated.
- *
- *  @see QATestEnvironment
- *  @see com.sun.jini.test.spec.lookupservice.QATestRegistrar
- */
-public class QATestUtils {
-
-    private static Logger logger = 
-	Logger.getLogger("com.sun.jini.qa.harness.test");
-
-    /* Class constructor */
-    public QATestUtils(){}
-
-    /** The number of milliseconds in 1 second */
-    public final static long N_MS_PER_SEC   = 1000;
-    /** The number of seconds in 1 minute */
-    public final static long N_SECS_PER_MIN = 60;
-    /** The number of milliseconds in 1 minute */
-    public final static long N_MS_PER_MIN   = N_MS_PER_SEC*N_SECS_PER_MIN;
-    /** Strings describing event transition states used in debugging */
-    public final static String[] trans_str = {"UNKNOWN",
-                                              "MATCH_NOMATCH",
-                                              "NOMATCH_MATCH",
-                                              "UNKNOWN",
-                                              "MATCH_MATCH"};
-
-    /** Class which models an event "tuple" (service,attribute,transition). 
-     *  
-     *  This class is used by some of the tests that wish to verify that the 
-     *  events received from the lookup service are the events expected; 
-     *  based on the templates used to register event notification requests.
-     */
-    public static class SrvcAttrTuple implements Serializable
-    {
-        static final long serialVersionUID = -8254953323094761933L;
-
-        /** @serial */
-        private Object srvcObj;
-        /** @serial */
-        private Object attrObj;
-        /** @serial */
-        private int transition;
-        /** @serial */
-        private ServiceItem[] srvcItems ;
-        /** @serial */
-        private Entry[][] attrs;
-
-        /** Creates a SrvcAttrTuple with the given transition value.
-         *  @param srvcItems the array of registered service items
-         *  @param attrs array of Entry type elements containing attributes
-         *  @param srvcObj the service component of the new tuple
-         *  @param attrObj the attribute component of the new tuple
-         *  @param transition the transition component of the new tuple
-         */
-        public SrvcAttrTuple(ServiceItem[] srvcItems,
-                             Entry[][]     attrs,
-                             Object        srvcObj,
-                             Object        attrObj,
-                             int           transition)
-        {
-            this.srvcItems  = srvcItems;
-            this.attrs      = attrs;
-
-            this.srvcObj    = srvcObj;
-            this.attrObj    = attrObj;
-            this.transition = transition;
-        }
-
-        /** Creates a SrvcAttrTuple with the "unknown" (0) transition value.
-         *  @param srvcItems the array of registered service items
-         *  @param attrs array of Entry type elements containing attributes
-         *  @param srvcObj the service component of the new tuple
-         *  @param attrObj the attribute component of the new tuple
-         */
-        public SrvcAttrTuple(ServiceItem[] srvcItems,
-                             Entry[][]     attrs,
-                             Object        srvcObj,
-                             Object        attrObj)
-        {
-            this.srvcItems  = srvcItems;
-            this.attrs      = attrs;
-
-            this.srvcObj    = srvcObj;
-            this.attrObj    = attrObj;
-            this.transition = 0;
-        }
-
-        /** Creates a SrvcAttrTuple with the given transition value
-         *  and null reference arrays of service items and attributes.
-         *  @param srvcObj the service component of the new tuple
-         *  @param attrObj the attribute component of the new tuple
-         *  @param transition the transition component of the new tuple
-         */
-        public SrvcAttrTuple(Object srvcObj,
-                             Object attrObj,
-                             int    transition)
-        {
-            this.srvcItems  = null;
-            this.attrs      = null;
-
-            this.srvcObj    = srvcObj;
-            this.attrObj    = attrObj;
-            this.transition = transition;
-        }
-
-        /** Creates a SrvcAttrTuple with the "unknown" (0) transition value
-         *  and null reference arrays of service items and attributes.
-         *  @param srvcObj the service component of the new tuple
-         *  @param attrObj the attribute component of the new tuple
-         */
-        public SrvcAttrTuple(Object srvcObj,
-                             Object attrObj)
-        {
-            this.srvcItems  = null;
-            this.attrs      = null;
-
-            this.srvcObj    = srvcObj;
-            this.attrObj    = attrObj;
-            this.transition = 0;
-        }
-
-        /** Sets this tuple equal to the given tuple
-         *  @param tuple the SrvcAttrTuple to set this tuple equal to
-         */
-        public void setEqualTo(SrvcAttrTuple tuple) {
-            this.srvcItems  = tuple.srvcItems;
-            this.attrs      = tuple.attrs;
-            this.srvcObj    = tuple.srvcObj;
-            this.attrObj    = tuple.attrObj;
-            this.transition = tuple.transition;
-        }
-
-        /** Returns the array of service items associated with this tuple */
-        public ServiceItem[] getSrvcItems() {
-            return srvcItems;
-        }
-
-        /** Sets the reference to the array of service items associated with
-         *  this tuple equal to the given reference
-         *  @param srvcItems the new array of service items
-         */
-        public void setSrvcItems(ServiceItem[] srvcItems) {
-            this.srvcItems = srvcItems;
-        }
-
-        /** Returns the array of attributes associated with this tuple */
-        public Entry[][] getAttrs() {
-            return attrs;
-        }
-
-        /** Sets the reference to the array of attributes associated with
-         *  this tuple equal to the given reference
-         *  @param attrs the new array-of-arrays of attributes
-         */
-        public void setAttrs(Entry[][] attrs) {
-            this.attrs = attrs;
-        }
-
-        /** Returns the service item associated with this tuple */
-        public Object getSrvcObj() {
-            return srvcObj;
-        }
-
-        /** Sets the reference to the service item associated with
-         *  this tuple equal to the given reference
-         *  @param srvcObj the new service item
-         */
-        public void setSrvcObj(Object srvcObj) {
-            this.srvcObj = srvcObj;
-        }
-
-        /** Returns the attribute associated with this tuple */
-        public Object getAttrObj() {
-            return attrObj;
-        }
-
-        /** Sets the reference to the attribute associated with
-         *  this tuple equal to the given reference
-         *  @param attrObj the new attribute
-         */
-        public void setAttrObj(Object attrObj) {
-            this.attrObj = attrObj;
-        }
-
-        /** Returns the transition associated with this tuple */
-        public int getTransition() {
-            return transition;
-        }
-
-        /** Sets the transition associated with this tuple equal to the 
-         *  given transition
-         *  @param transition the new transition value
-         */
-        public void setTransition(int transition) {
-            this.transition = transition;
-        }
-
-        /** Determines if the given object is equal to this tuple; where
-         *  two tuples are equal if their service items are equal, their
-         *  attributes are equal and their transitions are equal.
-         *  @param obj the tuple to compare to this tuple
-         *  @return boolean
-         */
-        public boolean equals(Object obj) {
-            int trans = ((SrvcAttrTuple)obj).getTransition();
-            return ( (objEquals(obj)) && (this.transition == trans) );
-        }
-
-        /** Determines if the service item and and the attribute of the 
-         *  given object are equal to the corresponding fields of this 
-         *  tuple; that is, this method ignores the transition values
-         *  of the tuples.
-         *  @param obj the tuple to compare to this tuple
-         *  @return boolean
-         */
-        public boolean objEquals(Object obj) {
-            if (this == obj) {
-                return true;
-            } else if ( (obj.getClass()).equals(SrvcAttrTuple.class) ) {
-                if ((srvcItems == null)||(attrs == null)) {
-                    return false;
-		}
-                int n=0;
-                int k=0;
-                Object srvc = ((SrvcAttrTuple)obj).getSrvcObj();
-                Object attr = ((SrvcAttrTuple)obj).getAttrObj();
-                try {
-                    n = getSrvcIndx(this.srvcObj,srvcItems);
-                    k = getAttrIndx(this.attrObj,attrs);
-                    if (    ((srvcItems[n].service).equals(srvc))
-                         && ((attrs[k][0]).equals(attr)) ) {
-                        return true;
-		    } else {
-                        return false;
-		    }
-                } catch (ArrayIndexOutOfBoundsException e) {
-                    return false;
-		}
-            } else {
-                return false;
-            }
-        }
-    }
-
-    /** Steps through the given array of service items searching for the
-     *  element that equals the given service item Object; returning the
-     *  element index if a match is found and -1 otherwise
-     *  @param obj service item object to search for
-     *  @param srvcItems array of service items to search
-     *  @return int (array index or -1 if no match found)
-     */
-    public static int getSrvcIndx(Object        obj,
-                                  ServiceItem[] srvcItems) {
-        try {
-            int n;
-	    /* get the srvc instance the input Object corresponds to */
-            for(n=0;n<srvcItems.length;n++) {
-                if ( (srvcItems[n].service).equals(obj) ) {
-                    break;
-                }
-            }
-            if (n < srvcItems.length) {
-                return n;
-	    } else {
-                return -1;
-	    }
-        } catch (ArrayIndexOutOfBoundsException e) {
-           return -1;
-        } catch (NullPointerException e) {
-            return -1;
-     	}
-    }
-
-    /** Steps through the given array of attribute objects searching for
-     *  the element that equals the given attribute Object; returning the
-     *  element index if a match is found and -1 otherwise
-     *  @param obj attribute object to search for
-     *  @return int (array index or -1 if no match found)
-     */
-    public static int getAttrIndx(Object     obj,
-                                  Entry[][]  attrs) {
-        try {
-            int n;
-	    /* get the attribute instance the input Object corresponds to */
-            for(n=0;n<attrs.length;n++) {
-                if ( (attrs[n][0]).equals(obj) ) {
-                    break;
-		}
-   	    }
-            if (n < attrs.length) {
-                return n;
-	    } else {
-                return -1;
-	    }
-        } catch (ArrayIndexOutOfBoundsException e) {
-           return -1;
-        } catch (NullPointerException e) {
-            return -1;
-     	}
-    }
-
-    /** Returns the current time in milliseconds 
-     *  @return long
-     */
-    public static long getCurTime() {
-	return System.currentTimeMillis();
-    }
-
-    /** Creates an instance of the given (loaded) class object. This method 
-     *  assumes that the loaded class has a constructor with a single argument
-     *  of type int That single int field of the new object will be
-     *  initialized to the given value.
-     *  @param classObj class type to instantiate
-     *  @param instanceIndx value to which to initialize the class field
-     *  @exception TestException usually indicates a failure
-     *  @return java.lang.Object 
-     */
-    public static Object createInstance(Class classObj,
-                                        int   instanceIndx)
-                                                         throws Exception
-    {
-        Class[] parameterTypes = { int.class };
-	    Constructor con = classObj.getConstructor(parameterTypes);
-            return con.newInstance(new Object[]{new Integer(instanceIndx)});
-    } 
-
-    /** Creates an instance of the given (loaded) class object. This method 
-     *  assumes that the loaded class has a constructor with a set of 
-     *  arguments corresponding to the contents of given array of Objects. 
-     *  The fields of the new object will be initialized to the values 
-     *  contained in the given array.
-     *  @param classObj class type to instantiate
-     *  @param constructorArgs array of Objects for field initialization
-     *  @return java.lang.Object 
-     */
-    public static Object createInstance(Class    classObj,
-                                        Object[] constructorArgs)
-                                                         throws Exception
-    {
-        Object o = null;
-        if (constructorArgs == null) {
-	    o = classObj.newInstance();
-        } else {
-            Class[] constructorArgTypes = new Class[constructorArgs.length];
-	    for (int i=0;i<constructorArgs.length;i++) {
-		constructorArgTypes[i] = constructorArgs[i].getClass();
-	    }
-	    Constructor con = classObj.getConstructor(constructorArgTypes);
-	    o = con.newInstance(constructorArgs);
-	}
-        return o;
-    } 
-
-    /** Computes a wait duration based on the given "start" time, a desired 
-     *  increment (assuming instanteous time -- the given deltaT), and an 
-     *  adjustment to correct for compute time (the current time). A negative 
-     *  duration will be treated as an invalid -- or "unresolved" -- test 
-     *  case. If the duration is non-negative, then this method will sleep 
-     *  for that many milliseconds, and then return.
-     *  @param baseT0 the start time
-     *  @param deltaT time increment
-     *  @exception TestException usually indicates a failure
-     */
-    public static void computeDurAndWait(long baseT0, long deltaT, Object lock) throws Exception
-    {
-        long finishTime = baseT0 + deltaT;
-        long dur = finishTime - System.currentTimeMillis();
-	if(dur > 0) {
-            do {
-                synchronized (lock) { lock.wait(dur); }
-                dur = finishTime - System.currentTimeMillis();
-            } while (dur > 0); // In case of spurious wakeup or notify.
-	} else {
-            throw new TestException("Environment problem; this configuration"
-                                    + " does not allow for the timing"
-                                    + " assumptions made by the test");
-                                    
-	}
-    }
-
-    /** Sleeps for the given amount of milliseconds
-     *  @param deltaT time in milliseconds to sleep
-     */
-    public static void waitDeltaT(long deltaT, Object lock) throws Exception {
-        long finish = System.currentTimeMillis() + deltaT;
-        synchronized (lock){
-            do {
-                lock.wait(deltaT);
-            } while (finish > System.currentTimeMillis());
-        }
-//	Thread.sleep(deltaT);
-    }
-
-    /** Returns true if the input argument is even; false otherwise
-     *  @param i integer to test for even or odd
-     */
-    public static boolean isEven(int i) {
-        return ((i&1) == 1 ? false:true);
-    }
-
-    /** Determines if all of the expected (and no un-expected) events 
-     *  have arrived. The test in this method depends on the semantics of 
-     *  event-notification. That is, it will use the fact that if the events
-     *  were generated for each service class in sequence (which they were),
-     *  although the events may arrive out of order, they can be arranged
-     *  back into the same sequence using RemoteEventComparator. 
-     *  This means we can expect, when examining the event corresponding 
-     *  to index i, that the serviceID returned in the ServiceEvent should 
-     *  correspond to the i_th service registered. If it does not,
-     *  remote events are missing and failure is declared.
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  NotifyOnAttrAdd
-     *                  NotifyOnAttrMod
-     *                  NotifyOnAttrDel
-     *                  NotifyOnSrvcLeaseExpiration
-     *
-     *  @param events vector containing the events to test
-     *  @param nExpectedEvnts number of events expected
-     *  @param expectedTransition the expected event transition
-     *  @param serviceRegs array of ServiceRegistrations of each service
-     *  @exception TestException usually indicates a failure
-     */
-    public static void verifyEventVector(List<ServiceEvent> events,
-                                         int nExpectedEvnts,
-                                         int expectedTransition,
-                                         ServiceRegistration[] serviceRegs)
-                                                         throws Exception
-    {
-        ServiceEvent evnt = null;
-        if (events.size() != nExpectedEvnts) {
-            throw new TestException("# of Events Received ("+
-                                             events.size()+
-                                             ") != # of Events Expected ("+
-                                             nExpectedEvnts+")");
-	} else {
-            Collections.sort(events, new RemoteEventComparator());
-            ServiceID evntSrvcID;
-            ServiceID expdSrvcID;
-            ServiceID handbackSrvcID;
-	    for(int i=0; i<events.size(); i++) {
-                evnt = (ServiceEvent)events.get(i);
-                if (evnt == null) {
-                    throw new TestException
-                             ("null Event returned from Vector at element "+i);
-	   	} else {
-                    if (evnt.getTransition() != expectedTransition) {
-			dumpEventIDs(events, serviceRegs);
-                        throw new TestException("Unexpected Transition returned ("+
-						evnt.getTransition()+")");
-		    } else {
-                        evntSrvcID = evnt.getServiceID();
-                        expdSrvcID = serviceRegs[i].getServiceID();
-                        if ( !(evntSrvcID.equals(expdSrvcID)) ) {
-                            throw new TestException("Service ID Received ("+
-						    evntSrvcID+
-						    ") != Service ID Expected ("+
-						    expdSrvcID+")");
-			} else {
-			    handbackSrvcID = 
-				(ServiceID)(evnt.getRegistrationObject().get());
-
-			    if ( !(handbackSrvcID.equals(expdSrvcID)) ) {
-				throw new TestException
-				    ("Handback Service ID ("+
-				     handbackSrvcID+
-				     ") != Service ID Expected ("+
-				     expdSrvcID+")");
-			    }
-			}
-		    }
-		}
-	    }
-	}
-	verifyEventItems(events);
-    }
-
-    public static void dumpEventIDs(List<ServiceEvent> events,
-                                    ServiceRegistration[] serviceRegs)
-    {
-        ServiceEvent evnt = null;
-	ServiceID evntSrvcID;
-	ServiceID expdSrvcID;
-	ServiceID handbackSrvcID;
-	for(int i=0; i<events.size(); i++) {
-	    evnt = (ServiceEvent)events.get(i);
-	    evntSrvcID = evnt.getServiceID();
-	    expdSrvcID = serviceRegs[i].getServiceID();
-	    System.out.println("Expected ID = " + expdSrvcID + ", received ID = " + evntSrvcID);
-	}
-    }
-
-    /** Verifies that the ServiceItem in each event is as expected.
-     *  If there is no later event with the same service ID, then
-     *  compare the item in the event with the current item in the
-     *  lookup service.  If the item in the event is null, then the
-     *  item must no longer exist in the lookup service, otherwise
-     *  the item must exist in the lookup service and be equal to
-     *  the one in the event.  We skip an event if there is a later
-     *  event with the same service ID, as that means the state of
-     *  the item recorded in the event was subsequently changed again.
-     *
-     *  @param events List containing the events to test
-     *  @exception TestException usually indicates a failure
-     */
-    public static void verifyEventItems(List<ServiceEvent> events)
-	throws Exception
-    {
-        Collections.sort(events, new RemoteEventComparator());
-	ServiceTemplate tmpl;
-    outer:
-	for (int i = 0; i < events.size(); i++) {
-	    ServiceEvent evnt = (ServiceEvent)events.get(i);
-	    for (int j = i + 1; j < events.size(); j++) {
-		ServiceEvent oevnt = (ServiceEvent)events.get(j);
-		if (evnt.getServiceID().equals(oevnt.getServiceID()))
-		    continue outer;
-	    }
-	    ServiceItem item = evnt.getServiceItem();
-	    tmpl = new ServiceTemplate(evnt.getServiceID(), null, null);
-	    ServiceRegistrar proxy = (ServiceRegistrar)evnt.getSource();
-	    proxy = (ServiceRegistrar) 
-		    QAConfig.getConfig().prepare("test.reggiePreparer",
-						      proxy);
-	    ServiceMatches matches;
-	    matches = proxy.lookup(tmpl, 1);
-	    if (item == null) {
-		if (matches.items.length != 0)
-		    throw new TestException(
-			      "verifyEventItems: event item is null, lookup returns non-null");
-	    } else {
-		if (matches.items.length == 0)
-		    throw new TestException(
-			      "verifyEventItems: event item is non-null, lookup returns null");
-		ServiceItem litem = matches.items[0];
-		if (!item.service.equals(litem.service))
-		    throw new TestException(
-			      "verifyEventItems: event item service does not equal lookup value");
-		if (!attrsEqual(item.attributeSets, litem.attributeSets))
-		     throw new TestException(
-			      "verifyEventItems: event item attrs do not equal lookup value");
-	    }
-	}
-    }
-
-    /** Tests if two arrays of attribute sets are the same length and
-     *  have equal elements, ignoring element ordering differences.
-     *
-     *  @param attrs1 an array of attribute sets
-     *  @param attrs2 an array of attribute sets
-     */
-    public static boolean attrsEqual(Entry[] attrs1, Entry[] attrs2) {
-	if (attrs1.length != attrs2.length)
-	    return false;
-    outer:
-	for (int i = 0; i < attrs1.length; i++) {
-	    for (int j = 0; j < attrs2.length; j++) {
-		if (attrs1[i].equals(attrs2[j]))
-		    continue outer;
-	    }
-	    return false;
-	}
-	return true;
-    }
-
-    /** Performs a simple lookup and a match lookup using only the serviceID
-     *  @param srvcItems array of registered service items 
-     *  @param templates array of used input to lookup()
-     *  @param proxy proxy of Registrar through which lookup is performed
-     *  @exception TestException usually indicates a failure
-     */
-    public static void doLookup(ServiceItem[] srvcItems,
-                                ServiceTemplate[] templates,
-				ServiceRegistrar proxy)  throws Exception
-    {
-        Object serviceObj = null;
-        ServiceMatches matches = null;
-        for (int i=0; i<templates.length; i++) {
-	    serviceObj = proxy.lookup(templates[i]);
-            if (!srvcItems[i].service.equals(serviceObj)) {
-                throw new TestException("srvcItems["+i+
-					"] != serviceObj returned by lookup()");
-	    }
-
-	    matches = proxy.lookup(templates[i],Integer.MAX_VALUE);
-            if (matches.totalMatches != 1) {
-                throw new TestException
-		    ("totalMatches != EXPECTED_N_MATCHES");
-	    } else {
-                if (!srvcItems[i].service.equals(matches.items[0].service)) {
-                    throw new TestException("srvcItems["+i+
-					    "] != items[0].service returned by lookup()");
-		}
-	    }
-	}
-    }
-
-    /** Steps through the given array of leases, comparing each element's
-     *  lease expiration against the given minimum lease expiration; a
-     *  failure exception will be thrown if any of the lease expirations
-     *  is less than the minimum expiration 
-     *  @param leases array of lease objects corresponding to each service 
-     *  @param minExpiration minimum lease expiration time
-     *  @exception TestException usually indicates a failure
-     *  @see net.jini.core.lease.Lease
-     */
-    public static void verifyLeases(Lease[] leases,
-                                    long minExpiration)  throws Exception
-    {
-	for(int i=0; i<leases.length; i++) {
-	    if(leases[i].getExpiration() < minExpiration) {
-                throw new TestException("verifyLeases: expiration of lease ["
-					+i+"] ("+leases[i].getExpiration()+
-					" ms) < expected min expiration ("
-					+minExpiration+" ms)");
-	    } else {
-		minExpiration = leases[i].getExpiration();
-	    }
-	}
-    }
-
-    /** Steps through the given array of leases, renewing each element's
-     *  lease with the given lease duration value
-     *  @param leases array of lease objects corresponding to each service 
-     *  @param leaseDuration lease duration to request in renewal
-     *  @exception TestException usually indicates a failure
-     *  @see net.jini.core.lease.Lease
-     */
-    public static void doRenewLease(Lease[] leases,
-                                    long leaseDuration) throws Exception
-    {
-        for(int i=0; i< leases.length; i++ ) {
-	    leases[i].renew(leaseDuration);
-	}
-    }
-
-    /** Steps through the given array of service items, searching for the
-     *  element that equals the given Object; returning the index of the
-     *  matching element or -1 if no match is found
-     *  @param srvcObj service item to search for 
-     *  @param srvcItems array of service items to search through 
-     *  @see net.jini.core.lookup.ServiceItem
-     */
-    public static int srvcIndxFrmSimpleLookup( Object        srvcObj,
-                                               ServiceItem[] srvcItems ) {
-        int indx = -1;
-        for (int j=0;((indx==-1)&&(j<srvcItems.length)); j++) {
-            if ((srvcItems[j].service.equals(srvcObj))) {
-               indx  = j;
-	    }
-	}
-        return indx;
-    }
-
-    /** Inserts the given value into the given histogram.
-     *  
-     *  Note that the method that calls this method must create the 
-     *  histogram. If the histogram is null, then this method will throw
-     *  a NullPointerException
-     *  @param value value to place in the histogram
-     *  @param histogram HashMap representing the histogram 
-     */
-    public static void srvcHistogram( int value,
-                                      HashMap histogram ) {
-        Integer histKey = new Integer(value);
-        Integer histVal = (Integer)histogram.get(histKey);
-        int newHistVal = ( (histVal==null) ? 1 : 1+histVal.intValue() );
-        Integer newValue = new Integer(newHistVal);
-        histogram.put(histKey,newValue);
-    }
-
-    /** Returns the value of the largest key index in the given histogram 
-     *  @param histogram HashMap representing the histogram 
-     *  @return int
-     */
-    public static int getMaxKeyHistogram( HashMap histogram ) {
-        int maxKey = 0;
-        int counter = 0;
-        if ( histogram != null ) {
-            int hSize = histogram.size();
-	    for ( int i=0; counter < hSize; i++ ) {
-	        if (histogram.get(new Integer(i)) != null) {
-                    counter++;
-                    if (counter >= hSize) {
-                        maxKey = i;
-		    }
-		}
-	    }
-	}
-        return maxKey;
-    }
-
-    /** Prints the values of the given histogram to stdout (for debugging) 
-     *  @param histogram HashMap representing the histogram 
-     */
-    public static void displayHistogram( HashMap histogram ) {
-	if ( histogram != null ) {
-	    for ( int i=0; i <= getMaxKeyHistogram(histogram); i++ ) {
-                System.out.println("histogram("+i+") = "
-                                          +histogram.get(new Integer(i)));
-	    }
-	}
-    }
-
-    /** Disregarding order, verify that the given set of class types is
-     *  equal to the given set of type descriptors. For the case where
-     *  the classType is assignable to net.jini.lookup.entry.ServiceType,
-     *  it is only required that the class associated with the typeDescriptor
-     *  also is assignable to net.jini.lookup.entry. This is to handle
-     *  the case where the actual class is 
-     *  com.sun.jini.lookup.entry.BasicServiceType,
-     *  which may be preferred. This would case an 'equals' comparison to fail.
-     *  In addition, a special case involves a check for the reggie proxy class.
-     *  Since the proxy used is configuration dependent, if a typeDescriptor
-     *  has the value "com.sun.jini.reggie.RegistrarProxy", then equality
-     *  will be satisfied if a classType can be found whose getName method
-     *  returns either "com.sun.jini.reggie.RegistrarProxy" or
-     *  "com.sun.jini.reggie.ConstrainableRegistrarProxy"
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  GetServiceTypesEmpty
-     *                  GetServiceTypesClass
-     *                  GetServiceTypesAttr
-     *
-     *  @param classTypes array of class types
-     *  @param typeDescriptors array of class name descriptors 
-     *  @exception TestException usually indicates a failure
-     */
-    public static boolean classTypesEqualTypeDescriptors
-                                            ( Class[] classTypes,
-                                              String[] typeDescriptors )
-    {
-        if (typeDescriptors == null) {
-            return (classTypes == null);
-	}
-	if (classTypes == null) {
-	    logger.log(Level.INFO, "classTypes is null");
-	}
-        if (classTypes.length != typeDescriptors.length) {
-	    logger.log(Level.INFO, "classTypes != typeDescriptors");
-	    for (int i = 0; i < classTypes.length; i++) {
-		logger.log(Level.INFO, 
-			   "classTypes[ " + i + "] = " + classTypes[i]);
-	    }
-	    for (int i = 0; i < typeDescriptors.length; i++) {
-		logger.log(Level.INFO, 
-			   "typeDescriptors[ " + i + "] = " 
-			   + typeDescriptors[i]);
-	    }
-            return false;
-	}
-	String reggieProxy = "com.sun.jini.reggie.RegistrarProxy";
-	String cReggieProxy = "com.sun.jini.reggie.ConstrainableRegistrarProxy";
-        iLoop:
-            for (int i=0; i<classTypes.length; i++) {
-                for (int j=0;(j<typeDescriptors.length); j++) {
-		    try {
-			Class c = Class.forName(typeDescriptors[j]);
-                        if (classTypes[i].equals(c)) {
-                            continue iLoop;
-	                }
-			Class serviceTypeClass = ServiceType.class;
-                        if (serviceTypeClass.isAssignableFrom(classTypes[i])) {
-			    if (serviceTypeClass.isAssignableFrom(c)) {
-			        continue iLoop;
-			    }
-			}
-			if (typeDescriptors[j].equals(reggieProxy)) {
-			    if (classTypes[i].getName().equals(reggieProxy)
-			     || classTypes[i].getName().equals(cReggieProxy)) {
-				continue iLoop;
-			    }
-			}
-		    } catch (ClassNotFoundException e) {
-			if (classTypes[i].getName().equals(typeDescriptors[j])) {
-			    continue iLoop;
-			}
-			if (typeDescriptors[j].equals(reggieProxy)) {
-			    if (classTypes[i].getName().equals(reggieProxy)
-			     || classTypes[i].getName().equals(cReggieProxy)) {
-				continue iLoop;
-			    }
-			}
-			logger.log(Level.INFO, 
-				   "Could not find service type class named " 
-				   + typeDescriptors[j]);
-		    }
-	        }
-	        logger.log(Level.INFO,
-			   "Could not find match for classTypes = " 
-			   + classTypes[i]);
-                return false;
-            }
-        return true; /* success */
-    }
-
-    /** Returns the number of classes in the chain of super classes of the
-     *  given Object; up to, but not including, the Object class itself
-     *  @param obj the Object to analyze for super classes
-     *  @exception TestException usually indicates a failure
-     *  @return int
-     */
-    public static int getNSuperClasses(Object obj) {
-        int n = 0;
-        try {
-            Class superClass = obj.getClass().getSuperclass();
-            while(true) {
-                if( !(superClass.getSuperclass() == null) ) {
-                    n++;
-                    superClass = superClass.getSuperclass();
-   	        } else {
-                    return n;
-	        }
-	    }
-        } catch (NullPointerException e) {
-            return 0;
-        }
-    }
-
-    /** Returns the nth super class in the chain of super classes of the
-     *  given Object; returns null if the given value of n is invalid.
-     *  @param obj the Object to analyze for super classes
-     *  @param n super class "index" to return
-     *  @exception TestException usually indicates a failure
-     *  @return int
-     */
-    public static Object getNthSuperClass(Object obj, int n) {
-        int totalN;
-        Class superClass = null;
-        try {
-            totalN = getNSuperClasses(obj);
-            if ((totalN > 0)&&(n>0)&&(n<=totalN)) {
-                superClass = obj.getClass().getSuperclass();
-                for(int i=1;i<n;i++) {
-                    superClass = superClass.getSuperclass();
-                }
-                return (Object)superClass;
-	    } else {
-                return null;
-	    }
-        } catch (NullPointerException e) {
-            return null;
-        }
-    }
-
-    /** Returns true if the given attribute objects match, else returns false
-     *  Note that the order of the input Objects is NOT important
-     *  @param attrObj0 first attribute object to compare
-     *  @param attrObj1 second attribute object to compare
-     *  @exception TestException usually indicates a failure
-     *  @return boolean
-     */
-    public static boolean attrsMatch(Object attrObj0, Object attrObj1) {
-        Object sObj = null;
-        Object cObj  = null;
-        if ( attrObj0.equals(attrObj1) ) {
-            return true;
-	} else if ( (attrObj0.getClass()).equals((attrObj1).getClass()) ) {
-            return false;
-	} else {
-	    if ((attrObj0.getClass()).isAssignableFrom(attrObj1.getClass())) {
-                /* cast attrObj1 to super class attrObj0 */
-                sObj = attrObj0;
-                cObj = attrObj1;
-	    } else if
-               ((attrObj1.getClass()).isAssignableFrom(attrObj0.getClass())) {
-                /* cast attrObj0 to super class attrObj1 */
-                sObj = attrObj1;
-                cObj = attrObj0;
-	    } else {
-                return false;
-	    }
-            return ((Attr)sObj).matches(cObj);
-	}
-    }
-
-    /** Returns true if the given attribute objects match, else returns false
-     *  Note that the order of the input Objects IS important
-     *  @param attrObj0 first attribute object to compare
-     *  @param attrObj1 second attribute object to compare
-     *  @param orderImportant true or false
-     *  @exception TestException usually indicates a failure
-     *  @return boolean
-     */
-    public static boolean attrsMatch(Object attrObj0,
-                                     Object attrObj1,
-                                     boolean orderImportant)
-    {
-        if (!orderImportant) {
-            return attrsMatch(attrObj0,attrObj1);
-	} else {
-            if ( attrObj0.equals(attrObj1) ) {
-                return true;
-	    } else if ( (attrObj0.getClass()).equals((attrObj1).getClass()) ) {
-                return true;
-   	    } else if((attrObj0.getClass()).isAssignableFrom
-                                                        (attrObj1.getClass())){
-                return ((Attr)attrObj0).matches(attrObj1);
-	    } else {
-                return false;
-	    }
-	}
-    }
-
-    /** Initializes the given SrvcAttrTuple state array element at the two
-     *  given index values to the corresponding values contained in the 
-     *  arguments named srvcItems and attrs
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  NotifyOnComboAttrAddNull
-     *                  NotifyOnComboAttrAddNonNull
-     *                  NotifyOnComboAttrModNull
-     *                  NotifyOnComboAttrModNonNull
-     *                  NotifyOnComboAttrDelNull
-     *                  NotifyOnComboAttrDelNonNull
-     *                  NotifyOnComboSrvcLeaseExp
-     *
-     *  @param srvcIndx index of the service item
-     *  @param attrIndx index of the attribute
-     *  @param superChainLen length of the service super class "chain"
-     *  @param srvcItems array of registered services
-     *  @param srvcsForEquals array of instantiated services for comparison
-     *  @param attrs array-of-arrays of attribute objects for matching
-     *  @param state the state array of tuples
-     *  @exception TestException usually indicates a failure
-     *  @see net.jini.core.lookup.ServiceItem
-     */
-    public static void initStateTupleArray
-                                        (int srvcIndx,
-                                         int attrIndx,
-                                         int superChainLen,
-                                         ServiceItem[] srvcItems,
-                                         ServiceItem[] srvcsForEquals,
-                                         Entry[][] attrs,
-                                         SrvcAttrTuple[][][] state)
-	throws Exception
-    {
-        state[srvcIndx][attrIndx][0]
-                               = new SrvcAttrTuple(srvcsForEquals,
-                                                   attrs,
-                                                   srvcItems[srvcIndx].service,
-                                                   attrs[attrIndx][0]);
-
-        Class superClass = null;
-        superClass = (srvcItems[srvcIndx].service).getClass().getSuperclass();
-        for(int i=1;i<superChainLen;i++) {
-            if( !(superClass.getSuperclass() == null) ) {
-                state[srvcIndx][attrIndx][i] =
-                         new SrvcAttrTuple(srvcsForEquals,attrs,
-                                           createInstance(superClass,srvcIndx),
-                                           attrs[attrIndx][0]);
-                superClass = superClass.getSuperclass();
-	    } else {
-                state[srvcIndx][attrIndx][i] =
-                             new SrvcAttrTuple(srvcsForEquals,attrs,
-                                               createInstance(superClass,null),
-                                               attrs[attrIndx][0]);
-                return;
-	    }
-	}
-    }
-
-    /** Initializes all of the elements in the given SrvcAttrTuple array to 
-     *  null for the attribute component of the Tuple; and to the 
-     *  corresponding service item for the service component
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  NotifyOnComboAttrAddNull
-     *                  NotifyOnComboAttrAddNonNull
-     *                  NotifyOnComboSrvcReg
-     *
-     *  @param srvcItems array of registered services
-     *  @param srvcsForEquals array of instantiated services for comparison
-     *  @param attrs array-of-arrays of attribute objects for matching
-     *  @param state the state array of tuples
-     *  @exception TestException usually indicates a failure
-     *  @see net.jini.core.lookup.ServiceItem
-     *  @see net.jini.core.entry.Entry
-     */
-    public static void initStateTupleArray
-                                        (ServiceItem[] srvcItems,
-                                         ServiceItem[] srvcsForEquals,
-                                         Entry[][] attrs,
-                                         SrvcAttrTuple[][][] state)
-	throws Exception
-    {
-        for(int i=0;i<state.length;i++) {
-            jLoop:
-            for(int j=0;j<state[i].length;j++) {
-                state[i][j][0] = new SrvcAttrTuple(srvcsForEquals,attrs,
-                                                   srvcItems[i].service,null);
-                Class superClass = null;
-                superClass = (srvcItems[i].service).getClass().getSuperclass();
-                for(int k=1;k<state[i][j].length;k++) {
-                    if( !(superClass.getSuperclass() == null) ) {
-                        state[i][j][k] = new SrvcAttrTuple
-                                                 (srvcsForEquals,attrs,
-                                                  createInstance(superClass,i),
-                                                  null);
-                            superClass = superClass.getSuperclass();
-		    } else {
-                        state[i][j][k] = new SrvcAttrTuple
-                                              (srvcsForEquals,attrs,
-                                               createInstance(superClass,null),
-                                               null);
-                        continue jLoop;
-		    }
-		}
-	    }
-	}
-    }
-
-    /** Retrieves the chain of super classes of the given object; up to, but
-     *  not including, the Object class itself. Returns a vector containing 
-     *  initialized instances of each class in the chain (including
-     *  the instance of the given object itself).
-     *
-     *  Note: this method is specific to the set of test service classes
-     *        that are registered during any typical lookup test. Thus,
-     *        this method should be invoked only on objects that belong to
-     *        a chain of classes contained in the set of test services; 
-     *        that is, the input object, as well as each of the super 
-     *        classes in the chain have a constructor that requires a 
-     *        single argument of type int.
-     *
-     *  @param obj object that is analyzed for its super classes
-     *  @param srvcItems array of registered services
-     *  @exception TestException usually indicates a failure
-     *  @return java.util.Vector 
-     *  @see net.jini.core.lookup.ServiceItem
-     */
-    public static Vector getSrvcSupersVector(Object        obj,
-                                             ServiceItem[] srvcItems)
-	throws Exception
-    {
-        int n;
-        Class superClass = null;
-        Vector objSupers = new Vector();
-        objSupers.addElement(obj);
-        superClass = obj.getClass().getSuperclass();
-        while(true) {
-            if( !(superClass.getSuperclass() == null) ) {
-                for(n=0;n<srvcItems.length;n++) {
-                    if (superClass.isInstance(srvcItems[n].service) ) {
-                        break;
-		    }
-		}
-                objSupers.addElement(createInstance(superClass,n));
-                superClass = superClass.getSuperclass();
-	    } else {
-                return objSupers;
-	    }
-	}
-    }
-
-    /** Retrieves the chain of super classes of the input object; up to, but
-     *  not including, the Object class itself. Returns a vector containing 
-     *  non-initialized instances of each class in the chain (including
-     *  the instance of the input object itself).
-     *
-     *  Note: this method should be invoked only on objects that have 
-     *        super classes containing no-arg constructors.
-     *
-     *  @param obj object that is analyzed for its super classes
-     *  @exception TestException usually indicates a failure
-     *  @return java.util.Vector 
-     */
-    public static Vector getNoArgSupersVector(Object obj) throws Exception {
-        Class superClass = null;
-        Vector objSupers = new Vector();
-        objSupers.addElement(obj);
-        superClass = obj.getClass().getSuperclass();
-        while(true) {
-            if( !(superClass.getSuperclass() == null) ) {
-		objSupers.addElement( superClass.newInstance() );
-                superClass = superClass.getSuperclass();
-	    } else {
-                return objSupers;
-	    }
-	}
-    }
-
-    /** From the assumption that the addition, modification or deletion 
-     *  of an attribute of one of the registered service classes will 
-     *  result in one or more events being generated by the lookup service, 
-     *  this method "predicts" all of the service/attribute "pairs" 
-     *  corresponding to the set of events that will be generated from 
-     *  the "base" pair represented by the input srvcObj/attrObj pair.
-     *  The number and "cause" of these events is dependent on the 
-     *  contents of the template or templates used to register the event 
-     *  notification requests with lookup. This method assumes that an 
-     *  event was registered using a template containing the class of 
-     *  both the input srvcObj argument and the attrObj argument.  
-     *
-     *  That is, given the template/event-registration-request assumption
-     *  just described, if attrObj is added to, modified on, or deleted from 
-     *  srvcObj, then an event will be generated for each service/attribute
-     *  pair in the lookup service which also matches one of the templates.
-     *
-     *  This method will populate the given tuples vector with the set of
-     *  service/attribute/transition "tuples" corresponding to the events
-     *  expected to be generated when the srvcObj's state is modified 
-     *  The tuples vector will contain all of the tuples that have accumulated
-     *  over the life of the current test run. Thus, because that vector
-     *  contains all of the expected pairs generated by previous calls to
-     *  this method, the tuples vector must be created and maintained --
-     *  outside of this method -- by the invoking class.
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  NotifyOnComboAttrAddNull
-     *                  NotifyOnComboAttrAddNonNull
-     *                  NotifyOnComboAttrModNull
-     *                  NotifyOnComboAttrModNonNull
-     *                  NotifyOnComboAttrDelNull
-     *                  NotifyOnComboAttrDelNonNull
-     *                  NotifyOnComboSrvcReg
-     *                  NotifyOnComboSrvcLeaseExp
-     *
-     *  @param srvcObj object whose state has changed
-     *  @param srvcItems array of registered services
-     *  @param srvcsForEquals array of instantiated services for comparison
-     *  @param attrs array-of-arrays of attribute objects for matching
-     *  @param nSrvcsPerClass number of service instances per class type
-     *  @param template template to use for matching
-     *  @param preEventState the state array of tuples prior to the event
-     *  @param postEventState the state array of tuples after the event
-     *  @param tuples vector in which the expected tuples are accumulated
-     *  @exception TestException usually indicates a failure
-     *  @see net.jini.core.lookup.ServiceItem
-     *  @see net.jini.core.entry.Entry
-     */
-    public static void setExpectedEvents(Object srvcObj,
-                                         ServiceItem[] srvcItems,
-                                         ServiceItem[] srvcsForEquals,
-                                         Entry[][] attrs,
-                                         int nSrvcsPerClass,
-                                         ServiceTemplate[][] template,
-                                         SrvcAttrTuple[][][] preEventState,
-                                         SrvcAttrTuple[][][] postEventState,
-                                         List tuples)
-                                                        throws Exception
-    {
-        int i=0;
-        int j=0;
-        SrvcAttrTuple tmplTuple;;
-	int s0 = getSrvcIndx(srvcObj,srvcItems);
-	int nAttrs = preEventState[0].length;
-	int trans;
-	int newSrvcIndx;
-	ServiceTemplate srvcTmpl;
-	for(j=0;j<nAttrs;j++) {
-	    srvcTmpl = template[s0/nSrvcsPerClass][j];
-	    for(i=0;i<(srvcTmpl.serviceTypes).length;i++) {
-		tmplTuple = new SrvcAttrTuple
-		    ( srvcsForEquals,attrs,
-		      createInstance(srvcTmpl.serviceTypes[i],s0),
-		      (srvcTmpl).attributeSetTemplates[0] );
-
-		if (  ((preEventState[s0][j][i]).getAttrObj() == null)
-		      &&((postEventState[s0][j][i]).getAttrObj()!= null))
-		    {
-		        /* attribute addition */
-                        if ( (postEventState[s0][j][i]).objEquals(tmplTuple) )
-			    {
-				trans = ServiceRegistrar.TRANSITION_NOMATCH_MATCH;
-
-				(preEventState[s0][j][i]).setEqualTo
-				    (postEventState[s0][j][i]);
-				newSrvcIndx = ((s0/nSrvcsPerClass)*nSrvcsPerClass)
-				    -(nSrvcsPerClass*i);
-				tuples.add(new SrvcAttrTuple
-				    (srvcsForEquals,attrs,
-				     srvcItems[newSrvcIndx].service,
-				     attrs[j][0],
-				     trans));
-			    } else {
-				break;
-			    }
-		    } else if( ((preEventState[s0][j][i]).getAttrObj() != null)
-			       &&((postEventState[s0][j][i]).getAttrObj()== null))
-			{
-			    /* attribute deletion */
-			    if ( (preEventState[s0][j][i]).objEquals(tmplTuple) ) {
-				trans = ServiceRegistrar.TRANSITION_MATCH_NOMATCH;
-
-				(preEventState[s0][j][i]).setEqualTo
-				    (postEventState[s0][j][i]);
-				newSrvcIndx = ((s0/nSrvcsPerClass)*nSrvcsPerClass)
-				    -(nSrvcsPerClass*i);
-
-				tuples.add(new SrvcAttrTuple
-				    (srvcsForEquals,attrs,
-				     srvcItems[newSrvcIndx].service,
-				     attrs[j][0],
-				     trans));
-			    } else {
-				break;
-			    }
-			} else if( ((preEventState[s0][j][i]).getAttrObj() != null)
-				   &&((postEventState[s0][j][i]).getAttrObj()!= null))
-			    {
-				/* attribute modification */
-				if ((postEventState[s0][j][i]).objEquals(tmplTuple)) {
-
-				    if ((postEventState[s0][j][i]).objEquals
-					(preEventState[s0][j][i]))
-					{
-					    trans
-						= ServiceRegistrar.TRANSITION_MATCH_MATCH;
-					} else {
-					    trans
-						= ServiceRegistrar.TRANSITION_NOMATCH_MATCH;
-
-					    (preEventState[s0][j][i]).setEqualTo
-						(postEventState[s0][j][i]);
-					}
-				    newSrvcIndx =((s0/nSrvcsPerClass)*nSrvcsPerClass)
-					-(nSrvcsPerClass*i);
-
-				    tuples.add(new SrvcAttrTuple
-					(srvcsForEquals,attrs,
-					 srvcItems[newSrvcIndx].service,
-					 attrs[j][0],
-					 trans));
-				} else {
-				    break;
-				}
-			    }
-	    }
-	}
-
-    }
-
-    /** From the assumption that an event was registered using a template
-     *  containing the class of both the input srvcObj argument and the
-     *  attrObj argument, this method "predicts" all of the service/attribute
-     *  "pairs" corresponding to the set of events that will be generated 
-     *  from the "base" pair represented by the input srvcObj/attrObj pair. 
-     *
-     *  This method will populate the given tuples vector with the set of
-     *  service/attribute/transition "tuples" corresponding to the events
-     *  expected to be generated when the srvcObj's state is modified 
-     *  The tuples vector will contain all of the tuples that have accumulated
-     *  over the life of the current test run. Thus, because that vector
-     *  contains all of the expected pairs generated by previous calls to
-     *  this method, the tuples vector must be created and maintained --
-     *  outside of this method -- by the invoking class.
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  NotifyOnEntryAttrSrvcReg
-     *                  NotifyOnEntryAttrAddNull
-     *                  NotifyOnEntryAttrAddNonNull
-     *
-     *  @param srvcIndx index into the template corresponding to the service
-     *  @param srvcItems array of registered services
-     *  @param srvcsForEquals array of instantiated services for comparison
-     *  @param attrs array-of-arrays of attribute objects for matching
-     *  @param template template to use for matching
-     *  @param state the state array of tuples after the event
-     *  @param tuples vector in which the expected tuples are accumulated
-     *  @exception TestException usually indicates a failure
-     *  @see net.jini.core.lookup.ServiceItem
-     *  @see net.jini.core.entry.Entry
-     */
-    public static void setExpectedEvents(int srvcIndx,
-                                         ServiceItem[] srvcItems,
-                                         ServiceItem[] srvcsForEquals,
-                                         Entry[][] attrs,
-                                         ServiceTemplate[] template,
-                                         SrvcAttrTuple[][][] state,
-                                         List tuples)
-                                                        throws Exception
-    {
-        int trans = ServiceRegistrar.TRANSITION_NOMATCH_MATCH;
-        Object tmplAttr = (template[srvcIndx]).attributeSetTemplates[0];
-
-        for(int i=0;i<state.length;i++) {
-            for(int j=0;j<state[i].length;j++) {
-                if (state[i][j][0] != null) {
-                    Object stateAttr = (state[i][j][0]).getAttrObj();
-                    if (stateAttr != null) {
-                        if (attrsMatch(stateAttr,tmplAttr,true)) {
-                            tuples.add(new SrvcAttrTuple
-                                               (srvcsForEquals,attrs,
-                                                (state[i][j][0]).getSrvcObj(),
-                                                stateAttr,
-                                                trans));
-		        }
-		    }
-		}
-	    }
-	}
-    }
-
-    /** Compares the number and content of the given set of expected events
-     *  to the given set of received events; where the event information 
-     *  is stored in the given vectors as objects of class type SrvcAttrTuple
-     *  @param receivedTuples array of received event tuples
-     *  @param expectedTuples array of expected event tuples
-     *  @param maxWaitTime maximum number of milliseconds to wait for events
-     *  @param showTime true/false: write elapsed time to standard output
-     *  @exception TestException usually indicates a failure
-     */
-    public static void verifyEventTuples(List receivedTuples, List expectedTuples, long maxWaitTime, boolean showTime, Object lock)
-                                                         throws Exception
-    {
-        int i,j;
-        long waitDeltaT = N_MS_PER_MIN;
-        long nMsWaited  = waitDeltaT;
-        /* give the Listener a chance to collect all events */
-        while(true) {
-	    try {
-                synchronized (lock){
-                    lock.wait(waitDeltaT);
-                }
-	    } catch (InterruptedException e) { }
-            if (showTime) {
-                System.out.println("Total Time: "
-                                   +(nMsWaited/N_MS_PER_MIN)+
-                                   " mins");
-	    }
-            if (receivedTuples.size() != expectedTuples.size()) {
-	        if (nMsWaited < maxWaitTime) {
-                    nMsWaited = nMsWaited + waitDeltaT;
-		} else {
-                    throw new TestException
-                     ("# of Events Received ("+receivedTuples.size()+
-                      ") != # of Events Expected ("+expectedTuples.size()+")");
-		}
-	    } else {
-                break;
-	    }
-	}
-        if (showTime) {
-            System.out.println("\n# of Events Expected = "
-                               +expectedTuples.size());
-            System.out.println("# of Events Received = "
-                               +receivedTuples.size()+"\n");
-            System.out.println
-                           ("# of seconds each event took to arrive (approx): "
-                   +(N_MS_PER_SEC*receivedTuples.size())/nMsWaited+
-                            " secs\n");
-            System.out.println
-                       ("Comparing Received Events to Expected Events ...\n");
-	}
-        verifyEventTupleContent(receivedTuples,expectedTuples);
-    }
-
-    /** Compares the number and content of the given set of expected events
-     *  to the given set of received events; where the event information 
-     *  is stored in the given vectors as objects of class type SrvcAttrTuple
-     *  @param receivedTuples array of received event tuples
-     *  @param expectedTuples array of expected event tuples
-     *  @param maxWaitTime maximum number of milliseconds to wait for events
-     *  @exception TestException usually indicates a failure
-     */
-    public static void verifyEventTuples(Vector  receivedTuples,
-                                         Vector  expectedTuples,
-                                         long    maxWaitTime)
-                                                         throws Exception
-    {
-        int i,j;
-        long waitDeltaT = N_MS_PER_MIN;
-        long nMsWaited  = waitDeltaT;
-        /* give the Listener a chance to collect all events */
-        while(true) {
-	    try {
-                Thread.sleep(waitDeltaT);
-	    } catch (InterruptedException e) { }
-            if (receivedTuples.size() != expectedTuples.size()) {
-	        if (nMsWaited < maxWaitTime) {
-                    nMsWaited = nMsWaited + waitDeltaT;
-		} else {
-                    throw new TestException
-                     ("# of Events Received ("+receivedTuples.size()+
-                      ") != # of Events Expected ("+expectedTuples.size()+")");
-		}
-	    } else {
-                break;
-	    }
-	}
-        verifyEventTupleContent(receivedTuples,expectedTuples);
-    }
-
-    /** Based on the number of service class instances and the number of
-     *  attributes per service participating in the current test run, 
-     *  this method computes and returns the maximum number of milliseconds
-     *  to wait for all events to arrive from the lookup service before 
-     *  attempting to verify the events.
-     *  @param nSrvcs total number of service instances registered
-     *  @param nAttrs total number of attribute instances
-     *  @return long 
-     */
-    public static long getMaxNMsToWaitForEvents(int nSrvcs,
-                                                int nAttrs) {
-        long maxTime = 10*nSrvcs*nAttrs*N_MS_PER_SEC;
-        if (maxTime < N_MS_PER_MIN) {
-            maxTime = N_MS_PER_MIN;
-	}
-        return maxTime;
-    }
-
-    /** Based on the number of service class instances and the number of
-     *  attributes per service participating in the current test run, 
-     *  this method computes and returns the maximum number of milliseconds
-     *  to wait for all events to arrive from the lookup service before 
-     *  attempting to verify the events.
-     *  @param nSrvcs total number of service instances registered
-     *  @param nAttrs total number of attribute instances
-     *  @param showTime true/false: write elapsed time to standard output
-     *  @return long 
-     */
-    public static long getMaxNMsToWaitForEvents(int nSrvcs,
-                                                int nAttrs,
-                                                boolean showTime) {
-        long maxTime = getMaxNMsToWaitForEvents(nSrvcs,nAttrs);
-        if (showTime) {
-            System.out.println("\nmaxNMsToWaitForEvents = "
-                               +(maxTime/N_MS_PER_MIN)+" mins");
-	}
-        return maxTime;
-    }
-
-    /** This method sets values for the maximum duration of all service
-     *  and event leases.
-     *  @param sysConfig the test config object
-     *  @param leaseDuration maximum service lease duration and event lease
-     *         duration in milliseconds
-     */
-    public static void setLeaseDuration(QAConfig sysConfig,
-                                        long leaseDuration) 
-    {
-        setLeaseDuration(sysConfig,leaseDuration,leaseDuration);
-    }
-
-    /** This method sets values for the maximum duration of all service
-     *  and event leases.
-     *  @param sysConfig the test config object
-     *  @param serviceLeaseDuration maximum service lease duration 
-     *         in milliseconds
-     *  @param eventLeaseDuration maximum event lease duration 
-     *         in milliseconds
-     */
-    public static void setLeaseDuration(QAConfig sysConfig,
-                                        long serviceLeaseDuration,
-                                        long eventLeaseDuration) 
-    {
-        sysConfig.addOverrideProvider(new ServiceLeaseOverrideProvider(
-            sysConfig, serviceLeaseDuration, eventLeaseDuration));
-    }
-
-    /** Prints the fields of each element (tuple) of the given tuples vector. 
-     *  Each element of the vector must be an instance of the class 
-     *  SrvcAttrTuple. This method is intended to be used only for
-     *  debugging.
-     *  @param tuples vector in which the expected tuples are accumulated
-     */
-    public static void displayTuples(Vector tuples) {
-        System.out.println
-          ("\n--------------------------------------------------------------");
-        int i=0;
-        Object tupleSrvc;
-        Object tupleAttr;
-        int trans;
-	try {
-            for(i=0;i<tuples.size();i++) {
-                tupleSrvc
-                     = ((SrvcAttrTuple)tuples.get(i)).getSrvcObj();
-                tupleAttr
-                     = ((SrvcAttrTuple)tuples.get(i)).getAttrObj();
-                trans
-                  = ((SrvcAttrTuple)tuples.get(i)).getTransition();
-                System.out.println("srvcObj    = "+tupleSrvc);
-                System.out.println("attrObj    = "+tupleAttr);
-                System.out.println("Transition = "+trans_str[trans]);
-                if(i<(tuples.size()-1))System.out.println(" ");
-            }
-	} catch (ClassCastException e) {
-            System.out.println
-                   ("displayTuples: ClassCastException (element at index i="+i+
-                    " can NOT be cast to type SrvcAttrTuple)");
-	} catch (ArrayIndexOutOfBoundsException e) {
-            System.out.println
-                   ("displayTuples: ArrayIndexOutOfBoundsException (i="+i+")");
-	}
-        System.out.println
-          ("--------------------------------------------------------------\n");
-    }
-
-    /** Check if an array contains the object. return true if it contains */
-    public static boolean isArrayContain(Object a[], Object o) {
-	for(int i=0; i<a.length; i++) 
-	    if (a[i].equals(o) )
-		return true;
-	return false;
-    }
- 
-
-    /** Prints the fields of each element (tuple) of the given state array. 
-     *  Each element of the array must be an instance of the class 
-     *  SrvcAttrTuple. This method is intended to be used only for
-     *  debugging.
-     *  @param state array of state tuples
-     */
-    private static void displayTuples(SrvcAttrTuple[][][] state) {
-        System.out.println
-          ("\n--------------------------------------------------------------");
-        int i=0;
-        int j=0;
-        int k=0;
-        Object tupleSrvc;
-        Object tupleAttr;
-        int trans;
-	try {
-            for(i=0;i<state.length;i++) {
-                for(j=0;j<(state[i]).length;j++) {
-                    for(k=0;k<(state[i][j]).length;k++) {
-                        tupleSrvc 
-                    = ((SrvcAttrTuple)state[i][j][k]).getSrvcObj();
-                        tupleAttr
-                    = ((SrvcAttrTuple)state[i][j][k]).getAttrObj();
-                        trans
-                    = ((SrvcAttrTuple)state[i][j][k]).getTransition();
-                        System.out.println("srvcObj    = "+tupleSrvc);
-                        System.out.println("attrObj    = "+tupleAttr);
-                        System.out.println("Transition = "+trans_str[trans]);
-                    if(k<(state[i][j]).length-1)System.out.println(" ");
-		    }
-                    if(j<(state[i]).length-1)System.out.println(" ");
-                }
-                if(i<state.length-1)System.out.println(" ");
-            }
-	} catch (ClassCastException e) {
-            System.out.println
-                        ("displayTuples: ClassCastException (element at i="+i+
-                         ",j="+j+" can NOT be cast to type SrvcAttrTuple)");
-	} catch (ArrayIndexOutOfBoundsException e) {
-            System.out.println
-                   ("displayTuples: ArrayIndexOutOfBoundsException (i="+i+
-                                                                  ",j="+j+")");
-	}
-        System.out.println
-          ("--------------------------------------------------------------\n");
-    }
-
-    /*  Compares the content of the given set of expected events to the given
-     *  set of received events (this method is shared by the overloaded 
-     *  versions of the method verifyEventTuples)
-     */
-    private static void verifyEventTupleContent(List  receivedTuples,
-                                                List  expectedTuples)
-                                                         throws Exception
-    {
-        int i,j;
-        iLoop:
-        for(i=0; i<receivedTuples.size(); i++) {
-	    /*  step through the vector containing the expected tuples
-             *  if the current received tuple is not in the set of 
-             *  expected tuples, declare failure
-             */
-           for(j=0;j<expectedTuples.size();j++) {
-                if((receivedTuples.get(i)).equals(expectedTuples.get(j))) {
-                    expectedTuples.remove(j);
-                    continue iLoop;
-		}
-	    }
-            throw new TestException
-                   ("Received an UNEXPECTED Event\nSrvc  = "
-                    +(((SrvcAttrTuple)receivedTuples.get(i)).getSrvcObj())+
-                    ",\nAttr  = "
-                    +(((SrvcAttrTuple)receivedTuples.get(i)).getAttrObj())+
-                    ",\nTrans = "
-                    +(((SrvcAttrTuple)receivedTuples.get(i)).getTransition()));
-        }
-    }
-
-    /** Removes any repeated elements from the ArrayList and then compares
-     *  the String elements in the array to the String elements in ArrayList.
-     *  Returns true if the sets are equal in size and if each element in
-     *  one set is equal to one element in the other set; returns false
-     *  otherwise.
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  SimpleAddMemberGroups
-     *                  SimpleSetMemberGroups
-     *                  SimpleRemoveMemberGroups
-     *
-     *  @param returnedGroups array of String elements from getMemberGroups
-     *  @param expectedGroups ArrayList of expected String elements
-     */
-    public static boolean groupsAreEqual(String[] returnedGroups,
-                                         ArrayList expectedGroups) {
-        ArrayList filteredList = removeRepeatedElems(expectedGroups);
-        if (returnedGroups.length != filteredList.size()) {
-            return false;
-	}
-	iLoop:
-        for(int i=0;i<filteredList.size();i++) {
-            for(int j=0;j<returnedGroups.length;j++) {
-                if (returnedGroups[j].equals((String)(filteredList.get(i)))) {
-                    continue iLoop;
-		}
-	    }
-            return false;
-        }
-        return true;
-    }
-
-    /** Removes any repeated elements from the input ArrayList; returns
-     *  a new ArrayList containing all unique elements from the input list.
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  SimpleAddMemberGroups
-     *                  SimpleSetMemberGroups
-     *                  SimpleRemoveMemberGroups
-     *
-     *  @param list ArrayList of String elements
-     */
-    public static ArrayList removeRepeatedElems(ArrayList list) {
-        ArrayList newList = new ArrayList();
-        iLoop:
-        for(int i=0;i<list.size();i++) {
-            String str = (String)(list.get(i));
-            for(int j=0; j<newList.size();j++) {
-                if (str.equals((String)(newList.get(j)))) {
-                    continue iLoop;
-		}
-	    }
-            newList.add(str);
-        }
-        return newList;
-    }
-
-    /** Removes all elements of the String array from the ArrayList; returns
-     *  a new ArrayList containing the elements of the original ArrayList 
-     *  minus elements from the String array.
-     *
-     *  This method is currently employed by the following test classes:
-     *
-     *                  SimpleRemoveMemberGroups
-     *
-     *  @param list ArrayList of String elements
-     *  @param strArray array of String elements
-     */
-    public static ArrayList removeListFromArray(ArrayList list,
-                                                String[] strArray) {
-        ArrayList newList = new ArrayList();
-        iLoop:
-        for(int i=0;i<list.size();i++) {
-            String str = (String)(list.get(i));
-            for(int j=0;j<strArray.length;j++) {
-                if (str.equals(strArray[j])) {
-                    continue iLoop;
-		}
-	    }
-            newList.add(str);
-        }
-        return newList;
-    }
-
-    /** Prints the elements of the input String array.
-     *  
-     *  This method is intended to be used only for debugging.
-     *  @param strArray array of String elements
-     */
-    public static void displayStringArray(String[] strArray) {
-        System.out.println(" ");
-        for(int i=0;i<strArray.length;i++) {
-	    if ((i>=0)&&(i<=9)) {
-                System.out.println("["+i+"]   = "+strArray[i]);
-            } else if ((i>=10)&&(i<=99)) {
-                System.out.println("["+i+"]  = "+strArray[i]);
-   	    } else {
-                System.out.println("["+i+"] = "+strArray[i]);
-            }
-	}
-    }
-
-    /** Prints the elements of the input ArrayList.
-     *  
-     *  Each element of the ArrayList must be of type String. This method 
-     *  is intended to be used only for debugging.
-     *  @param list ArrayList of String elements
-     */
-    public static void displayStringArrayList(ArrayList list) {
-        System.out.println(" ");
-        for(int i=0;i<list.size();i++) {
-	    if ((i>=0)&&(i<=9)) {
-                System.out.println("["+i+"]   = "+(String)(list.get(i)));
-            } else if ((i>=10)&&(i<=99)) {
-                System.out.println("["+i+"]  = "+(String)(list.get(i)));
-   	    } else {
-                System.out.println("["+i+"] = "+(String)(list.get(i)));
-            }
-	}
-    }
-
-    /** Determines if the input Objects are equal; where equality is defined
-     *  by Class equality and field equality. A special case is subclasses
-     *  of net.jini.lookup.entry.ServiceType. If both objects are assignable
-     *  to ServiceType, then class equality is not required. This is necessary
-     *  to handle the case where com.sun.jini.lookup.entry.BasicServiceType
-     *  is being compared, and one of the object was obtained from a preferred
-     *  class loader.
-     *
-     *  @param obj0 the to compare to obj1 for equality
-     *  @param obj1 the to compare to obj0 for equality
-     *  @return boolean
-     */
-    public static boolean objsAreEqual(Object obj0, Object obj1) {
-        Class obj0Class = (obj0).getClass();
-        Class obj1Class = (obj1).getClass();
-        if (!(obj1Class.equals(obj0Class))) {
-            Class st = net.jini.lookup.entry.ServiceType.class;
-	    if (!st.isAssignableFrom(obj0Class)
-                || !st.isAssignableFrom(obj1Class)) {
-                return false;
-            }
-        }
-        Field[] obj0Fields = obj0Class.getFields();
-        Field[] obj1Fields = obj1Class.getFields();
-        try {
-	    jLoop:
-            for(int j=0;j<obj0Fields.length;j++) {
-                String name0 = (obj0Fields[j]).getName();
-                for(int k=0;k<obj1Fields.length;k++) {
-                    String name1 = (obj1Fields[k]).getName();
-                    if (name0.equals(name1)) {
-                        Object field0 = (obj0Fields[j]).get(obj0);
-                        Object field1 = (obj1Fields[k]).get(obj1);
-			if (field0 == null) {
-			    if (field1 != null)
-				return false;
-			    continue jLoop;
-			} else if (field0.equals(field1)) {
-                            continue jLoop;
-                        } else {
-                            return false;
-                        }
-		    }
-		}
-                return false;
-            }
-        } catch (IllegalAccessException e) {
-            return false;
-	}
-        return true;
-    }
-}
+/*
+ * 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 com.sun.jini.test.spec.lookupservice;
+
+import com.sun.jini.test.spec.lookupservice.attribute.Attr;
+import com.sun.jini.test.spec.lookupservice.ServiceLeaseOverrideProvider;
+import net.jini.core.lookup.ServiceEvent;
+import net.jini.core.lookup.ServiceRegistrar;
+import net.jini.core.lookup.ServiceRegistration;
+import net.jini.core.lookup.ServiceID;
+import net.jini.core.lookup.ServiceItem;
+import net.jini.core.lookup.ServiceMatches;
+import net.jini.core.lookup.ServiceTemplate;
+import net.jini.core.entry.Entry;
+import net.jini.lookup.entry.ServiceType;
+import net.jini.core.lease.*;
+import java.rmi.RemoteException;
+import java.io.Serializable;
+import java.io.IOException;
+import java.util.Vector;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+
+import com.sun.jini.qa.harness.QAConfig;
+import com.sun.jini.qa.harness.TestException;
+import com.sun.jini.qa.harness.QATestEnvironment;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/** Provides useful constants and utility methods and classes for all 
+ *  classes of the Lookup component of the Jini System. Each field and 
+ *  member class, and most methods, contained in this class is public 
+ *  and static; this class does not need to be instantiated.
+ *
+ *  @see QATestEnvironment
+ *  @see com.sun.jini.test.spec.lookupservice.QATestRegistrar
+ */
+public class QATestUtils {
+
+    private static Logger logger = 
+	Logger.getLogger("com.sun.jini.qa.harness.test");
+
+    /* Class constructor */
+    public QATestUtils(){}
+
+    /** The number of milliseconds in 1 second */
+    public final static long N_MS_PER_SEC   = 1000;
+    /** The number of seconds in 1 minute */
+    public final static long N_SECS_PER_MIN = 60;
+    /** The number of milliseconds in 1 minute */
+    public final static long N_MS_PER_MIN   = N_MS_PER_SEC*N_SECS_PER_MIN;
+    /** Strings describing event transition states used in debugging */
+    public final static String[] trans_str = {"UNKNOWN",
+                                              "MATCH_NOMATCH",
+                                              "NOMATCH_MATCH",
+                                              "UNKNOWN",
+                                              "MATCH_MATCH"};
+
+    /** Class which models an event "tuple" (service,attribute,transition). 
+     *  
+     *  This class is used by some of the tests that wish to verify that the 
+     *  events received from the lookup service are the events expected; 
+     *  based on the templates used to register event notification requests.
+     */
+    public static class SrvcAttrTuple implements Serializable
+    {
+        static final long serialVersionUID = -8254953323094761933L;
+
+        /** @serial */
+        private Object srvcObj;
+        /** @serial */
+        private Object attrObj;
+        /** @serial */
+        private int transition;
+        /** @serial */
+        private ServiceItem[] srvcItems ;
+        /** @serial */
+        private Entry[][] attrs;
+
+        /** Creates a SrvcAttrTuple with the given transition value.
+         *  @param srvcItems the array of registered service items
+         *  @param attrs array of Entry type elements containing attributes
+         *  @param srvcObj the service component of the new tuple
+         *  @param attrObj the attribute component of the new tuple
+         *  @param transition the transition component of the new tuple
+         */
+        public SrvcAttrTuple(ServiceItem[] srvcItems,
+                             Entry[][]     attrs,
+                             Object        srvcObj,
+                             Object        attrObj,
+                             int           transition)
+        {
+            this.srvcItems  = srvcItems;
+            this.attrs      = attrs;
+
+            this.srvcObj    = srvcObj;
+            this.attrObj    = attrObj;
+            this.transition = transition;
+        }
+
+        /** Creates a SrvcAttrTuple with the "unknown" (0) transition value.
+         *  @param srvcItems the array of registered service items
+         *  @param attrs array of Entry type elements containing attributes
+         *  @param srvcObj the service component of the new tuple
+         *  @param attrObj the attribute component of the new tuple
+         */
+        public SrvcAttrTuple(ServiceItem[] srvcItems,
+                             Entry[][]     attrs,
+                             Object        srvcObj,
+                             Object        attrObj)
+        {
+            this.srvcItems  = srvcItems;
+            this.attrs      = attrs;
+
+            this.srvcObj    = srvcObj;
+            this.attrObj    = attrObj;
+            this.transition = 0;
+        }
+
+        /** Creates a SrvcAttrTuple with the given transition value
+         *  and null reference arrays of service items and attributes.
+         *  @param srvcObj the service component of the new tuple
+         *  @param attrObj the attribute component of the new tuple
+         *  @param transition the transition component of the new tuple
+         */
+        public SrvcAttrTuple(Object srvcObj,
+                             Object attrObj,
+                             int    transition)
+        {
+            this.srvcItems  = null;
+            this.attrs      = null;
+
+            this.srvcObj    = srvcObj;
+            this.attrObj    = attrObj;
+            this.transition = transition;
+        }
+
+        /** Creates a SrvcAttrTuple with the "unknown" (0) transition value
+         *  and null reference arrays of service items and attributes.
+         *  @param srvcObj the service component of the new tuple
+         *  @param attrObj the attribute component of the new tuple
+         */
+        public SrvcAttrTuple(Object srvcObj,
+                             Object attrObj)
+        {
+            this.srvcItems  = null;
+            this.attrs      = null;
+
+            this.srvcObj    = srvcObj;
+            this.attrObj    = attrObj;
+            this.transition = 0;
+        }
+
+        /** Sets this tuple equal to the given tuple
+         *  @param tuple the SrvcAttrTuple to set this tuple equal to
+         */
+        public void setEqualTo(SrvcAttrTuple tuple) {
+            this.srvcItems  = tuple.srvcItems;
+            this.attrs      = tuple.attrs;
+            this.srvcObj    = tuple.srvcObj;
+            this.attrObj    = tuple.attrObj;
+            this.transition = tuple.transition;
+        }
+
+        /** Returns the array of service items associated with this tuple */
+        public ServiceItem[] getSrvcItems() {
+            return srvcItems;
+        }
+
+        /** Sets the reference to the array of service items associated with
+         *  this tuple equal to the given reference
+         *  @param srvcItems the new array of service items
+         */
+        public void setSrvcItems(ServiceItem[] srvcItems) {
+            this.srvcItems = srvcItems;
+        }
+
+        /** Returns the array of attributes associated with this tuple */
+        public Entry[][] getAttrs() {
+            return attrs;
+        }
+
+        /** Sets the reference to the array of attributes associated with
+         *  this tuple equal to the given reference
+         *  @param attrs the new array-of-arrays of attributes
+         */
+        public void setAttrs(Entry[][] attrs) {
+            this.attrs = attrs;
+        }
+
+        /** Returns the service item associated with this tuple */
+        public Object getSrvcObj() {
+            return srvcObj;
+        }
+
+        /** Sets the reference to the service item associated with
+         *  this tuple equal to the given reference
+         *  @param srvcObj the new service item
+         */
+        public void setSrvcObj(Object srvcObj) {
+            this.srvcObj = srvcObj;
+        }
+
+        /** Returns the attribute associated with this tuple */
+        public Object getAttrObj() {
+            return attrObj;
+        }
+
+        /** Sets the reference to the attribute associated with
+         *  this tuple equal to the given reference
+         *  @param attrObj the new attribute
+         */
+        public void setAttrObj(Object attrObj) {
+            this.attrObj = attrObj;
+        }
+
+        /** Returns the transition associated with this tuple */
+        public int getTransition() {
+            return transition;
+        }
+
+        /** Sets the transition associated with this tuple equal to the 
+         *  given transition
+         *  @param transition the new transition value
+         */
+        public void setTransition(int transition) {
+            this.transition = transition;
+        }
+
+        /** Determines if the given object is equal to this tuple; where
+         *  two tuples are equal if their service items are equal, their
+         *  attributes are equal and their transitions are equal.
+         *  @param obj the tuple to compare to this tuple
+         *  @return boolean
+         */
+        public boolean equals(Object obj) {
+            int trans = ((SrvcAttrTuple)obj).getTransition();
+            return ( (objEquals(obj)) && (this.transition == trans) );
+        }
+
+        /** Determines if the service item and and the attribute of the 
+         *  given object are equal to the corresponding fields of this 
+         *  tuple; that is, this method ignores the transition values
+         *  of the tuples.
+         *  @param obj the tuple to compare to this tuple
+         *  @return boolean
+         */
+        public boolean objEquals(Object obj) {
+            if (this == obj) {
+                return true;
+            } else if ( (obj.getClass()).equals(SrvcAttrTuple.class) ) {
+                if ((srvcItems == null)||(attrs == null)) {
+                    return false;
+		}
+                int n=0;
+                int k=0;
+                Object srvc = ((SrvcAttrTuple)obj).getSrvcObj();
+                Object attr = ((SrvcAttrTuple)obj).getAttrObj();
+                try {
+                    n = getSrvcIndx(this.srvcObj,srvcItems);
+                    k = getAttrIndx(this.attrObj,attrs);
+                    if (    ((srvcItems[n].service).equals(srvc))
+                         && ((attrs[k][0]).equals(attr)) ) {
+                        return true;
+		    } else {
+                        return false;
+		    }
+                } catch (ArrayIndexOutOfBoundsException e) {
+                    return false;
+		}
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /** Steps through the given array of service items searching for the
+     *  element that equals the given service item Object; returning the
+     *  element index if a match is found and -1 otherwise
+     *  @param obj service item object to search for
+     *  @param srvcItems array of service items to search
+     *  @return int (array index or -1 if no match found)
+     */
+    public static int getSrvcIndx(Object        obj,
+                                  ServiceItem[] srvcItems) {
+        try {
+            int n;
+	    /* get the srvc instance the input Object corresponds to */
+            for(n=0;n<srvcItems.length;n++) {
+                if ( (srvcItems[n].service).equals(obj) ) {
+                    break;
+                }
+            }
+            if (n < srvcItems.length) {
+                return n;
+	    } else {
+                return -1;
+	    }
+        } catch (ArrayIndexOutOfBoundsException e) {
+           return -1;
+        } catch (NullPointerException e) {
+            return -1;
+     	}
+    }
+
+    /** Steps through the given array of attribute objects searching for
+     *  the element that equals the given attribute Object; returning the
+     *  element index if a match is found and -1 otherwise
+     *  @param obj attribute object to search for
+     *  @return int (array index or -1 if no match found)
+     */
+    public static int getAttrIndx(Object     obj,
+                                  Entry[][]  attrs) {
+        try {
+            int n;
+	    /* get the attribute instance the input Object corresponds to */
+            for(n=0;n<attrs.length;n++) {
+                if ( (attrs[n][0]).equals(obj) ) {
+                    break;
+		}
+   	    }
+            if (n < attrs.length) {
+                return n;
+	    } else {
+                return -1;
+	    }
+        } catch (ArrayIndexOutOfBoundsException e) {
+           return -1;
+        } catch (NullPointerException e) {
+            return -1;
+     	}
+    }
+
+    /** Returns the current time in milliseconds 
+     *  @return long
+     */
+    public static long getCurTime() {

[... 1454 lines stripped ...]