createNewCurrentStep(theResults[0], entry, store, action.getId(), step, previousIds, transientVars, ps);
if (!action.isFinish()) { createNewCurrentStep(theResults[0], entry, store, action.getId(), step, previousIds, transientVars, ps); }
    protected boolean transitionWorkflow(WorkflowEntry entry, List currentSteps, WorkflowStore store, WorkflowDescriptor wf, ActionDescriptor action, Map transientVars, Map inputs, PropertySet ps) throws WorkflowException {        Map cache = (Map) stateCache.get();        if (cache != null) {            cache.clear();        } else {            stateCache.set(new HashMap());        }        Step step = getCurrentStep(wf, action.getId(), currentSteps, transientVars, ps);        // validate transientVars (optional)        Map unmodifiableTransients = Collections.unmodifiableMap(transientVars);        if (action.getValidators().size() > 0) {            verifyInputs(entry, action.getValidators(), unmodifiableTransients, ps);        }        //we're leaving the current step, so let's execute its post-functions        //check if we actually have a current step        if (step != null) {            List stepPostFunctions = wf.getStep(step.getStepId()).getPostFunctions();            for (Iterator iterator = stepPostFunctions.iterator();                    iterator.hasNext();) {                FunctionDescriptor function = (FunctionDescriptor) iterator.next();                executeFunction(function, transientVars, ps);            }        }        // preFunctions        List preFunctions = action.getPreFunctions();        for (Iterator iterator = preFunctions.iterator(); iterator.hasNext();) {            FunctionDescriptor function = (FunctionDescriptor) iterator.next();            executeFunction(function, transientVars, ps);        }        // check each conditional result        List conditionalResults = action.getConditionalResults();        List extraPreFunctions = null;        List extraPostFunctions = null;        ResultDescriptor[] theResults = new ResultDescriptor[1];        for (Iterator iterator = conditionalResults.iterator();                iterator.hasNext();) {            ConditionalResultDescriptor conditionalResult = (ConditionalResultDescriptor) iterator.next();            if (passesConditions(null, conditionalResult.getConditions(), unmodifiableTransients, ps, (step != null) ? step.getStepId() : (-1))) {                //if (evaluateExpression(conditionalResult.getCondition(), entry, wf.getRegisters(), null, transientVars)) {                theResults[0] = conditionalResult;                if (conditionalResult.getValidators().size() > 0) {                    verifyInputs(entry, conditionalResult.getValidators(), unmodifiableTransients, ps);                }                extraPreFunctions = conditionalResult.getPreFunctions();                extraPostFunctions = conditionalResult.getPostFunctions();                break;            }        }        // use unconditional-result if a condition hasn't been met        if (theResults[0] == null) {            theResults[0] = action.getUnconditionalResult();            verifyInputs(entry, theResults[0].getValidators(), unmodifiableTransients, ps);            extraPreFunctions = theResults[0].getPreFunctions();            extraPostFunctions = theResults[0].getPostFunctions();        }        if (log.isDebugEnabled()) {            log.debug("theResult=" + theResults[0].getStep() + " " + theResults[0].getStatus());        }        if ((extraPreFunctions != null) && (extraPreFunctions.size() > 0)) {            // run any extra pre-functions that haven't been run already            for (Iterator iterator = extraPreFunctions.iterator();                    iterator.hasNext();) {                FunctionDescriptor function = (FunctionDescriptor) iterator.next();                executeFunction(function, transientVars, ps);            }        }        // go to next step        if (theResults[0].getSplit() != 0) {            // the result is a split request, handle it correctly            SplitDescriptor splitDesc = wf.getSplit(theResults[0].getSplit());            Collection results = splitDesc.getResults();            List splitPreFunctions = new ArrayList();            List splitPostFunctions = new ArrayList();            //check all results in the split and verify the input against any validators specified            //also build up all the pre and post functions that should be called.            for (Iterator iterator = results.iterator(); iterator.hasNext();) {                ResultDescriptor resultDescriptor = (ResultDescriptor) iterator.next();                if (resultDescriptor.getValidators().size() > 0) {                    verifyInputs(entry, resultDescriptor.getValidators(), unmodifiableTransients, ps);                }                splitPreFunctions.addAll(resultDescriptor.getPreFunctions());                splitPostFunctions.addAll(resultDescriptor.getPostFunctions());            }            // now execute the pre-functions            for (Iterator iterator = splitPreFunctions.iterator();                    iterator.hasNext();) {                FunctionDescriptor function = (FunctionDescriptor) iterator.next();                executeFunction(function, transientVars, ps);            }            // now make these steps...            boolean moveFirst = true;            theResults = new ResultDescriptor[results.size()];            results.toArray(theResults);            for (Iterator iterator = results.iterator(); iterator.hasNext();) {                ResultDescriptor resultDescriptor = (ResultDescriptor) iterator.next();                Step moveToHistoryStep = null;                if (moveFirst) {                    moveToHistoryStep = step;                }                long[] previousIds = null;                if (step != null) {                    previousIds = new long[] {step.getId()};                }                createNewCurrentStep(resultDescriptor, entry, store, action.getId(), moveToHistoryStep, previousIds, transientVars, ps);                moveFirst = false;            }            // now execute the post-functions            for (Iterator iterator = splitPostFunctions.iterator();                    iterator.hasNext();) {                FunctionDescriptor function = (FunctionDescriptor) iterator.next();                executeFunction(function, transientVars, ps);            }        } else if (theResults[0].getJoin() != 0) {            // this is a join, finish this step...            JoinDescriptor joinDesc = wf.getJoin(theResults[0].getJoin());            step = store.markFinished(step, action.getId(), new Date(), theResults[0].getOldStatus(), context.getCaller());            store.moveToHistory(step);            // ... now check to see if the expression evaluates            // (get only current steps that have a result to this join)            Collection joinSteps = new ArrayList();            joinSteps.add(step);            //currentSteps = store.findCurrentSteps(id); // shouldn't need to refresh the list            for (Iterator iterator = currentSteps.iterator();                    iterator.hasNext();) {                Step currentStep = (Step) iterator.next();                if (currentStep.getId() != step.getId()) {                    StepDescriptor stepDesc = wf.getStep(currentStep.getStepId());                    if (stepDesc.resultsInJoin(theResults[0].getJoin())) {                        joinSteps.add(currentStep);                    }                }            }            //we also need to check history steps that were finished before this one            //that might be part of the join            List historySteps = store.findHistorySteps(entry.getId());            for (Iterator i = historySteps.iterator(); i.hasNext();) {                Step historyStep = (Step) i.next();                if (historyStep.getId() != step.getId()) {                    StepDescriptor stepDesc = wf.getStep(historyStep.getStepId());                    if (stepDesc.resultsInJoin(theResults[0].getJoin())) {                        joinSteps.add(historyStep);                    }                }            }            JoinNodes jn = new JoinNodes(joinSteps);            transientVars.put("jn", jn);            //todo verify that 0 is the right value for currentstep here            if (passesConditions(null, joinDesc.getConditions(), unmodifiableTransients, ps, 0)) {                // move the rest without creating a new step ...                ResultDescriptor joinresult = joinDesc.getResult();                if (joinresult.getValidators().size() > 0) {                    verifyInputs(entry, joinresult.getValidators(), unmodifiableTransients, ps);                }                // now execute the pre-functions                for (Iterator iterator = joinresult.getPreFunctions().iterator();                        iterator.hasNext();) {                    FunctionDescriptor function = (FunctionDescriptor) iterator.next();                    executeFunction(function, transientVars, ps);                }                long[] previousIds = new long[joinSteps.size()];                int i = 1;                for (Iterator iterator = joinSteps.iterator();                        iterator.hasNext();) {                    Step currentStep = (Step) iterator.next();                    if (currentStep.getId() != step.getId()) {                        //if this is already a history step (eg, for all join steps completed prior to this one),                        //we don't move it, since it's already history.                        if (!historySteps.contains(currentStep)) {                            store.moveToHistory(currentStep);                        }                        previousIds[i] = currentStep.getId();                        i++;                    }                }                // ... now finish this step normally                previousIds[0] = step.getId();                theResults[0] = joinDesc.getResult();                //we pass in null for the current step since we've already moved it to history above                createNewCurrentStep(joinDesc.getResult(), entry, store, action.getId(), null, previousIds, transientVars, ps);                // now execute the post-functions                for (Iterator iterator = joinresult.getPostFunctions().iterator();                        iterator.hasNext();) {                    FunctionDescriptor function = (FunctionDescriptor) iterator.next();                    executeFunction(function, transientVars, ps);                }            }        } else {            // normal finish, no splits or joins            long[] previousIds = null;            if (step != null) {                previousIds = new long[] {step.getId()};            }            createNewCurrentStep(theResults[0], entry, store, action.getId(), step, previousIds, transientVars, ps);        }        // postFunctions (BOTH)        if (extraPostFunctions != null) {            for (Iterator iterator = extraPostFunctions.iterator();                    iterator.hasNext();) {                FunctionDescriptor function = (FunctionDescriptor) iterator.next();                executeFunction(function, transientVars, ps);            }        }        List postFunctions = action.getPostFunctions();        for (Iterator iterator = postFunctions.iterator(); iterator.hasNext();) {            FunctionDescriptor function = (FunctionDescriptor) iterator.next();            executeFunction(function, transientVars, ps);        }        //if executed action was an initial action then workflow is activated        if ((wf.getInitialAction(action.getId()) != null) && (entry.getState() != WorkflowEntry.ACTIVATED)) {            changeEntryState(entry.getId(), WorkflowEntry.ACTIVATED);        }        //if it's a finish action, then we halt        if (action.isFinish()) {            completeEntry(action, entry.getId(), getCurrentSteps(entry.getId()));            return true;        }        //get available autoexec actions        int[] availableAutoActions = getAvailableAutoActions(entry.getId(), inputs);        for (int j = 0; j < availableAutoActions.length; j++) {            int actionId = availableAutoActions[j];            doAction(entry.getId(), actionId, inputs);            break;        }        return false;    }