/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
<<<<<<< Updated upstream
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
=======
 * 
 *     https://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.lifecycle;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Iterator;
import javax.jdo.Extent;
import javax.jdo.JDOFatalException;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.lifecycle.StateTransitionObj;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> Test State Transitions <br>
 * <B>Keywords:</B> lifecycle <br>
 * <B>Assertion IDs:</B> A5.9-1 through A5.9-190 <B>Assertion Description: </B> All possible state
 * transistions are being tested in this test.
 */
public class StateTransitions extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertions A5.9-1 through A5.9-190 (StateTransitions) failed: ";

  /**
   * The <code>main</code> is called when the class is directly executed from the command line.
   *
   * @param args The arguments passed to the program.
   */
  public static void main(String[] args) {
    BatchTestRunner.run(StateTransitions.class);
  }

  private Transaction transaction;
  private int scenario;
  private int operation;
  private int current_state;
  private int expected_state;
  private int new_state;

  /** Operations that cause state changes */
  private static final int MAKEPERSISTENT = 0;

  private static final int DELETEPERSISTENT = 1;
  private static final int MAKETRANSACTIONAL = 2;
  private static final int MAKENONTRANSACTIONAL = 3;
  private static final int MAKETRANSIENT = 4;
  private static final int COMMITNORETAINVALUES = 5;
  private static final int COMMITRETAINVALUES = 6;
  private static final int ROLLBACKNORESTOREVALUES = 7;
  private static final int ROLLBACKRESTOREVALUES = 8;
  private static final int REFRESHDATASTORE = 9;
  private static final int REFRESHOPTIMISTIC = 10;
  private static final int EVICT = 11;
  private static final int READOUTSIDETX = 12;
  private static final int READOPTIMISTIC = 13;
  private static final int READDATASTORE = 14;
  private static final int WRITEOUTSIDETX = 15;
  private static final int WRITEINSIDETX = 16;
  private static final int RETRIEVEOUTSIDETX = 17;
  private static final int RETRIEVEINSIDETX = 18;
  private static final int DETACHALLONCOMMIT = 19;
  private static final int DETACHCOPYOUTSIDETXNTRTRU = 20;
  private static final int DETACHCOPYOUTSIDETXNTRFLS = 21;
  private static final int DETACHCOPYINSIDEDATASTORETX = 22;
  private static final int DETACHCOPYINSIDEOPTIMISTICTX = 23;
  private static final int SERIALIZEOUTSIDETX = 24;
  private static final int SERIALIZEDATASTORE = 25;
  private static final int SERIALIZEOPTIMISTIC = 26;

  private static final int NUM_OPERATIONS = 27;

  private static final String[] operations = {
    "makePersistent",
    "deletePersistent",
    "makeTransactional",
    "makeNontransactional",
    "makeTransient",
    "commit, retainValues=false",
    "commit, retainValues=true",
    "rollback, restoreValues=false",
    "rollback, restoreValues=true",
    "refresh with active datastore tx",
    "refresh with active optimistic tx",
    "evict",
    "read field outside tx",
    "read field with active optimistic tx",
    "read field with active datastore tx",
    "write field outside tx",
    "write field with active tx",
    "retrieve outside tx",
    "retrieve with active tx",
    "commit, detachAllOnCommit=true",
    "detachCopy outside tx with NontransactionalRead=true",
    "detachCopy outside tx with NontransactionalRead=false",
    "detachCopy with active datastore tx",
    "detachCopy with active optimistic tx",
    "serialize outside tx",
    "serialize with active datastore tx",
    "serialize with active optimistic tx"
  };

  /** Illegal state transitions */
  private static final int UNCHANGED = -1;

  private static final int ERROR = -2;
  private static final int IMPOSSIBLE = -3;
  private static final int NOT_APPLICABLE = -4;
  private static final int UNSPECIFIED = -5;

  /** State transitions */
  public static final int[][] transitions = { // [operation] [current state] = new state
    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // makePersistent
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, PERSISTENT_NEW,
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, DETACHED_CLEAN,
      DETACHED_DIRTY
    },

    // deletePersistent
    {
      ERROR, PERSISTENT_NEW_DELETED, PERSISTENT_DELETED,
      PERSISTENT_DELETED, PERSISTENT_DELETED, ERROR,
      ERROR, UNCHANGED, UNCHANGED,
      PERSISTENT_DELETED, PERSISTENT_DELETED, ERROR,
      ERROR
    },

    // makeTransactional
    {
      TRANSIENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, PERSISTENT_DIRTY, ERROR,
      ERROR
    },

    // makeNontransactional
    {
      ERROR, ERROR, PERSISTENT_NONTRANSACTIONAL,
      ERROR, UNCHANGED, TRANSIENT,
      ERROR, ERROR, ERROR,
      UNCHANGED, UNCHANGED, ERROR,
      ERROR
    },

    // makeTransient
    {
      UNCHANGED, ERROR, TRANSIENT,
      ERROR, TRANSIENT, UNCHANGED,
      UNCHANGED, ERROR, ERROR,
      TRANSIENT, ERROR, ERROR,
      ERROR
    },

    // commit, retainValues = false
    {
      UNCHANGED, HOLLOW, HOLLOW,
      HOLLOW, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, TRANSIENT,
      UNCHANGED, HOLLOW, UNCHANGED,
      UNCHANGED
    },

    // commit, retainValues = true
    {
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NONTRANSACTIONAL,
      PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, TRANSIENT,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED
    },

    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // rollback, restoreValues = false
    {
      UNCHANGED, TRANSIENT, HOLLOW,
      HOLLOW, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, HOLLOW,
      UNCHANGED, HOLLOW, UNCHANGED,
      UNCHANGED
    },

    // rollback, restoreValues = true
    {
      UNCHANGED, TRANSIENT, PERSISTENT_NONTRANSACTIONAL,
      PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, PERSISTENT_NONTRANSACTIONAL,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // refresh with active datastore transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED
    },

    // refresh with active optimistic transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_NONTRANSACTIONAL, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED
    },

    // evict
    {
      NOT_APPLICABLE, UNCHANGED, HOLLOW,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      HOLLOW, HOLLOW, UNCHANGED,
      UNCHANGED
    },

    // read field outside transaction
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // read field with active optimistic transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, UNCHANGED,
      UNCHANGED, UNSPECIFIED, UNSPECIFIED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // read field with active datastore transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNSPECIFIED, UNSPECIFIED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // write field outside transaction
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      PERSISTENT_NONTRANSACTIONAL_DIRTY, UNCHANGED, DETACHED_DIRTY,
      UNCHANGED
    },

    // write field with active transaction
    {
      UNCHANGED, UNCHANGED, PERSISTENT_DIRTY,
      UNCHANGED, PERSISTENT_DIRTY, TRANSIENT_DIRTY,
      UNCHANGED, ERROR, ERROR,
      PERSISTENT_DIRTY, UNCHANGED, DETACHED_DIRTY,
      UNCHANGED
    },

    // retrieve outside transaction
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // retrieve with active transaction
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // commit, detachAllOnCommit = true
    {
      UNCHANGED, DETACHED_CLEAN, DETACHED_CLEAN,
      DETACHED_CLEAN, DETACHED_CLEAN, UNCHANGED,
      TRANSIENT_CLEAN, TRANSIENT, TRANSIENT,
      DETACHED_CLEAN, DETACHED_CLEAN, UNCHANGED,
      UNCHANGED
    },

    //  TRANSIENT,                      PERSISTENT_NEW,                     PERSISTENT_CLEAN,
    //  PERSISTENT_DIRTY,               HOLLOW,                             TRANSIENT_CLEAN,
    //  TRANSIENT_DIRTY,                PERSISTENT_NEW_DELETED,             PERSISTENT_DELETED,
    //  PERSISTENT_NONTRANSACTIONAL,    PERSISTENT_NONTRANSACTIONAL_DIRTY,  DETACHED_CLEAN,
    //  DETACHED_DIRTY

    // detachCopy outside tx with NontransactionalRead=true
    {
      ERROR, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, PERSISTENT_NONTRANSACTIONAL, ERROR,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // detachCopy outside tx with NontransactionalRead=false
    {
      ERROR, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, ERROR, ERROR,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      ERROR, ERROR, ERROR,
      ERROR
    },

    // detachCopy with active datastore tx
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, PERSISTENT_NEW,
      PERSISTENT_NEW, ERROR, ERROR,
      PERSISTENT_CLEAN, IMPOSSIBLE, UNCHANGED,
      UNCHANGED
    },

    // detachCopy with active optimistic tx
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_NONTRANSACTIONAL, PERSISTENT_NEW,
      PERSISTENT_NEW, ERROR, ERROR,
      UNCHANGED, IMPOSSIBLE, UNCHANGED,
      UNCHANGED
    },

    // serialize outside tx
    {
      UNCHANGED, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, UNCHANGED, IMPOSSIBLE,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // serialize with active datastore tx
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, PERSISTENT_CLEAN, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      PERSISTENT_CLEAN, UNCHANGED, UNCHANGED,
      UNCHANGED
    },

    // serialize with active optimistic tx
    {
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, UNCHANGED,
      UNCHANGED
    },
  };

  private static final int DATASTORE_TX = 0;
  private static final int OPTIMISTIC_TX = 1;
  private static final int NO_TX = 2;

  private static final String[] scenario_string = {
    "datastore transaction", "optimistic transaction", "no transaction"
  };

  private static final boolean[][] applies_to_scenario = {
    //  Datastore   Optimistic      No tx
    {true, true, false}, // makePersistent
    {true, true, false}, // deletePersistent
    {true, true, false}, // makeTransactional
    {true, true, false}, // makeNontransactional
    {true, true, false}, // makeTransient
    {true, true, false}, // commit RetainValues = false
    {true, true, false}, // commit RetainValues = true
    {true, true, false}, // rollback RestoreValues = false
    {true, true, false}, // rollback RestoreValues = true
    {true, false, false}, // refresh with active datastore transaction
    {false, true, false}, // refresh with active optimistic transaction
    {true, true, false}, // evict
    {false, false, true}, // read field outside of a transaction
    {false, true, false}, // read field with active optimistic transaction
    {true, false, false}, // read field with active datastore transaction
    {false, false, true}, // write field or makeDirty outside of a transaction
    {true, true, false}, // write field or makeDirty with active transaction
    {false, true, true}, // retrieve outside of a transaction or with active optimistic transaction
    {true, false, false}, // retrieve with active datastore transaction
    {true, true, false}, // commit, DetachAllOnCommit = true
    {false, false, true}, // detachCopy outside tx with NonTransactionaRead=true
    {false, false, true}, // detachCopy outside tx with NonTransactionaRead=false
    {true, false, false}, // detachCopy with active datastore tx
    {false, true, false}, // detachCopy with active optimistic tx
    {false, false, true}, // serialize outside tx
    {true, false, false}, // serialize with active datastore tx
    {false, true, false} // serialize with active optimistic tx
  };

  /**
   * @see org.apache.jdo.tck.JDO_Test#localSetUp()
   */
  @Override
  protected void localSetUp() {
    pm = getPM();
    addTearDownClass(StateTransitionObj.class);
    generatePersistentInstances();
  }

  public void test() {
    scenario = DATASTORE_TX;
    checkTransitions();

    if (isOptimisticSupported()) {
      scenario = OPTIMISTIC_TX;
      checkTransitions();
    }

    scenario = NO_TX;
    checkTransitions();
    failOnError();
  }

  /** */
  private void generatePersistentInstances() {
    if (doPersistentInstancesExist()) return;
    int i;
    Transaction t = pm.currentTransaction();
    t.begin();
    for (i = 0; i < 50; ++i) {
      StateTransitionObj sto = new StateTransitionObj(i);
      sto.writeField(i);
      pm.makePersistent(sto);
    }
    t.commit();
    if (!doPersistentInstancesExist())
      if (debug) logger.debug("StateTransitions unable to create instances of StateTransitionsObj");
  }

  /** */
  private boolean doPersistentInstancesExist() {
    boolean ret;
    Transaction t = pm.currentTransaction();
    t.begin();
    Extent<StateTransitionObj> e = pm.getExtent(StateTransitionObj.class, false);
    Iterator<StateTransitionObj> iter = e.iterator();
    ret = iter.hasNext();
    t.rollback();
    return ret;
  }

  /**
   * @param transaction the transaction
   */
  public void prepareTransactionAndJDOSettings(Transaction transaction) {
    transaction.setNontransactionalRead(false);
    transaction.setNontransactionalWrite(false);
    if (scenario != NO_TX) {
      if (operation == COMMITNORETAINVALUES) transaction.setRetainValues(false);
      if (operation == COMMITRETAINVALUES) transaction.setRetainValues(true);
      if (operation == ROLLBACKNORESTOREVALUES) transaction.setRestoreValues(false);
      if (operation == ROLLBACKRESTOREVALUES) transaction.setRestoreValues(true);
      if (operation == DETACHALLONCOMMIT) pm.setDetachAllOnCommit(true);
      else pm.setDetachAllOnCommit(false);

      transaction.setOptimistic(scenario == OPTIMISTIC_TX);
      transaction.begin();
      if (!transaction.isActive())
        if (debug) logger.debug("StateTransitions: Transaction should be active, but it is not");
    } else {
      if (operation == READOUTSIDETX
          || operation == RETRIEVEOUTSIDETX
          || operation == DETACHCOPYOUTSIDETXNTRTRU
          || operation == SERIALIZEOUTSIDETX) {
        transaction.setNontransactionalRead(true);
      }
      if (operation == WRITEOUTSIDETX || current_state == PERSISTENT_NONTRANSACTIONAL_DIRTY) {
        transaction.setNontransactionalWrite(true);
      }
    }
  }

  /** */
  void checkTransitions() {
    for (operation = 0; operation < NUM_OPERATIONS; ++operation) {
      // rule out situations that do not apply
      if (!applies_to_scenario[operation][scenario]) continue;
      if ((operation == READOUTSIDETX
              || operation == RETRIEVEOUTSIDETX
              || operation == DETACHCOPYOUTSIDETXNTRTRU
              || operation == SERIALIZEOUTSIDETX)
          && !isNontransactionalReadSupported()) continue;
      if (operation == WRITEOUTSIDETX && !isNontransactionalWriteSupported()) continue;
      if (operation == COMMITRETAINVALUES && !isRetainValuesSupported()) continue;
      if (operation == MAKENONTRANSACTIONAL
          && !(isNontransactionalReadSupported() || isNontransactionalWriteSupported())) continue;
      int NUM_JDO1_STATES = NUM_STATES - 2; // JDO1 is tested so far here.
      for (current_state = 0; current_state < NUM_JDO1_STATES; ++current_state) {
        if (scenario == OPTIMISTIC_TX && current_state == PERSISTENT_CLEAN) continue;
        if ((current_state == TRANSIENT_CLEAN || current_state == TRANSIENT_DIRTY)
            && !isTransientTransactionalSupported())
          continue; // this state is not supported by implementation
        if (current_state == PERSISTENT_NONTRANSACTIONAL
            && !(isNontransactionalReadSupported() || isNontransactionalWriteSupported()))
          continue; // this state is not supported by implementation
        if (current_state == PERSISTENT_NONTRANSACTIONAL_DIRTY
            && !isNontransactionalWriteSupported()) continue;

        expected_state = transitions[operation][current_state];
        if (expected_state == IMPOSSIBLE) continue;
        if (expected_state == NOT_APPLICABLE) continue;
        if (expected_state == UNSPECIFIED) continue;
        if (expected_state == UNCHANGED) expected_state = current_state;
        try {
          transaction = pm.currentTransaction();
          if (transaction.isActive()) {
            if (debug) logger.debug("Transaction is active (but should not be), rolling back");
            transaction.rollback();
          }

          prepareTransactionAndJDOSettings(transaction);

          printSituation();

          StateTransitionObj obj = getInstanceInState(current_state);
          if (obj == null) { // could not get object in state
            if (transaction.isActive()) transaction.rollback();
            continue;
          }

          // Apply operation, catching possible exception
          Exception e = null;
          try {
            applyOperation(operation, obj);
          } catch (Exception excep) {
            if (excep instanceof javax.jdo.JDOUserException) {
              e = excep;
            } else {
              appendMessage(
                  ASSERTION_FAILED
                      + NL
                      + "StateTransitions: "
                      + scenario_string[scenario]
                      + "; current state "
                      + states[current_state]
                      + NL
                      + operations[operation]
                      + "; unexpected exception:"
                      + excep);
              continue;
            }
          }

          // Get new state, verify correct transition and exceptions occurred
          new_state = currentState(obj);
          if (expected_state == ERROR) {
            if (e == null) {
              appendMessage(
                  ASSERTION_FAILED
                      + NL
                      + "StateTransitions: "
                      + scenario_string[scenario]
                      + "; current state "
                      + states[current_state]
                      + NL
                      + operations[operation]
                      + "; JDOUserException should have been thrown");
            } else {
              if (!compareStates(new_state, current_state)) {
                appendMessage(
                    ASSERTION_FAILED
                        + NL
                        + "StateTransitions: "
                        + scenario_string[scenario]
                        + "; current state "
                        + states[current_state]
                        + NL
                        + operations[operation]
                        + "; JDOUserException properly thrown, but instance should remain in current state,"
                        + "instance changed state to "
                        + states[new_state]);
              }
            }
          }
          if (!compareStates(new_state, expected_state)) {
            appendMessage(
                ASSERTION_FAILED
                    + NL
                    + "StateTransitions: "
                    + scenario_string[scenario]
                    + "; current state "
                    + states[current_state]
                    + NL
                    + operations[operation]
                    + " transitioned instance to invalid state "
                    + states[new_state]
                    + "; expected state "
                    + states[expected_state]);
          }
          if (transaction.isActive()) transaction.rollback();
        } catch (Exception unexpected_exception) {
          if (debug) {
            unexpected_exception.printStackTrace();
          }
          if (transaction.isActive()) transaction.rollback();
          appendMessage(
              ASSERTION_FAILED
                  + NL
                  + "StateTransitions: "
                  + scenario_string[scenario]
                  + "; current state "
                  + states[current_state]
                  + NL
                  + operations[operation]
                  + "; unexpected exception caught: "
                  + unexpected_exception);
        }
      }
    }
  }

  /** */
  void printSituation() {
    if (debug) {
      logger.debug(
          " ("
              + scenario_string[scenario]
              + ", initial state="
              + states[current_state]
              + ", operation="
              + operations[operation]
              + ")");
    }
  }

  /** */
  @SuppressWarnings("ThrowFromFinallyBlock")
  void applyOperation(int operation, StateTransitionObj stobj) {
    StateTransitionObj obj = stobj;
    switch (operation) {
      case MAKEPERSISTENT:
        {
          pm.makePersistent(obj);
          break;
        }
      case DELETEPERSISTENT:
        {
          pm.deletePersistent(obj);
          break;
        }
      case MAKETRANSACTIONAL:
        {
          pm.makeTransactional(obj);
          break;
        }
      case MAKENONTRANSACTIONAL:
        {
          pm.makeNontransactional(obj);
          break;
        }
      case MAKETRANSIENT:
        {
          pm.makeTransient(obj);
          break;
        }
      case COMMITNORETAINVALUES:
      case COMMITRETAINVALUES:
      case DETACHALLONCOMMIT:
        {
          pm.currentTransaction().commit();
          break;
        }
      case ROLLBACKNORESTOREVALUES:
      case ROLLBACKRESTOREVALUES:
        {
          pm.currentTransaction().rollback();
          break;
        }
      case REFRESHDATASTORE:
      case REFRESHOPTIMISTIC:
        {
          pm.refresh(obj);
          break;
        }
      case EVICT:
        {
          pm.evict(obj);
          break;
        }
      case READOUTSIDETX:
      case READOPTIMISTIC:
      case READDATASTORE:
        {
          obj.readField();
          break;
        }
      case WRITEOUTSIDETX:
      case WRITEINSIDETX:
        {
          obj.writeField(42);
          break;
        }
      case RETRIEVEOUTSIDETX:
      case RETRIEVEINSIDETX:
        {
          pm.retrieve(obj);
          break;
        }
      case DETACHCOPYOUTSIDETXNTRTRU:
      case DETACHCOPYOUTSIDETXNTRFLS:
      case DETACHCOPYINSIDEDATASTORETX:
      case DETACHCOPYINSIDEOPTIMISTICTX:
        {
          pm.detachCopy(obj);
          break;
        }
      case SERIALIZEOUTSIDETX:
      case SERIALIZEDATASTORE:
      case SERIALIZEOPTIMISTIC:
        {
          ObjectOutputStream oos = null;
          try {
            oos = new ObjectOutputStream(new ByteArrayOutputStream());
            oos.writeObject(obj);
          } catch (IOException e) {
            throw new JDOFatalException(e.getMessage(), e);
          } finally {
            if (oos != null) {
              try {
                oos.close();
              } catch (IOException e) {
                throw new JDOFatalException(e.getMessage(), e);
              }
            }
          }
          break;
        }
      default:
        {
          appendMessage(
              ASSERTION_FAILED
                  + NL
                  + "StateTransitions: "
                  + scenario_string[scenario]
                  + "; internal error, illegal operation: "
                  + operation);
        }
    }
  }

  /**
   * Get an instance in the specified state.
   *
   * @param state the state
   * @return instance in the specified state.
   */
  public StateTransitionObj getInstanceInState(int state) {
    switch (state) {
      case TRANSIENT:
        return getTransientInstance();
      case PERSISTENT_NEW:
        return getPersistentNewInstance();
      case PERSISTENT_CLEAN:
        return getPersistentCleanInstance();
      case PERSISTENT_DIRTY:
        return getPersistentDirtyInstance();
      case HOLLOW:
        return getHollowInstance();
      case TRANSIENT_CLEAN:
        return getTransientCleanInstance();
      case TRANSIENT_DIRTY:
        return getTransientDirtyInstance();
      case PERSISTENT_NEW_DELETED:
        return getPersistentNewDeletedInstance();
      case PERSISTENT_DELETED:
        return getPersistentDeletedInstance();
      case PERSISTENT_NONTRANSACTIONAL:
        return getPersistentNontransactionalInstance();
      case PERSISTENT_NONTRANSACTIONAL_DIRTY:
        return getPersistentNontransactionalDirtyInstance();
      case DETACHED_CLEAN:
        return getDetachedCleanInstance();
      case DETACHED_DIRTY:
        return getDetachedDirtyInstance();
      default:
        return null;
    }
  }

  /**
   * @return transient instance
   */
  public StateTransitionObj getTransientInstance() {
    StateTransitionObj obj = new StateTransitionObj(23);
    int curr = currentState(obj);
    if (curr != TRANSIENT) {
      if (debug) {
        logger.debug(
            "StateTransitions: Unable to create transient instance, state is " + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent new instance
   */
  public StateTransitionObj getPersistentNewInstance() {
    StateTransitionObj obj = getTransientInstance();
    if (obj == null) return null;
    pm.makePersistent(obj); // should transition to persistent-new
    int curr = currentState(obj);
    if (curr != PERSISTENT_NEW) {
      if (debug) {
        logger.debug(
            "StateTransitions: Unable to create persistent-new instance"
                + " from transient instance via makePersistent(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent clean instance
   */
  public StateTransitionObj getPersistentCleanInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    StateTransitionObj sto = obj;
    sto.readField();
    int curr = currentState(sto);
    if (curr != PERSISTENT_CLEAN) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-clean instance"
                + " from a hollow instance by reading a field, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent dirty instance
   */
  public StateTransitionObj getPersistentDirtyInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    StateTransitionObj pcobj = obj;
    pcobj.writeField(23);
    int curr = currentState(obj);
    if (curr != PERSISTENT_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-dirty instance"
                + " from a hollow instance by writing a field, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return hollow instance
   */
  public StateTransitionObj getHollowInstance() {
    if (!transaction.isActive()) transaction.begin();
    if (!transaction.isActive())
      if (debug) logger.debug("getHollowInstance: Transaction should be active, but it is not");

    Extent<StateTransitionObj> extent = pm.getExtent(StateTransitionObj.class, false);
    Iterator<StateTransitionObj> iter = extent.iterator();
    if (!iter.hasNext()) {
      if (debug) logger.debug("Extent for StateTransitionObj should not be empty");
      return null;
    }
    StateTransitionObj obj = iter.next();

    pm.makeTransactional(obj);
    transaction.setRetainValues(false);
    transaction.commit(); // This should put the instance in the HOLLOW state

    prepareTransactionAndJDOSettings(transaction);

    int curr = currentState(obj);
    if (curr != HOLLOW && curr != PERSISTENT_NONTRANSACTIONAL) {
      if (debug) {
        logger.debug(
            "getHollowInstance: Attempt to get hollow instance via accessing extent failed, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return transient clean instance
   */
  public StateTransitionObj getTransientCleanInstance() {
    StateTransitionObj obj = getTransientInstance();
    if (obj == null) return null;
    pm.makeTransactional(obj);
    int curr = currentState(obj);
    if (curr != TRANSIENT_CLEAN) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create transient-clean instance"
                + " from a transient instance via makeTransactional(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return transient dirty instance
   */
  public StateTransitionObj getTransientDirtyInstance() {
    StateTransitionObj obj = getTransientCleanInstance();
    if (obj == null) return null;
    StateTransitionObj pcobj = obj;
    pcobj.writeField(23);
    int curr = currentState(obj);
    if (curr != TRANSIENT_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create transient-dirty instance"
                + " from a transient-clean instance via modifying a field, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persitent new deleted instance
   */
  public StateTransitionObj getPersistentNewDeletedInstance() {
    StateTransitionObj obj = getPersistentNewInstance();
    if (obj == null) return null;
    pm.deletePersistent(obj); // should transition to persistent-new-deleted
    int curr = currentState(obj);
    if (curr != PERSISTENT_NEW_DELETED) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-new-deleted instance"
                + " from a persistent-new instance via deletePersistent, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persitent deleted instance
   */
  public StateTransitionObj getPersistentDeletedInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    pm.deletePersistent(obj);
    int curr = currentState(obj);
    if (curr != PERSISTENT_DELETED) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-deleted instance"
                + " from a persistent instance via deletePersistent(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persient nontransactional instance
   */
  public StateTransitionObj getPersistentNontransactionalInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    boolean nontransactionalRead = pm.currentTransaction().getNontransactionalRead();
    pm.currentTransaction().setNontransactionalRead(true);
    obj.readField();
    pm.makeNontransactional(obj);
    pm.currentTransaction().setNontransactionalRead(nontransactionalRead);
    int curr = currentState(obj);
    if (curr != PERSISTENT_NONTRANSACTIONAL && curr != HOLLOW) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-nontransactional instance"
                + " from a persistent-clean instance via makeNontransactional(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persient nontransactional dirty instance
   */
  public StateTransitionObj getPersistentNontransactionalDirtyInstance() {
    StateTransitionObj obj = getPersistentNontransactionalInstance();
    if (obj == null) return null;
    obj.writeField(10000);
    int curr = currentState(obj);
    if (curr != PERSISTENT_NONTRANSACTIONAL_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create persistent-nontransactional-dirty instance"
                + " from a persistent-clean instance via makeNontransactional()/JDOHelper.makeDirty,"
                + " state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return detached clean instance
   */
  public StateTransitionObj getDetachedCleanInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    obj = pm.detachCopy(obj);
    int curr = currentState(obj);
    if (curr != DETACHED_CLEAN) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create detached-clean instance"
                + " from a persistent-clean instance via detachCopy,"
                + " state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return detached dirty instance
   */
  public StateTransitionObj getDetachedDirtyInstance() {
    StateTransitionObj obj = getHollowInstance();
    if (obj == null) return null;
    obj = pm.detachCopy(obj);
    obj.writeField(1000);
    int curr = currentState(obj);
    if (curr != DETACHED_DIRTY) {
      if (debug) {
        logger.debug(
            "StateTransition: Unable to create detached-dirty instance"
                + " from a persistent-clean instance via detachCopy/persistent field modification,"
                + " state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }
}
