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

package org.apache.jdo.tck.lifecycle;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
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 StateTransitionsReturnedObjects extends JDO_Test {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertions A5.9-1 through A5.5.8 (serialization, detachment, attachment) 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(StateTransitionsReturnedObjects.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 MAKEPERSISTENTOPTIMISTIC = 0;

  private static final int MAKEPERSISTENTDATASTORE = 1;
  private static final int DETACHCOPYOUTSIDETXNTRTRU = 2;
  private static final int DETACHCOPYOUTSIDETXNTRFLS = 3;
  private static final int DETACHCOPYINSIDEDATASTORETX = 4;
  private static final int DETACHCOPYINSIDEOPTIMISTICTX = 5;
  private static final int SERIALIZEOUTSIDETX = 6;
  private static final int SERIALIZEINSIDETX = 7;

  private static final int NUM_OPERATIONS = 8;

  private static final String[] operations = {
    "makePersistent with active optimistic tx",
    "makePersistent with active datastore tx",
    "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 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[][] statesOfReturnedObjects = { // [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 optimistic transaction
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, PERSISTENT_NEW,
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, PERSISTENT_NONTRANSACTIONAL,
      PERSISTENT_DIRTY
    },

    // makePersistent datastore transaction
    {
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, PERSISTENT_NEW,
      PERSISTENT_NEW, UNCHANGED, UNCHANGED,
      UNCHANGED, UNCHANGED, PERSISTENT_CLEAN,
      PERSISTENT_DIRTY
    },

    // detachCopy outside tx with NontransactionalRead=true
    {
      ERROR, IMPOSSIBLE, IMPOSSIBLE,
      IMPOSSIBLE, DETACHED_CLEAN, ERROR,
      IMPOSSIBLE, IMPOSSIBLE, IMPOSSIBLE,
      DETACHED_CLEAN, UNSPECIFIED, DETACHED_CLEAN,
      UNSPECIFIED
    },

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

    // detachCopy with active datastore tx
    {
      DETACHED_CLEAN, DETACHED_CLEAN, DETACHED_CLEAN,
      DETACHED_CLEAN, DETACHED_CLEAN, DETACHED_CLEAN,
      DETACHED_CLEAN, ERROR, ERROR,
      DETACHED_CLEAN, IMPOSSIBLE, DETACHED_CLEAN,
      DETACHED_CLEAN
    },

    // detachCopy with active optimistic tx
    {
      DETACHED_CLEAN, DETACHED_CLEAN, DETACHED_CLEAN,
      DETACHED_CLEAN, DETACHED_CLEAN, DETACHED_CLEAN,
      DETACHED_CLEAN, ERROR, ERROR,
      DETACHED_CLEAN, IMPOSSIBLE, DETACHED_CLEAN,
      DETACHED_CLEAN
    },

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

    // serialize with active tx
    {
      UNCHANGED, DETACHED_CLEAN, DETACHED_CLEAN,
      DETACHED_CLEAN, DETACHED_CLEAN, TRANSIENT,
      TRANSIENT, TRANSIENT, TRANSIENT,
      DETACHED_CLEAN, TRANSIENT, 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
    {false, true, false}, // makePersistent active optimistic transaction
    {true, false, false}, // makePersistent active datastore transaction
    // since the spec leaves detachCopy outside tx a bit underspecified,
    // we decided to disable this scanario for now
    {false, false, true}, // detachCopy outside tx with NontransactionalRead=true
    {false, false, false}, // detachCopy outside tx with NontransactionalRead=false
    {true, true, false}, // detachCopy with active datastore tx
    {true, true, false}, // detachCopy with active optimistic tx
    {false, false, true}, // serialize outside tx
    {true, true, false} // serialize with active 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(
            "StateTransitionsReturnedObjects 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) {
    if (scenario != NO_TX) {
      transaction.setNontransactionalRead(false);
      transaction.setNontransactionalWrite(false);
      pm.setDetachAllOnCommit(false);

      transaction.setOptimistic(scenario == OPTIMISTIC_TX);
      transaction.begin();
      if (!transaction.isActive())
        if (debug)
          logger.debug(
              "StateTransitionsReturnedObjects: Transaction should be active, but it is not");
    } else {
      if (operation == DETACHCOPYOUTSIDETXNTRTRU || operation == SERIALIZEOUTSIDETX) {
        transaction.setNontransactionalRead(true);
      }
      if (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 == DETACHCOPYOUTSIDETXNTRTRU || operation == SERIALIZEOUTSIDETX)
          && !isNontransactionalReadSupported()) continue;

      for (current_state = 0; current_state < NUM_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 = statesOfReturnedObjects[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;
          Object returnedObject = null;
          try {
            returnedObject = applyOperation(operation, obj);
          } catch (Exception excep) {
            if (excep instanceof javax.jdo.JDOUserException) {
              e = excep;
            } else {
              appendMessage(
                  ASSERTION_FAILED
                      + NL
                      + "StateTransitionsReturnedObjects: "
                      + scenario_string[scenario]
                      + "; current state "
                      + states[current_state]
                      + NL
                      + operations[operation]
                      + "; unexpected exception: "
                      + excep);
              continue;
            }
          }

          if (expected_state == ERROR) {
            if (e == null) {
              appendMessage(
                  ASSERTION_FAILED
                      + NL
                      + "StateTransitionsReturnedObjects: "
                      + scenario_string[scenario]
                      + "; current state "
                      + states[current_state]
                      + NL
                      + operations[operation]
                      + "; JDOUserException should have been thrown");
            } else {
              int stateOfObj = currentState(obj);
              if (stateOfObj != current_state) {
                appendMessage(
                    ASSERTION_FAILED
                        + NL
                        + "StateTransitionsReturnedObjects: "
                        + 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[stateOfObj]);
              }
            }
          } else {
            // Get new state, verify correct transition and exceptions occurred
            new_state = currentState(returnedObject);
            if (!compareStates(new_state, expected_state)) {
              appendMessage(
                  ASSERTION_FAILED
                      + NL
                      + "StateTransitionsReturnedObjects: "
                      + scenario_string[scenario]
                      + "; current state "
                      + states[current_state]
                      + NL
                      + operations[operation]
                      + " returned instance in invalid state "
                      + states[new_state]
                      + "; expected state "
                      + states[expected_state]);
            }
          }
          if (transaction.isActive()) transaction.rollback();
        } catch (Exception unexpected_exception) {
          if (transaction.isActive()) transaction.rollback();
          appendMessage(
              ASSERTION_FAILED
                  + NL
                  + "StateTransitionsReturnedObjects: "
                  + 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]
              + ", "
              + operations[operation]
              + ")");
    }
  }

  /** */
  @SuppressWarnings("ThrowFromFinallyBlock")
  Object applyOperation(int operation, StateTransitionObj stobj) {
    Object result = null;
    StateTransitionObj obj = stobj;
    switch (operation) {
      case MAKEPERSISTENTOPTIMISTIC:
      case MAKEPERSISTENTDATASTORE:
        result = pm.makePersistent(obj);
        break;

      case DETACHCOPYOUTSIDETXNTRTRU:
      case DETACHCOPYOUTSIDETXNTRFLS:
      case DETACHCOPYINSIDEDATASTORETX:
      case DETACHCOPYINSIDEOPTIMISTICTX:
        result = pm.detachCopy(obj);
        break;

      case SERIALIZEOUTSIDETX:
      case SERIALIZEINSIDETX:
        ObjectOutputStream oos = null;
        ObjectInputStream ois = null;
        try {
          ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
          oos = new ObjectOutputStream(byteArrayOutputStream);
          oos.writeObject(obj);
          ois =
              new ObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
          result = ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
          throw new JDOFatalException(e.getMessage(), e);
        } finally {
          try {
            if (oos != null) {
              oos.close();
            }
            if (ois != null) {
              ois.close();
            }
          } catch (IOException e) {
            throw new JDOFatalException(e.getMessage(), e);
          }
        }
        break;

      default:
        appendMessage(
            ASSERTION_FAILED
                + NL
                + "StateTransitionsReturnedObjects: "
                + scenario_string[scenario]
                + "; internal error, illegal operation: "
                + operation);
    }
    return result;
  }

  /**
   * 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(
            "StateTransitionsReturnedObjects: 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(
            "StateTransitionsReturnedObjects: 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(
            "StateTransitionsReturnedObjects: 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(
            "StateTransitionsReturnedObjects: 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(
            "StateTransitionsReturnedObjects: 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(
            "StateTransitionsReturnedObjects: Unable to create transient-dirty instance"
                + " from a transient-clean instance via modifying a field, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent 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(
            "StateTransitionsReturnedObjects: Unable to create persistent-new-deleted instance"
                + " from a persistent-new instance via deletePersistent, state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent 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(
            "StateTransitionsReturnedObjects: Unable to create persistent-deleted instance"
                + " from a persistent instance via deletePersistent(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent 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(
            "StateTransitionsReturnedObjects: Unable to create persistent-nontransactional instance"
                + " from a persistent-clean instance via makeNontransactional(), state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }

  /**
   * @return persistent 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(
            "StateTransitionsReturnedObjects: 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(
            "StateTransitionsReturnedObjects: 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(
            "StateTransitionsReturnedObjects: Unable to create detached-dirty instance"
                + " from a persistent-clean instance via detachCopy/persistent field modification,"
                + " state is "
                + states[curr]);
      }
      return null;
    }
    return obj;
  }
}
