/// <summary>
        /// Search program operations implementing the
        /// Independent search plan operation (searching of positive application condition)
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildIndependent(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            PatternGraph independentPatternGraph)
        {
            // fill needed elements array for CheckPartialMatchByIndependent
            string[] neededElements = ComputeNeededElements(independentPatternGraph);

            CheckPartialMatchByIndependent checkIndependent =
               new CheckPartialMatchByIndependent(neededElements);
            SearchProgramOperation continuationPoint =
                insertionPoint.Append(checkIndependent);
            checkIndependent.NestedOperationsList =
                new SearchProgramList(checkIndependent);
            insertionPoint = checkIndependent.NestedOperationsList;

            bool enclosingIsNegative = isNegative;
            isNegative = false;
            PatternGraph enclosingPatternGraph = patternGraphWithNestingPatterns.Peek();
            patternGraphWithNestingPatterns.Push(independentPatternGraph);
            isoSpaceNeverAboveMaxIsoSpace = patternGraphWithNestingPatterns.Peek().maxIsoSpace < (int)LGSPElemFlags.MAX_ISO_SPACE;
            bool parallelizedBak = parallelized;
            parallelized &= patternGraphWithNestingPatterns.Peek().parallelizedSchedule != null; // the idpt within a parallelized head may be non-parallelized
            int indexOfScheduleBak = indexOfSchedule;
            if(parallelized) indexOfSchedule = 0; // the idpt of a parallelized body at index 1 is still only at index 0

            string independentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());
            bool independentContainsSubpatterns = independentPatternGraph.embeddedGraphsPlusInlined.Length >= 1
                || independentPatternGraph.alternativesPlusInlined.Length >= 1
                || independentPatternGraph.iteratedsPlusInlined.Length >= 1;
            InitializeNegativeIndependentMatching initIdpt = new InitializeNegativeIndependentMatching(
                independentContainsSubpatterns,
                independentNamePrefix,
                isoSpaceNeverAboveMaxIsoSpace,
                parallelized);
            insertionPoint = insertionPoint.Append(initIdpt);
            insertionPoint = insertVariableDeclarationsNegIdpt(insertionPoint, independentPatternGraph);

            //---------------------------------------------------------------------------
            // build independent pattern
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                0,
                insertionPoint);
            //---------------------------------------------------------------------------

            FinalizeNegativeIndependentMatching finalize = new FinalizeNegativeIndependentMatching(
                isoSpaceNeverAboveMaxIsoSpace, parallelized);
            insertionPoint = insertionPoint.Append(finalize);

            // independent pattern built by now
            // continue at the end of the list handed in
            insertionPoint = continuationPoint;

            // the matcher program of independent didn't find a match,
            // we fell through the loops and reached this point -> abort the matching process / try next candidate
            CheckContinueMatchingOfIndependentFailed abortMatching =
                new CheckContinueMatchingOfIndependentFailed(checkIndependent, independentPatternGraph.isIterationBreaking);
            checkIndependent.CheckIndependentFailed = abortMatching;
            insertionPoint = insertionPoint.Append(abortMatching);

            patternGraphWithNestingPatterns.Pop();
            parallelized = parallelizedBak;
            indexOfSchedule = indexOfScheduleBak;
            isNegative = enclosingIsNegative;

            //---------------------------------------------------------------------------
            // build next operation
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                currentOperationIndex + 1,
                insertionPoint);
            //---------------------------------------------------------------------------

            return insertionPoint;
        }
        /// <summary>
        /// move outwards from starting point on until operation to continue at is found
        /// appending restore isomorphy at insertion point for isomorphy written on the way
        /// returns operation to continue at
        /// </summary>
        private static SearchProgramOperation MoveOutwardsAppendingRemoveIsomorphy(
            SearchProgramOperation startingPoint,
            ref SearchProgramOperation insertionPoint,
            string[] neededElementsForCheckOperation,
            SearchProgramOperation outermostOperation,
            SearchProgram topLevelSearchProgram)
        {
            // currently focused operation on our way outwards
            SearchProgramOperation op = startingPoint;
            // move outwards until operation to continue at is found
            bool creationPointOfDominatingElementFound = false;
            bool iterationReached = false;

            do
            {
                op = op.Previous;

                // insert code to clean up isomorphy information written by candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidate)
                {
                    AcceptCandidate writeIsomorphy =
                        op as AcceptCandidate;
                    AbandonCandidate restoreIsomorphy =
                        new AbandonCandidate(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode,
                            writeIsomorphy.NeverAboveMaxIsoSpace,
                            writeIsomorphy.Parallel,
                            writeIsomorphy.LockForAllThreads);
                    insertionPoint = insertionPoint.Append(restoreIsomorphy);
                }
                // insert code to clean up isomorphy information written by global candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidateGlobal)
                {
                    AcceptCandidateGlobal writeIsomorphy =
                        op as AcceptCandidateGlobal;
                    AbandonCandidateGlobal removeIsomorphy =
                        new AbandonCandidateGlobal(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode,
                            writeIsomorphy.NeverAboveMaxIsoSpace,
                            writeIsomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(removeIsomorphy);
                }
                // insert code to clean up isomorphy information written by patternpath candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidatePatternpath)
                {
                    AcceptCandidatePatternpath writeIsomorphy =
                        op as AcceptCandidatePatternpath;
                    AbandonCandidatePatternpath removeIsomorphy =
                        new AbandonCandidatePatternpath(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode);
                    insertionPoint = insertionPoint.Append(removeIsomorphy);
                }
                // insert code to remove iterated pattern acceptance
                if (op is AcceptIterated)
                {
                    AcceptIterated acceptIterated =
                        op as AcceptIterated;
                    AbandonIterated abandonIterated =
                        new AbandonIterated();
                    insertionPoint = insertionPoint.Append(abandonIterated);
                }
                // insert code to undo subpattern matching initialization if we leave the subpattern matching method
                if (op is InitializeSubpatternMatching)
                {
                    InitializeSubpatternMatching initialize =
                        op as InitializeSubpatternMatching;
                    FinalizeSubpatternMatching finalize =
                        new FinalizeSubpatternMatching(initialize.Type);
                    insertionPoint = insertionPoint.Append(finalize);
                }
                // insert code to undo negative/independent matching initialization if we leave the negative/independent matching method
                if (op is InitializeNegativeIndependentMatching)
                {
                    InitializeNegativeIndependentMatching initialize =
                        op as InitializeNegativeIndependentMatching;
                    FinalizeNegativeIndependentMatching finalize =
                        new FinalizeNegativeIndependentMatching(initialize.NeverAboveMaxIsoSpace, initialize.Parallel);
                    insertionPoint = insertionPoint.Append(finalize);
                }

                // determine operation to continue at
                // found by looking at the graph elements
                // the check operation depends on / is dominated by
                // its the first element iteration on our way outwards the search program
                // after or at the point of a get element operation
                // of some dominating element the check depends on
                // (or the outermost operation if no iteration is found until it is reached)
                if (op is GetCandidate || op is BothDirectionsIteration)
                {
                    if (creationPointOfDominatingElementFound == false)
                    {
                        if (neededElementsForCheckOperation != null)
                        {
                            foreach (string dominating in neededElementsForCheckOperation)
                            {
                                GetCandidate            getCandidate   = op as GetCandidate;
                                BothDirectionsIteration bothDirections = op as BothDirectionsIteration;
                                if (getCandidate != null && getCandidate.PatternElementName == dominating ||
                                    bothDirections != null && bothDirections.PatternElementName == dominating)
                                {
                                    creationPointOfDominatingElementFound = true;
                                    iterationReached = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // needed elements == null means everything fits,
                            // take first element iteration on our way outwards the search program
                            // (or the outermost operation if no iteration is found until it is reached)
                            creationPointOfDominatingElementFound = true;
                            iterationReached = false;
                        }
                    }
                    if (op is GetCandidateByIteration || op is GetCandidateByIterationParallel || op is BothDirectionsIteration)
                    {
                        iterationReached = true;
                    }
                }
            }while(!(creationPointOfDominatingElementFound && iterationReached) &&
                   op != outermostOperation);

            return(op);
        }
        /// <summary>
        /// Search program operations implementing the
        /// Negative search plan operation (searching of negative application condition)
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildNegative(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            PatternGraph negativePatternGraph)
        {
            // fill needed elements array for CheckPartialMatchByNegative
            string[] neededElements = ComputeNeededElements(negativePatternGraph);

            CheckPartialMatchByNegative checkNegative =
               new CheckPartialMatchByNegative(neededElements);
            SearchProgramOperation continuationPoint =
                insertionPoint.Append(checkNegative);
            checkNegative.NestedOperationsList =
                new SearchProgramList(checkNegative);
            insertionPoint = checkNegative.NestedOperationsList;

            bool enclosingIsNegative = isNegative;
            bool enclosingIsNestedInNegative = isNestedInNegative;
            isNegative = true;
            isNestedInNegative = true;
            PatternGraph enclosingPatternGraph = patternGraphWithNestingPatterns.Peek();
            patternGraphWithNestingPatterns.Push(negativePatternGraph);
            isoSpaceNeverAboveMaxIsoSpace = patternGraphWithNestingPatterns.Peek().maxIsoSpace < (int)LGSPElemFlags.MAX_ISO_SPACE;
            bool parallelizedBak = parallelized;
            parallelized &= patternGraphWithNestingPatterns.Peek().parallelizedSchedule != null; // the neg within a parallelized head may be non-parallelized
            int indexOfScheduleBak = indexOfSchedule;
            if(parallelized) indexOfSchedule = 0; // the neg of a parallelized body at index 1 is still only at index 0

            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());
            bool negativeContainsSubpatterns = negativePatternGraph.embeddedGraphsPlusInlined.Length >= 1
                || negativePatternGraph.alternativesPlusInlined.Length >= 1
                || negativePatternGraph.iteratedsPlusInlined.Length >= 1;
            InitializeNegativeIndependentMatching initNeg = new InitializeNegativeIndependentMatching(
                negativeContainsSubpatterns, 
                negativeIndependentNamePrefix, 
                isoSpaceNeverAboveMaxIsoSpace,
                parallelized);
            insertionPoint = insertionPoint.Append(initNeg);
            insertionPoint = insertVariableDeclarationsNegIdpt(insertionPoint, negativePatternGraph);

            //---------------------------------------------------------------------------
            // build negative pattern
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                0,
                insertionPoint);
            //---------------------------------------------------------------------------

            FinalizeNegativeIndependentMatching finalize = new FinalizeNegativeIndependentMatching(
                isoSpaceNeverAboveMaxIsoSpace, parallelized);
            insertionPoint = insertionPoint.Append(finalize);

            // negative pattern built by now
            // continue at the end of the list handed in
            insertionPoint = continuationPoint;
            patternGraphWithNestingPatterns.Pop();
            parallelized = parallelizedBak;
            indexOfSchedule = indexOfScheduleBak;
            isNegative = enclosingIsNegative;
            isNestedInNegative = enclosingIsNestedInNegative;

            //---------------------------------------------------------------------------
            // build next operation
            insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram(
                currentOperationIndex + 1,
                insertionPoint);
            //---------------------------------------------------------------------------

            return insertionPoint;
        }