/*
 * 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 e = pm.getExtent(StateTransitionObj.class, false);
        Iterator 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] + ")");
        }
    }

    /** */
    Object applyOperation(int operation, StateTransitionObj stobj)
    {
        Object result = null;
        StateTransitionObj obj = (StateTransitionObj) 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 e) {
                    throw new JDOFatalException(e.getMessage(), e);
                } catch (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 = (StateTransitionObj) 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 = (StateTransitionObj) 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 extent = pm.getExtent(StateTransitionObj.class, false);
        Iterator iter = extent.iterator();
        if( !iter.hasNext() ){
            if (debug)
                logger.debug("Extent for StateTransitionObj should not be empty");
            return null;
        }
        StateTransitionObj obj = (StateTransitionObj) 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 = (StateTransitionObj) 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 = (StateTransitionObj) 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 = (StateTransitionObj) 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;
    }
}
