/// <summary>
        /// Search program operations implementing the
        /// setup parallelized Extend Incoming|Outgoing|IncomingOrOutgoing search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelIncidentSetup(
            SearchProgramOperation insertionPoint,
            SearchPlanNodeNode source,
            SearchPlanEdgeNode target,
            IncidentEdgeType edgeType)
        {
            // iterate available incident edges
            SearchPlanNodeNode node = source;
            SearchPlanEdgeNode currentEdge = target;
            IncidentEdgeType incidentType = edgeType;
            GetCandidateByIterationParallelSetup incidentIteration;
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();

            if(incidentType == IncidentEdgeType.Incoming || incidentType == IncidentEdgeType.Outgoing)
            {
                incidentIteration = new GetCandidateByIterationParallelSetup(
                    GetCandidateByIterationType.IncidentEdges,
                    currentEdge.PatternElement.Name,
                    node.PatternElement.Name,
                    incidentType,
                    rulePatternClassName,
                    patternGraph.name,
                    parameterNames,
                    false,
                    wasIndependentInlined(patternGraph, indexOfSchedule),
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
                return insertionPoint.Append(incidentIteration);
            }
            else // IncidentEdgeType.IncomingOrOutgoing
            {
                if(currentEdge.PatternEdgeSource == currentEdge.PatternEdgeTarget)
                {
                    // reflexive edge without direction iteration as we don't want 2 matches 
                    incidentIteration = new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.Incoming,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        false,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    return insertionPoint.Append(incidentIteration);
                }
                else
                {
                    BothDirectionsIteration directionsIteration =
                        new BothDirectionsIteration(currentEdge.PatternElement.Name);
                    directionsIteration.NestedOperationsList = new SearchProgramList(directionsIteration);
                    SearchProgramOperation continuationPoint = insertionPoint.Append(directionsIteration);
                    insertionPoint = directionsIteration.NestedOperationsList;

                    incidentIteration = new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IncidentEdges,
                        currentEdge.PatternElement.Name,
                        node.PatternElement.Name,
                        IncidentEdgeType.IncomingOrOutgoing,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        true,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
                    return insertionPoint.Append(incidentIteration);
                }
            }
        }
        /// <summary>
        /// Search program operations implementing the
        /// setup parallelized PickFromIndex search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelPickFromIndexSetup(
            SearchProgramOperation insertionPoint,
            SearchPlanNode target,
            IndexAccess index)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = "";
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();
            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
            GetCandidateByIterationParallelSetup elementsIteration;
            if(index is IndexAccessEquality)
            {
                IndexAccessEquality indexEquality = (IndexAccessEquality)index;
                SourceBuilder equalityExpression = new SourceBuilder();
                indexEquality.Expr.Emit(equalityExpression);
                elementsIteration =
                    new GetCandidateByIterationParallelSetup(
                        GetCandidateByIterationType.IndexElements,
                        target.PatternElement.Name,
                        index.Index.Name,
                        iterationType,
                        indexSetType,
                        IndexAccessType.Equality,
                        equalityExpression.ToString(),
                        isNode,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        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 GetCandidateByIterationParallelSetup(
                        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,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        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 GetCandidateByIterationParallelSetup(
                        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,
                        rulePatternClassName,
                        patternGraph.name,
                        parameterNames,
                        wasIndependentInlined(patternGraph, indexOfSchedule),
                        emitProfiling,
                        packagePrefixedActionName,
                        !firstLoopPassed);
            }
            return insertionPoint.Append(elementsIteration);
        }
        /// <summary>
        /// Search program operations implementing the
        /// setup parallelized PickFromStorage search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelPickFromStorageSetup(
            SearchProgramOperation insertionPoint,
            SearchPlanNode target,
            StorageAccess storage)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            bool isDict = TypesHelper.DotNetTypeToXgrsType(storage.Variable.type).StartsWith("set") || TypesHelper.DotNetTypeToXgrsType(storage.Variable.type).StartsWith("map");
            string negativeIndependentNamePrefix = "";
            PatternGraph patternGraph = 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);

            GetCandidateByIterationParallelSetup elementsIteration =
                new GetCandidateByIterationParallelSetup(
                    GetCandidateByIterationType.StorageElements,
                    target.PatternElement.Name,
                    storage.Variable.Name,
                    iterationType,
                    isDict,
                    isNode,
                    rulePatternClassName,
                    patternGraph.Name,
                    parameterNames,
                    wasIndependentInlined(patternGraph, indexOfSchedule),
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
            return insertionPoint.Append(elementsIteration);
        }
        /// <summary>
        /// Search program operations implementing the
        /// setup parallelized PickFromStorageDependent search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelPickFromStorageDependentSetup(
            SearchProgramOperation insertionPoint,
            SearchPlanNode source,
            SearchPlanNode target,
            StorageAccess storage)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            bool isDict = storage.Attribute.Attribute.Kind == AttributeKind.SetAttr || storage.Attribute.Attribute.Kind == AttributeKind.MapAttr;
            string negativeIndependentNamePrefix = "";
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();

            // 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);

            GetCandidateByIterationParallelSetup elementsIteration =
                new GetCandidateByIterationParallelSetup(
                    GetCandidateByIterationType.StorageAttributeElements,
                    target.PatternElement.Name,
                    source.PatternElement.Name,
                    source.PatternElement.typeName,
                    storage.Attribute.Attribute.Name,
                    iterationType,
                    isDict,
                    isNode,
                    rulePatternClassName,
                    patternGraph.name,
                    parameterNames,
                    wasIndependentInlined(patternGraph, indexOfSchedule),
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
            return insertionPoint.Append(elementsIteration);
        }
        /// <summary>
        /// Search program operations implementing the
        /// setup parallelized Lookup search plan operation
        /// are created and inserted into search program
        /// </summary>
        private SearchProgramOperation buildParallelLookupSetup(
            SearchProgramOperation insertionPoint,
            SearchPlanNode target)
        {
            bool isNode = target.NodeType == PlanNodeType.Node;
            string negativeIndependentNamePrefix = "";
            PatternGraph patternGraph = patternGraphWithNestingPatterns.Peek();

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

            // iterate available graph elements
            GetCandidateByIterationParallelSetup elementsIteration =
                new GetCandidateByIterationParallelSetup(
                    GetCandidateByIterationType.GraphElements,
                    target.PatternElement.Name,
                    isNode,
                    rulePatternClassName,
                    patternGraph.name,
                    parameterNames,
                    insertionPointAfterTypeIteration != continuationPointAfterTypeIteration,
                    wasIndependentInlined(patternGraph, indexOfSchedule),
                    emitProfiling,
                    packagePrefixedActionName,
                    !firstLoopPassed);
            return insertionPoint.Append(elementsIteration);
        }