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 2013/04/15 17:26:46 UTC

svn commit: r1468119 [9/15] - in /river/jtsk/skunk/qa_refactor/trunk: qa/src/com/sun/jini/qa/harness/ qa/src/com/sun/jini/test/impl/mahalo/ qa/src/com/sun/jini/test/resources/ qa/src/com/sun/jini/test/share/ qa/src/com/sun/jini/test/spec/javaspace/conf...

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java?rev=1468119&r1=1468118&r2=1468119&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java Mon Apr 15 15:26:44 2013
@@ -1,5164 +1,5164 @@
-/*
- * 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.mercury;
-
-import com.sun.jini.config.Config;
-import com.sun.jini.constants.TimeConstants;
-import com.sun.jini.constants.ThrowableConstants;
-import com.sun.jini.landlord.FixedLeasePeriodPolicy;
-import com.sun.jini.landlord.LeasedResource;
-import com.sun.jini.landlord.LeaseFactory;
-import com.sun.jini.landlord.LeasePeriodPolicy;
-import com.sun.jini.landlord.LeasePeriodPolicy.Result;
-import com.sun.jini.landlord.Landlord.RenewResults;
-import com.sun.jini.landlord.LocalLandlord;
-import com.sun.jini.landlord.LandlordUtil;
-import com.sun.jini.logging.Levels;
-import com.sun.jini.lookup.entry.BasicServiceType;
-import com.sun.jini.lookup.entry.LookupAttributes;
-import com.sun.jini.proxy.ThrowThis;
-import com.sun.jini.reliableLog.ReliableLog;
-import com.sun.jini.reliableLog.LogException;
-import com.sun.jini.reliableLog.LogHandler;
-import com.sun.jini.start.LifeCycle;
-import com.sun.jini.start.Starter;
-import com.sun.jini.thread.InterruptedStatusThread;
-import com.sun.jini.thread.ReadersWriter;
-import com.sun.jini.thread.ReadersWriter.ConcurrentLockException;
-import com.sun.jini.thread.ReadyState;
-import com.sun.jini.thread.RetryTask;
-import com.sun.jini.thread.TaskManager;
-import com.sun.jini.thread.WakeupManager;
-import net.jini.activation.ActivationExporter;
-import net.jini.config.Configuration;
-import net.jini.config.ConfigurationProvider;
-import net.jini.config.ConfigurationException;
-import net.jini.config.NoSuchEntryException;
-import net.jini.core.constraint.RemoteMethodControl;
-import net.jini.export.Exporter;
-import net.jini.export.ProxyAccessor;
-import net.jini.id.Uuid;
-import net.jini.id.UuidFactory;
-import net.jini.jeri.BasicILFactory;
-import net.jini.jeri.BasicJeriExporter;
-import net.jini.jeri.tcp.TcpServerEndpoint;
-import net.jini.security.BasicProxyPreparer;
-import net.jini.security.ProxyPreparer;
-import net.jini.security.proxytrust.ServerProxyTrust;
-import net.jini.security.TrustVerifier;
-
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.rmi.activation.Activatable;
-import java.rmi.activation.ActivationException;
-import java.rmi.activation.ActivationGroup;
-import java.rmi.activation.ActivationGroupID;
-import java.rmi.activation.ActivationID;
-import java.rmi.activation.ActivationSystem;
-import java.rmi.MarshalledObject;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Random;
-import java.util.TreeMap;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginContext;
-import javax.security.auth.login.LoginException;
-
-import net.jini.core.discovery.LookupLocator;
-import net.jini.core.entry.Entry;
-import net.jini.core.event.RemoteEventListener;
-import net.jini.core.event.RemoteEvent;
-import net.jini.core.event.UnknownEventException;
-import net.jini.core.lease.Lease;
-import net.jini.core.lease.LeaseDeniedException;
-import net.jini.core.lease.UnknownLeaseException;
-import net.jini.core.lookup.ServiceID;
-import net.jini.discovery.DiscoveryGroupManagement;
-import net.jini.discovery.DiscoveryLocatorManagement;
-import net.jini.discovery.DiscoveryManagement;
-import net.jini.discovery.LookupDiscoveryManager;
-import net.jini.event.InvalidIteratorException;
-import net.jini.event.MailboxRegistration;
-import net.jini.event.MailboxPullRegistration;
-import net.jini.lookup.entry.ServiceInfo;
-import net.jini.lookup.JoinManager;
-import net.jini.discovery.LookupDiscovery;
-
-/**
- * <tt>MailboxImpl</tt> implements the server side of the event 
- * mailbox service.
- * <p>
- * Client-side proxies make the appropriate transformation from client
- * requests to the methods of this class.
- *
- * @author Sun Microsystems, Inc.
- *
- * @since 1.1
- */
-
-/*
-Implementation Details:
-
-The runtime state of this service is basically maintained in the following
-data structures:
-   * regByID - contains the Uuid to Registration mapping
-   * regByExpiration - contains a time sorted ordering of 
-       Registration objects
-   * pendingReg - contains a list of Uuids that have been
-       enabled for event delivery
-   * activeReg - contains a list of Uuids that have an
-       event delivery task in progress
-
-Note that the latter 3 data structures can be rebuilt from the first, so only
-regByID is actually stored to and retrieved from disk. 
-
-See init() for exact details of how transient state gets rebuilt.
-See takeSnapshot() for exact details of what gets stored.
-See recoverSnapshot() for exact details of what gets retrieved.
-*/
-
-class MailboxImpl implements MailboxBackEnd, TimeConstants, 
-    ServerProxyTrust, ProxyAccessor, Starter
- 
-{
-
-    /** Logger and configuration component name for Norm */
-    static final String MERCURY = "com.sun.jini.mercury";
-
-    /** Logger for lease related messages */
-    static final Logger leaseLogger = 
-        Logger.getLogger(MERCURY + ".lease");
-    
-    /** Logger for event delivery related messages */
-    static final Logger deliveryLogger = 
-        Logger.getLogger(MERCURY + ".delivery");
-    
-    /** Logger for service administration related messages */
-    static final Logger adminLogger = 
-        Logger.getLogger(MERCURY + ".admin");
-    
-    /** Logger for service initialization related messages */
-    static final Logger initLogger = 
-        Logger.getLogger(MERCURY + ".init");
-    
-    /** Logger for event reception related messages */
-    static final Logger receiveLogger = 
-        Logger.getLogger(MERCURY + ".receive");
-    
-    /** Logger for lease expiration related messages */
-    static final Logger expirationLogger = 
-        Logger.getLogger(MERCURY + ".expiration");
-    
-    /** Logger for service recovery related messages */
-    static final Logger recoveryLogger = 
-        Logger.getLogger(MERCURY + ".recovery");
-    
-    /** Logger for service persistence related messages */
-    static final Logger persistenceLogger = 
-        Logger.getLogger(MERCURY + ".persistence");
-    
-    /** Logger for (successful) service startup message */
-    static final Logger startupLogger =
-        Logger.getLogger(MERCURY + ".startup");
-   
-    /** Logger for service operation messages */
-    static final Logger operationsLogger =
-        Logger.getLogger(MERCURY + ".operations");
-
-    static final String mailboxSourceClass = 
-	MailboxImpl.class.getName();
-
-    private static final String notifierSourceClass = 
-	Notifier.class.getName();
-
-    private static final String notifyTaskSourceClass = 
-	NotifyTask.class.getName();
-
-    private static final String destroyThreadSourceClass = 
-	DestroyThread.class.getName();
-
-    private static final String expirationThreadSourceClass = 
-	ExpirationThread.class.getName();
-
-    private static final String registrationLogObjSourceClass = 
-	RegistrationLogObj.class.getName();
-
-    private static final String registrationEnabledLogObjSourceClass = 
-	RegistrationEnabledLogObj.class.getName();
-
-    private static final String registrationDisabledLogObjSourceClass = 
-	RegistrationDisabledLogObj.class.getName();
-
-    private static final String registrationIteratorEnabledLogObjSourceClass = 
-	RegistrationIteratorEnabledLogObj.class.getName();
-    
-    private static final String lookupGroupsChangedLogObjSourceClass = 
-	LookupGroupsChangedLogObj.class.getName();
-
-    private static final String lookupLocatorsChangedLogObjSourceClass = 
-	LookupLocatorsChangedLogObj.class.getName();
-
-    private static final String attrsAddedLogObjSourceClass = 
-	AttrsAddedLogObj.class.getName();
-
-    private static final String attrsModifiedLogObjSourceClass = 
-	AttrsModifiedLogObj.class.getName();
-
-    private static final String registrationRenewedLogObjSourceClass = 
-	RegistrationRenewedLogObj.class.getName();
-
-    private static final String registrationCancelledLogObjSourceClass = 
-	RegistrationCancelledLogObj.class.getName();
-
-    private static final String unknownEventExceptionLogObjSourceClass = 
-	UnknownEventExceptionLogObj.class.getName();
-
-    private static final String snapshotThreadSourceClass = 
-	SnapshotThread.class.getName();
-
-    /** ServiceInfo product value */
-    private static final String PRODUCT = "EventMailbox";
-    /** ServiceInfo manufacturer value */
-    private static final String MANUFACTURER = "Sun Microsystems, Inc.";
-    /** ServiceInfo vendor value */
-    private static final String VENDOR = MANUFACTURER;
-    /** ServiceInfo version value */
-    private static final String VERSION = 
-	com.sun.jini.constants.VersionConstants.SERVER_VERSION;
-    /** Log format version */
-    private static final int LOG_VERSION = 2;
-
-    /** The inner proxy of this server */
-    private /*final*/ volatile MailboxBackEnd serverStub;
-    /** The outter proxy of this server */
-    private /*final*/ volatile MailboxProxy mailboxProxy;
-    /** The admin proxy of this server */
-    private /*final*/ volatile MailboxAdminProxy mailboxAdminProxy;
-    /** Concurrent object (lock) to control read and write access */
-    private final ReadersWriter concurrentObj = new ReadersWriter();
-    /** Map from <code>Uuid</code> to <code>ServiceRegistration</code> */
-    // HashMap is unsynchronized, but we are performing external
-    // synchronization via the <code>concurrentObj</code> field. 
-    private final HashMap<Uuid,ServiceRegistration> regByID; 
-    /**
-     * Identity map of <tt>ServiceRegistration</tt>, ordered by lease 
-     * expiration. This is a parallel data structure to <code>regByID</code>.
-     */
-    // TreeMap is unsynchronized, but we are performing external
-    // synchronization via the <code>concurrentObj</code> field. 
-    private final TreeMap<ServiceRegistration,ServiceRegistration> regByExpiration;
-    /** 
-     * List of <tt>ServiceRegistration</tt>s that have event 
-     * delivery enabled, but don't have any event delivery tasks 
-     * currently scheduled.
-     */
-    // Using an ArrayList for random access performance. 
-    // ArrayList is unsynchronized, but we are performing external
-    // synchronization via the <code>concurrentObj</code> field. 
-    private final List<Uuid> pendingReg;
-    /**
-     * Map of <tt>ServiceRegistration</tt>s that have event 
-     * delivery enabled and have event delivery tasks currently 
-     * scheduled.
-     */
-    // HashMap is unsynchronized, but we are performing external
-    // synchronization via the <code>concurrentObj</code> field. 
-    private final Map<Uuid,NotifyTask> activeReg;
-    /** Reliable log to hold registration state information */
-    // Note that event state is kept separately
-    private final ReliableLog log;
-    /** Flag indicating whether system is in a state of recovery */
-    private volatile boolean inRecovery;
-    /** Current number of records in the Log File since the last snapshot */
-    private int logFileSize = 0;
-    /** Log File must contain this many records before a snapshot is allowed */
-// TODO (FCS)- allow this to be a user configurable parameter
-    private int logToSnapshotThreshold = 50;
-    /** Object on which the snapshot-taking thread will synchronize */
-    private final Object snapshotNotifier = new Object();
-    /** Snapshot-taking thread */
-    private final Thread snapshotter;
-    /** The login context, for logging out */
-    protected final LoginContext loginContext;
-    /** Name of persistence directory */
-    private final String persistenceDirectory;
-    /** Proxy preparer for listeners */
-    private final ProxyPreparer listenerPreparer;
-    /** The exporter for exporting and unexporting */
-    protected final Exporter exporter;
-   /** ServiceID returned from the lookup registration process */
-    private volatile Uuid serviceID;
-    /** Our activation ID */
-    private final ActivationID activationID;
-    /** Whether the activation ID has been prepared */
-    private final boolean activationPrepared;
-    /** The activation system, prepared */
-    private final ActivationSystem activationSystem;
-    /** <code>EventLogIterator</code> generator */
-    private final EventLogFactory eventLogFactory;
-    /** <code>LeasePeriodPolicy</code> for this service */
-    private final LeasePeriodPolicy leasePolicy; 
-    /** <code>LandLordLeaseFactory</code> we use to create leases */
-    private volatile LeaseFactory leaseFactory;
-    /** LocalLandlord to use with LandlordUtil calls */
-    private final LocalLandlordAdaptor localLandlord = new LocalLandlordAdaptor();
-    /** Manager for joining lookup services */
-    private JoinManager joiner = null;
-    /** 
-     * DiscoveryManager for joining lookup services. 
-     * This can always be obtained from the JoinManager, so
-     * this is just used as a shortcut.
-     */
-    private DiscoveryManagement lookupDiscMgr = null;
-
-    /** The attributes to use when joining lookup services */
-    private final Entry[] baseLookupAttrs = new Entry[] { 
-	    new ServiceInfo(PRODUCT, MANUFACTURER, VENDOR, VERSION, "", ""),
-            new BasicServiceType("Event Mailbox")
-    };
-    private Entry[] lookupAttrs = new Entry[] {};
-    /** 
-     * The lookup groups we should join. 
-     * Default is to join no groups. 
-     */
-    private String[] lookupGroups = LookupDiscovery.NO_GROUPS;
-    /** 
-     * The lookup locators we should join 
-     * Default is to join with no locators. 
-     */
-    private LookupLocator[] lookupLocators = new LookupLocator[0];
-    /* Preparer for initial and new lookup locators this service should
-     * discover and join.
-     */
-    private static ProxyPreparer locatorToJoinPreparer;
-    /* Preparer for lookup locators this service should discover and join
-     * that were previously prepared and which were recovered from this
-     * service's persisted state.
-     */
-    private static ProxyPreparer recoveredLocatorToJoinPreparer;
-   /** Event delivery thread */
-    private final Thread notifier;
-    /** Object for coordinating actions with the notification thread */
-    private final Object eventNotifier = new Object();
-    /** Registration expirer thread */
-    private final Thread expirer;
-    /** Earliest expiration time of any registration */
-    private long minRegExpiration = Long.MAX_VALUE;
-    /** Object for coordinating actions with the expire thread */
-    private final Object expirationNotifier = new Object();
-    /** Object for coordinating the destroy process */
-    private final Object destroyLock = new Object();
-    /** 
-     * Flag that denotes whether or not destroy has already been called.
-     * The variable is guarded by <code>destroyLock</code>.
-     */
-    private volatile boolean destroySucceeded = false;
-    /**
-     * When destroying the space, how long to wait for a clean
-     * unexport (which allows the destroy call to return) before
-     * giving up calling <code>unexport(true)</code>
-     */
-    private final long maxUnexportDelay;
-    /** Length of time to sleep between unexport attempts */
-    private final long unexportRetryDelay;
-    /** 
-     * Object used to prevent access to this service during the service's
-     *  initialization or shutdown processing.
-     */
-    private final ReadyState readyState = new ReadyState();
-    /**
-     * <code>LifeCycle</code> object used to notify starter framework
-     * that this object's implementation reference, if any, should not
-     * be held onto any longer. This is only used in the non-activatable case.
-     */
-    private volatile LifeCycle lifeCycle;
-    /**
-     * <code>boolean</code> flag used to determine persistence support.
-     * Defaulted to true, and overridden in the constructor overload that takes
-     * a <code>boolean</code> argument.
-     */
-    private final boolean persistent;
-    
-     // The following two fields are only required by start, called by the
-    // constructor thread and set to null after starting.
-    private Configuration config;
-    private Throwable thrown;
-    private volatile boolean started = false;
-    
-    ///////////////////////
-    // Activation Methods
-    ///////////////////////
-
-    public Object getProxy() {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "getProxy");
-	}
-	if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "getProxy", serverStub);
-	}
-	return serverStub;
-    }
-
-    /* inherit javadoc */
-    public Object getServiceProxy() {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "getServiceProxy");
-	}
-        readyState.check();
-	if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "getServiceProxy", mailboxProxy);
-	}
-        return mailboxProxy;
-    }
-
-    /* inherit javadoc */
-    public Object getAdmin() throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "getAdmin");
-	}
-        readyState.check();
-	if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "getAdmin", mailboxAdminProxy);
-	}
-        return mailboxAdminProxy;
-    }
-
-    /**
-     * Activation constructor
-     *
-     * @param activationID activation ID passed in by the activation daemon.
-     * @param data state data needed to re-activate a Mercury server
-     */
-    MailboxImpl(ActivationID activationID, MarshalledObject data) 
-	throws Exception
-    {
-        this((String[])data.get(), activationID, true, new Object[] {activationID, data} );
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.entering(mailboxSourceClass, 
-//	        "MailboxImpl", 
-//		new Object[] {activationID, data});
-//	}
-//	this.activationID = activationID;
-//	try {
-//	    // Initialize state
-//	    init((String[])data.get());
-//	} catch (Throwable e) {
-//	    cleanup();
-//	    initFailed(e);
-//	}	  
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.exiting(mailboxSourceClass, 
-//	        "MailboxImpl");
-//	}
-    }
-    
-    /////////////////////////
-    // Non-Activation Methods
-    /////////////////////////
-    /** 
-     * Constructor for creating transient (i.e. non-activatable) service 
-     * instances. 
-     * State information is still logged to persistent storage.
-     * This method is only intended for debugging purposes at this time.
-     *  
-     */
-    // @param log directory where persistent state is maintained
-    MailboxImpl(String[] configArgs, LifeCycle lc, boolean persistent) 
-	throws Exception
-    {
-        this(configArgs, null, persistent, new Object[] {Arrays.asList(configArgs), lc, Boolean.valueOf(persistent)});
-	lifeCycle = lc; 
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.entering(mailboxSourceClass, 
-//	        "MailboxImpl", 
-//		new Object[] { configArgs, lc, Boolean.valueOf(persistent)});
-//	}
-//	try {
-//	    lifeCycle = lc;
-//	    this.persistent = persistent;
-//            init(configArgs);
-//	} catch (Throwable e) {
-//	    cleanup();
-//	    initFailed(e);
-//	}	  
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.exiting(mailboxSourceClass, 
-//	        "MailboxImpl");
-//	}
-    }
-    
-    private MailboxImpl(String[] configArgs, final ActivationID activID, final boolean persistant, Object [] logMessage){
-        if (operationsLogger.isLoggable(Level.FINER)) {
-            operationsLogger.entering(
-		MailboxImpl.class.getName(), "MailboxImpl",logMessage );
-	}
-        this.persistent = persistant;
-        MailboxImplInit init = null;
-        final Configuration config;
-        LoginContext loginContext = null;
-        try {
-           if (operationsLogger.isLoggable(Level.FINER)) {
-                operationsLogger.entering(mailboxSourceClass, 
-                    "init", (Object[])configArgs);
-           }
-           config =
-                ConfigurationProvider.getInstance(
-                    configArgs, getClass().getClassLoader());
-            loginContext = (LoginContext) config.getEntry(
-                MERCURY, "loginContext", LoginContext.class, null);
-            if (loginContext != null) {
-//                doInitWithLogin(config, loginContext);
-                /* */
-                if (operationsLogger.isLoggable(Level.FINER)) {
-                    operationsLogger.entering(mailboxSourceClass, 
-                        "doInitWithLogin", new Object[] { config, loginContext});
-                }
-                loginContext.login();
-                try {
-                    init = Subject.doAsPrivileged(
-                        loginContext.getSubject(),
-                        new PrivilegedExceptionAction<MailboxImplInit>() {
-                            public MailboxImplInit run() throws Exception {
-//                                doInit(config);
-                                // Create these threads here so they inherit
-                                // current context.
-                                return new MailboxImplInit(config,
-                                        persistant, 
-                                        activID, 
-                                        baseLookupAttrs, 
-                                        new LocalLogHandler(),
-                                        persistant ? new SnapshotThread(): null,
-                                        new Notifier(config),
-                                        new ExpirationThread()
-                                        );
-                            }
-                        },
-                        null);
-                } catch (PrivilegedActionException e) {
-                    try {
-                        loginContext.logout();
-                    } catch (LoginException le) {
-        //TODO - Move to end of cleanup()
-                        if (initLogger.isLoggable(Levels.HANDLED)) {
-                            initLogger.log(Levels.HANDLED, "Trouble logging out", le);
-                        }
-                    }
-                    throw e.getException();
-                }
-                if (operationsLogger.isLoggable(Level.FINER)) {
-                    operationsLogger.exiting(mailboxSourceClass, 
-                        "doInitWithLogin");
-                }
-                /* */
-            } else {
-//                doInit(config);
-                init = new MailboxImplInit(config, 
-                        persistant, 
-                        activID, 
-                        baseLookupAttrs, 
-                        new LocalLogHandler(),
-                        persistant ? new SnapshotThread(): null,
-                        new Notifier(config),
-                        new ExpirationThread()
-                        );
-                
-            }
-            if (operationsLogger.isLoggable(Level.FINER)) {
-                operationsLogger.exiting(mailboxSourceClass, 
-                    "init");
-            }
-        } catch (Throwable t){
-            thrown = t;
-        } finally {
-            if (init != null){
-                activationID = init.activationID;
-                activationSystem = init.activationSystem;
-                activationPrepared = init.activationPrepared;
-                exporter = init.exporter;
-                listenerPreparer = init.listenerPreparer;
-                locatorToJoinPreparer = init.locatorToJoinPreparer;
-                leasePolicy = init.leasePolicy;
-                persistenceDirectory = init.persistenceDirectory;
-                recoveredLocatorToJoinPreparer = init.recoveredLocatorToJoinPreparer;
-                logToSnapshotThreshold = init.logToSnapshotThreshold;
-                log = init.log;
-                serviceID = init.serviceID;
-                lookupGroups = init.lookupGroups;
-                lookupLocators = init.lookupLocators;
-                lookupAttrs = init.lookupAttrs;
-                maxUnexportDelay = init.maxUnexportDelay;
-                unexportRetryDelay = init.unexportRetryDelay;
-                lookupDiscMgr = init.lookupDiscMgr;
-                regByExpiration = init.regByExpiration;
-                regByID = init.regByID;
-                activeReg = init.activeReg;
-                /** <code>EventLogIterator</code> generator */
-                eventLogFactory = init.eventLogFactory;
-                pendingReg = init.pendingReg;
-                snapshotter = init.snapshotter;
-                notifier = init.notifier;
-                expirer = init.expirer;
-                this.config = init.config;
-                this.loginContext = loginContext;
-                
-            } else {
-                activationID = activID;
-                activationSystem = null;
-                activationPrepared = false;
-                exporter = null;
-                listenerPreparer = null;
-                locatorToJoinPreparer = null;
-                leasePolicy = null;
-                persistenceDirectory = null;
-                recoveredLocatorToJoinPreparer = null;
-                logToSnapshotThreshold = 0;
-                log = null;
-                serviceID = null;
-                lookupGroups = null;
-                lookupLocators = null;
-                lookupAttrs = null;
-                maxUnexportDelay = 0;
-                unexportRetryDelay = 0;
-                lookupDiscMgr = null;
-                regByExpiration = null;
-                regByID = null;
-                activeReg = null;
-                /** <code>EventLogIterator</code> generator */
-                eventLogFactory = null;
-                pendingReg = null;
-                snapshotter = null;
-                notifier = null;
-                expirer = null;
-                this.config = null;
-                this.loginContext = loginContext;
-            }
-            // Assign fields.
-        }
-        
-    }
-
-//    /** Initialization common to both activatable and transient instances. */
-//    private void init(String[] configArgs) 
-//	throws Exception
-//    {
-//       if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.entering(mailboxSourceClass, 
-//	        "init", (Object[])configArgs);
-//       }
-//       final Configuration config =
-//            ConfigurationProvider.getInstance(
-//	        configArgs, getClass().getClassLoader());
-//        loginContext = (LoginContext) config.getEntry(
-//            MERCURY, "loginContext", LoginContext.class, null);
-//        if (loginContext != null) {
-//            doInitWithLogin(config, loginContext);
-//        } else {
-//            doInit(config);
-//	}
-//	if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.exiting(mailboxSourceClass, 
-//	        "init");
-//	}
-//    }
-    
-    /** 
-     * Method that attempts to login before delegating the
-     * rest of the initialization process to <code>doInit</code>
-     */
-//    private void doInitWithLogin(final Configuration config, 
-//        LoginContext loginContext) throws Exception 
-//    {
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.entering(mailboxSourceClass, 
-//	        "doInitWithLogin", new Object[] { config, loginContext});
-//	}
-//        loginContext.login();
-//	try {
-//            Subject.doAsPrivileged(
-//                loginContext.getSubject(),
-//                new PrivilegedExceptionAction() {
-//                    public Object run() throws Exception {
-//                        doInit(config);
-//                        return null;
-//                    }
-//                },
-//                null);
-//	} catch (PrivilegedActionException e) {
-//	    try {
-//	        loginContext.logout();
-//	    } catch (LoginException le) {
-////TODO - Move to end of cleanup()
-//		if (initLogger.isLoggable(Levels.HANDLED)) {
-//	            initLogger.log(Levels.HANDLED, "Trouble logging out", le);
-//		}
-//	    }
-//	    throw e.getException();
-//        }
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.exiting(mailboxSourceClass, 
-//	        "doInitWithLogin");
-//	}
-//    }
-    
-//    /** Initialization common to both activatable and transient instances. */
-//    private void doInit(Configuration config) throws Exception { 
-//
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.entering(mailboxSourceClass, 
-//	        "doInit", config);
-//	}
-////TODO - defer "big" default object to catch block around getNonNullEntry()
-//    
-//        // Get activation specific configuration items, if activated
-//	if (activationID != null) {
-//            ProxyPreparer activationSystemPreparer =
-//                (ProxyPreparer) Config.getNonNullEntry(config,
-//	            MERCURY, "activationSystemPreparer", 
-//		    ProxyPreparer.class, new BasicProxyPreparer());
-//            if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "activationSystemPreparer: {0}", 
-//	        activationSystemPreparer);
-//	    }		
-//            activationSystem =
-//                (ActivationSystem) activationSystemPreparer.prepareProxy(
-//                    ActivationGroup.getSystem());
-//            if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, "Prepared activation system is: {0}", 
-//	        activationSystem);
-//	    }		
-//            ProxyPreparer activationIdPreparer = 
-//	        (ProxyPreparer)  Config.getNonNullEntry(config,
-//	            MERCURY, "activationIdPreparer", 
-//		    ProxyPreparer.class, new BasicProxyPreparer());
-//            if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "activationIdPreparer: {0}", 
-//	        activationIdPreparer);
-//	    }		
-//            activationID = (ActivationID) activationIdPreparer.prepareProxy(
-//                activationID);
-//            if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, "Prepared activationID is: {0}", 
-//	        activationID);
-//	    }		
-//            activationPrepared = true;
-//	
-//            exporter = (Exporter)Config.getNonNullEntry(config,
-//	        MERCURY, "serverExporter", Exporter.class,
-//		new ActivationExporter(
-//		    activationID, 
-//		    new BasicJeriExporter(
-//		        TcpServerEndpoint.getInstance(0), 
-//			new BasicILFactory(), false, true)),
-//		activationID);
-//            if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "Activatable service exporter is: {0}", 
-//	        exporter);
-//	    }		
-//	} else { //Get non-activatable configuration items
-//            exporter = (Exporter) Config.getNonNullEntry(config,
-//                MERCURY, "serverExporter", Exporter.class, 
-//		new BasicJeriExporter(
-//		    TcpServerEndpoint.getInstance(0), 
-//		    new BasicILFactory(), false, true));
-//            if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, 
-//		"Non-activatable service exporter is: {0}", exporter);		
-//	    }
-//	}
-//
-//        listenerPreparer = (ProxyPreparer) Config.getNonNullEntry(
-//	    config, MERCURY, "listenerPreparer", ProxyPreparer.class,
-//            new BasicProxyPreparer());
-//        if (initLogger.isLoggable(Level.CONFIG)) {
-//            initLogger.log(Level.CONFIG, "Listener preparer is: {0}", 
-//	    listenerPreparer);	
-//	}
-//	
-//        /* Get the proxy preparers for the lookup locators to join */
-//        locatorToJoinPreparer = (ProxyPreparer)Config.getNonNullEntry
-//             (config, MERCURY, "locatorToJoinPreparer",
-//              ProxyPreparer.class, new BasicProxyPreparer());
-//        if (initLogger.isLoggable(Level.CONFIG)) {
-//            initLogger.log(Level.CONFIG, "Locator preparer is: {0}", 
-//	    locatorToJoinPreparer);
-//	}	
-//	
-//        // Create lease policy -- used by recovery logic, below
-//        leasePolicy = (LeasePeriodPolicy) Config.getNonNullEntry(config,
-//	    MERCURY, "leasePeriodPolicy", LeasePeriodPolicy.class,
-//            new FixedLeasePeriodPolicy(3 * HOURS, 1 * HOURS));
-//        if (initLogger.isLoggable(Level.CONFIG)) {
-//            initLogger.log(Level.CONFIG, "LeasePeriodPolicy is: {0}", 
-//	    leasePolicy);
-//	}	
-//	    
-//	// Note: referenced by recovery logic in rebuildTransientState()	
-//        ProxyPreparer recoveredListenerPreparer = null;
-//        if (persistent) {
-//	    persistenceDirectory = 
-//	        (String)Config.getNonNullEntry(
-//                    config, MERCURY, "persistenceDirectory", String.class);
-//            if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "Persistence directory is: {0}", 
-//	        persistenceDirectory);
-//	    }	
-//	    // Note: referenced by recovery logic in rebuildTransientState()	
-//            recoveredListenerPreparer = 
-//	        (ProxyPreparer) Config.getNonNullEntry(
-//	        config, MERCURY, "recoveredListenerPreparer", ProxyPreparer.class,
-//                new BasicProxyPreparer());
-//            if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "Recovered listener preparer is: {0}", 
-//	        recoveredListenerPreparer);	
-//	    }
-//	    // Note: referenced by recovery logic, below	
-//            recoveredLocatorToJoinPreparer = (ProxyPreparer)Config.getNonNullEntry
-//                 (config, MERCURY, "recoveredLocatorToJoinPreparer",
-//                  ProxyPreparer.class, new BasicProxyPreparer());
-//            if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "Recovered locator preparer is: {0}", 
-//	        recoveredLocatorToJoinPreparer);
-//	    }	
-//
-//	    logToSnapshotThreshold = Config.getIntEntry(config,
-//                MERCURY, "logToSnapshotThreshold", 50, 0, Integer.MAX_VALUE);
-//	    
-////            log = new ReliableLog(persistenceDirectory, new LocalLogHandler());
-//
-//	    if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, "Recovering persistent state");
-//	    }
-//            inRecovery = true;
-//            log.recover();
-//            inRecovery = false;
-//	}
-//
-//	if (serviceID == null) { // First time up, get initial values
-//	    if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, "Getting initial values.");
-//	    }
-//	    serviceID = UuidFactory.generate();
-//	    if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, "ServiceID: {0}", serviceID);
-//	    }
-//	    // Can be null for ALL_GROUPS
-//            lookupGroups = (String[])config.getEntry(MERCURY, 
-//	        "initialLookupGroups", String[].class, 
-//		new String[] { "" }); //default to public group
-//	    if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "Initial groups:");
-//	        dumpGroups(lookupGroups, initLogger, Level.CONFIG);
-//	    }
-//	    /*
-//	     * Note: Configuration provided locators are assumed to be 
-//	     * prepared already.
-//	     */
-//            lookupLocators = (LookupLocator[]) Config.getNonNullEntry(config,
-//	        MERCURY, "initialLookupLocators", LookupLocator[].class, 
-//		new LookupLocator[0]);
-//	    if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "Initial locators:");
-//	        dumpLocators(lookupLocators, initLogger, Level.CONFIG);
-//	    }
-//
-//            final Entry[] initialAttrs = 
-//	        (Entry[])Config.getNonNullEntry(config,
-//	            MERCURY, "initialLookupAttributes" ,
-//		    Entry[].class, new Entry[0]);
-//	    if (initLogger.isLoggable(Level.CONFIG)) {
-//                initLogger.log(Level.CONFIG, "Initial lookup attributes:");
-//	        dumpAttrs(initialAttrs, initLogger, Level.CONFIG);
-//	    }
-//            if (initialAttrs.length == 0) {
-//                lookupAttrs = baseLookupAttrs;
-//            } else {
-//                lookupAttrs = 
-//		    new Entry[initialAttrs.length + baseLookupAttrs.length];
-//                int i=0;
-//                for (int j=0; j<baseLookupAttrs.length; j++, i++)
-//                    lookupAttrs[i] = baseLookupAttrs[j];
-//                for (int j=0; j<initialAttrs.length; j++, i++)
-//                    lookupAttrs[i] = initialAttrs[j];
-//            }
-//	    if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, 
-//		    "Combined lookup attributes:"); 
-//	        dumpAttrs(lookupAttrs, initLogger, Level.FINEST);
-//	    }
-//        } else { // recovered logic
-//	    if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, "Preparing recovered locators:"); 
-//	        dumpLocators(lookupLocators, initLogger, Level.FINEST);
-//	    }
-//            prepareExistingLocators(
-//	        recoveredLocatorToJoinPreparer, lookupLocators);
-////TODO - Add recovered state debug: groups, locators, etc.
-//	}
-//	
-//        if (persistent) {
-//	    // Take snapshot of current state.
-//	    if (initLogger.isLoggable(Level.FINEST)) {
-//                initLogger.log(Level.FINEST, "Taking snapshot.");
-//	    }
-//            log.snapshot();
-//
-//            // Reconstruct any transient state, if necessary.
-//            rebuildTransientState(recoveredListenerPreparer);
-//	    
-//            /*  ----  ----- */
-//	    // Start snapshot thread belongs in start method
-////	    snapshotter = new SnapshotThread();
-//            snapshotter.start();
-//	}
-//        
-//	maxUnexportDelay = Config.getLongEntry(config, MERCURY, 
-//	    "maxUnexportDelay", 2 * MINUTES, 0, Long.MAX_VALUE);
-//
-//	unexportRetryDelay = Config.getLongEntry(config, MERCURY, 
-//	    "unexportRetryDelay", SECONDS, 1, Long.MAX_VALUE);
-//        
-//        /*  ---  The following will go into start method --- */
-//
-//        // Start threads
-////	notifier = new Notifier(config);
-//        notifier.start();
-////	expirer = new ExpirationThread();
-//        expirer.start();
-//
-//	// Export server instance and get its reference
-//	serverStub = (MailboxBackEnd)exporter.export(this);
-//        if (initLogger.isLoggable(Level.FINEST)) {
-//            initLogger.log(Level.FINEST, "Service stub is: {0}", 
-//	    serverStub);	
-//	}	
-//
-//        // Create the proxy that will be registered in the lookup service
-//        mailboxProxy = 
-//	    MailboxProxy.create(serverStub, serviceID);
-//        if (initLogger.isLoggable(Level.FINEST)) {
-//            initLogger.log(Level.FINEST, "Service proxy is: {0}", 
-//	    mailboxProxy);
-//	}		
-//
-//        // Create the admin proxy for this service
-//        mailboxAdminProxy = 
-//	    MailboxAdminProxy.create(serverStub, serviceID);
-//        if (initLogger.isLoggable(Level.FINEST)) {
-//            initLogger.log(Level.FINEST, "Service admin proxy is: {0}", 
-//	    mailboxAdminProxy);		
-//	}
-//
-//	// Create leaseFactory
-//	leaseFactory = new LeaseFactory(serverStub, serviceID);
-//
-//        // Get shorthand reference to the discovery manager
-//	try {
-//            lookupDiscMgr  = 
-//                (DiscoveryManagement)Config.getNonNullEntry(config,
-//	            MERCURY, "discoveryManager",
-//                    DiscoveryManagement.class);
-//            if(lookupDiscMgr instanceof DiscoveryGroupManagement) {
-//                 // Verify proper initial state ---> NO_GROUPS
-//                String[] groups =
-//                    ((DiscoveryGroupManagement)lookupDiscMgr).getGroups();
-//                if( (groups == DiscoveryGroupManagement.ALL_GROUPS) ||
-//                    (groups.length != 0) )
-//                {
-//                    throw new ConfigurationException(
-//                        "discoveryManager entry must be configured " +
-//		        " with no groups.");
-//                }//endif
-//	    } else {
-//               throw new ConfigurationException(
-//                    "discoveryManager entry must implement " +
-//                    "DiscoveryGroupManagement");
-//            }
-//	    
-//            if(lookupDiscMgr instanceof DiscoveryLocatorManagement) {
-//                LookupLocator[] locs =
-//                        ((DiscoveryLocatorManagement)lookupDiscMgr).getLocators();
-//                if( (locs != null) && (locs.length != 0) ) {
-//                    throw new ConfigurationException(
-//                        "discoveryManager entry must be configured " +
-//		        "with no locators");
-//                }//endif
-//	    } else {
-//                throw new ConfigurationException(
-//                    "discoveryManager entry must implement " +
-//                    "DiscoveryLocatorManagement");
-//            }  
-//	    
-//	    ((DiscoveryGroupManagement)lookupDiscMgr).setGroups(lookupGroups);
-//	    ((DiscoveryLocatorManagement)lookupDiscMgr).setLocators(lookupLocators);
-//	} catch (NoSuchEntryException e) {
-//	    lookupDiscMgr  =
-//		new LookupDiscoveryManager(lookupGroups, lookupLocators,
-//                    null, config);
-//	}
-//        if (initLogger.isLoggable(Level.FINEST)) {
-//            initLogger.log(Level.FINEST, "Discovery manager is: {0}", 
-//	    lookupDiscMgr);
-//	}		
-//
-//        ServiceID lookupID = new ServiceID(
-//	    serviceID.getMostSignificantBits(),
-//	    serviceID.getLeastSignificantBits());
-//
-//	if (initLogger.isLoggable(Level.FINEST)) {
-//            initLogger.log(Level.FINEST, "Creating JoinManager.");
-//	}
-//	joiner = new JoinManager(
-//	    mailboxProxy,                // service object
-//	    lookupAttrs,               // service attributes
-//	    lookupID,                 // Service ID
-//	    lookupDiscMgr,             // DiscoveryManagement ref - default
-//	    null,                      // LeaseRenewalManager reference
-//	    config); 
-//	                      
-//        if (operationsLogger.isLoggable(Level.FINER)) {
-//	    operationsLogger.exiting(mailboxSourceClass, 
-//	        "doInit");
-//	}
-//        readyState.ready();
-//
-//	if (startupLogger.isLoggable(Level.INFO)) {
-//            startupLogger.log
-//                   (Level.INFO, "Mercury started: {0}", this);
-//        }
-//
-//    } // End doInit()
-//    
-    public void start() throws Exception {
-        if (started) return;
-        concurrentObj.writeLock();
-        started = true; // mutual exclusion
-        try {
-            if (thrown != null) throw thrown;
-            if (persistent){
-                // Start snapshot thread belongs in start method
-    //	    snapshotter = new SnapshotThread();
-                snapshotter.start();
-            }
-
-            /*  ---  The following will go into start method --- */
-
-            // Start threads
-    //	notifier = new Notifier(config);
-            notifier.start();
-    //	expirer = new ExpirationThread();
-            expirer.start();
-
-            // Export server instance and get its reference
-            serverStub = (MailboxBackEnd)exporter.export(this);
-            if (initLogger.isLoggable(Level.FINEST)) {
-                initLogger.log(Level.FINEST, "Service stub is: {0}", 
-                serverStub);	
-            }	
-
-            // Create the proxy that will be registered in the lookup service
-            mailboxProxy = 
-                MailboxProxy.create(serverStub, serviceID);
-            if (initLogger.isLoggable(Level.FINEST)) {
-                initLogger.log(Level.FINEST, "Service proxy is: {0}", 
-                mailboxProxy);
-            }		
-
-            // Create the admin proxy for this service
-            mailboxAdminProxy = 
-                MailboxAdminProxy.create(serverStub, serviceID);
-            if (initLogger.isLoggable(Level.FINEST)) {
-                initLogger.log(Level.FINEST, "Service admin proxy is: {0}", 
-                mailboxAdminProxy);		
-            }
-
-            // Create leaseFactory
-            leaseFactory = new LeaseFactory(serverStub, serviceID);
-
-            // Get shorthand reference to the discovery manager
-            try {
-                lookupDiscMgr  = 
-                    (DiscoveryManagement)Config.getNonNullEntry(config,
-                        MERCURY, "discoveryManager",
-                        DiscoveryManagement.class);
-                if(lookupDiscMgr instanceof DiscoveryGroupManagement) {
-                     // Verify proper initial state ---> NO_GROUPS
-                    String[] groups =
-                        ((DiscoveryGroupManagement)lookupDiscMgr).getGroups();
-                    if( (groups == DiscoveryGroupManagement.ALL_GROUPS) ||
-                        (groups.length != 0) )
-                    {
-                        throw new ConfigurationException(
-                            "discoveryManager entry must be configured " +
-                            " with no groups.");
-                    }//endif
-                } else {
-                   throw new ConfigurationException(
-                        "discoveryManager entry must implement " +
-                        "DiscoveryGroupManagement");
-                }
-
-                if(lookupDiscMgr instanceof DiscoveryLocatorManagement) {
-                    LookupLocator[] locs =
-                            ((DiscoveryLocatorManagement)lookupDiscMgr).getLocators();
-                    if( (locs != null) && (locs.length != 0) ) {
-                        throw new ConfigurationException(
-                            "discoveryManager entry must be configured " +
-                            "with no locators");
-                    }//endif
-                } else {
-                    throw new ConfigurationException(
-                        "discoveryManager entry must implement " +
-                        "DiscoveryLocatorManagement");
-                }  
-
-                ((DiscoveryGroupManagement)lookupDiscMgr).setGroups(lookupGroups);
-                ((DiscoveryLocatorManagement)lookupDiscMgr).setLocators(lookupLocators);
-            } catch (NoSuchEntryException e) {
-                lookupDiscMgr  =
-                    new LookupDiscoveryManager(lookupGroups, lookupLocators,
-                        null, config);
-            }
-            if (initLogger.isLoggable(Level.FINEST)) {
-                initLogger.log(Level.FINEST, "Discovery manager is: {0}", 
-                lookupDiscMgr);
-            }		
-
-            ServiceID lookupID = new ServiceID(
-                serviceID.getMostSignificantBits(),
-                serviceID.getLeastSignificantBits());
-
-            if (initLogger.isLoggable(Level.FINEST)) {
-                initLogger.log(Level.FINEST, "Creating JoinManager.");
-            }
-            joiner = new JoinManager(
-                mailboxProxy,                // service object
-                lookupAttrs,               // service attributes
-                lookupID,                 // Service ID
-                lookupDiscMgr,             // DiscoveryManagement ref - default
-                null,                      // LeaseRenewalManager reference
-                config); 
-
-            if (operationsLogger.isLoggable(Level.FINER)) {
-                operationsLogger.exiting(mailboxSourceClass, 
-                    "doInit");
-            }
-            readyState.ready();
-
-            if (startupLogger.isLoggable(Level.INFO)) {
-                startupLogger.log
-                       (Level.INFO, "Mercury started: {0}", this);
-            }
-        } catch (Throwable t){
-            cleanup();
-	    initFailed(t);
-        } finally {
-            config = null;
-            thrown = null;
-            concurrentObj.writeUnlock();
-        }
-    }
-
-    // Rebuilds internal data structures after a restart.
-    private void rebuildTransientState(ProxyPreparer recoveredListenerPreparer) {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "rebuildTransientState", recoveredListenerPreparer);
-	}
-
-	// Reconstruct regByExpiration and pendingReg data structures,
-	// if necessary.
-	if (!regByID.isEmpty()) {
-	    if (recoveryLogger.isLoggable(Level.FINEST)) {
-                recoveryLogger.log(Level.FINEST, "Rebuilding transient state ...");
-            }
-	    Collection regs = regByID.values();
-	    Iterator iter = regs.iterator();
-	    ServiceRegistration reg = null;
-	    Uuid uuid = null;
-            EventLogIterator eli = null; 
-	    while (iter.hasNext()) {
-	        reg = (ServiceRegistration)iter.next(); // get Reg
-	        uuid = (Uuid)reg.getCookie();           // get its Uuid
-	        if (recoveryLogger.isLoggable(Level.FINEST)) {
-                    recoveryLogger.log(Level.FINEST, "Checking reg : {0}", reg);
-		}
-	        // Check if registration is still current
-	        if (ensureCurrent(reg)) {
-	            if (recoveryLogger.isLoggable(Level.FINEST)) {
-                        recoveryLogger.log(Level.FINEST,
-			"Restoring reg transient state ...");
-		    }
-                    try {
-                        reg.restoreTransientState(recoveredListenerPreparer);
-                    } catch (Exception e) {
-	                if (recoveryLogger.isLoggable(Levels.HANDLED)) {
-                            recoveryLogger.log(Levels.HANDLED,
-			        "Trouble restoring reg transient state", e);
-			}
-                        try {
-                            reg.setEventTarget(null);
-                        } catch (IOException ioe) {
-                            throw new AssertionError(
-                                "Setting a null target threw an exception: "
-                                + ioe);
-                        }
-                    }  
-		    		
-	            if (recoveryLogger.isLoggable(Level.FINEST)) {
-                        recoveryLogger.log(Level.FINEST,
-			    "Reinitializing iterator ...");
-	            }
-		    // regenerate an EventLogIterator for this Reg
-		    // Note that event state is maintained separately
-		    // through the event log mechanism.
-                    eli = persistent?
-		        eventLogFactory.iterator(uuid, 
-		            getEventLogPath(persistenceDirectory, uuid)):
-			eventLogFactory.iterator(uuid); 
-		    reg.setIterator(eli);
-	            if (recoveryLogger.isLoggable(Level.FINEST)) {
-                        recoveryLogger.log(Level.FINEST, 
-		        "Adding registration to expiration watch list");
-		    }
-		    // Put Reg into time sorted collection
-	            regByExpiration.put(reg, reg);
-
-	            // Check if registration needs to be added to the
-	            // pending list. Note, we could have processed
-	            // an "enabled" log record during recovery, so 
-	            // only add it if it's not already there.
-	            // We don't need to check activeReg since the
-	            // the notifier hasn't kicked in yet. Don't call
-	            // enableRegistration() since it clears the "unknown
-	            // events" list which we want to maintain.
-	            if (reg.hasEventTarget() &&
-	                !pendingReg.contains(uuid))
-		    {
-	                if (recoveryLogger.isLoggable(Level.FINEST)) {
-                            recoveryLogger.log(Level.FINEST, 
-			        "Adding registration to pending task list");
-			}
-        	        pendingReg.add(uuid);
-
-	            }
-	        } else {
-	            /* Registration has expired, so remove it via the iterator,
-		     * which is the only "safe" way to do it during a traversal.
-		     * Call the overloaded version of removeRegistration()
-		     * which will avoid directly removing the registration
-		     * from regByID (which would result in a 
-		     * ConcurrentModificationException). See Bug 4507320.
-		     */
-    	            if (recoveryLogger.isLoggable(Level.FINEST)) {
-                        recoveryLogger.log(Level.FINEST,
-			    "Removing expired registration: ");
-		    }
-		    iter.remove();
-	            removeRegistration(uuid, reg, true);
-	        }
-	    }
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "rebuildTransientState");
-	}
-    }
-    /*
-     *
-     */
-    private void cleanup() {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, "cleanup");
-	}
-        if (serverStub != null) { // implies that exporter != null
-	    try {
-                if(initLogger.isLoggable(Level.FINEST)) {
-                    initLogger.log(Level.FINEST, "Unexporting service");
-		}		    
-	        exporter.unexport(true);
-	    } catch (Throwable t) {
-                if(initLogger.isLoggable(Levels.HANDLED)) {
-                    initLogger.log(Levels.HANDLED, "Trouble unexporting service", t);
-		}		    
-	    }
-	}
-	
-	if (joiner != null) {
-	    try {
-                if(initLogger.isLoggable(Level.FINEST)) {
-                    initLogger.log(Level.FINEST, "Terminating join manager");
-		}		    
-	        joiner.terminate();
-	    } catch (Throwable t) {
-                if(initLogger.isLoggable(Levels.HANDLED)) {
-                    initLogger.log(Levels.HANDLED, 
-		    "Trouble terminating join manager", t);
-		}		    
-	    }
-	}
-	if (lookupDiscMgr != null) {
-	    try {
-                if(initLogger.isLoggable(Level.FINEST)) {
-                    initLogger.log(Level.FINEST, 
-		    "Terminating lookup discovery manager");		    
-		}
-	        lookupDiscMgr.terminate();
-	    } catch (Throwable t) {
-                if(initLogger.isLoggable(Levels.HANDLED)) {
-                    initLogger.log(Levels.HANDLED, 
-		    "Trouble terminating lookup discovery manager", t);	
-		}	    
-	    }
-	}
-   	if (notifier != null) {
-	    try {
-                if(initLogger.isLoggable(Level.FINEST)) {
-                    initLogger.log(Level.FINEST, 
-		        "Interrupting notifier");	
-		}	    
-	        notifier.interrupt();
-	    } catch (Throwable t) {
-                if(initLogger.isLoggable(Levels.HANDLED)) {
-                    initLogger.log(Levels.HANDLED, 
-		        "Trouble interrupting notifier", t);		    
-		}
-	    }
-	}
-   	if (expirer != null) {
-	    try {
-                if(initLogger.isLoggable(Level.FINEST)) {
-                    initLogger.log(Level.FINEST, 
-		        "Interrupting expirer");
-		}		    
-	        expirer.interrupt();
-	    } catch (Throwable t) {
-                if(initLogger.isLoggable(Levels.HANDLED)) {
-                    initLogger.log(Levels.HANDLED, 
-		        "Trouble interrupting expirer", t);	
-		}	    
-	    }
-	}
-        if (snapshotter != null) {
-	    try {
-                if(initLogger.isLoggable(Level.FINEST)) {
-                    initLogger.log(Level.FINEST, 
-		        "Interrupting snapshotter");
-		}		    
-	        snapshotter.interrupt();
-	    } catch (Throwable t) {
-                if(initLogger.isLoggable(Levels.HANDLED)) {
-                    initLogger.log(Levels.HANDLED, 
-		        "Trouble interrupting snapshotter", t);	
-		}	    
-	    }
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, "cleanup");
-	}
-    }
-
-    ///////////////////////////
-    // MailboxBackEnd Methods
-    ///////////////////////////
-
-    // This method's javadoc is inherited from an interface of this class
-    public MailboxRegistration register(long leaseDuration) 
-	throws RemoteException, LeaseDeniedException
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    return registerDo(leaseDuration);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-    
-    // This method's javadoc is inherited from an interface of this class
-    public MailboxPullRegistration pullRegister(long leaseDuration) 
-	throws RemoteException, LeaseDeniedException
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    return registerDo(leaseDuration);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-    
-    // This method's javadoc is inherited from an interface of this class
-    public void enableDelivery(Uuid uuid, RemoteEventListener target) 
-	throws RemoteException, ThrowThis 
-    {
-        readyState.check();
-        RemoteEventListener preparedTarget = null;
-        if (target == null) {
-            disableDelivery(uuid);
-	    return;
-        } else {
-            try {
-                preparedTarget =
-                    (RemoteEventListener) 
-		        listenerPreparer.prepareProxy(target);
-                if(deliveryLogger.isLoggable(Level.FINEST)) {
-                    deliveryLogger.log(Level.FINEST, 
-		        "prepared listener: {0}", preparedTarget);
-		}
-	    } catch (RemoteException e) {
-                throw new ThrowThis(e);
-            }
-	}
-	concurrentObj.writeLock();
-	try {
-	    enableDeliveryDo(uuid, preparedTarget);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-	
-    // This method's javadoc is inherited from an interface of this class
-    public void disableDelivery(Uuid uuid) 
-	throws RemoteException, ThrowThis 
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    disableDeliveryDo(uuid);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public RemoteEventIteratorData getRemoteEvents(
-	Uuid uuid) 
-	throws RemoteException, ThrowThis
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    return getRemoteEventsDo(uuid);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }	   
-    
-    // This method's javadoc is inherited from an interface of this class
-    public Collection getNextBatch(
-	Uuid regId, Uuid iterId, long timeout, Object lastEventCookie) 
-	throws InvalidIteratorException, ThrowThis
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    return getNextBatchDo(regId, iterId, timeout, lastEventCookie);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }	   
-    
-    // This method's javadoc is inherited from an interface of this class
-    public void addUnknownEvents(
-	Uuid uuid, Collection unknownEvents) 
-	throws RemoteException, ThrowThis
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    addUnknownEventsDo(uuid, unknownEvents);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }	
-    
-    // This method's javadoc is inherited from an interface of this class
-    public void notify(Uuid registrationID, RemoteEvent theEvent) 
-	throws UnknownEventException, RemoteException, ThrowThis
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    notifyDo(registrationID, theEvent);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-
-
-    ////////////////////////
-    // Landlord Methods
-    ////////////////////////
-
-    // inherit javadoc from parent
-    public long renew(Uuid cookie, long extension)
-	    throws LeaseDeniedException, UnknownLeaseException, RemoteException 
-    {
-        readyState.check();
-	concurrentObj.priorityWriteLock();
-	try {
-	    return renewDo(cookie, extension);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-
-    // inherit javadoc from parent
-    public void cancel(Uuid cookie)
-	    throws UnknownLeaseException, RemoteException 
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    cancelDo(cookie);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-
-    // inherit javadoc from parent
-    public RenewResults renewAll(Uuid[] cookies, long[] extension)
-	    throws RemoteException 
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    return renewAllDo(cookies, extension);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-
-    // inherit javadoc from parent
-    public Map cancelAll(Uuid[] cookies) throws RemoteException 
-    {
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    return cancelAllDo(cookies);
-        } finally {
-	    concurrentObj.writeUnlock();
-	}
-    }
-
-    //////////////////////////////////
-    // DestroyAdmin methods
-    //////////////////////////////////
-
-    // This method's javadoc is inherited from an interface of this class
-    public void destroy() {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "destroy");
-	}
-        readyState.check();
-        
-        /* 
-         * Try to "interrupt" any existing blocking calls so that they return
-         * early and don't hold up the subsequent unexporting process.
-         * Notes:
-         * - there's still a chance for more blocking calls to arrive
-         * between "here" and when the unexport actually takes place, so we'll 
-         * have do this again later on.
-         * - need a lock here since we are notifying write waiters. Could get
-         * away with just a readLock since the waiters are "writers", but 
-         * getting a writeLock will work should there ever be "readers" waiting 
-         * too.
-         */
-	concurrentObj.writeLock();
-	try {
-            ServiceRegistration[] regs = 
-                (ServiceRegistration[])regByID.values().toArray(
-                    new ServiceRegistration[regByID.size()]);
-            if (adminLogger.isLoggable(Level.FINEST)) {
-                adminLogger.log(Level.FINEST,
-                    "Notifying {0} possible registrations",
-                     Integer.valueOf(regByID.size()));
-            }
-            for (int i=0; i < regs.length; i++) {
-                //Remove registrations from internal structures.
-                removeRegistration(regs[i].getCookie(), regs[i]);
-                // Notify any associated iterations so they can return early
-                concurrentObj.waiterNotify(regs[i].getIteratorNotifier());            
-                if(adminLogger.isLoggable(Level.FINEST)) {
-                    adminLogger.log(Level.FINEST, 
-                        "Iterator for reg {0} notified",
-                        regs[i]);
-                }
-            }
-        } finally {
-	    concurrentObj.writeUnlock();
-	}        
-        
-	(new DestroyThread()).start();
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "destroy");
-	}
-    }
-
-
-    //////////////////////////////////
-    // JoinAdmin methods
-    //////////////////////////////////
-
-    // This method's javadoc is inherited from an interface of this class
-    public Entry[] getLookupAttributes() throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "getLookupAttributes");
-	}
-        readyState.check();
-	concurrentObj.readLock();
-	try {
-            if (operationsLogger.isLoggable(Level.FINER)) {
-	        operationsLogger.exiting(mailboxSourceClass, 
-	            "getLookupAttributes");
-            }
-	    return lookupAttrs;
-	} finally {
-	    concurrentObj.readUnlock();
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void addLookupAttributes(Entry[] attrSets) throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "addLookupAttributes");
-	}
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    // delegate functionality to JoinManager
-	    joiner.addAttributes(attrSets, true);
-	    lookupAttrs = joiner.getAttributes();
-	    // Log the modification
-	    addLogRecord(new AttrsAddedLogObj(attrSets));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "addLookupAttributes");
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void modifyLookupAttributes(Entry[] attrSetTemplates,
-				       Entry[] attrSets)
-	throws RemoteException
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "modifyLookupAttributes");
-	}
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    // delegate functionality to JoinManager
-	    joiner.modifyAttributes(attrSetTemplates, attrSets, true);
-	    lookupAttrs = joiner.getAttributes();
-	    // Log the modification
-	    addLogRecord(new AttrsModifiedLogObj(attrSetTemplates, attrSets));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "modifyLookupAttributes");
-	}
-    }
-
-
-    // This method's javadoc is inherited from an interface of this class
-    public String[] getLookupGroups() throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "getLookupGroups");
-	}
-        readyState.check();
-	concurrentObj.readLock();
-	try {
-            if (operationsLogger.isLoggable(Level.FINER)) {
-	        operationsLogger.exiting(mailboxSourceClass, 
-	            "getLookupGroups");
-	    }
-	    return lookupGroups;
-	} finally {
-	    concurrentObj.readUnlock();
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void addLookupGroups(String[] groups) throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "addLookupGroups");
-	}
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    try {
-	        // delegate functionality to discovery manager
-		((DiscoveryGroupManagement)lookupDiscMgr).addGroups(groups);
-	    } catch (IOException e) {
-		throw new RuntimeException(e.toString());
-	    }
-	    lookupGroups = ((DiscoveryGroupManagement)lookupDiscMgr).getGroups();
-	    // Log the modification
-            addLogRecord(new LookupGroupsChangedLogObj(lookupGroups));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "addLookupGroups");
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void removeLookupGroups(String[] groups) throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "removeLookupGroups");
-	}
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    // delegate functionality to discovery manager
-	    ((DiscoveryGroupManagement)lookupDiscMgr).removeGroups(groups);
-	    lookupGroups = ((DiscoveryGroupManagement)lookupDiscMgr).getGroups();
-	    // Log the modification
-            addLogRecord(new LookupGroupsChangedLogObj(lookupGroups));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "removeLookupGroups");
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void setLookupGroups(String[] groups) throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "setLookupGroups");
-	}
-        readyState.check();
-	concurrentObj.writeLock();
-	try {
-	    try {
-	        // delegate functionality to discovery manager
-		((DiscoveryGroupManagement)lookupDiscMgr).setGroups(groups);
-	    } catch (IOException e) {
-		throw new RuntimeException(e.toString());
-	    }
-	    lookupGroups = ((DiscoveryGroupManagement)lookupDiscMgr).getGroups();
-	    // Log the modification
-            addLogRecord(new LookupGroupsChangedLogObj(lookupGroups));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "setLookupGroups");
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public LookupLocator[] getLookupLocators() throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "getLookupLocators");
-	}
-        readyState.check();
-	concurrentObj.readLock();
-	try {
-            if (operationsLogger.isLoggable(Level.FINER)) {
-	        operationsLogger.exiting(mailboxSourceClass, 
-    	            "getLookupLocators");
-            }
-	    return lookupLocators;
-	} finally {
-	    concurrentObj.readUnlock();
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void addLookupLocators(LookupLocator[] locators)
-	throws RemoteException
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "addLookupLocators");
-	}
-        readyState.check();
-        /* Prepare outside of sync block because of possible remote call */
-	prepareNewLocators(locatorToJoinPreparer,locators);
-	concurrentObj.writeLock();
-	try {
-	    // delegate functionality to discovery manager
-	    ((DiscoveryLocatorManagement)lookupDiscMgr).addLocators(locators);
-	    lookupLocators = 
-	        ((DiscoveryLocatorManagement)lookupDiscMgr).getLocators();
-	    // Log the modification
-	    addLogRecord(new LookupLocatorsChangedLogObj(lookupLocators));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "addLookupLocators");
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void removeLookupLocators(LookupLocator[] locators)
-	throws RemoteException
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "removeLookupLocators");
-	}
-        readyState.check();
-        /* Prepare outside of sync block because of possible remote call */
-	prepareNewLocators(locatorToJoinPreparer,locators);
-	concurrentObj.writeLock();
-	try {
-	    // delegate functionality to discovery manager
-	    ((DiscoveryLocatorManagement)lookupDiscMgr).removeLocators(locators);
-	    lookupLocators = 
-	        ((DiscoveryLocatorManagement)lookupDiscMgr).getLocators();
-	    // Log the modification
-	    addLogRecord(new LookupLocatorsChangedLogObj(lookupLocators));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "removeLookupLocators");
-	}
-    }
-
-    // This method's javadoc is inherited from an interface of this class
-    public void setLookupLocators(LookupLocator[] locators)
-	throws RemoteException
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "setLookupLocators");
-	}
-        readyState.check();
-        /* Prepare outside of sync block because of possible remote call */
-	prepareNewLocators(locatorToJoinPreparer,locators);
-	concurrentObj.writeLock();
-	try {
-	    // delegate functionality to discovery manager
-	    ((DiscoveryLocatorManagement)lookupDiscMgr).setLocators(locators);
-	    lookupLocators = 
-	        ((DiscoveryLocatorManagement)lookupDiscMgr).getLocators();
-	    // Log the modification
-	    addLogRecord(new LookupLocatorsChangedLogObj(lookupLocators));
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "setLookupLocators");
-	}
-    }
-
-
-    /**
-     * Utility method that adds the provided EventID
-     * to the given registration's "unknown" event list.
-     * If the mailbox receives another event, on this registration's
-     * behalf, and its EventID is on this list, the service will 
-     * throw a UnknownEventException back to the event sender.
-     */
-    private void addUnknownEvent(Uuid regID, EventID evid) {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	    "addUnknownEvent", new Object[] {regID, evid});
-	}
-	concurrentObj.writeLock();
-	try {
-            addUnknownEventDo(regID, evid);
-	} finally {
-	    concurrentObj.writeUnlock();
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "addUnknownEvent");
-	}
-    }
-    
-    /**
-     * Performs the actual logic for adding an unknown event to the
-     * given registration's unknown event list. Assumes caller
-     * holds a write lock.
-     */
-    private void addUnknownEventDo(Uuid regID, EventID evid) {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	    "addUnknownEventDo", new Object[] {regID, evid});
-	}
-        //Ensure that the registration is still valid
-        ServiceRegistration reg = (ServiceRegistration)regByID.get(regID);
-        if(reg == null || !ensureCurrent(reg)) {
-            return; // nothing to do ... registration is gone
-        }
-        if(deliveryLogger.isLoggable(Level.FINEST)) {
-            deliveryLogger.log(Level.FINEST, "Using reg: {0} ", reg);
-        }
-
-        // TODO - check if already there and save a log record.
-        // Add EventID to the list
-        reg.getUnknownEvents().put(evid, evid);
-        // Log this event
-        addLogRecord(new UnknownEventExceptionLogObj(regID, evid));
-
-        if(deliveryLogger.isLoggable(Level.FINEST)) {
-            deliveryLogger.log(Level.FINEST, "UnknownEvents size: {0}", 
-                Integer.valueOf(reg.getUnknownEvents().size()));
-        }
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "addUnknownEventDo");
-	}
-    }
-    
-    /**
-     * Utility method that tries to obtain the ServiceRegistration
-     * object associated with the given Uuid.  If there is
-     * no associated ServiceRegistration object, or it has expired,
-     * this method will throw a "wrapped" NoSuchObjectException.
-     * Note: If the NoSuchObjectException was not wrapped, then
-     * the RMI system would wrap into a ServerException (since it's 
-     * a RemoteEvent).  The proxies for this service know how to unwrap
-     * the ThrowThis object and re-throw the NoSuchObjectException back on
-     * the client-side.
-     */
-    private ServiceRegistration getServiceRegistration(Uuid regID) 
-        throws ThrowThis
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "getServiceRegistration", regID);
-	}
-        ServiceRegistration reg = (ServiceRegistration)regByID.get(regID); 
-	if(reg == null) { // either expired or never existed
-	    throw new ThrowThis( 
-		new NoSuchObjectException("Not managing requested " +
-	            "registration object"));
-	} else if(!ensureCurrent(reg)) { // check validity
-	    throw new ThrowThis( 
-		new NoSuchObjectException("Requested registration object" +
-		    "has expired"));
-	}
-	// Must be a valid registration at this point
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "getServiceRegistration", reg);
-	}
-	return reg;
-    }
-
-    /**
-     * Utility method that calls the overloaded version that accepts a boolean,
-     * which is set to false.
-     */
-    private void removeRegistration(Uuid regID, ServiceRegistration reg) {
-        removeRegistration(regID, reg, false);
-    }
-    
-    /**
-     * Utility method that consolidates registration removal activities.
-     * It's called when registration's are either expired or cancelled.
-     */
-    private void removeRegistration(Uuid regID, ServiceRegistration reg,
-                                    boolean initializing) 
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "removeRegistration", 
-	        new Object[] {regID, reg, Boolean.valueOf(initializing)});
-	}
- 
-        // Remove Reg from data structures, if present.
-	// If initializing, don't remove directly from regByID since we
-	// currently traversing it via an iterator. Assumption is that
-	// the caller has already removed it via the iterator.
-	// See Bug 4507320. 
-        if (!initializing) {
-	    regByID.remove(regID);
-	}
-	regByExpiration.remove(reg);
-	boolean exists = pendingReg.remove(regID);
-	NotifyTask task = (NotifyTask)activeReg.remove(regID);
-	if (task != null) { // cancel active task, if any
-	    task.cancel();
-	    if(deliveryLogger.isLoggable(Level.FINEST)) {
-                deliveryLogger.log(Level.FINEST, 
-		    "Cancelling active notification task for {0}", regID);
-	    }
-	}
-
-	// Delete any associated resources
-	try {
-	    if(persistenceLogger.isLoggable(Level.FINEST)) {
-                persistenceLogger.log(Level.FINEST, 
-		    "Removing logs for {0}", reg);
-            }
-	    EventLogIterator iter = reg.iterator();
-	    if (iter != null) // iter is null when recovering state
-		iter.destroy();
-	} catch (IOException ioe) {
-	    if(persistenceLogger.isLoggable(Levels.HANDLED)) {
-                persistenceLogger.log(Levels.HANDLED, 
-		    "Trouble removing logs", ioe);
-	    }
-	    // Did the best we could ... continue.
-	}
-
-
-	// Sanity check
-	if (exists && task != null) {
-	    if(leaseLogger.isLoggable(Level.SEVERE)) {
-                leaseLogger.log(Level.SEVERE, 
-		    "ERROR: Registration was found "
-	            + "on both the active and pending lists");
-	    }
-// TODO (FCS)- throw assertion error
-	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "removeRegistration");
-	}
-    }
-
-    /**
-     * Utility method that returns the associated File object
-     * for the given Uuid's persistence directory 
-     */
-    static File getEventLogPath(String parent, Uuid uuid) {
-        return new File(parent, uuid.toString());
-    }
-
-    /** Actual implementation of the registration process. */
-    private Registration registerDo(long duration) {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "registerDo", Long.valueOf(duration));
-	}
-        if (duration < 1 && duration != Lease.ANY) 
-	    throw new IllegalArgumentException(
-	        "Duration must be a positive value");
-        // Create new ServiceRegistration object
-        Uuid uuid = UuidFactory.generate(); 
-        EventLogIterator iter = persistent?
-	    eventLogFactory.iterator(uuid, 
-	        getEventLogPath(persistenceDirectory, uuid)):
-	    eventLogFactory.iterator(uuid);
-        ServiceRegistration reg = new ServiceRegistration(uuid, iter);
-        Lease l = null;
-        try {
-	    Result r = 
-	        leasePolicy.grant(reg, duration);
-	    reg.setExpiration(r.expiration);
-            l = leaseFactory.newLease(uuid, r.expiration);
-//TODO - destroy iter if leaseFor throws any exception
-	} catch (LeaseDeniedException lde) {
-	    // Should never happen in our implementation.
-	    // Re-throw as an internal exception.
-	    throw new InternalMailboxException("Registration lease was denied", 
-		                               lde);
-	}
-        // Add registration to internal data structures 
-        addRegistration(reg);
-
-        // log a record of this event
-        addLogRecord(new RegistrationLogObj(reg));
-
-        // Check expiration and notify expiration thread to 
-        // wake up earlier than scheduled, if needed.
-	if (reg.getExpiration() < minRegExpiration) {
-	    minRegExpiration = reg.getExpiration();
-            if (expirationLogger.isLoggable(Level.FINEST)) {
-                expirationLogger.log(Level.FINEST,"Notifying expiration thread");
-            }
-	    concurrentObj.waiterNotify(expirationNotifier);
-	}
-
-	if(leaseLogger.isLoggable(Level.FINEST)) {
-            leaseLogger.log(Level.FINEST, 
-		"Generated new lease for: {0}", reg);
-	    reg.dumpInfo(leaseLogger);
-	}
-
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "registerDo");
-	}
-        // Return client-side proxy for the ServiceRegistration
-	return Registration.create(uuid, serverStub, l);
-    }
-    
-    /** 
-     * Utility method used to add a registration to our state information. 
-     * This method is invoked from <code>registerDo()</code> as well as
-     * <code> RegistrationLogObj.apply()</code>.  
-     */
-    private void addRegistration(ServiceRegistration reg) {
-	regByID.put(reg.getCookie(), reg);
-	regByExpiration.put(reg, reg);
-    }
-
-    /** Performs the actual registration renewal logic */
-    private long renewDo(Uuid cookie, long extension)
-        throws UnknownLeaseException, LeaseDeniedException 
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "renewDo", new Object[] { cookie, Long.valueOf(extension)});
-	}
-        if (extension < 1 && extension != Lease.ANY)
-	    throw new IllegalArgumentException(
-	        "Duration must be a positive value");
-    
-        ServiceRegistration reg = null;
-	long expiration = 0;
-        
-	if(leaseLogger.isLoggable(Level.FINEST)) {
-            leaseLogger.log(Level.FINEST, 
-		"Attempting to renew {0}''s lease for {1} sec",
-		new Object[] {cookie, Long.valueOf(extension/1000)}); 
-	}
-	
-	// Get registration of interest
-        Result r;
-	try { 
-            // Note: the following method will throw a ThrowThis exception
-            // if the registration is invalid (i.e. expired or non-existent)
-	    reg = getServiceRegistration(cookie);
-	    // delegate renewal to policy object
-	    r = leasePolicy.renew(reg, extension);
-	    reg.setExpiration(r.expiration);
-	    // Log this event
-	    addLogRecord(new RegistrationRenewedLogObj(cookie, 
-	                                               reg.getExpiration()));
-
-	    // remove then add to cause a resort to occur
-	    regByExpiration.remove(reg);
-	    regByExpiration.put(reg, reg);
-	} catch (ThrowThis tt) {
-	    // Registration doesn't exist or has expired
-	    if(leaseLogger.isLoggable(Level.FINEST)) {
-                leaseLogger.log(Level.FINEST, 
-		    "Lease for {0} was NOT renewed", cookie);
-	    }
-	    throw new UnknownLeaseException("Not managing requested lease");
-	}
-
-	if(leaseLogger.isLoggable(Level.FINEST)) {
-            leaseLogger.log(Level.FINEST, 
-	        "Lease for {0} was renewed", cookie);
-	    reg.dumpInfo(leaseLogger);
-	}
-	
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "renewDo", Long.valueOf(r.duration));
-	}
-	return r.duration;
-    }
-    
-    
-    /** Performs the actual registration cancellation logic */
-    private void cancelDo(Uuid cookie) throws UnknownLeaseException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "cancelDo", cookie);
-	}
-        ServiceRegistration reg = null;
-
-    	if(leaseLogger.isLoggable(Level.FINEST)) {
-            leaseLogger.log(Level.FINEST, 
-	        "Attempting to cancel lease for: {0}", cookie); 
-    	}
-
-	try { 
-            // Note: the following method will throw a ThrowThis exception
-            // if the registration is invalid (i.e. expired or non-existent)
-	    reg = getServiceRegistration(cookie);
-	    // Remove registration from internal data structures
-            removeRegistration(cookie, reg);
-            // Log this event
-	    addLogRecord(new RegistrationCancelledLogObj(cookie));
-	    // Notify expiration thread in case we deleted the registration
-	    // nearest to expiration, so it can recompute minRegExpiration.
-            if (reg.getExpiration() == minRegExpiration) {
-                if(expirationLogger.isLoggable(Level.FINEST)) {
-                    expirationLogger.log(Level.FINEST, 
-	                "Notifying expiration thread");
-                }
-	        concurrentObj.waiterNotify(expirationNotifier);
-	    }
-            // Notify any pending iterations
-            concurrentObj.waiterNotify(reg.getIteratorNotifier());            
-            if(expirationLogger.isLoggable(Level.FINEST)) {
-                expirationLogger.log(Level.FINEST, "Iterator notified");
-            }
-            
-	} catch (ThrowThis tt) {
-	    // Registration doesn't exist or has expired
-	    throw new UnknownLeaseException("Not managing requested lease");
-	}
-    	if(leaseLogger.isLoggable(Level.FINEST)) {
-            leaseLogger.log(Level.FINEST, 
-	        "Lease cancelled for: {0}", cookie); 
-    	}
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "cancelDo");
-	}
-    }
-    
-    /** Performs the actual renewAll logic */
-    private RenewResults renewAllDo(Uuid[] cookie, long[] extension)
-	    throws RemoteException 
-    {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "renewAllDo");
-	}
-	int count = cookie.length;
-
-	if(leaseLogger.isLoggable(Level.FINEST)) {
-            leaseLogger.log(Level.FINEST, 
-	        "Attempting to renew a batch of {0} leases", 
-		Integer.valueOf(count)); 
-	}
-
-	// Delegate functionality to Landlord utility
-	final RenewResults rslt = LandlordUtil.renewAll(localLandlord,
-							cookie,	extension);
-
-	if(rslt.denied == null)  {
-	    if(leaseLogger.isLoggable(Level.FINEST)) {
-                leaseLogger.log(Level.FINEST, 
-	            "Batch renew totally successful");
-	    }
-	} else {
-	    if(leaseLogger.isLoggable(Level.FINEST)) {
-                leaseLogger.log(Level.FINEST, 
-	            "Batch renew contained exceptions");
-	    }
-	}
-
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.exiting(mailboxSourceClass, 
-	        "renewAllDo");
-	}
-	return rslt;
-    }	     
-
-    /** Performs the actual cancelAll logic */
-    private Map cancelAllDo(Uuid[] cookie) throws RemoteException {
-        if (operationsLogger.isLoggable(Level.FINER)) {
-	    operationsLogger.entering(mailboxSourceClass, 
-	        "cancelAllDo");
-	}
-	int count = cookie.length;
-	if(leaseLogger.isLoggable(Level.FINEST)) {

[... 8012 lines stripped ...]