/// <summary>
        /// Search program operations implementing the
        /// ActionPreset search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildActionPreset(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());
            Debug.Assert(negativeIndependentNamePrefix == "", "Top-level maybe preset in negative/independent search plan");
            Debug.Assert(programType != SearchProgramType.Subpattern, "Maybe preset in subpattern");
            Debug.Assert(programType != SearchProgramType.AlternativeCase, "Maybe preset in alternative");
            Debug.Assert(programType != SearchProgramType.Iterated, "Maybe preset in iterated");

            // get candidate from inputs
            GetCandidateByDrawing fromInputs =
                new GetCandidateByDrawing(
                    GetCandidateByDrawingType.FromInputs,
                    target.PatternElement.Name,
                    isNode);
            insertionPoint = insertionPoint.Append(fromInputs);

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check candidate for isomorphy 
            if (isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            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
        /// parallelized PickFromIndex search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelPickFromIndex(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            IndexAccess index,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = "";
            string iterationType = TypesHelper.TypeName(index.Index is AttributeIndexDescription ?
                ((AttributeIndexDescription)index.Index).GraphElementType :
                ((IncidenceCountIndexDescription)index.Index).StartNodeType);
            string indexSetType = NamesOfEntities.IndexSetType(model.ModelName);

            // iterate available index elements
            GetCandidateByIterationParallel elementsIteration;
            if(index is IndexAccessEquality)
            {
                IndexAccessEquality indexEquality = (IndexAccessEquality)index;
                SourceBuilder equalityExpression = new SourceBuilder();
                indexEquality.Expr.Emit(equalityExpression);
                elementsIteration =
                    new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Equality,
                        equalityExpression.ToString(),
                        isNode,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            else if(index is IndexAccessAscending)
            {
                IndexAccessAscending indexAscending = (IndexAccessAscending)index;
                SourceBuilder fromExpression = new SourceBuilder();
                if(indexAscending.From != null)
                    indexAscending.From.Emit(fromExpression);
                SourceBuilder toExpression = new SourceBuilder();
                if(indexAscending.To != null)
                    indexAscending.To.Emit(toExpression);
                elementsIteration =
                    new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Ascending,
                        indexAscending.From != null ? fromExpression.ToString() : null,
                        indexAscending.IncludingFrom,
                        indexAscending.To != null ? toExpression.ToString() : null,
                        indexAscending.IncludingTo,
                        isNode,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            else //if(index is IndexAccessDescending)
            {
                IndexAccessDescending indexDescending = (IndexAccessDescending)index;
                SourceBuilder fromExpression = new SourceBuilder();
                if(indexDescending.From != null)
                    indexDescending.From.Emit(fromExpression);
                SourceBuilder toExpression = new SourceBuilder();
                if(indexDescending.To != null)
                    indexDescending.To.Emit(toExpression);
                elementsIteration =
                    new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Descending,
                        indexDescending.From != null ? fromExpression.ToString() : null,
                        indexDescending.IncludingFrom,
                        indexDescending.To != null ? toExpression.ToString() : null,
                        indexDescending.IncludingTo,
                        isNode,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            firstLoopPassed = true;

            SearchProgramOperation continuationPoint =
                insertionPoint.Append(elementsIteration);
            elementsIteration.NestedOperationsList =
                new SearchProgramList(elementsIteration);
            insertionPoint = elementsIteration.NestedOperationsList;

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within candidate iteration built by now -
            // continue at the end of the list after storage iteration
            insertionPoint = continuationPoint;

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// parallelized Extend Incoming|Outgoing|IncomingOrOutgoing search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelIncident(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNodeNode source,
            SearchPlanEdgeNode target,
            IsomorphyInformation isomorphy,
            IncidentEdgeType edgeType)
        {
#if RANDOM_LOOKUP_LIST_START
            // insert list heads randomization, thus randomized extend
            RandomizeListHeads randomizeListHeads =
                new RandomizeListHeads(
                    RandomizeListHeadsTypes.IncidentEdges,
                    target.PatternElement.Name,
                    source.PatternElement.Name,
                    getIncoming);
            insertionPoint = insertionPoint.Append(randomizeListHeads);
#endif

            // iterate available incident edges
            SearchPlanNodeNode node = source;
            SearchPlanEdgeNode currentEdge = target;
            IncidentEdgeType incidentType = edgeType;
            SearchProgramOperation continuationPoint;
            GetCandidateByIterationParallel incidentIteration;
            if(incidentType == IncidentEdgeType.Incoming || incidentType == IncidentEdgeType.Outgoing)
            {
                incidentIteration = new GetCandidateByIterationParallel(
                    GetCandidateByIterationType.IncidentEdges,
                    currentEdge.PatternElement.Name,
                    node.PatternElement.Name,
                    incidentType,
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
                firstLoopPassed = true;
                incidentIteration.NestedOperationsList = new SearchProgramList(incidentIteration);
                continuationPoint = insertionPoint.Append(incidentIteration);
                insertionPoint = incidentIteration.NestedOperationsList;
            }
            else // IncidentEdgeType.IncomingOrOutgoing
            {
                if(currentEdge.PatternEdgeSource == currentEdge.PatternEdgeTarget)
                {
                    // reflexive edge without direction iteration as we don't want 2 matches 
                    incidentIteration = new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.Incoming,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    firstLoopPassed = true;
                    incidentIteration.NestedOperationsList = new SearchProgramList(incidentIteration);
                    continuationPoint = insertionPoint.Append(incidentIteration);
                    insertionPoint = incidentIteration.NestedOperationsList;
                }
                else
                {
                    incidentIteration = new GetCandidateByIterationParallel(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.IncomingOrOutgoing,
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    firstLoopPassed = true;
                    incidentIteration.NestedOperationsList = new SearchProgramList(incidentIteration);
                    continuationPoint = insertionPoint.Append(incidentIteration);
                    insertionPoint = incidentIteration.NestedOperationsList;
                }
            }

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointOfConnectednessCheck;
            insertionPoint = decideOnAndInsertCheckConnectednessOfIncidentEdgeFromNode(
                insertionPoint, target, source, edgeType == IncidentEdgeType.Incoming,
                out continuationPointOfConnectednessCheck);

            // check candidate for isomorphy 
            string negativeIndependentNamePrefix = "";
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        false,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        false,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        false,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within incident iteration built by now -
            // continue at the end of the list after incident edges iteration
            insertionPoint = continuationPoint;

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// parallelized Lookup search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelLookup(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = "";

#if RANDOM_LOOKUP_LIST_START
            // insert list heads randomization, thus randomized lookup
            RandomizeListHeads randomizeListHeads =
                new RandomizeListHeads(
                    RandomizeListHeadsTypes.GraphElements,
                    target.PatternElement.Name,
                    isNode);
            insertionPoint = insertionPoint.Append(randomizeListHeads);
#endif

            // iterate available graph elements
            GetCandidateByIterationParallel elementsIteration =
                new GetCandidateByIterationParallel(
                    GetCandidateByIterationType.GraphElements,
                    target.PatternElement.Name,
                    isNode,
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
            firstLoopPassed = true;
            SearchProgramOperation continuationPoint =
                insertionPoint.Append(elementsIteration);
            elementsIteration.NestedOperationsList =
                new SearchProgramList(elementsIteration);
            insertionPoint = elementsIteration.NestedOperationsList;

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within candidate iteration built by now -
            // continue at the end of the list after candidate iteration
            insertionPoint = continuationPoint;

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// parallelized PickFromStorageDependent search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelPickFromStorageDependent(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode source,
            SearchPlanNode target,
            StorageAccess storage,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            bool isDict = storage.Attribute.Attribute.Kind == AttributeKind.SetAttr || storage.Attribute.Attribute.Kind == AttributeKind.MapAttr;
            string negativeIndependentNamePrefix = "";

            // iterate available storage elements
            string iterationType;
            if(isDict)
                if(storage.Attribute.Attribute.Kind == AttributeKind.SetAttr)
                {
                    iterationType = "System.Collections.Generic.KeyValuePair<"
                        + TypesHelper.XgrsTypeToCSharpType(storage.Attribute.Attribute.ValueType.GetKindName(), model) + ","
                        + "de.unika.ipd.grGen.libGr.SetValueType" + ">";
                }
                else
                {
                    iterationType = "System.Collections.Generic.KeyValuePair<"
                        + TypesHelper.XgrsTypeToCSharpType(storage.Attribute.Attribute.KeyType.GetKindName(), model) + ","
                        + TypesHelper.XgrsTypeToCSharpType(storage.Attribute.Attribute.ValueType.GetKindName(), model) + ">";
                }
            else
                iterationType = TypesHelper.XgrsTypeToCSharpType(storage.Attribute.Attribute.ValueType.GetKindName(), model);

            GetCandidateByIterationParallel elementsIteration =
                new GetCandidateByIterationParallel(
                    GetCandidateByIterationType.StorageAttributeElements,
                    target.PatternElement.Name,
                    source.PatternElement.Name,
                    source.PatternElement.typeName,
                    storage.Attribute.Attribute.Name,
                    iterationType,
                    isDict,
                    isNode,
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
            firstLoopPassed = true;
            SearchProgramOperation continuationPoint =
                insertionPoint.Append(elementsIteration);
            elementsIteration.NestedOperationsList =
                new SearchProgramList(elementsIteration);
            insertionPoint = elementsIteration.NestedOperationsList;

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within candidate iteration built by now -
            // continue at the end of the list after storage iteration nesting level
            insertionPoint = continuationPoint;

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// MapWithStorageDependent search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildMapWithStorageDependent(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode source,
            SearchPlanNode target,
            StorageAccess storage,
            StorageAccessIndex index,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());

            // storage muss ein container typ nach graph element sein, index muss ein elementarer typ sein

            if(storage.Variable != null && index.Variable != null) ;// das kann hier nicht auftreten; 
            if(storage.Variable != null && index.GlobalVariable != null) ;// das kann hier nicht auftreten; 
            if(storage.Variable != null && index.Attribute != null) ;// neu
            if(storage.Variable != null && index.GraphElement != null) ;// alt, siehe unten

            if(storage.GlobalVariable != null && index.Variable != null) ;// das kann hier nicht auftreten; 
            if(storage.GlobalVariable != null && index.GlobalVariable != null) ;// das kann hier nicht auftreten; 
            if(storage.GlobalVariable != null && index.Attribute != null) ;// neu
            if(storage.GlobalVariable != null && index.GraphElement != null) ;// neu

            if(storage.Attribute != null && index.Variable != null) ;// neu
            if(storage.Attribute != null && index.GlobalVariable != null) ;// neu
            if(storage.Attribute != null && index.Attribute != null) ;// kann nicht auftreten, 2 abhängigkeiten
            if(storage.Attribute != null && index.GraphElement != null) ;// kann nicht auftreten, 2 anhängigkeiten
            
            // get candidate from storage-map, only creates variable to hold it, get is fused with check for map membership
            GetCandidateByDrawing elementFromStorage =
                new GetCandidateByDrawing(
                    GetCandidateByDrawingType.MapWithStorage,
                    target.PatternElement.Name,
                    source.PatternElement.Name,
                    storage.Variable.Name,
                    TypesHelper.GetStorageValueTypeName(storage.Variable.type),
                    isNode);
            insertionPoint = insertionPoint.Append(elementFromStorage);

            // check existence of candidate in storage map 
            CheckCandidateMapWithStorage checkElementInStorage =
                new CheckCandidateMapWithStorage(
                    target.PatternElement.Name,
                    source.PatternElement.Name,
                    storage.Variable.Name,
                    TypesHelper.GetStorageKeyTypeName(storage.Variable.type),
                    isNode);
            insertionPoint = insertionPoint.Append(checkElementInStorage);

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }
            if(continuationPointAfterConnectednessCheck == insertionPoint)
                continuationPointAfterConnectednessCheck = null;

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // check candidate for global isomorphy 
            if(programType == SearchProgramType.Subpattern
                || programType == SearchProgramType.AlternativeCase
                || programType == SearchProgramType.Iterated)
            {
                if(!isomorphy.TotallyHomomorph)
                {
                    CheckCandidateForIsomorphyGlobal checkIsomorphy =
                        new CheckCandidateForIsomorphyGlobal(
                            target.PatternElement.Name,
                            isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(),
                            isNode,
                            isoSpaceNeverAboveMaxIsoSpace,
                            isomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(checkIsomorphy);
                }
            }

            // check candidate for pattern path isomorphy
            if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath)
            {
                CheckCandidateForIsomorphyPatternPath checkIsomorphy =
                    new CheckCandidateForIsomorphyPatternPath(
                        target.PatternElement.Name,
                        isNode,
                        patternGraphWithNestingPatterns.Peek().isPatternpathLocked,
                        getCurrentLastMatchAtPreviousNestingLevel());
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            if(continuationPointAfterConnectednessCheck != null)
                insertionPoint = continuationPointAfterConnectednessCheck;

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// Implicit Source|Target|SourceOrTarget search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildImplicit(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanEdgeNode source,
            SearchPlanNodeNode target,
            IsomorphyInformation isomorphy,
            ImplicitNodeType nodeType)
        {
            // get candidate = demanded node from edge
            SearchProgramOperation continuationPoint;
            insertionPoint = insertImplicitNodeFromEdge(insertionPoint, source, target, nodeType,
                out continuationPoint);
            if (continuationPoint == insertionPoint)
                continuationPoint = null;

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            SearchPlanNodeNode otherNodeOfOriginatingEdge = null;
            if (nodeType == ImplicitNodeType.Source) otherNodeOfOriginatingEdge = source.PatternEdgeTarget;
            if (nodeType == ImplicitNodeType.Target) otherNodeOfOriginatingEdge = source.PatternEdgeSource;
            if (source.PatternEdgeTarget == source.PatternEdgeSource) // reflexive sign needed in unfixed direction case, too
                otherNodeOfOriginatingEdge = source.PatternEdgeSource;
            insertionPoint = decideOnAndInsertCheckConnectednessOfImplicitNodeFromEdge(
                insertionPoint, target, source, otherNodeOfOriginatingEdge, out continuationPointAfterConnectednessCheck);
            if (continuationPoint == null && continuationPointAfterConnectednessCheck != insertionPoint)
                continuationPoint = continuationPointAfterConnectednessCheck;

            // check candidate for isomorphy 
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());
            if (isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        true,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // check candidate for global isomorphy 
            if (programType == SearchProgramType.Subpattern 
                || programType == SearchProgramType.AlternativeCase
                || programType == SearchProgramType.Iterated)
            {
                if(!isomorphy.TotallyHomomorph)
                {
                    CheckCandidateForIsomorphyGlobal checkIsomorphy =
                        new CheckCandidateForIsomorphyGlobal(
                            target.PatternElement.Name,
                            isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(),
                            true,
                            isoSpaceNeverAboveMaxIsoSpace,
                            isomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(checkIsomorphy);
                }
            }

            // check candidate for pattern path isomorphy
            if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath)
            {
                CheckCandidateForIsomorphyPatternPath checkIsomorphy =
                    new CheckCandidateForIsomorphyPatternPath(
                        target.PatternElement.Name,
                        true,
                        patternGraphWithNestingPatterns.Peek().isPatternpathLocked,
                        getCurrentLastMatchAtPreviousNestingLevel());
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        true,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        true,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            if (continuationPoint != null)
                insertionPoint = continuationPoint;

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// Cast search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildCast(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode source,
            SearchPlanNode target,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());

            // get candidate from other element (the cast is simply the following type check)
            GetCandidateByDrawing fromOtherElementForCast =
                new GetCandidateByDrawing(
                    GetCandidateByDrawingType.FromOtherElementForCast,
                    target.PatternElement.Name,
                    source.PatternElement.Name,
                    isNode);
            insertionPoint = insertionPoint.Append(fromOtherElementForCast);

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // check candidate for global isomorphy 
            if(programType == SearchProgramType.Subpattern
                || programType == SearchProgramType.AlternativeCase
                || programType == SearchProgramType.Iterated)
            {
                if(!isomorphy.TotallyHomomorph)
                {
                    CheckCandidateForIsomorphyGlobal checkIsomorphy =
                        new CheckCandidateForIsomorphyGlobal(
                            target.PatternElement.Name,
                            isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(),
                            isNode,
                            isoSpaceNeverAboveMaxIsoSpace,
                            isomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(checkIsomorphy);
                }
            }

            // check candidate for pattern path isomorphy
            if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath)
            {
                CheckCandidateForIsomorphyPatternPath checkIsomorphy =
                    new CheckCandidateForIsomorphyPatternPath(
                        target.PatternElement.Name,
                        isNode,
                        patternGraphWithNestingPatterns.Peek().isPatternpathLocked,
                        getCurrentLastMatchAtPreviousNestingLevel());
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// PickByUnique or PickByUniqueDependent search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildPickByUnique(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            UniqueLookup uniqueLookup,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());

            SourceBuilder expression = new SourceBuilder();
            uniqueLookup.Expr.Emit(expression);

            // get candidate from unique index, only creates variable to hold it, get is fused with check for index membership
            GetCandidateByDrawing elementByUnique =
                new GetCandidateByDrawing(
                    GetCandidateByDrawingType.MapByUnique,
                    target.PatternElement.Name,
                    expression.ToString(),
                    isNode);
            insertionPoint = insertionPoint.Append(elementByUnique);

            // check existence of candidate in unique map 
            CheckCandidateMapByUnique checkElementInUniqueMap =
                new CheckCandidateMapByUnique(
                    target.PatternElement.Name,
                    isNode);
            insertionPoint = insertionPoint.Append(checkElementInUniqueMap);

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }
            if(continuationPointAfterConnectednessCheck == insertionPoint)
                continuationPointAfterConnectednessCheck = null;

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // check candidate for global isomorphy 
            if(programType == SearchProgramType.Subpattern
                || programType == SearchProgramType.AlternativeCase
                || programType == SearchProgramType.Iterated)
            {
                if(!isomorphy.TotallyHomomorph)
                {
                    CheckCandidateForIsomorphyGlobal checkIsomorphy =
                        new CheckCandidateForIsomorphyGlobal(
                            target.PatternElement.Name,
                            isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(),
                            isNode,
                            isoSpaceNeverAboveMaxIsoSpace,
                            isomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(checkIsomorphy);
                }
            }

            // check candidate for pattern path isomorphy
            if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath)
            {
                CheckCandidateForIsomorphyPatternPath checkIsomorphy =
                    new CheckCandidateForIsomorphyPatternPath(
                        target.PatternElement.Name,
                        isNode,
                        patternGraphWithNestingPatterns.Peek().isPatternpathLocked,
                        getCurrentLastMatchAtPreviousNestingLevel());
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            if(continuationPointAfterConnectednessCheck != null)
                insertionPoint = continuationPointAfterConnectednessCheck;

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// PickFromStorage search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildPickFromStorage(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            StorageAccess storage,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            bool isDict = TypesHelper.DotNetTypeToXgrsType(storage.Variable.type).StartsWith("set") || TypesHelper.DotNetTypeToXgrsType(storage.Variable.type).StartsWith("map");
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());

            // iterate available storage elements
            string iterationType;
            if(isDict) iterationType = "System.Collections.Generic.KeyValuePair<"
                + TypesHelper.GetStorageKeyTypeName(storage.Variable.type) + ","
                + TypesHelper.GetStorageValueTypeName(storage.Variable.type) + ">";
            else
                iterationType = TypesHelper.GetStorageKeyTypeName(storage.Variable.type);
            GetCandidateByIteration elementsIteration =
                new GetCandidateByIteration(
                    GetCandidateByIterationType.StorageElements,
                    target.PatternElement.Name,
                    storage.Variable.Name,
                    iterationType,
                    isDict,
                    isNode,
                    parallelized,
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
            firstLoopPassed = true;

            SearchProgramOperation continuationPoint =
                insertionPoint.Append(elementsIteration);
            elementsIteration.NestedOperationsList =
                new SearchProgramList(elementsIteration);
            insertionPoint = elementsIteration.NestedOperationsList;

            // check type of candidate
            insertionPoint = decideOnAndInsertCheckType(insertionPoint, target);

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if(isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }

            // check candidate for isomorphy 
            if(isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // check candidate for global isomorphy 
            if(programType == SearchProgramType.Subpattern
                || programType == SearchProgramType.AlternativeCase
                || programType == SearchProgramType.Iterated)
            {
                if(!isomorphy.TotallyHomomorph)
                {
                    CheckCandidateForIsomorphyGlobal checkIsomorphy =
                        new CheckCandidateForIsomorphyGlobal(
                            target.PatternElement.Name,
                            isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(),
                            isNode,
                            isoSpaceNeverAboveMaxIsoSpace,
                            isomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(checkIsomorphy);
                }
            }

            // check candidate for pattern path isomorphy
            if(patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath)
            {
                CheckCandidateForIsomorphyPatternPath checkIsomorphy =
                    new CheckCandidateForIsomorphyPatternPath(
                        target.PatternElement.Name,
                        isNode,
                        patternGraphWithNestingPatterns.Peek().isPatternpathLocked,
                        getCurrentLastMatchAtPreviousNestingLevel());
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if(isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within candidate iteration built by now -
            // continue at the end of the list after storage iteration nesting level
            insertionPoint = continuationPoint;

            if(storage.Variable != null) ; // alt, siehe oben
            if(storage.GlobalVariable != null) ; // neu -- wenn es ein container-typ ist iterieren, wenn es ein elementarer typ ist eine einfache zuweisung -- und kein != null handling
            if(storage.Attribute != null) ; // das kann hier nicht auftreten

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// Lookup search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildLookup(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());

            // decide on and insert operation determining type of candidate
            SearchProgramOperation continuationPointAfterTypeIteration;
            SearchProgramOperation insertionPointAfterTypeIteration =
                decideOnAndInsertGetType(insertionPoint, target,
                out continuationPointAfterTypeIteration);
            insertionPoint = insertionPointAfterTypeIteration;

#if RANDOM_LOOKUP_LIST_START
            // insert list heads randomization, thus randomized lookup
            RandomizeListHeads randomizeListHeads =
                new RandomizeListHeads(
                    RandomizeListHeadsTypes.GraphElements,
                    target.PatternElement.Name,
                    isNode);
            insertionPoint = insertionPoint.Append(randomizeListHeads);
#endif

            // iterate available graph elements
            GetCandidateByIteration elementsIteration =
                new GetCandidateByIteration(
                    GetCandidateByIterationType.GraphElements,
                    target.PatternElement.Name,
                    isNode,
                    parallelized,
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
            firstLoopPassed = true;
            SearchProgramOperation continuationPoint =
                insertionPoint.Append(elementsIteration);
            elementsIteration.NestedOperationsList =
                new SearchProgramList(elementsIteration);
            insertionPoint = elementsIteration.NestedOperationsList;

            // check connectedness of candidate
            SearchProgramOperation continuationPointAfterConnectednessCheck;
            if (isNode)
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfNodeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanNodeNode)target, out continuationPointAfterConnectednessCheck);
            }
            else
            {
                insertionPoint = decideOnAndInsertCheckConnectednessOfEdgeFromLookupOrPickOrMap(
                    insertionPoint, (SearchPlanEdgeNode)target, out continuationPointAfterConnectednessCheck);
            }

            // check candidate for isomorphy 
            if (isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // check candidate for global isomorphy 
            if (programType==SearchProgramType.Subpattern 
                || programType==SearchProgramType.AlternativeCase
                || programType==SearchProgramType.Iterated)
            {
                if(!isomorphy.TotallyHomomorph)
                {
                    CheckCandidateForIsomorphyGlobal checkIsomorphy =
                        new CheckCandidateForIsomorphyGlobal(
                            target.PatternElement.Name,
                            isomorphy.GloballyHomomorphPatternElementsAsListOfStrings(),
                            isNode,
                            isoSpaceNeverAboveMaxIsoSpace,
                            isomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(checkIsomorphy);
                }
            }

            // check candidate for pattern path isomorphy
            if (patternGraphWithNestingPatterns.Peek().isPatternGraphOnPathFromEnclosingPatternpath)
            {
                CheckCandidateForIsomorphyPatternPath checkIsomorphy =
                    new CheckCandidateForIsomorphyPatternPath(
                        target.PatternElement.Name,
                        isNode,
                        patternGraphWithNestingPatterns.Peek().isPatternpathLocked,
                        getCurrentLastMatchAtPreviousNestingLevel());
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            // everything nested within candidate iteration built by now -
            // continue at the end of the list at type iteration nesting level
            insertionPoint = continuationPoint;

            // everything nested within type iteration built by now
            // continue at the end of the list handed in
            if (insertionPointAfterTypeIteration != continuationPointAfterTypeIteration)
            {
                // if type was drawn then the if is not entered (insertion point==continuation point)
                // thus we continue at the continuation point of the candidate iteration
                // otherwise if type was iterated
                // we continue at the continuation point of the type iteration
                insertionPoint = continuationPointAfterTypeIteration;
            }

            return insertionPoint;
        }
        /// <summary>
        /// Search program operations implementing the
        /// NegIdptPreset search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildNegIdptPreset(
            SearchProgramOperation insertionPoint,
            int currentOperationIndex,
            SearchPlanNode target,
            IsomorphyInformation isomorphy)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = NegativeIndependentNamePrefix(patternGraphWithNestingPatterns.Peek());
            Debug.Assert(negativeIndependentNamePrefix != "", "Negative/Independent preset in top-level search plan");

            // an inlined independet preset is differently named, must be assigned first
            if(target.PatternElement.PresetBecauseOfIndependentInlining)
            {
                // get candidate from other element (the cast is simply the following type check)
                GetCandidateByDrawing inlinedIndependentPreset =
                    new GetCandidateByDrawing(
                        GetCandidateByDrawingType.FromOtherElementForAssign,
                        target.PatternElement.Name,
                        target.PatternElement.Name + "_inlined_" + patternGraphWithNestingPatterns.Peek().Name,
                        isNode);
                insertionPoint = insertionPoint.Append(inlinedIndependentPreset);
            }

            // check candidate for isomorphy 
            if (isomorphy.CheckIsMatchedBit)
            {
                CheckCandidateForIsomorphy checkIsomorphy =
                    new CheckCandidateForIsomorphy(
                        target.PatternElement.Name,
                        isomorphy.PatternElementsToCheckAgainstAsListOfStrings(),
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(checkIsomorphy);
            }

            // accept candidate (write isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            {
                AcceptCandidate acceptCandidate =
                    new AcceptCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(acceptCandidate);
            }

            // mark element as visited
            target.Visited = true;

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

            // unmark element for possibly following run
            target.Visited = false;

            // abandon candidate (restore isomorphy information)
            if (isomorphy.SetIsMatchedBit)
            { // only if isomorphy information was previously written
                AbandonCandidate abandonCandidate =
                    new AbandonCandidate(
                        target.PatternElement.Name,
                        negativeIndependentNamePrefix,
                        isNode,
                        isoSpaceNeverAboveMaxIsoSpace,
                        isomorphy.Parallel,
                        isomorphy.LockForAllThreads);
                insertionPoint = insertionPoint.Append(abandonCandidate);
            }

            return insertionPoint;
        }