Main Method to demo the functionality
@param persistenceManager Open and valid persistence manager
491368
@SuppressWarnings("unchecked")
    static void demo(PersistenceManager persistenceManager) throws OnyxException
    {

        // This is a simple example of how to use the stream() api to iterate through payment records and dynamically update the payment record
        // with very specific data driven format.
        final Query paymentQuery = new Query(Payment.class, new QueryCriteria("amount", QueryCriteriaOperator.GREATER_THAN_EQUAL, 1.0));

        // Basically, this code will find all the payments under a specific amount and add a kind note to that payment.
        //
        // Notice the stream interface we are using is QueryStream.  This is specifically for iterating through the data in its entity format as opposed to
        // a generic structure.
        //noinspection RedundantCast
        persistenceManager.stream(paymentQuery, (QueryStream<Payment>) (payment, internalPersistenceManager) -> {
            payment.setNotes("The Deadbeat with account number: " + payment.getInvoice().getAccount().getAccountId() + " didn't pay anything cause he/she is broke!!!");
            try {
                internalPersistenceManager.saveEntity(payment);
            } catch (OnyxException e) {
                e.printStackTrace();
            }
        });

        // In this example we need to do some more complex actions due to the scale of the model updates.  We happened to orphan a field that
        // we want to use to populate other data.  In this case, just because we have removed the field does not mean the data has been lost.
        // We specifically use the QueryMapStream so that the entity is in format of a Map and we can see the hidden fields that no longer exist.
        //
        // This example moves the balanceDue from the account and puts it on the invoice where the property belongs.
        //
        // Note: If the account was saved after model updates, the attribute will no longer be available for us to read.
        final Query accountQuery = new Query(Account.class, new QueryCriteria("accountId", QueryCriteriaOperator.NOT_NULL));

        persistenceManager.stream(accountQuery, (QueryMapStream) (o, internalPersistenceManager) -> {
            try {

                @SuppressWarnings("RedundantCast")
                Map mapValue = (Map)o;
                // Ensure the property still exists within the data.
                if(mapValue.containsKey("balanceDue"))
                {
                    double balanceDue = (double) mapValue.get("balanceDue");

                    // This field has been updated to long in the new data model but, the old data model persisted it as an int.  So, that is the reason why we cast it as an integer.
                    int accountId = (int) mapValue.get("accountId");

                    // Get the latest invoice
                    final QueryCriteria fetchInvoiceCriteria = new QueryCriteria("invoiceId", QueryCriteriaOperator.NOT_NULL).and("account.accountId", QueryCriteriaOperator.EQUAL, accountId);
                    final Query invoiceQuery = new Query(Invoice.class, fetchInvoiceCriteria);
                    invoiceQuery.setQueryOrders(Collections.singletonList(new QueryOrder("invoiceDate", false)));
                    invoiceQuery.setMaxResults(1);

                    final List<Invoice> invoices = internalPersistenceManager.executeQuery(invoiceQuery);

                    Invoice latestInvoice = null;

                    // Ensure there is an invoice associated to the account.
                    if (invoices.size() > 0) {
                        latestInvoice = invoices.get(0);
                    }

                    // Update the invoice to the balance due on the Account.
                    if (latestInvoice != null) {
                        latestInvoice.setAmount(balanceDue);
                        internalPersistenceManager.saveEntity(latestInvoice);
                    }
                }

            }catch (OnyxException e)
            {
                e.printStackTrace();
            }

        });




    }
406496
private void startStorageAdapter() throws Exception {
        // create the storage adapter that will write our metrics/inventory data to backend storage on server
        this.storageAdapter = new HawkularStorageAdapter();
        this.storageAdapter.initialize(
                feedId,
                configuration.getStorageAdapter(),
                diagnostics,
                httpClientBuilder);

        // provide our storage adapter to the proxies - allows external apps to use them to store its own data
        inventoryStorageProxy.setStorageAdapter(storageAdapter);

        // log our own diagnostic reports
        this.diagnosticsReporter = JBossLoggingReporter.forRegistry(this.diagnostics.getMetricRegistry())
                .convertRatesTo(TimeUnit.SECONDS)
                .convertDurationsTo(TimeUnit.MILLISECONDS)
                .outputTo(Logger.getLogger(getClass()))
                .withLoggingLevel(LoggingLevel.DEBUG)
                .build();

        if (this.configuration.getDiagnostics().isEnabled()) {
            diagnosticsReporter.start(this.configuration.getDiagnostics().getInterval(),
                    this.configuration.getDiagnostics().getTimeUnits());
        }
    }
291427
private void createPersistentStore() throws MessageStoreException {
        if (TraceComponent.isAnyTracingEnabled()
            && tc.isEntryEnabled())
            SibTr.entry(tc, "createPersistentStore");

        _persistentStore = new MessageProcessorStore(new SIBUuid8(_engine.getUuid()),
                        _msgStore, _txManager);

        if (TraceComponent.isAnyTracingEnabled()
            && tc.isEntryEnabled())
            SibTr.exit(tc, "createPersistentStore");
    }
1346945
static void demo(PersistenceManager persistenceManager)
    {

        try {
            // Fetch an account.  Notice that the id is now a long rather than an integer.
            Account account = persistenceManager.findById(Account.class, 1L);
            assert account != null;
            assert account.getAccountId() == 1L;

            // The Account Name is a new field and is now persistable.
            // This demonstrates that we can now take
            // advantage of the new field.
            account.setAccountName("Utility Bill");
            persistenceManager.saveEntity(account);

            // Verify it was indeed persisted
            account = persistenceManager.findById(Account.class, 1L);
            assert account != null;
            assert account.getAccountName().equals("Utility Bill");

            // Notice, the one thing that we cannot demonstrate is that we removed a field, "balanceDue"
            // Don't worry, we can add it back and the data will still be there since it has not been orphaned.
        } catch (OnyxException e)
        {
            e.printStackTrace();
            assert false;
        }
    }
59830
public static void main(String... args) {
    // Step 1. Enable OpenCensus Metrics.
    try {
      setupOpenCensusAndPrometheusExporter();
    } catch (IOException e) {
      System.err.println("Failed to create and register OpenCensus Prometheus Stats exporter " + e);
      return;
    }

    BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));

    while (true) {
      try {
        readEvaluateProcessLine(stdin);
      } catch (IOException e) {
        System.err.println("EOF bye " + e);
        return;
      } catch (Exception e) {
        recordTaggedStat(KEY_METHOD, "repl", M_ERRORS, new Long(1));
        return;
      }
    }
  }
470816
public static void main(String[] args) throws Exception {
    AlluxioFramework framework = new AlluxioFramework();
    JCommander jc = new JCommander(framework);
    try {
      jc.parse(args);
    } catch (Exception e) {
      System.out.println(e.getMessage());
      jc.usage();
      System.exit(1);
    }
    framework.run();
  }
689981
private void createDestinationManager() {
        if (TraceComponent.isAnyTracingEnabled()
            && tc.isEntryEnabled())
            SibTr.entry(tc, "createDestinationManager");

        _destinationManager = new DestinationManager(this, _persistentStore);

        if (TraceComponent.isAnyTracingEnabled()
            && tc.isEntryEnabled())
            SibTr.exit(tc, "createDestinationManager");
    }
1324360
public void main() {

        fMain = new Frame("HSQLDB Database Manager for Zaurus");
        imgEmpty = createImage(new MemoryImageSource(2, 2, new int[4 * 4], 2,
                2));

        fMain.setIconImage(imgEmpty);
        fMain.addWindowListener(this);

        MenuBar bar = new MenuBar();

        // no shortcuts used
        String[] fitems = {
            "-Connect...", "--", "-Open Script...", "-Save Script...",
            "-Save Result...", "--", "-Exit"
        };

        addMenu(bar, "File", fitems);

        String[] vitems = {
            "-Refresh Tree", "--", "-View Tree", "-View Command",
            "-View Result", "-View Editor", "--", "-Results in Grid",
            "-Results in Text"
        };

        addMenu(bar, "View", vitems);

        String[] sitems = {
            "-SELECT", "-INSERT", "-UPDATE", "-DELETE", "--", "-CREATE TABLE",
            "-DROP TABLE", "-CREATE INDEX", "-DROP INDEX", "--", "-SCRIPT",
            "-SHUTDOWN", "--", "-Test Script"
        };

        addMenu(bar, "SQL", sitems);

        Menu recent = new Menu("Recent");

        mRecent = new Menu("Recent");

        bar.add(mRecent);

        String[] soptions = {
            "-AutoCommit on", "-AutoCommit off", "-Commit", "-Rollback", "--",
            "-Disable MaxRows", "-Set MaxRows to 100", "--", "-Logging on",
            "-Logging off", "--",
            "-Insert test data"    // , "-Transfer"
        };

        addMenu(bar, "Options", soptions);

        String[] shelp = { "-Show HTML-Help in browser" };

        addMenu(bar, "?", shelp);
        fMain.setMenuBar(bar);
        fMain.setSize(defWidth, defHeight);
        fMain.add("Center", this);
        initGUI();

        sRecent = new String[iMaxRecent];

        Dimension d    = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension size = fMain.getSize();

        // (ulrivo): arguments from command line or
        // full size on screen with less than 640 width
        if (d.width > 640) {
            fMain.setLocation((d.width - size.width) / 2,
                              (d.height - size.height) / 2);
        } else if (defWidth > 0 && defHeight > 0) {
            fMain.setLocation(defLocX, defLocY);
            fMain.setSize(defWidth, defHeight);
        } else {
            fMain.setLocation(0, 0);
            fMain.setSize(d);
        }

        fMain.show();

        // (ulrivo): load query from command line
        if (defQuery != null) {
            txtCommand.setText(DatabaseManagerCommon.readFile(defQuery));
        }

        txtCommand.requestFocus();
    }
1256695
protected final void requestCheckpoint(boolean persistent)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "requestCheckpoint",
                        new Object[] { new Boolean(persistent) });

        // During restart checkpointHelper is not running so don't request a checkpoint.
        // A checkpoint is forced at startup once it is safe to do so.
        if (checkpointHelper != null)
            checkpointHelper.requestCheckpoint(persistent);

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "requestCheckpoint");
    }
483313
public PersistenceManager getPersistenceManager() {
        if (persistenceManager == null) {
            try {
                persistenceManager = getPresentationManager().newPersistenceManager();
            } catch (Exception ex) {
                getPresentationManager().error(ex);
                throw new ConnectionNotFoundException();
            }
        }
        return persistenceManager;
    }
1280452
public static void main(String[] args) {
        JmxDemo demo=new JmxDemo();
        demo.addNotificationListener((notification, handback) -> System.out.println(">> " + notification + ", handback=" + handback), null, "myHandback");
        demo.startNotifications();

        MBeanServer server=Util.getMBeanServer();
        if(server != null) {
            try {
                JmxConfigurator.register(demo, server, "demo:name=DemoObject");
                while(true) {
                    Util.sleep(10000);
                }
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
1124465
private static void closeDB(PersistenceManager pm) {
        if (pm.currentTransaction().isActive()) {
            pm.currentTransaction().rollback();
        }
        pm.close();
        pm.getPersistenceManagerFactory().close();
    }
894301
protected void start() {
        final EventManager eventManager = BeanManager.getInstance().getReference(EventManager.class);
        for (final AbstractEventListener<?> eventListener : eventListeners) {
            eventManager.registerListener(eventListener);
        }
    }
671684
public static void main(String[] args) throws Exception {
		try (Split ignored = SimonManager.getStopwatch("org.javasimon.examples.jmx.main").start()) {
			Class.forName("org.h2.Driver");
			Class.forName("org.javasimon.jdbc4.Driver");

			MonitoredApplication s = new MonitoredApplication();
			s.setUp();

			Connection conn = null;
			try {
				conn = DriverManager.getConnection("jdbc:simon:h2:mem:db1");

				//noinspection UnusedDeclaration
				try (Split ops = SimonManager.getStopwatch("org.javasimon.examples.jmx.sql").start()) {
					s.doInsert(conn);
					s.doSelect(conn);
				}
			} finally {
				if (conn != null) {
					conn.close();
				}
			}
		}

		System.out.println("Simon monitor hierarchy:\n" + SimonUtils.simonTreeString(SimonManager.getRootSimon()));

		register();
		waitForEnterPressed();
		unregister();
	}
1223368
public void performRecovery(ObjectManagerState objectManagerState)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass
                        , "performRecovery"
                        , " objectManager=" + objectManagerState + "(ObjectManagerState)"
                          + ")"
                            );

        objectManagerState.checkpointEndSeen = true;

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass
                       , "performRecovery"
                            );
    }
17569
protected final void shutdown()
                    throws ObjectManagerException
    {
        final String methodName = "shutdown";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName);

        Exception exceptionCaughtDuringShutdown = null;

        synchronized (this) {
            // Make the state change.
            setState(ObjectManagerState.nextStateForStartShutdown);
        } // synchronized (this).

        // Block the creation of new transactions.
        currentMaximumActiveTransactions = 0; // Don't start any new transactions.

        // Defect 496893
        // Call our event callbacks at this point as we are no 
        // longer open for business.
        synchronized (this)
        {
            if (callbacks != null)
            {
                java.util.Iterator it = callbacks.iterator();
                while (it.hasNext())
                {
                    ObjectManagerEventCallback callback = (ObjectManagerEventCallback) it.next();

                    callback.notification(ObjectManagerEventCallback.objectManagerStopped, null);
                }
            }
        }

        // Back out all transactions that are not in prepared state.
        if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled())
            trace.debug(this,
                        cclass,
                        methodName,
                        "Backout remaining unprepared transactions:1231");

        // Count the number of transactions in each state.
        int[] transactionsPerState = new int[InternalTransaction.stateNames.length];
        try {
            for (java.util.Iterator registeredTransactionIterator = registeredInternalTransactions.values().iterator(); registeredTransactionIterator.hasNext();) {
                InternalTransaction registeredTransaction = (InternalTransaction) registeredTransactionIterator.next();
                synchronized (registeredTransaction) {
                    if (registeredTransaction.state == Transaction.stateInactive
                        || registeredTransaction.state == Transaction.stateActiveNonPersistent
                        || registeredTransaction.state == Transaction.stateActivePersistent) {

                        // Check that the transaction did not commit or backout before we synchronized on it.
                        if (registeredInternalTransactions.get(new Long(registeredTransaction.getLogicalUnitOfWork().identifier)) == registeredTransaction) {
                            // Use getExternalTransaction because we need to ensure that any application will have its external
                            // Transaction terminated.
                            Transaction transaction = registeredTransaction.getExternalTransaction();
                            transaction.setTerminationReason(Transaction.terminatedShutdown);
                            transaction.backout(false); // Do not reuse this transaction.
                        } //  if ( registeredInternalTransactions...
                    } // if (   registeredTransaction.state...

                    transactionsPerState[registeredTransaction.state]++;
                } // synchronized (registeredTransaction).
            } // for registeredInternalTransactions.
        } catch (Exception exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                methodName,
                                                exception,
                                                "1:1263:1.62");
            exceptionCaughtDuringShutdown = exception;
        } // try.

        if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled()) {
            Object[] objects = new Object[transactionsPerState.length];
            for (int i = 0; i < transactionsPerState.length; i++)
                objects[i] = InternalTransaction.stateNames[i] + "=" + Integer.toString(transactionsPerState[i]);
            trace.debug(this, cclass, methodName, "Transactions in each state:1271");
            trace.debug(this, cclass, methodName, objects);
        } // if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled()).

        synchronized (this) {
            // Make the state change.
            setState(ObjectManagerState.nextStateForShutdown);
        } // synchronized (this).

        try {
            // Take a checkpoint. ObjectStores with STRATEGY_SAVE_ONLY_ON_SHUTDOWN can now safely
            // update their data.
            if (checkpointHelper != null) {
                checkpointHelper.waitForCheckpoint(true);
                checkpointHelper.shutdown(); // Terminate the checkpoint thread.
                checkpointHelper = null;
            } // if (checkpointHelper != null).
        } catch (Exception exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                methodName,
                                                exception,
                                                "1:1294:1.62");
            exceptionCaughtDuringShutdown = exception;
        } // try.

        // Set all active transactions to a state that wont allow any more actions.
        // We cannot do this before the checkpoint as this sets the InternalTransactions
        // into stateTerminated and excludes them from the checkpoint. As a consequence
        // applications might get data into the log after the last checkpoint has started.
        try {
            for (java.util.Iterator transactionIterator = registeredInternalTransactions.values().iterator(); transactionIterator.hasNext();) {
                InternalTransaction internalTransaction = (InternalTransaction) transactionIterator.next();
                internalTransaction.shutdown();
            } // for... registeredInternalTransactions.
        } catch (Exception exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                methodName,
                                                exception,
                                                "1:1315:1.62");
            exceptionCaughtDuringShutdown = exception;
        } // try.

        //    if (reportStatistics) { // Stop monitoring statistics.
        //      if (statisticsHelper != null)
        //        statisticsHelper.shutdown();
        //      statisticsHelper = null;
        //    } // if (reportStatistics)

        // Close all of the ObjecStores.
        synchronized (objectStores) {
            java.util.Iterator objectStoreIterator = objectStores.values().iterator();
            while (objectStoreIterator.hasNext()) {
                try {
                    ObjectStore objectStore = (ObjectStore) objectStoreIterator.next();
                    objectStore.close();
                } catch (Exception exception) {
                    // No FFDC Code Needed.
                    ObjectManager.ffdc.processException(this, cclass, methodName, exception, "1:1334:1.62");
                    exceptionCaughtDuringShutdown = exception;
                } // try.
            } // While objectStoreIterator.hasNext().
        } // synchronized (objectStores).

        // Close the logger.
        try {
            if (logOutput != null) {
                logOutput.close();
                logOutput = null;
            } // if (logOutput != null).
        } catch (Exception exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                methodName,
                                                exception,
                                                "1:1352:1.62");
            exceptionCaughtDuringShutdown = exception;
        } // try.

        // Close the log file and realease the lock on it.
        try {
            if (logLock != null)
                logLock.release();
            if (logFile != null)
                logFile.close();
        } catch (java.io.IOException exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                methodName,
                                                exception,
                                                "1:1368:1.62");

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           methodName,
                           "via PermanentIOException");
            throw new PermanentIOException(this,
                                           exception);
        } // catch (java.io.IOException exception).

        synchronized (ObjectManager.objectManagerStates) {
            ObjectManager.objectManagerStates.remove(logFileName);
        } // synchronized (ObjectManager.objectManagerStates).

        // Help garbage collection.
        registeredInternalTransactions.clear();
        registeredInternalTransactions = null;

        // Let any waiters know we are closed for business.
        synchronized (this) {
            notifyAll();
        }

        trace.debug(cclass, methodName, "ObjectManager using logFile " + logFileName + " has shut down.");

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       methodName
                       , new Object[] { exceptionCaughtDuringShutdown });
        if (exceptionCaughtDuringShutdown != null)
            throw new UnexpectedExceptionException(this,
                                                   exceptionCaughtDuringShutdown);
    } // shutdown().

    /**
     * A non blocking request to shutdown the ObjectManager.
     * Used by helper threads when they encounter a fatal error.
     */
    protected void requestShutdown()
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "shutdown");

        new ShutdownHelper();

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "requestShutdown");
    } // requestShutdown().

    /**
     * Terminates the ObjectManagerState, without taking a checkpoint.
     * The allows the ObjectManager to be restarted as if it had crashed.
     * Used for testing emergency restart and also for performing an emergency shutdown
     * if a fatal error has been detected.
     * This form of shutdown continues even if it encounters errors.
     * 
     * @throws ObjectManagerException
     */
    protected final void shutdownFast()
                    throws ObjectManagerException
    {
        final String methodName = "shutdownFast";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        methodName);

        Exception exceptionCaughtDuringShutdown = null;

        if (!inShutdown())
        {
            synchronized (this) {
                // Make the state change.
                setState(ObjectManagerState.nextStateForStartShutdown);
            } // synchronized (this).

            // Defect 496893
            // Call our event callbacks at this point as we are no 
            // longer open for business.
            notifyCallbacks(ObjectManagerEventCallback.objectManagerStopped, null);

            // Terminate the checkpoint thread.
            try {
                if (checkpointHelper != null) {
                    checkpointHelper.shutdown();
                    checkpointHelper = null;
                } // if (checkpointHelper != null).
            } catch (Exception exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    methodName,
                                                    exception,
                                                    "1:1470:1.62");
                exceptionCaughtDuringShutdown = exception;
            } // try.

            // Now that the CheckpointHelper has stopped we can move to stopped state
            // knowing that the ObjectStores will not be flushed while we are in stopped state. 

            synchronized (this) {
                // Make the state change.
                setState(ObjectManagerState.nextStateForShutdown);
            } // synchronized (this).

            // Close all of the ObjecStores.
            synchronized (objectStores) {
                java.util.Iterator objectStoreIterator = objectStores.values().iterator();
                while (objectStoreIterator.hasNext()) {
                    try {
                        ObjectStore objectStore = (ObjectStore) objectStoreIterator.next();
                        objectStore.close();
                    } catch (Exception exception) {
                        // No FFDC Code Needed.
                        ObjectManager.ffdc.processException(this, cclass, methodName, exception, "1:1491:1.62");
                        exceptionCaughtDuringShutdown = exception;
                    } // try.
                } // while objectStoreIterator.hasNext().
            } // synchronized (objectStores).

            // Close the logger.
            try {
                if (logOutput != null) {
                    logOutput.close();
                    logOutput = null;
                } // if (logOutput != null).
            } catch (Exception exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    methodName,
                                                    exception,
                                                    "1:1509:1.62");
                exceptionCaughtDuringShutdown = exception;
            } // try.

            try {
                if (logLock != null)
                    logLock.release();
                if (logFile != null)
                    logFile.close();
            } catch (java.io.IOException exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    methodName,
                                                    exception,
                                                    "1:1524:1.62");

                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               methodName,
                               "PermanentIOException:1530");
                throw new PermanentIOException(this,
                                               exception);
            } // catch (java.io.IOException exception).

            synchronized (ObjectManager.objectManagerStates) {
                ObjectManager.objectManagerStates.remove(logFileName);
            } // synchronized (ObjectManager.objectManagerStates).

            // Let any waiters know we are ready for business.
            synchronized (this) {
                notifyAll();
            }
        }// end of if(!inshutdown)

        trace.debug(cclass, methodName, "ObjectManager using logFile " + logFileName + " has shut down without performing a final checkpoint");

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       methodName,
                       new Object[] { exceptionCaughtDuringShutdown });
        if (exceptionCaughtDuringShutdown != null)
            throw new UnexpectedExceptionException(this,
                                                   exceptionCaughtDuringShutdown);
    } // shutdownFast().

    /**
     * Recognise the existence of an ObjectStore used by this ObjectManager.
     * It is possible to move an objectStore to another ObjectManager and to change its
     * name. To move or rename an ObjectStore deRegister it then Create a new ObjectStore
     * with the same file moved to its new location, or with a different ObjectManager.
     * This will work so long as the ObjectStore identifier is not in use in the
     * new ObjectManager. Be aware that if the store is added to another ObjectManager
     * which had previously used the ObjectStore identifier there may be phantom
     * references to the Objects in the moved store. Also there may be objects in
     * the moved store which are unreachable because they are referenced by objects
     * in the old ObjectManager.
     * 
     * @param objectStore to be registered with this ObjectManager. The name must be currently unknown in the
     *            ObjectManager.
     * @throws ObjectManagerException, with no change made.
     */
    protected void registerObjectStore(ObjectStore objectStore)
                    throws ObjectManagerException {
        final String methodName = "registerObjectStore";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        methodName,
                        new Object[] { objectStore });

        synchronized (objectStores) {

            ObjectStore existingObjectStore = getObjectStoreByName(objectStore.getName());
            if (existingObjectStore != null) {
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               methodName,
                               new Object[] { "DuplicateObjectStoreNameException:1594",
                                             objectStore.getName() });
                throw new DuplicateObjectStoreNameException(this,
                                                            objectStore.getName(),
                                                            existingObjectStore);
            } // if (existingObjectStore != null).

            objectStore.open(this); // Now ready for use.

            // If this a new ObjectStore, as opposed to one that has been recovered from a serialized version
            // in a checkpoint or from a file, then set its identifier.
            if (objectStore.getIdentifier() == ObjectStore.IDENTIFIER_NOT_SET) {
                // Allocate a new Identifier for the Object Store, which we know is unique.
                maximumObjectStoreIdentifier++;
                objectStore.setIdentifier((int) maximumObjectStoreIdentifier);
            } else {

                // The identifier is already set. Presumably because this is an old store being added to the
                // ObjectManager again. Check that its identifier is not already in use and move the
                // maximumObjectStoreIdentifier past this one.
                existingObjectStore = (ObjectStore) objectStores.get(new Integer(objectStore.getIdentifier()));
                if (existingObjectStore != null) {
                    objectStore.close();
                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this,
                                   cclass,
                                   methodName,
                                   new Object[] { "DuplicateObjectStoreNameException:1621",
                                                 objectStore.getName() });
                    throw new DuplicateObjectStoreIdentifierException(this,
                                                                      objectStore.getName(),
                                                                      objectStore.getIdentifier(),
                                                                      existingObjectStore);

                } // if duplicate identifier.
                maximumObjectStoreIdentifier = Math.max(maximumObjectStoreIdentifier, objectStore.getIdentifier());
            } // if (objectStore.getIdentifier() == ObjectStore.IDENTIFIER_NOT_SET).

            Transaction transaction = getTransaction();
            transaction.lock(this);

            // We are about to change the ObjectManagerState so we will need to compensate for any failure
            // if we fail before we commit the transaction. We don't worry abut the mamximumObjectStoreIdentfier
            // because it has been allocated to the store and could legitimately be used by it if the registration
            // is retried later but before the ObjectManager shuts down.
            try {
                objectStores.put(new Integer(objectStore.getIdentifier()),
                                 objectStore);
                // We may have previously added ObjectManagerState and we set ourselves to state ready at construction time
                // so we replace, rather than add.
                transaction.replace(this);

                // We can now use the ObjectStore, we can also use it during recovery because the replace operation
                // will have made it available again.

                // It the ObjectStore holds restart data,
                // create or reset the namedObjects map.
                Token namedObjectsToken = null;
                if (objectStore.getContainsRestartData()) {
                    TreeMap namedObjectsTree = getNamedObjects(objectStore, transaction);
                    namedObjectsToken = namedObjectsTree.getToken();
                    if (namedObjects != null) {
                        // Sync up what we found with what we have.
                        namedObjectsTree.clear(transaction);
                        namedObjectsTree.putAll((TreeMap) namedObjects.getManagedObject(), transaction);
                    } // if (namedObjects != null).

                } // if (objectStore.getContainsRestartData()).

                // Also save backup copies of ObjectManagerstate.
                saveClonedState(transaction);
                // Adjust the size of the space reserved for a CheckpointStartLogRecord. If this fails
                // the reference to the transaction will be found by the garbage collector and backed out.
                long newCheckpointStartLogRecordSize = ((new CheckpointStartLogRecord(this)).getBytesLeft() / FileLogOutput.pageSize + 1) * FileLogOutput.pageSize;
                logOutput.reserve(newCheckpointStartLogRecordSize - checkpointStartLogRecordSize);
                checkpointStartLogRecordSize = newCheckpointStartLogRecordSize;

                transaction.commit(false);

                // Now all the updates have been done make any new namedObjects visible.
                if (namedObjects == null)
                    namedObjects = namedObjectsToken;

            } catch (ObjectManagerException exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    methodName,
                                                    exception,
                                                    "1:1683:1.62");
                objectStores.remove(new Integer(objectStore.getIdentifier()));
                transaction.backout(false);

                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this, cclass, methodName, new Object[] { exception });
                throw exception;
            } // try...

        } // synchronized (objectStores).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       methodName);
    } // registerObjectStore().

    /**
     * Recognise an ObjectStore by a new logical name at the next start of the ObjectManager.
     * 
     * @param objectStore to be renamed.
     * @param newName of the store.
     * @throws ObjectManagerException
     */
    protected void renameObjectStore(ObjectStore objectStore, String newName)
                    throws ObjectManagerException {
        final String methodName = "renameObjectStore";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        methodName,
                        new Object[] { objectStore, newName });

        synchronized (objectStores) {
            // Is this store registered, if not there is nothing to do?
            ObjectStore existingObjectStore = getObjectStoreByName(objectStore.getName());
            if (existingObjectStore == null) {
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               methodName,
                               new Object[] { "Store not registered:1724" });
                return;
            }

            // Is the newName currently in use?
            existingObjectStore = getObjectStoreByName(newName);
            if (existingObjectStore != null) {
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               methodName,
                               new Object[] { "DuplicateObjectStoreNameException:1735",
                                             newName,
                                             objectStore.getName() });
                throw new DuplicateObjectStoreNameException(this,
                                                            newName,
                                                            existingObjectStore);
            } // if (existingObjectStore != null).

            Transaction transaction = getTransaction();
            transaction.lock(this);

            String oldName = objectStore.getName();
            // We are about to change the ObjectManagerState so we will need to compensate for any failure
            // if we fail before we commit the transaction. We don't worry abut the mamximumObjectStoreIdentfier
            // because it has been allocated to the store and could legitimately be used by it if the registration
            // is retried later but before the ObjectManager shuts down.
            try {
                objectStore.setLogicalName(newName);
                // We may have previously added ObjectManagerState and we set ourselves to state ready at construction time
                // so we replace, rather than add.
                transaction.replace(this);

                // Also save backup copies of ObjectManagerstate.
                saveClonedState(transaction);
                // Adjust the size of the space reserved for a CheckpointStartLogRecord. If this fails
                // the reference to the transaction will be found by the garbage collector and backed out.
                long newCheckpointStartLogRecordSize = ((new CheckpointStartLogRecord(this)).getBytesLeft() / FileLogOutput.pageSize + 1) * FileLogOutput.pageSize;
                logOutput.reserve(newCheckpointStartLogRecordSize - checkpointStartLogRecordSize);
                checkpointStartLogRecordSize = newCheckpointStartLogRecordSize;

                transaction.commit(false);

            } catch (ObjectManagerException exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    methodName,
                                                    exception,
                                                    "1:1773:1.62");
                if (objectStore instanceof AbstractObjectStore)
                    ((AbstractObjectStore) objectStore).storeName = oldName;
                transaction.backout(false);

                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this, cclass, methodName, new Object[] { exception });
                throw exception;
            } // try...
        } // synchronized (objectStores).

        // Force a full checkpoint so that the caller can be sure that the log will start from
        // a checkpoint containing the new name.
        waitForCheckpoint(true);

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       methodName);
    } // renameObjectStore().

    /**
     * Locate the namedObjects tree in an Object Store and create it if necessary.
     * 
     * @param objectStore which should contain the namedObjects tree.
     * @param transaction controlling any creation.
     * @return TreeMap the NamedObjects.
     * @throws ObjectManagerException
     */
    private final TreeMap getNamedObjects(ObjectStore objectStore,
                                          Transaction transaction)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getNamedObjects",
                        new Object[] { objectStore, transaction });

        //  Locate any existing copy.
        Token namedObjectsToken = new Token(objectStore,
                                            ObjectStore.namedObjectTreeIdentifier.longValue());
        // Swap for the definitive Token, if there is one.
        namedObjectsToken = objectStore.like(namedObjectsToken);
        TreeMap namedObjectsTree = (TreeMap) namedObjectsToken.getManagedObject();

        // First time through make a TreeMap.
        if (namedObjectsTree == null) {
            namedObjectsTree = new TreeMap();
            namedObjectsToken.setManagedObject(namedObjectsTree);
            namedObjectsTree.reserveAndAdd(transaction, objectStore);
        } // if (namedObjectsTree == null).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getNamedObjects",
                       new Object[] { namedObjectsTree });
        return namedObjectsTree;
    } // getNamedObjects().

    /**
     * Cease to recognise the existence of an ObjectStore used by this ObjectManager.
     * 
     * @param objectStore to be deRegistered from this ObjectManager.
     *            The name must be currently known in the ObjectManager.
     * @throws ObjectManagerException
     */
    protected final void deRegisterObjectStore(ObjectStore objectStore)
                    throws ObjectManagerException {
        final String methodName = "deRegisterObjectStore";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, new Object[] { objectStore });

        // Flush out as much data from the store as we can. If there are any in flight
        // transactions their updates will not get applied to the store after now.
        waitForCheckpoint(objectStore.getPersistence());

        synchronized (objectStores) {
            Transaction transaction = getTransaction();
            transaction.lock(this);

            // See if the ObjectStore contains the nameObjects Tree before we close it
            // and destroy the namedObjects ManagedObject.
            if (namedObjects != null) {
                if (namedObjects.getObjectStore() == objectStore) {
                    namedObjects = null;
                } // if (namedObjects.getObjectStore()...
            } // if (namedObjects != null).

            objectStore.close();
            objectStores.remove(new Integer(objectStore.getIdentifier()));

            transaction.replace(this);

            saveClonedState(transaction);

            // Adjust the size of the space reserved for a CheckpointStartLogRecord. If this fails
            // the reference to the transaction will be found by the garbage collector and backed out.
            long newCheckpointStartLogRecordSize = ((new CheckpointStartLogRecord(this)).getBytesLeft() / FileLogOutput.pageSize + 1) * FileLogOutput.pageSize;
            logOutput.reserve(newCheckpointStartLogRecordSize - checkpointStartLogRecordSize);
            checkpointStartLogRecordSize = newCheckpointStartLogRecordSize;
            transaction.commit(false);

            // Look for a new definitive copy of the namedObjects Tree, if necessary.
            setDefinitiveNamedObjects();
        } // synchronized (objectStores).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    } // deRegisterObjectStore().

    /**
     * Establish the definitive namedObjects tree in namedObjects, if not already set.
     * Caller must be synchronised on objectStores.
     */
    private void setDefinitiveNamedObjects()
    {
        for (java.util.Iterator objectStoreIterator = objectStores.values().iterator(); objectStoreIterator.hasNext() && namedObjects == null;) {
            ObjectStore objectStore = (ObjectStore) objectStoreIterator.next();

            if (objectStore.getContainsRestartData()) {
                // Locate any existing copy.
                Token namedObjectsToken = new Token(objectStore,
                                                    ObjectStore.namedObjectTreeIdentifier.longValue());
                // Swap for the definitive Token, if there is one.
                namedObjects = objectStore.like(namedObjectsToken);
            } // if (objectStore.getContainsRestartData()).
        } // for ( ObjectStores...
    } // setDefinitiveNamedObjects().

    /**
     * Locate an ObjectStore used by this objectManager.
     * 
     * @param objectStoreIdentifier The unique identifier for the ObjectStore.
     * @return ObjectStore found matching the identifier.
     * @throws ObjectManagerException
     */
    protected ObjectStore getObjectStore(int objectStoreIdentifier)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getObjectStore",
                        new Integer(objectStoreIdentifier));

        ObjectStore objectStore = null; // ObjectStore to return.
        if (objectStoreIdentifier == defaultObjectStoreIdentifier)
            objectStore = defaultObjectStore;
        else {
            synchronized (objectStores) {
                objectStore = (ObjectStore) objectStores.get(new Integer(objectStoreIdentifier));
                if (objectStore == null) {
                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this,
                                   cclass,
                                   "getOjectStore",
                                   "via NonEexistantObjectStoreException"
                                                   + " objectStoreIdentifier="
                                                   + objectStoreIdentifier
                                                   + "(int)");
                    throw new NonExistentObjectStoreException(this,
                                                              objectStoreIdentifier);
                } // if(objectStore == null).
            } // synchronized (objectStores).
        } // if (objectStoreIdentifier == defaultObjectStoreIdentifier).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getObjectStore",
                       objectStore);
        return objectStore;
    } // getObjectStore().

    /**
     * Locate an ObjectStore used by this objectManager.
     * 
     * @param objectStoreName which is the name of the ObjectStore.
     * @return ObjectStore found matching the identifier.
     * @throws ObjectManagerException
     */
    protected final ObjectStore getObjectStore(String objectStoreName)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getObjectStore",
                        "objectStoreName=" + objectStoreName + "(String)");

        ObjectStore objectStore = null; // ObjectStore to return.
        synchronized (objectStores) {
            objectStore = getObjectStoreByName(objectStoreName);
        } // synchronized (objectStores).

        if (objectStore == null) {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "getObjectStore",
                           "via UnknownObjectStoreException" + " objectStoreName=" + objectStoreName + "(String)");
            throw new UnknownObjectStoreException(this,
                                                  objectStoreName);
        } // if(objectStore == null).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getObjectStore",
                       "returns objectStore=" + objectStore + "(ObjectStore)");
        return objectStore;
    } // End of method getObjectStore.

    /**
     * Locate an ObjectStore used by this objectManager by comparing its name.
     * The caller must already be synchronized on objectManagerstate.objectStores.
     * 
     * @param objectStoreName which is the name of the ObjectStore.
     * @return ObjectStore found matching the identifier or null if there is none.
     * @throws ObjectManagerException
     */
    private final ObjectStore getObjectStoreByName(String objectStoreName)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getObjectStoreByName",
                        new String(objectStoreName));

        ObjectStore objectStore = null; // ObjectStore to return.
        // Look for an existing ObjectStore of the same name.
        // We dont keep an index by name as this is only used infrequently and there
        // usually are only a few ObjectStores.
        java.util.Iterator objectStoreIterator = objectStores.values()
                        .iterator();
        while (objectStoreIterator.hasNext() && objectStore == null) {
            ObjectStore existingObjectStore = (ObjectStore) objectStoreIterator.next();
            if (existingObjectStore.getName()
                            .equals(objectStoreName)) {
                objectStore = existingObjectStore;
            } // if (existingObjectStore.getName...
        } // While objectStoreIterator.hasNext().

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getObjectStoreByName",
                       "returns objectStore=" + objectStore + "(ObjectStore)");
        return objectStore;
    } // End of method getObjectStoreByName.

    /**
     * Create an iterator over all ObjectStores known to this ObjectManager.
     * 
     * @return java.util.Iterator over ObjectStores.
     * @throws ObjectManagerException
     */
    final java.util.Iterator getObjectStoreIterator()
                    throws ObjectManagerException {
        final String methodName = "getObjectStoreIterator";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName);

        // make a copy of the objecStores map because the caller cannot synchronise on it.
        java.util.ArrayList storesList = new java.util.ArrayList(objectStores.values());
        java.util.Iterator objectStoreIterator = storesList.iterator();

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName, objectStoreIterator);
        return objectStoreIterator;
    } // getObjectStoreIterator().

    /**
     * Factory method to create or reuse a transaction for use with the ObjectManager.
     * 
     * To detect orphaned transactions, ie. transactions not referenced elsewhere in the JVM. we will keep a reference to
     * the internalTransaction and make a weak reference to the container we pass to the application. When the container
     * Transaction appears on the orphanTransactionsQueue we know the calling application has lost all references to it.
     * At this point we can attempt to reuse it.
     * 
     * @return Transaction the new transaction.
     * @throws ObjectManagerException
     */
    protected final Transaction getTransaction()
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getTransaction");

        InternalTransaction internalTransaction = (InternalTransaction) freeTransactions.removeOne();

        if (internalTransaction != null) {
            registerTransaction(internalTransaction);
            if (gatherStatistics)
                reusedTransactions++;

        } else {
            // We need to make a new InternalTransaction.
            synchronized (registeredInternalTransactions) {
                if (totalTransactions >= maximumActiveTransactions) {
                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this,
                                   cclass,
                                   "getTransaction",
                                   new Object[] { new Long(totalTransactions),
                                                 new Long(maximumActiveTransactions) });
                    throw new TooManyTransactionsException(this,
                                                           maximumActiveTransactions);
                } // if (totalTransactions >= maximumActiveTransactions)

                if (totalTransactions >= currentMaximumActiveTransactions) {
                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this,
                                   cclass,
                                   "getTransaction",
                                   new Object[] { new Long(totalTransactions),
                                                 new Long(currentMaximumActiveTransactions) });
                    throw new TransactionCapacityExceededException(this,
                                                                   totalTransactions,
                                                                   currentMaximumActiveTransactions);
                } // if (totalTransactions >= currentMaximumActiveTransactions)

                // Make a new transaction.
                internalTransaction = new InternalTransaction(this,
                                                              new LogicalUnitOfWork(++maximumLogicalUnitOfWorkIdentifier));
                totalTransactions++;
            } // synchronized (registeredInternalTransactions).
        } // if (internalTransaction != null).

        Transaction transaction = internalTransaction.getExternalTransaction();

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getTransaction",
                       transaction);
        return transaction;
    } // getTransaction().

    /**
     * Recognise the existance of a transaction involving this objectManager.
     * 
     * @param internalTransaction to be registered.
     * @throws ObjectManagerException
     */
    protected final void registerTransaction(InternalTransaction internalTransaction)
                    throws ObjectManagerException {
        final String methodName = "registerTransaction";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, internalTransaction);

        LogicalUnitOfWork logicalUnitOfWork = internalTransaction.getLogicalUnitOfWork();
        InternalTransaction registeredTransaction = (InternalTransaction) registeredInternalTransactions.put(new Long(logicalUnitOfWork.identifier),
                                                                                                             internalTransaction);
        if (registeredTransaction != null) {
            // Make the duplicate transaction useless.
            registeredTransaction.terminate(Transaction.terminatedDuplicate);
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this, cclass, methodName, new Object[] { internalTransaction,
                                                                   registeredTransaction });
            throw new DuplicateTransactionException(this, internalTransaction, registeredTransaction);
        } // if(registeredTransaction != null).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    } // registerTransaction().

    /**
     * Cease to recognise the existance of an InternalTransaction involving this objectManager. Hold it ready for reuse.
     * 
     * @param internalTransaction to be deregistered.
     * @throws ObjectManagerException
     */
    protected final void deRegisterTransaction(InternalTransaction internalTransaction)
                    throws ObjectManagerException
    {
        final String methodName = "deRegisterTransaction";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        methodName,
                        new Object[] { internalTransaction });

        LogicalUnitOfWork logicalUnitOfWork = internalTransaction.getLogicalUnitOfWork();
        InternalTransaction registeredTransaction = (InternalTransaction) registeredInternalTransactions.remove(new Long(logicalUnitOfWork.identifier));

        if (registeredTransaction == null) {
            // Make the duplicate transaction useless.
            internalTransaction.terminate(Transaction.terminatedDuplicate);
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           methodName,
                           new Object[] { "via NonExistantTransactionException", logicalUnitOfWork });
            throw new NonExistentTransactionException(this,
                                                      internalTransaction);
        } // if(registeredTransaction == null).

        // Make the InternalTransaction available for reuse.
        InternalTransaction freeTransaction = (InternalTransaction) freeTransactions.put(new Long(logicalUnitOfWork.identifier),
                                                                                         internalTransaction);
        if (freeTransaction != null) {
            // Make the duplicate transaction useless.
            internalTransaction.terminate(Transaction.terminatedDuplicate);
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           methodName,
                           new Object[] { internalTransaction, freeTransaction }
                                );
            throw new DuplicateTransactionException(this,
                                                    internalTransaction,
                                                    freeTransaction);
        } // if(freeTransaction != null).
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       methodName);
    } // deRegisterTransaction().

    /**
     * Notifies the ObjectManagerState that a transaction has completed all its activity
     * for one LogicalUnitOfWork. Here we decide whether or not to trigger a checkpoint.
     * 
     * @param internalTransaction which completed its work.
     * @param persistentWorkDone true is any persistent work was done.
     * @throws ObjectManagerException
     */
    protected final void transactionCompleted(InternalTransaction internalTransaction,
                                              boolean persistentWorkDone)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "transactionCompleted",
                        new Object[] { internalTransaction, new Boolean(persistentWorkDone) });

        // Bump count of transactions.
        if (persistentWorkDone) {
            persistentTransactionsSinceLastCheckpoint++;
            // has the threshold been breached
            if (persistentTransactionsSinceLastCheckpoint > persistentTransactionsPerCheckpoint) {
                suggestCheckpoint(true);
            }
        }
        else {
            nonPersistentTransactionsSinceLastCheckpoint++;
            // has the threshold been breached 
            if (nonPersistentTransactionsSinceLastCheckpoint > nonPersistentTransactionsPerCheckpoint) {
                suggestCheckpoint(false);
            }
        } // if (persistentWorkDone)

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "transactionCompleted");
    } // transactionCompleted().

    /**
     * Delays return if we need to delay the allocation of new transactions while the checkpoint
     * helper catches up.
     * 
     * @throws ObjectManagerException
     */
    protected final void transactionPacing()
                    throws ObjectManagerException
    {
        final String methodName = "transactionPacing";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        methodName);

        // Make sure logOutput exists because during shutdown we set it to null.
        LogOutput localLogOutput = logOutput;
        if (localLogOutput == null) {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this, cclass, methodName, new Object[] { new Integer(state),
                                                                   stateNames[state] });
            throw new InvalidStateException(this, state, stateNames[state]);
        } // if (localLogOutput == null).

        // If the log is full, introduce a delay to allow checkpoint to run.
        // We assume that if we let the application thread run immediately it would do
        // more persistent work. This approach is better than penalising all threads, including
        // those that do non persistent work when transactions are reused or getTransaction
        // is called, however it does also penalise threads that do no more persistent work.
        // Only block transactions that can wait, ones invoked by the ckeckpointThread would block if we
        // waited for a checkpoint to complete.
        if (localLogOutput.isOcupancyHigh()) {
            if (gatherStatistics)
                transactionsDelayedForLogFull++;

            // Behave like persistent work was done.
            waitForCheckpoint(true);

//      Object lock = new Object();
//      synchronized (lock) {
//        if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled())
//          trace.debug(this,
//                     cclass,
//                     "transactionCompleted",
//                     "About to wait for "+ checkpointDelay + " milliseconds."
//                    );
//        try {
//          // Let some transactions complete.
//          // We need to wait for longer than the time it takes for a checkpoint to complete.
//          lock.wait(checkpointDelay*2);
//        } catch (InterruptedException exception) {
//          // No FFDC Code Needed.
//          ObjectManager.ffdc.processException(this,
//                                cclass,
//                                "transactionCompleted",
//                                exception,
//                                "1:2295:1.62");
//
//          if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
//            trace.exit(this,
//                       cclass,
//                       "transactionCompleted",
//                       exception);
//          throw new UnexpectedExceptionException(this,
//                                                 exception);
//        } // catch (InterruptedException exception).
//      } // synchronized (lock).
        } // if (locaLogOutput.isOcupancyHigh()).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       methodName);
    } // transactionPacing().

    /**
     * Locate a transaction registered with this objectManager. If the transaction does not already exists then create it.
     * If there is a new XID in the LogicalUnitOfWork assign it to the transaction. Only called during recovery so the
     * external Transaction returned is not registered.
     * 
     * @param logicalUnitOfWork identifying the transaction.
     * @return Transaction identified by the LogicalUnitOfWork.
     * @throws ObjectManagerException
     */
    protected final Transaction getTransaction(LogicalUnitOfWork logicalUnitOfWork)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getTransaction",
                        new Object[] { logicalUnitOfWork });

        InternalTransaction internalTransaction = null;
        // Should not be neccesary to synchronize as we are only called during recovery, which is single threaded.
        internalTransaction = (InternalTransaction) registeredInternalTransactions.get(new Long(logicalUnitOfWork.identifier));
        // If we found an InternalTransaction, keep its LogicalUnitOfWork and abandon the one we were given.

        if (internalTransaction == null) {
            // Have a look in the freeTransactions.
            internalTransaction = (InternalTransaction) freeTransactions.remove(new Long(logicalUnitOfWork.identifier));
            if (internalTransaction != null)
                registerTransaction(internalTransaction);
        } // if(internalTransaction == null).

        if (internalTransaction == null) {
            // Make sure we not reuse this logical unit of work identifier again.
            maximumLogicalUnitOfWorkIdentifier = Math.max(logicalUnitOfWork.identifier,
                                                          maximumLogicalUnitOfWorkIdentifier);
            // Create an InternalTransaction to use the LogicaUnitOfWork we were given.
            internalTransaction = new InternalTransaction(this,
                                                          logicalUnitOfWork);

        } else { // pre existing transaction found.
            // See if we have seen the transactions XID for the first time?
            if (logicalUnitOfWork.XID != null && internalTransaction.getXID() == null)
                // No check to see if the XID's are different.
                internalTransaction.setXID(logicalUnitOfWork.XID);
        } // if(internalTransaction == null).

        // Transaction to return.
        Transaction transaction = new Transaction(internalTransaction);
        // Not transaction = getExternalTransaction(), because this is only used internally
        // at restart by logRecords. If we used getExternalTransaction() it would make weak
        // references that would be found by the garbage collector causing it to BackOut
        // the transaction befpore recovery is completed.

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getTransaction",
                       transaction);
        return transaction;
    } // getTransaction().

    /**
     * Locate a transaction registered with this objectManager. with the same XID as the one passed. If a null XID is
     * passed this will return any registered transaction with a null XID.
     * 
     * @param XID Xopen identifier.
     * @return Transaction identified by the XID.
     * @throws ObjectManagerException
     */
    protected final Transaction getTransactionByXID(byte[] XID)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled()) {
            trace.entry(this,
                        cclass,
                        "getTransactionByXID");
            trace.bytes(this,
                        cclass,
                        XID);
        } // if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled()).

        Transaction externalTransaction = null; // Transaction to return.

        // Look at all registeredInternalTransactions.
        for (java.util.Iterator transactionIterator = registeredInternalTransactions.values()
                        .iterator(); transactionIterator.hasNext();) {
            InternalTransaction internalTransaction = (InternalTransaction) transactionIterator.next();
            byte[] transactionXID = internalTransaction.getXID();
            if (java.util.Arrays.equals(transactionXID,
                                        XID)) {
                externalTransaction = internalTransaction.getExternalTransaction();
                break;
            } // if (Arrays.equals(transactionsXID,XID)
        } // for... registeredInternalTransactions.

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getTransactionByXID",
                       "returns externalTransaction=" + externalTransaction + "(Transaction)");
        return externalTransaction;
    } // End of method getTransactionByXID.

    /**
     * Create an iterator over all transactions known to this ObjectManager. The iterator returned is safe against
     * concurrent modification of the set of transactions, new transactions created after the iterator is created may not
     * be covered by the iterator.
     * 
     * @return java.util.Iterator over Transactions.
     * @throws ObjectManagerException
     */
    protected final java.util.Iterator getTransactionIterator()
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getTransactionIterator");

        java.util.Iterator transactionIterator = new TransactionIterator();

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getTransactionIterator",
                       transactionIterator);
        return transactionIterator;
    } // getTransactionIterator().

    /**
     * Find and complete transactions that are no longer addressable. Top up the freeTransactions pool.
     * 
     * @throws ObjectManagerException
     */
    private void completeOrphanTransactions()
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "completeOrphanTransactions");

        // Find a reference that has become unreachable,
        // because the external Transaction that owns it is itself unreachable.
        InternalTransaction.TransactionReference transactionReference = (InternalTransaction.TransactionReference) orphanTransactionsQueue.poll();
        while (transactionReference != null) {
            transactionReference.complete();
            transactionReference = (InternalTransaction.TransactionReference) orphanTransactionsQueue.poll();
        } // while( transactionReference != null).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "completeOrphanTransactions");
    } // completeOrphanTransactions().

    /**
     * Genrates logSequenceNumber for non persistent ManagedObjects that dont write log records.
     * 
     * @return long a logSequenceNumber that is bigger than any returned so far for this run of the ObjectManager.
     * @throws ObjectManagerException
     */
    protected long getDummyLogSequenceNumber()
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getDummyLogSequenceNumber");

        long usableLogSequenceNumber;
        // Take a lock on the log and increment the log sequence number.
        synchronized (dummyLogSequenceNumberLock) {
            dummyLogSequenceNumber++; // Set the current Sequence number.
            usableLogSequenceNumber = dummyLogSequenceNumber;
        } // synchronized (dummyLogSequenceNumberLock).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getDummyLogSequenceNumber",
                       new Long(usableLogSequenceNumber));
        return usableLogSequenceNumber;
    } // End of method getDummyLogSequenceNumber.

    /**
     * @return Returns the current transactionUnlockSequence.
     *         Note that this hides the getTransactionUnlockSequence() method in managedObject
     *         to give the global unlock sequence.
     */
    protected final long getGlobalTransactionUnlockSequence()
    {
        synchronized (transactionUnlockSequenceLock) {
            return transactionUnlockSequence;
        } // synchronized (transactionUnlockSequenceLock).
    }

    /**
     * Caller must be synchronized on transactionUnlockSequenceLock.
     * 
     * @return Returns the next transactionUnlockSequence.
     */
    protected final long getNewGlobalTransactionUnlockSequence()
    {
        return ++transactionUnlockSequence;
    }

    /**
     * @param idealSize the ideal Size of the ObjectManagerByteArrayOutputStream requested.
     *            The actual stream returned may have less than this bytes capacity but it can be expanded,
     *            it may have more than this capacity byt it may not be all used.
     * @return ObjectManagerByteArrayOutputStream ready for use.
     */
    final ObjectManagerByteArrayOutputStream getbyteArrayOutputStreamFromPool(int idealSize) {
        int index = (Thread.currentThread().hashCode());
        index = (index >>> 5) % byteArrayOutputStreamPools.length;
        java.util.List byteArrayOutputStreamPool = byteArrayOutputStreamPools[index];

        ObjectManagerByteArrayOutputStream byteArrayOutputStream = null;
        synchronized (byteArrayOutputStreamPool) {
            if (byteArrayOutputStreamPool.isEmpty() || idealSize > maximumByteArrayOutputStreamSize) {
                byteArrayOutputStream = new ObjectManagerByteArrayOutputStream(idealSize);
            } else {
                byteArrayOutputStream = (ObjectManagerByteArrayOutputStream) byteArrayOutputStreamPool.remove(byteArrayOutputStreamPool.size() - 1);
            } // if (byteArrayOutputStreamPool.isEmpty()).
        } // synchronized(byteArrayOutputStreamPool).
        return byteArrayOutputStream;
    } // getbyteArrayOutputStreamFromPool().

    /**
     * @param byteArrayOutputStream to be reset and reused.
     */
    final void returnByteArrayOutputStreamToPool(ObjectManagerByteArrayOutputStream byteArrayOutputStream) {
        int index = (Thread.currentThread().hashCode());
        index = (index >>> 5) % byteArrayOutputStreamPools.length;
        java.util.List byteArrayOutputStreamPool = byteArrayOutputStreamPools[index];

        // Keep small ones back for reuse, discard the large ones.
        if (byteArrayOutputStream.size() <= maximumByteArrayOutputStreamSize) {
            synchronized (byteArrayOutputStreamPool) {
                if (byteArrayOutputStreamPool.size() < byteArrayOutputStreamPoolSize) {
                    byteArrayOutputStream.reset();
                    byteArrayOutputStreamPool.add(byteArrayOutputStream);
                } // if (byteArrayOutputStreamPool.size() < byteArrayOutputStreamPoolSize).
            } // synchronized (byteArrayOutputStreamPool).
        } // if (byteArrayOutputStream.size() < maximumByteArrayOutputStreamSize).
    } // returnByteArrayOutputStreamToPool.

    /*
     * Builds a set of properties containing the current statistics. @return java.util.Map the statistics.
     */
    protected java.util.Map captureStatistics()
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "captureStatistics");

        java.util.Map statistics = new java.util.HashMap();

        statistics.put("totalCheckpointsTaken",
                       Long.toString(totalCheckpointsTaken));
        statistics.put("waitingBetweenCheckpointsMilliseconds",
                       Long.toString(waitingBetweenCheckpointsMilliseconds));
        statistics.put("flushingCheckpointStartMilliseconds",
                       Long.toString(flushingCheckpointStartMilliseconds));
        statistics.put("pausedDuringCheckpointMilliseconds",
                       Long.toString(pausedDuringCheckpointMilliseconds));
        statistics.put("flushingObjectStoresForCheckpointMilliseconds",
                       Long.toString(flushingObjectStoresForCheckpointMilliseconds));
        statistics.put("flushingEndCheckpointMilliseconds",
                       Long.toString(flushingEndCheckpointMilliseconds));
        statistics.put("threadsWaitingForCheckpoint",
                       Integer.toString(checkpointHelper.threadsWaitingForCheckpoint));
        statistics.put("currentMaximumActiveTransactions",
                       Long.toString(currentMaximumActiveTransactions));
        statistics.put("registeredInternalTransactions.size()",
                       Integer.toString(registeredInternalTransactions.size()));
        statistics.put("freeTransactions.size()",
                       Integer.toString(freeTransactions.size()));
        statistics.put("totalTransactions",
                       Long.toString(totalTransactions));
        statistics.put("reusedTransactions",
                       Long.toString(reusedTransactions));
        statistics.put("totalTransactionsRequiringCheckpoint",
                       Long.toString(totalTransactionsRequiringCheckpoint));
        statistics.put("maximumTransactionsInAnyCheckpoint",
                       Long.toString(maximumTransactionsInAnyCheckpoint));
        statistics.put("transactionsDelaydForLogFull",
                       Long.toString(transactionsDelayedForLogFull));
        int byteArrayOutputStreamPoolsSize = 0;
        for (int i = 0; i < byteArrayOutputStreamPools.length; i++)
            byteArrayOutputStreamPoolsSize = byteArrayOutputStreamPoolsSize + byteArrayOutputStreamPools[i].size();
        statistics.put("byteArrayOutputStreamPoolsSize",
                       Integer.toString(byteArrayOutputStreamPoolsSize));

        totalCheckpointsTaken = 0;
        waitingBetweenCheckpointsMilliseconds = 0;
        flushingCheckpointStartMilliseconds = 0;
        pausedDuringCheckpointMilliseconds = 0;
        flushingObjectStoresForCheckpointMilliseconds = 0;
        flushingEndCheckpointMilliseconds = 0;
        reusedTransactions = 0;
        totalTransactionsRequiringCheckpoint = 0;
        maximumTransactionsInAnyCheckpoint = 0;
        transactionsDelayedForLogFull = 0;

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "captureStatistics",
                       statistics);
        return statistics;
    } // method captureStatistics().

    /*
     * @returns int the current state for the ObjectManagerState.
     */
    protected int getObjectManagerStateState()
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "getState");

        int stateToReturn = state;

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "getState",
                       stateToReturn + " " + ObjectManagerState.stateNames[stateToReturn]);
        return stateToReturn;
    } // method getObjectManagerStateState().

    /**
     * Makes a state transition. Call must be single threaded through this.
     * 
     * @param nextState the map of the next state.
     * @throws ObjectManagerException
     */
    void setState(int[] nextState)
                    throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "setState",
                        new Object[] { nextState,
                                      new Integer(state),
                                      stateNames[state] });

        previousState = state; // Capture the previous state for dump.
        state = nextState[state]; // Make the state change.

        if (state == stateError) {
            StateErrorException stateErrorException = new StateErrorException(this,
                                                                              previousState,
                                                                              stateNames[previousState]);
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                "setState",
                                                stateErrorException,
                                                "1:2674:1.62");

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "setState",
                           new Object[] { stateErrorException,
                                         new Integer(state),
                                         stateNames[state] });
            throw stateErrorException;
        } // if (state == stateError).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "setState",
                       new Object[] { new Integer(state),
                                     stateNames[state] });
    } // setState().

    // --------------------------------------------------------------------------
    // extends ManagedObject.
    // --------------------------------------------------------------------------

    /**
     * Replace the state of this object with the same object in some other state. Used for to restore the before image if
     * a transaction rolls back or is read from the log during restart.
     * 
     * @param other is the object this object is to become a clone of.
     * @throws ObjectManagerException
     */
    public void becomeCloneOf(ManagedObject other)
                    throws ObjectManagerException {
        final String methodName = "becomeCloneOf";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, other);

        ObjectManagerState otherObjectManagerState = (ObjectManagerState) other;

        maximumObjectStoreIdentifier = otherObjectManagerState.maximumObjectStoreIdentifier;
        persistentTransactionsPerCheckpoint = otherObjectManagerState.persistentTransactionsPerCheckpoint;
        nonPersistentTransactionsPerCheckpoint = otherObjectManagerState.nonPersistentTransactionsPerCheckpoint;
        logFullTriggerCheckpointThreshold = otherObjectManagerState.logFullTriggerCheckpointThreshold;
        logFullPostCheckpointThreshold = otherObjectManagerState.logFullPostCheckpointThreshold;
        maximumActiveTransactions = otherObjectManagerState.maximumActiveTransactions;
        checkpointDelay = otherObjectManagerState.checkpointDelay;
        coldStartLogFileName = otherObjectManagerState.coldStartLogFileName;
        coldStartTime = otherObjectManagerState.coldStartTime;

        if (mainObjectManagerState) {
            synchronized (objectStores) {
                mergeObjectStores(otherObjectManagerState);
                setDefinitiveNamedObjects();
            }
        } else
            objectStores = otherObjectManagerState.objectStores;

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    } // becomeCloneOf().

    /**
     * Merge the otherObjectManagerState.objectStores with our own.
     * Caller must be synchronized on objecStores.
     * 
     * 1) New unknown object stores are opend and added to the known objectStores set. 2) Existing oobjectStores are
     * retained, and not replaced with the new one, this allows apps to continue using the ones they may already have
     * reference to. 3) ObjectStores not present in the new set are closed and removed from the objectStores set.
     * 
     * @param otherObjectManagerState
     * @throws ObjectManagerException
     */
    private void mergeObjectStores(ObjectManagerState otherObjectManagerState)
                    throws ObjectManagerException
    {
        // Merge the other ObjectStores, with those already active in this ObjectManagerState.
        // Make sure we have all of the new ObjectStores.
        for (java.util.Iterator objectStoreIterator = otherObjectManagerState.objectStores.values().iterator(); objectStoreIterator.hasNext();) {
            ObjectStore objectStore = (ObjectStore) objectStoreIterator.next();
            // We cannot use objectManagerState.getObjectStore,
            // because it throws NonExistantObjectStoreException.
            Object existingStore = objectStores.get(new Integer(objectStore.getIdentifier()));
            if (existingStore == null) {
                objectStore.open(this);
                objectStores.put(new Integer(objectStore.getIdentifier()),
                                 objectStore);

                // Does the store contain a the definitive copy of the namedObjects Tree?
                if (objectStore.getContainsRestartData()
                    && namedObjects == null) {
                    // We do not need to create the tree if it does not exist because the original transaction
                    // will have taken care of that.
                    Token namedObjectsToken = new Token(objectStore,
                                                        ObjectStore.namedObjectTreeIdentifier.longValue());
                    // Swap for the definitive Token, if there is one.
                    namedObjectsToken = objectStore.like(namedObjectsToken);

                } // if (objectStore.getContainsRestartData())...
            } // if (existingStore == null).
        } // for otherObjectManagerstate.objectStores...

        // Remove any ObjectStores in this objectStores but not in the otherObjectManagerState.objectStores.
        for (java.util.Iterator objectStoreIterator = objectStores.values().iterator(); objectStoreIterator.hasNext();) {
            ObjectStore objectStore = (ObjectStore) objectStoreIterator.next();
            // We cannot use objectManagerState.getObjectStore,
            // because it throws NonExistantObjectStoreException.
            Object newObjectStore = otherObjectManagerState.objectStores.get(new Integer(objectStore.getIdentifier()));
            if (newObjectStore == null) {
                objectStore.close();
                objectStores.remove(new Integer(objectStore.getIdentifier()));
                // No need to modify the namedObjects Tree as that is taken care of by the rest of the transaction.

                // See if the ObjectStore contains the nameObjects Tree?
                if (namedObjects != null) {
                    if (namedObjects.getObjectStore() == objectStore) {
                        namedObjects = null;
                    } // if (namedObjects.getObjectStore()...
                } // if (namedObjects != null).

            } // if (existingStore == null).
        } // for otherObjectManagerstate.objectStores...

        // It is now safe to restore tokens which make reference to their ObjectStores.

    } // mergeObjectStores().

    // --------------------------------------------------------------------------
    // Simplified serialization.
    // --------------------------------------------------------------------------

    /**
     * No argument constructor.
     * 
     * @exception ObjectManagerException
     */
    ObjectManagerState()
        throws ObjectManagerException
    {
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        "<init>");

        // We are the not the real state, just a copy as yet.
        mainObjectManagerState = false;

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       "<init>");
    } // ObjectManagerState().

    private static final byte simpleSerialVersion = 0;

    /*
     * (non-Javadoc)
     * 
     * @see int SimplifiedSerialization.getSignature()
     */
    protected int getSignature()
    {
        return signature_ObjectManagerState;
    } // getSignature().

    /*
     * (non-Javadoc)
     * 
     * @see com.ibm.ws.objectManager.SimplifiedSerialization#estimatedLength()
     */
    public long estimatedLength() {
        return serializedSize;
    }

    /*
     * (non-Javadoc)
     * 
     * @see SimplifiedSerialization.writeObject(java.io.DataInputStream)
     */
    public void writeObject(java.io.DataOutputStream dataOutputStream)
                    throws ObjectManagerException {
        final String methodName = "writeObject";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, dataOutputStream);

        try {
            dataOutputStream.writeByte(simpleSerialVersion);
            super.writeObject(dataOutputStream);

            // ObjectStores are serialized first because any references to ManagedObjects will
            // indirectly refer to them.
            //TODO Make ObjecStores managedObjects, store them individually in the restartObjectStores!
            //TODO This lets them use simpleSerialization and any admin changes are transactional.
            java.io.ObjectOutputStream objectOutputStream = new java.io.ObjectOutputStream(dataOutputStream);
            synchronized (objectStores) {
                objectOutputStream.writeObject(objectStores);
            }
            objectOutputStream.close();

            dataOutputStream.writeLong(maximumObjectStoreIdentifier);
            dataOutputStream.writeLong(persistentTransactionsPerCheckpoint);
            dataOutputStream.writeLong(nonPersistentTransactionsPerCheckpoint);
            dataOutputStream.writeFloat(logFullTriggerCheckpointThreshold);
            dataOutputStream.writeFloat(logFullPostCheckpointThreshold);
            dataOutputStream.writeLong(maximumActiveTransactions);
            dataOutputStream.writeInt(checkpointDelay);
            dataOutputStream.writeUTF(coldStartLogFileName);
            dataOutputStream.writeLong(coldStartTime);
            // Note the serialized size ready for the next time we serialize.
            serializedSize = dataOutputStream.size();

        } catch (java.io.IOException exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this, cclass, methodName, exception, "1:2887:1.62");

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this, cclass, methodName, exception);
            throw new PermanentIOException(this,
                                           exception);
        } // catch (java.io.IOException exception).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    } // writeObject().

    /*
     * (non-Javadoc)
     * 
     * @see SimplifiedSerialization.readObject(java.io.DataInputStream,ObjectManagerState)
     */
    public void readObject(java.io.DataInputStream dataInputStream,
                           ObjectManagerState objectManagerState)
                    throws ObjectManagerException {
        final String methodName = "readObject";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this,
                        cclass,
                        methodName,
                        new Object[] { dataInputStream,
                                      objectManagerState });

        try {
            byte version = dataInputStream.readByte();
            if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled())
                trace.debug(this,
                            cclass,
                            methodName,
                            new Byte(version));
            super.readObject(dataInputStream,
                             objectManagerState);

            // There is no transient data in either SingleFileObjectStore or SingleNonNioFileObjectStore, 
            // and the two disk formats are identical. Hence we can flip between the two types of store
            // according to whether we are running on an Nio capable JVM or not.
            // PK73292.1
            // Disable this migration code by default. Allow it to be toggled via a compile
            // time flag.
            java.io.ObjectInputStream objectInputStream;

            if (migrateObjectStores)
            {
                objectInputStream = new java.io.ObjectInputStream(dataInputStream)
                {
                    /*
                     * (non-Javadoc)
                     * 
                     * @see java.io.ObjectInputStream#readClassDescriptor()
                     */
                    protected java.io.ObjectStreamClass readClassDescriptor() throws java.io.IOException, java.lang.ClassNotFoundException
                    {
                        final String methodName = "readClassDescriptor";

                        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                            trace.entry(this, cclass, methodName);

                        java.io.ObjectStreamClass objectStreamClass = super.readClassDescriptor();
                        if (objectStreamClass.getName().equals("com.ibm.ws.objectManager.SingleFileObjectStore")
                            && !nioAvailable)
                        {
                            if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled())
                                trace.debug(this, cclass, methodName, new Object[] { "Migrating:2950", objectStreamClass });

                            // PK73292
                            // use Class.forName() to delay class loading of object store 
                            // implementation until this code path is taken.
                            objectStreamClass = java.io.ObjectStreamClass.lookup(Class.forName("com.ibm.ws.objectManager.SingleNonNioFileObjectStore"));
                        }
                        else if (objectStreamClass.getName().equals("com.ibm.ws.objectManager.SingleNonNioFileObjectStore")
                                 && nioAvailable)
                        {
                            if (Tracing.isAnyTracingEnabled() && trace.isDebugEnabled())
                                trace.debug(this, cclass, methodName, new Object[] { "Migrating:2960", objectStreamClass });

                            // PK73292
                            // use Class.forName() to delay class loading of object store 
                            // implementation until this code path is taken.
                            objectStreamClass = java.io.ObjectStreamClass.lookup(Class.forName("com.ibm.ws.objectManager.SingleFileObjectStore"));
                        } // if (   objectStreamClass.getName().

                        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                            trace.exit(this, cclass, methodName, new Object[] { objectStreamClass });
                        return objectStreamClass;
                    } // readClassDescriptor().
                };
            }
            else
            {
                objectInputStream = new java.io.ObjectInputStream(dataInputStream);
            }

            objectStores = (java.util.Map) objectInputStream.readObject();
            objectInputStream.close();

            // ObjectStores are merged in becomeCloneOf().

            maximumObjectStoreIdentifier = dataInputStream.readLong();
            persistentTransactionsPerCheckpoint = dataInputStream.readLong();
            nonPersistentTransactionsPerCheckpoint = dataInputStream.readLong();
            logFullTriggerCheckpointThreshold = dataInputStream.readFloat();
            logFullPostCheckpointThreshold = dataInputStream.readFloat();
            maximumActiveTransactions = dataInputStream.readLong();
            checkpointDelay = dataInputStream.readInt();
            coldStartLogFileName = dataInputStream.readUTF();
            dataInputStream.readLong();

        } catch (java.io.IOException exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                methodName,
                                                exception,
                                                "1:2999:1.62");

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           methodName,
                           new Object[] { "PermanentIOException:%C", exception });
            throw new PermanentIOException(this,
                                           exception);

        } catch (java.lang.ClassNotFoundException exception) {
            // No FFDC Code Needed.
            ObjectManager.ffdc.processException(this,
                                                cclass,
                                                methodName,
                                                exception,
                                                "1:3015:1.62");

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           methodName,
                           new Object[] { "ClassNotFoundException:3021", exception });
            throw new com.ibm.ws.objectManager.ClassNotFoundException(this, exception);

        } // catch (java.io.IOException exception).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this,
                       cclass,
                       methodName);
    } // readObject().

    void registerEventCallback(ObjectManagerEventCallback callback) {
        final String methodName = "registerEventCallback";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, callback);

        synchronized (callbacks) {
            callbacks.add(callback);
        }

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    } // registerEventCallback().

    void notifyCallbacks(int event, Object[] args) {
        final String methodName = "notifyCallbacks";
        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.entry(this, cclass, methodName, new Object[] { new Integer(event), args });

        synchronized (callbacks) {
            for (java.util.Iterator iterator = callbacks.iterator(); iterator.hasNext();) {
                ObjectManagerEventCallback callback = (ObjectManagerEventCallback) iterator.next();
                callback.notification(event, args);
            } // for.        
        } // synchronized (callbacks).

        if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
            trace.exit(this, cclass, methodName);
    } // notifyCallbacks.

    /*
     * Check to see if we are in shutdown mode. This will true if we are
     * either in 'shutdown started' or 'stopped'.
     */
    protected boolean inShutdown() throws ObjectManagerException
    {
        if (getObjectManagerStateState() == stateShutdownStarted ||
            getObjectManagerStateState() == stateStopped)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    //--------------------------------------------------------------------------
    // extends Object.
    // --------------------------------------------------------------------------

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    public String toString()
    {
        return new String("ObjectManagerState"
                          + "(" + logFileName + ")"
                          + "/" + stateNames[state]
                          + " " + super.toString());
    } // toString().

    // ----------------------------------------------------------------------------------------------
    // Inner classes
    // ----------------------------------------------------------------------------------------------

    /*
     * 
     * @author Andrew_Banks
     * 
     * Gives up an ExternalTransaction covering the next InternalTransaction.
     */
    private class TransactionIterator
                    implements java.util.Iterator
    {
        java.util.Iterator internalTransactionIterator;

        TransactionIterator()
        {
            internalTransactionIterator = registeredInternalTransactions.values()
                            .iterator();
        }

        public boolean hasNext()
        {
            return internalTransactionIterator.hasNext();
        }

        public Object next()
        {
            InternalTransaction internalTransaction = (InternalTransaction) internalTransactionIterator.next();
            Transaction transaction = internalTransaction.getExternalTransaction();
            return transaction;
        }

        public void remove()
        {
            throw new UnsupportedOperationException();
        }
    } // inner class TransactionIterator .

    /**
     * The worker thread that executes a checkpoint.
     */
    protected class CheckpointHelper
                    implements Runnable
    {
        private boolean running = true; // True if we are not finished.
        private boolean waiting = false; // True if waiting.
        private boolean checkpointRequested = false; // True if a checkpoint is requested.
        private boolean persistentTransactions = false; // True is persitent work is t be checkpointed.
        private Exception abnormalTerminationException = null;
        private long checkpointCycle = 0; // Identifies the checkpoint.
        protected Thread checkpointThread = null;
        private int threadsWaitingForCheckpoint = 0;

        /**
         * Constructor
         * 
         * @throws ObjectManagerException
         */
        CheckpointHelper()
            throws ObjectManagerException
        {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            "<init>");

            checkpointThread = new Thread(this);

            checkpointThread.setName("CheckpointHelper");
            // Run the CheckpointHelper in preference to other threads.
            checkpointThread.setPriority(Thread.NORM_PRIORITY + 1);
            // checkpointThread.setPriority(Thread.MAX_PRIORITY);

            // synchronize to make sure the CheckpointHelper starts before
            // any requests are admited.
            synchronized (this) {
                checkpointThread.start();
                try {
                    wait();
                } catch (InterruptedException exception) {
                    // No FFDC Code Needed.
                    ObjectManager.ffdc.processException(this,
                                                        cclass,
                                                        "waitForCheckpoint",
                                                        exception,
                                                        "1:3180:1.62");

                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this,
                                   cclass,
                                   "waitForCheckpoint",
                                   exception);
                    throw new UnexpectedExceptionException(this,
                                                           exception);

                } // catch (InterruptedException exception).
            } // synchronized (this).

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "<init>");
        } // CheckpointHelper().

        // ----------------------------------------------------------------------------------------------
        // implements runnable
        // ----------------------------------------------------------------------------------------------

        public void run()
        {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            "run");

            // Outer try/catch block treats all unexpected errors as terminal
            // and shuts down the Objectmanager if any occur.
            try {
                for (;;) {
                    boolean nextCheckpointPersistentence;
                    synchronized (this) {
                        checkpointCycle++; // Move on to the next cycle.
                        notifyAll(); // Release threads waiting for the checkpoint.
                        threadsWaitingForCheckpoint = 0;

                        if (!running)
                            break;

                        if (!checkpointRequested) { // Should we wait?
                            waiting = true;
                            // InterruptedException is caught by the outer try/catch block.
                            wait();
                            waiting = false;
                        } // if (!checkpointRequested).
                        checkpointRequested = false;
                        nextCheckpointPersistentence = persistentTransactions;
                        persistentTransactions = false;
                    } // synchronized (this).

                    // Perform the checkpoint while not synchronized, this allows new requests
                    // to be made without blocking.
                    // ObjectmanagerdException is caught by the outer try/catch block.
                    if (running) // We might have just shutdown.
                        performCheckpoint(nextCheckpointPersistentence); // Perform the checkpoint.

                } // for (;;).
            } catch (Exception exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    "run",
                                                    exception,
                                                    "1:3247:1.62");

                running = false;
                abnormalTerminationException = exception;
                // Make one asynchronous request to shutdown the ObjectManager.
                requestShutdown();
                synchronized (this) {
                    // We are shutting down now so notify all. The abnormalexception
                    // has been set so this should indicate to the caller that the
                    // checkpoint did fail.
                    notifyAll();
                } // synchronized (this).
            } // catch (ObjectManagerException exception).

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "run");
        } // run().

        /**
         * A non blocking request that a checkpoint should be performed.
         * Will return before the checkpoint is complete.
         * 
         * @param persistent true if persistent transactions are to be checkpointed.
         * @throws ObjectManagerException
         */
        synchronized void requestCheckpoint(boolean persistent)
                        throws ObjectManagerException
        {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            "requestCheckpoint",
                            new Object[] { new Boolean(persistent) });

            // Has something previously gone wrong?
            if (abnormalTerminationException != null) {
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               "requestCheckpoint",
                               abnormalTerminationException);
                throw new UnexpectedExceptionException(this,
                                                       abnormalTerminationException);
            } // if (abnormalTerminationException != null).
              // Any request arriving after we have stopped running, at shutdown will not be honoured.
            checkpointRequested = true;
            persistentTransactions = persistentTransactions || persistent;
            if (waiting) {
                notify();
            } // if (waiting).

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "requestCheckpoint");
        } // requestCheckpoint().

        /**
         * A non blocking suggestion that a checkpoint should be performed.
         * Will return before the checkpoint is complete.
         * This is different to requestCheckpoint in that it will only trigger a checkpoint
         * if the checkpointer helper is not already running (if it is sleeping). This is
         * useful to avoid a double checkpoint when the checkpoint is triggered by occupancy
         * or number of transactions.
         * 
         * A small window exists in which callers could really mean that a checkpoint should
         * run based on up-to-date numbers. So callers of this method should not rely on the
         * fact that a checkpoint will happen as a result of this call, in addition to any
         * that is currently in progress. Callers requiring this should use requestCheckpoint
         * or waitForCheckpoint.
         * 
         * It always updates persistentTransactions if appropriate.
         * 
         * @param persistent true if persistent transactions are to be checkpointed.
         * @throws ObjectManagerException
         */
        synchronized void suggestCheckpoint(boolean persistent)
                        throws ObjectManagerException
        {
            if (trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            "suggestCheckpoint",
                            new Object[] { new Boolean(persistent) });

            // Has something previously gone wrong?
            if (abnormalTerminationException != null) {
                if (trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               "requestCheckpoint",
                               abnormalTerminationException);
                throw new UnexpectedExceptionException(this,
                                                       abnormalTerminationException);
            } // if (abnormalTerminationException != null).

            // Any request arriving after we have stopped running, at shutdown will not be honoured.
            persistentTransactions = persistentTransactions || persistent;
            if (waiting) {
                checkpointRequested = true;
                notify();
            } // if (waiting).

            if (trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "suggestCheckpoint");
        } // suggestCheckpoint().

        /**
         * A blocking call to checkpoint, returns when checkpoint is complete.
         * 
         * @param persistent true if persisent state is to be checkpointed.
         * @throws ObjectManagerException
         */
        private synchronized void waitForCheckpoint(boolean persistent)
                        throws ObjectManagerException
        {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            "waitForCheckpoint",
                            new Boolean(persistent));

            long endCycle;
            if (waiting) {
                // Currently inactive so wait for then next checkpoint.
                endCycle = checkpointCycle;
            } else {
                // Currently checkpointing, wait for another checkpoint after this one finishes.
                endCycle = checkpointCycle + 1;
            } // if (waiting).

            while (endCycle >= checkpointCycle
                   && abnormalTerminationException == null) {
                requestCheckpoint(persistent);
                threadsWaitingForCheckpoint++;
                try {
                    wait();
                } catch (InterruptedException exception) {
                    // No FFDC Code Needed.
                    ObjectManager.ffdc.processException(this,
                                                        cclass,
                                                        "waitForCheckpoint",
                                                        exception,
                                                        "1:3393:1.62");

                    if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                        trace.exit(this,
                                   cclass,
                                   "waitForCheckpoint",
                                   exception);
                    throw new UnexpectedExceptionException(this,
                                                           exception);

                } // catch (InterruptedException exception).
            } // while (startCycle == checkpointCycle).

            // Was there a happy ending?
            if (abnormalTerminationException != null) {
                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               "waitForCheckpoint",
                               abnormalTerminationException);
                throw new UnexpectedExceptionException(this,
                                                       abnormalTerminationException);
            } // if (abnormalTerminationException != null).

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "waitForCheckpoint");
        } // waitForCheckpoint().

        /*
         * Terminate the CheckpointHelper.
         */
        void shutdown()
                        throws ObjectManagerException
        {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            "shutdown");

            synchronized (this) {
                running = false;

                if (waiting)
                    notify();
            } // synchronize (this).

            // Wait for the worker thread to complete.
            try {
                checkpointThread.join();
            } catch (InterruptedException exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    "shutdown",
                                                    exception,
                                                    "1:3450:1.62");

                if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                    trace.exit(this,
                               cclass,
                               "shutdown",
                               exception);
                throw new UnexpectedExceptionException(this,
                                                       exception);
            } // catch (InterruptedException exception).

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "shutdown");
        } // shutdown().
    } // checkpointHelper().

    /**
     * Handles asynchronous requests to shut down the ObjectManager.
     */
    private class ShutdownHelper
                    implements Runnable
    {
        /**
         * Constructor
         */
        ShutdownHelper()
        {
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            "<init>");

            Thread shutdownThread = new Thread(this);
            shutdownThread.setName("ShutdownHelper");
            shutdownThread.start();

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           "<init>");
        } // ShutdownHelper().

        // ---------------------------------------------------------------------------------
        // implements Runnable.
        // ---------------------------------------------------------------------------------
        public void run() {
            final String methodName = "run";
            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.entry(this,
                            cclass,
                            methodName);
            // Make one attempt to shutdown, if anything goes wrong just report the problem
            // but dont attempt any recovery. If we are here it will be because something
            // unexpected has happened and we don't want to make things any worse.
            try {
                // Use ShutdownFast because any attempt to backout Transactions or take a
                // Checkpoint is likely to fail.
                shutdownFast();
            } catch (Exception exception) {
                // No FFDC Code Needed.
                ObjectManager.ffdc.processException(this,
                                                    cclass,
                                                    methodName,
                                                    exception,
                                                    "1:3516:1.62");

            } // catch (InterruptedException exception).

            if (Tracing.isAnyTracingEnabled() && trace.isEntryEnabled())
                trace.exit(this,
                           cclass,
                           methodName);
        } // run().
    } // inner class shutdownHelper().
}
841177
public final void zooActivateRead() {
		if (DBTracer.TRACE) DBTracer.logCall(this);
		switch (getStatus()) {
		case DETACHED_CLEAN:
			//nothing to do
			return;
		case HOLLOW_PERSISTENT_NONTRANSACTIONAL:
			try {
				Session session = context.getSession();
				session.lock();
				if (session.isClosed()) {
					throw DBLogger.newUser("The PersistenceManager of this object is not open.");
				}
				if (!session.isActive() && !session.getConfig().getNonTransactionalRead()) {
					throw DBLogger.newUser("The PersistenceManager of this object is not active " +
							"(-> use begin()).");
				}
				jdoZooGetNode().refreshObject(this);
			} finally {
				context.getSession().unlock();
			}
			return;
		case PERSISTENT_DELETED:
		case PERSISTENT_NEW_DELETED:
			throw DBLogger.newUser("The object has been deleted.");
		case PERSISTENT_NEW:
		case PERSISTENT_CLEAN:
		case PERSISTENT_DIRTY:
			//nothing to do
			return;
		case TRANSIENT:
		case TRANSIENT_CLEAN:
		case TRANSIENT_DIRTY:
			//not persistent yet
			return;

		default:
			throw new IllegalStateException("" + getStatus());
		}
	}