void abortAll() throws IOException {
    Iterator myTxns = theTxns.keySet().iterator();

    while (myTxns.hasNext()) {
      TxnId myId = (TxnId) myTxns.next();

      TxnState myState = getState(myId);

      try {
        int myStatus = myState.getStatus();

        if ((myStatus == TransactionConstants.PREPARED)
            || (myStatus == TransactionConstants.ACTIVE)) {

          /*
           *  AbortAll is a naive operation in that it has no
           *  awareness of a specific transaction thus it cannot
           *  explicitly vote one of them off so we must do it
           *  ourselves
           */
          myState.vote();
          myState.abort();
          myTxns.remove();
        }

      } catch (TransactionException aTE) {
        // Whoops, got nailed checking status, logged in the call
        // nothing to do.
      }
    }
  }
  private void writeObject(ObjectOutputStream anOut) throws IOException {
    anOut.writeObject(LogVersion.VERSION);

    /*
      We only save PREPARED transactions, ignoring ACTIVES because
      they are transient and their state changes won't be applied
      until we've issued prepare and then commit or abort.  The ACTIVES
      will either die due to failure or, post the sync, add operations
      to the log.  Note that, whilst a transaction is active, it generates
      no log records at all hence the reason we don't need to save them.
      Commited or aborted updates in cache which need flushing to disk
      should have already been sync'd before we get this far.
    */
    ArrayList myPrepared = new ArrayList();

    // Write out clock
    //
    anOut.writeObject(theClock);

    Iterator myTxns = theTxns.keySet().iterator();

    while (myTxns.hasNext()) {
      TxnId myId = (TxnId) myTxns.next();

      TxnState myState = getState(myId);

      try {
        int myStatus = myState.getStatus();

        if (myStatus == TransactionConstants.PREPARED) {
          myPrepared.add(myState);
        }

      } catch (TransactionException aTE) {
        // Whoops, got nailed checking status, logged in the call
        // nothing to do.
      }
    }

    anOut.writeInt(myPrepared.size());

    for (int i = 0; i < myPrepared.size(); i++) {
      anOut.writeObject(myPrepared.get(i));
    }

    /*
     Write out any user-code snapshot contributions
    */
    ArrayList myContributions = new ArrayList();

    synchronized (theSnapshotContributors) {
      for (int i = 0; i < theSnapshotContributors.size(); i++) {
        myContributions.add(
            ((SnapshotContributor) theSnapshotContributors.get(i)).getContribution());
      }
    }

    Serializable[] myUserData = new Serializable[myContributions.size()];
    myUserData = (Serializable[]) myContributions.toArray(myUserData);

    anOut.writeObject(myUserData);
  }