/// <summary>
        /// Inserts code to handle case negative/independent pattern was found
        /// at the given position, returns position after inserted operations
        /// </summary>
        private SearchProgramOperation insertPatternFoundNegativeIndependent(SearchProgramOperation insertionPoint)
        {
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraph);

            if (isNegative)
            {
                // build the negative pattern was matched operation
                NegativePatternMatched patternMatched = new NegativePatternMatched(
                    NegativeIndependentPatternMatchedType.WithoutSubpatterns, negativeIndependentNamePrefix);
                insertionPoint = insertionPoint.Append(patternMatched);

                // abort the matching process
                CheckContinueMatchingOfNegativeFailed abortMatching =
                    new CheckContinueMatchingOfNegativeFailed(patternGraph.isIterationBreaking);
                insertionPoint = insertionPoint.Append(abortMatching);
            }
            else
            {
                // build the independent pattern was matched operation
                IndependentPatternMatched patternMatched = new IndependentPatternMatched(
                    NegativeIndependentPatternMatchedType.WithoutSubpatterns,
                    negativeIndependentNamePrefix);
                insertionPoint = insertionPoint.Append(patternMatched);

                if (!isNestedInNegative) // no match object needed(/available) if independent is part of negative
                {
                    // fill the match object with the candidates 
                    // which have passed all the checks for being a match
                    insertionPoint = insertInlinedMatchObjectCreation(insertionPoint,
                        patternGraph, MatchObjectType.Independent);
                    insertionPoint = insertMatchObjectBuilding(insertionPoint, 
                        patternGraph, MatchObjectType.Independent, false);
                    insertionPoint = insertMatchObjectBuilding(insertionPoint,
                        patternGraph, MatchObjectType.Independent, true);

                    // if an independent was inlined, we have to insert the local match into a set used for duplicate checking
                    if(wasIndependentInlined(patternGraph, indexOfSchedule))
                        insertionPoint = insertFillForDuplicateMatchChecking(insertionPoint);
                }

                // continue the matching process outside
                CheckContinueMatchingOfIndependentSucceeded continueMatching =
                    new CheckContinueMatchingOfIndependentSucceeded();
                insertionPoint = insertionPoint.Append(continueMatching);
            }

            return insertionPoint;
        }
        ///////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Completes check operations in search program from given currentOperation on
        /// (taking borderlines set by enclosing search program and check negative into account)
        /// Completion:
        /// - determine continuation point
        /// - insert remove isomorphy opertions needed for continuing there
        /// - insert continuing operation itself
        /// </summary>
        private static void CompleteCheckOperations(
            SearchProgramOperation currentOperation,
            SearchProgramOperation enclosingSearchProgram, // might be a negative/independent in case these are nested
            AlternativeCaseMatching enclosingAlternativeCase,
            CheckPartialMatchByNegativeOrIndependent enclosingCheckNegativeOrIndependent,
            SearchProgram topLevelSearchProgram)
        {
            // mainly dispatching and iteration method, traverses search program
            // real completion done in MoveOutwardsAppendingRemoveIsomorphyAndJump
            // outermost operation for that function is computed here, regarding negative patterns
            // program nesting structure: search program - [alternative] - [negative|independent]*

            // complete check operations by inserting failure code
            // find them in depth first search of search program
            while (currentOperation != null)
            {
                //////////////////////////////////////////////////////////
                if (currentOperation is CheckCandidate)
                //////////////////////////////////////////////////////////
                {
                    CheckCandidate checkCandidate =
                        (CheckCandidate)currentOperation;
                    checkCandidate.CheckFailedOperations =
                        new SearchProgramList(checkCandidate);
                    string[] neededElementsForCheckOperation = new string[1];
                    neededElementsForCheckOperation[0] = checkCandidate.PatternElementName;
                    MoveOutwardsAppendingRemoveIsomorphyAndJump(
                        checkCandidate,
                        neededElementsForCheckOperation,
                        enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                        topLevelSearchProgram);
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is CheckPartialMatch)
                //////////////////////////////////////////////////////////
                {
                    if (currentOperation is CheckPartialMatchByCondition)
                    {
                        CheckPartialMatchByCondition checkCondition =
                            (CheckPartialMatchByCondition)currentOperation;
                        checkCondition.CheckFailedOperations =
                            new SearchProgramList(checkCondition);
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkCondition,
                            checkCondition.NeededElements,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckPartialMatchForDuplicate)
                    {
                        CheckPartialMatchForDuplicate checkDuplicateMatch =
                            (CheckPartialMatchForDuplicate)currentOperation;
                        checkDuplicateMatch.CheckFailedOperations =
                            new SearchProgramList(checkDuplicateMatch);
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkDuplicateMatch,
                            checkDuplicateMatch.NeededElements,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckPartialMatchByNegativeOrIndependent)
                    {
                        CheckPartialMatchByNegativeOrIndependent checkNegativeOrIndependent =
                            (CheckPartialMatchByNegativeOrIndependent)currentOperation;

                        // ByNegative/ByIndependent is handled in CheckContinueMatchingFailed
                        // of the negative/independent case - enter negative/independent case
                        CompleteCheckOperations(
                            checkNegativeOrIndependent.NestedOperationsList,
                            enclosingCheckNegativeOrIndependent ?? enclosingSearchProgram,
                            enclosingCheckNegativeOrIndependent != null ? null : enclosingAlternativeCase,
                            checkNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckPartialMatchForSubpatternsFound)
                    {
                        CheckPartialMatchForSubpatternsFound checkSubpatternsFound =
                            (CheckPartialMatchForSubpatternsFound)currentOperation;

                        if (enclosingCheckNegativeOrIndependent == null)
                        {
                            // determine insertion point within check failed operations
                            // to append the nested check maximum matches
                            SearchProgramOperation insertionPoint =
                                checkSubpatternsFound.CheckFailedOperations;
                            while (insertionPoint.Next != null)
                            {
                                insertionPoint = insertionPoint.Next;
                            }

                            // append nested check maximum matches
                            CheckMaximumMatchesType checkMaxMatchesType = CheckMaximumMatchesType.Action;
                            if (enclosingSearchProgram is SearchProgramOfSubpattern ||
                                enclosingSearchProgram is SearchProgramOfAlternative)
                            {
                                checkMaxMatchesType = CheckMaximumMatchesType.Subpattern;
                            }
                            else if (enclosingSearchProgram is SearchProgramOfIterated)
                            {
                                checkMaxMatchesType = CheckMaximumMatchesType.Iterated;
                            }
                            CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                                new CheckContinueMatchingMaximumMatchesReached(checkMaxMatchesType, false,
                                                                               enclosingSearchProgram is SearchProgramOfActionParallelizationBody);
                            insertionPoint.Append(checkMaximumMatches);

                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkSubpatternsFound,
                                null,
                                enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                                topLevelSearchProgram);
                        }

                        // check subpatterns found has a further check maximum matches
                        // or check continue matching of negative failed nested within check failed code
                        // give it its special bit of attention here
                        CompleteCheckOperations(
                            checkSubpatternsFound.CheckFailedOperations,
                            enclosingSearchProgram,
                            enclosingAlternativeCase,
                            enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else
                    {
                        Debug.Assert(false, "unknown check partial match operation");
                    }
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is CheckContinueMatching)
                //////////////////////////////////////////////////////////
                {
                    if (currentOperation is CheckContinueMatchingMaximumMatchesReached)
                    {
                        CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                            (CheckContinueMatchingMaximumMatchesReached)currentOperation;
                        checkMaximumMatches.CheckFailedOperations =
                            new SearchProgramList(checkMaximumMatches);

                        if (checkMaximumMatches.ListHeadAdjustment)
                        {
                            MoveOutwardsAppendingListHeadAdjustment(checkMaximumMatches, checkMaximumMatches.InParallelizedBody);
                        }

                        string[] neededElementsForCheckOperation = new string[0];
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkMaximumMatches,
                            neededElementsForCheckOperation,
                            enclosingSearchProgram,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingOfNegativeFailed)
                    {
                        CheckContinueMatchingOfNegativeFailed checkFailed =
                            (CheckContinueMatchingOfNegativeFailed)currentOperation;
                        checkFailed.CheckFailedOperations =
                            new SearchProgramList(checkFailed);
                        if (checkFailed.IsIterationBreaking)
                        {
                            string[] neededElementsForCheckOperation = new string[0];
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                neededElementsForCheckOperation,
                                enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                        else
                        {
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                enclosingCheckNegativeOrIndependent.NeededElements,
                                enclosingAlternativeCase ?? enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                    }
                    else if (currentOperation is CheckContinueMatchingOfIndependentSucceeded)
                    {
                        CheckContinueMatchingOfIndependentSucceeded checkSucceeded =
                            (CheckContinueMatchingOfIndependentSucceeded)currentOperation;
                        checkSucceeded.CheckFailedOperations = // yep, rotten wording
                                                               new SearchProgramList(checkSucceeded);
                        MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump(
                            checkSucceeded,
                            (CheckPartialMatchByIndependent)enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingOfIndependentFailed)
                    {
                        CheckContinueMatchingOfIndependentFailed checkFailed =
                            (CheckContinueMatchingOfIndependentFailed)currentOperation;
                        checkFailed.CheckFailedOperations =
                            new SearchProgramList(checkFailed);
                        if (checkFailed.IsIterationBreaking)
                        {
                            string[] neededElementsForCheckOperation = new string[0];
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                neededElementsForCheckOperation,
                                enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                        else
                        {
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                checkFailed.CheckIndependent.NeededElements,
                                enclosingAlternativeCase ?? enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                    }
                    else if (currentOperation is CheckContinueMatchingTasksLeft)
                    {
                        CheckContinueMatchingTasksLeft tasksLeft =
                            (CheckContinueMatchingTasksLeft)currentOperation;

                        // determine insertion point within check failed operations
                        // to append the nested check maximum matches
                        SearchProgramOperation insertionPoint =
                            tasksLeft.CheckFailedOperations;
                        while (insertionPoint.Next != null)
                        {
                            insertionPoint = insertionPoint.Next;
                        }

                        // append nested check maximum matches
                        CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                            new CheckContinueMatchingMaximumMatchesReached(
                                enclosingSearchProgram is SearchProgramOfIterated ? CheckMaximumMatchesType.Iterated : CheckMaximumMatchesType.Subpattern,
                                false, topLevelSearchProgram is SearchProgramOfActionParallelizationBody);
                        insertionPoint.Append(checkMaximumMatches);

                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            tasksLeft,
                            null,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                            topLevelSearchProgram);

                        // check tasks left has a further check maximum matches nested within check failed code
                        // give it its special bit of attention here
                        CompleteCheckOperations(
                            tasksLeft.CheckFailedOperations,
                            enclosingSearchProgram,
                            enclosingAlternativeCase,
                            enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingIteratedPatternNonNullMatchFound)
                    {
                        // was built completely, nothing to complete
                    }
                    else
                    {
                        Debug.Assert(false, "unknown check abort matching operation");
                    }
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is AlternativeCaseMatching)
                //////////////////////////////////////////////////////////
                {
                    // depth first
                    CompleteCheckOperations(
                        currentOperation.GetNestedSearchOperationsList(),
                        enclosingSearchProgram,
                        (AlternativeCaseMatching)currentOperation,
                        null,
                        topLevelSearchProgram);
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation.IsSearchNestingOperation())
                //////////////////////////////////////////////////////////
                {
                    // depth first
                    CompleteCheckOperations(
                        currentOperation.GetNestedSearchOperationsList(),
                        enclosingSearchProgram,
                        enclosingAlternativeCase,
                        enclosingCheckNegativeOrIndependent,
                        topLevelSearchProgram);
                }

                // breadth
                currentOperation = currentOperation.Next;
            }
        }
        /// <summary>
        /// Inserts code to check whether the subpatterns were found and code for case there were some
        /// at the given position, returns position after inserted operations
        /// </summary>
        private SearchProgramOperation insertCheckForSubpatternsFoundNegativeIndependent(SearchProgramOperation insertionPoint)
        {
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraph);

            // check whether there were no subpattern matches found
            CheckPartialMatchForSubpatternsFound checkSubpatternsFound =
                new CheckPartialMatchForSubpatternsFound(negativeIndependentNamePrefix);
            SearchProgramOperation continuationPointAfterSubpatternsFound =
                   insertionPoint.Append(checkSubpatternsFound);
            checkSubpatternsFound.CheckFailedOperations =
                new SearchProgramList(checkSubpatternsFound);
            insertionPoint = checkSubpatternsFound.CheckFailedOperations;

            if (isNegative)
            {
                // ---- check failed, some subpattern matches found, negative pattern and subpatterns were matched
                // build the negative pattern was matched operation
                NegativePatternMatched patternMatched = new NegativePatternMatched(
                    NegativeIndependentPatternMatchedType.ContainingSubpatterns, negativeIndependentNamePrefix);
                insertionPoint = insertionPoint.Append(patternMatched);

                // ---- abort the matching process
                CheckContinueMatchingOfNegativeFailed abortMatching =
                    new CheckContinueMatchingOfNegativeFailed(patternGraph.isIterationBreaking);
                insertionPoint = insertionPoint.Append(abortMatching);
            }
            else
            {
                // ---- check failed, some subpattern matches found, independent pattern and subpatterns were matched
                // build the independent pattern was matched operation
                IndependentPatternMatched patternMatched = new IndependentPatternMatched(
                    NegativeIndependentPatternMatchedType.ContainingSubpatterns,
                    negativeIndependentNamePrefix);
                insertionPoint = insertionPoint.Append(patternMatched);

                if (!isNestedInNegative) // no match object needed(/available) if independent is part of negative
                {
                    // ---- fill the match object with the candidates 
                    // ---- which have passed all the checks for being a match
                    insertionPoint = insertInlinedMatchObjectCreation(insertionPoint, 
                        patternGraph, MatchObjectType.Independent);
                    insertionPoint = insertMatchObjectBuilding(insertionPoint,
                        patternGraph, MatchObjectType.Independent, false);
                    insertionPoint = insertMatchObjectBuilding(insertionPoint,
                        patternGraph, MatchObjectType.Independent, true);

                    // if an independent was inlined, we have to insert the local match into a set used for duplicate checking
                    if(wasIndependentInlined(patternGraph, indexOfSchedule))
                        insertionPoint = insertFillForDuplicateMatchChecking(insertionPoint);
                }

                // ---- continue the matching process outside
                CheckContinueMatchingOfIndependentSucceeded continueMatching =
                    new CheckContinueMatchingOfIndependentSucceeded();
                insertionPoint = insertionPoint.Append(continueMatching);
            }

            // nesting level up
            insertionPoint = continuationPointAfterSubpatternsFound;

            return insertionPoint;
        }