/// <summary>
        /// "listentrick": append search program operations to adjust list heads
        /// i.e. set list entry point to element after last found,
        /// so that next searching starts there - performance optimization
        /// (leave graph in the state of our last visit (searching it))
        /// </summary>
        private static void MoveOutwardsAppendingListHeadAdjustment(
            CheckContinueMatchingMaximumMatchesReached checkMaximumMatches,
            bool inParallelizedBody)
        {
            // todo: avoid adjusting list heads twice for lookups of same type

            // insertion point for candidate failed operations
            SearchProgramOperation insertionPoint =
                checkMaximumMatches.CheckFailedOperations;
            SearchProgramOperation op = checkMaximumMatches;

            do
            {
                if (op is GetCandidateByIteration)
                {
                    GetCandidateByIteration candidateByIteration =
                        op as GetCandidateByIteration;
                    if (candidateByIteration.Type == GetCandidateByIterationType.GraphElements)
                    {
                        AdjustListHeads adjustElements =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.GraphElements,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.IsNode,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustElements);
                    }
                    else if (candidateByIteration.Type == GetCandidateByIterationType.IncidentEdges)
                    {
                        AdjustListHeads adjustIncident =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.IncidentEdges,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.StartingPointNodeName,
                                candidateByIteration.EdgeType,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustIncident);
                    }
                }
                else if (op is GetCandidateByIterationParallel)
                {
                    GetCandidateByIterationParallel candidateByIteration =
                        op as GetCandidateByIterationParallel;
                    if (candidateByIteration.Type == GetCandidateByIterationType.GraphElements)
                    {
                        AdjustListHeads adjustElements =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.GraphElements,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.IsNode,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustElements);
                    }
                    else if (candidateByIteration.Type == GetCandidateByIterationType.IncidentEdges)
                    {
                        AdjustListHeads adjustIncident =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.IncidentEdges,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.StartingPointNodeName,
                                candidateByIteration.EdgeType,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustIncident);
                    }
                }

                op = op.Previous;
            }while(op != null);
        }
        /// <summary>
        /// "listentrick": append search program operations to adjust list heads
        /// i.e. set list entry point to element after last found,
        /// so that next searching starts there - performance optimization
        /// (leave graph in the state of our last visit (searching it))
        /// </summary>
        private void MoveOutwardsAppendingListHeadAdjustment(
            CheckContinueMatchingMaximumMatchesReached checkMaximumMatches,
            bool inParallelizedBody)
        {
            // todo: avoid adjusting list heads twice for lookups of same type

            // insertion point for candidate failed operations
            SearchProgramOperation insertionPoint =
                checkMaximumMatches.CheckFailedOperations;
            SearchProgramOperation op = checkMaximumMatches;
            do
            {
                if(op is GetCandidateByIteration)
                {
                    GetCandidateByIteration candidateByIteration =
                        op as GetCandidateByIteration;
                    if(candidateByIteration.Type == GetCandidateByIterationType.GraphElements)
                    {
                        AdjustListHeads adjustElements =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.GraphElements,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.IsNode,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustElements);
                    }
                    else if(candidateByIteration.Type==GetCandidateByIterationType.IncidentEdges)
                    {
                        AdjustListHeads adjustIncident =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.IncidentEdges,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.StartingPointNodeName,
                                candidateByIteration.EdgeType,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustIncident);
                    }
                }
                else if(op is GetCandidateByIterationParallel)
                {
                    GetCandidateByIterationParallel candidateByIteration =
                        op as GetCandidateByIterationParallel;
                    if(candidateByIteration.Type == GetCandidateByIterationType.GraphElements)
                    {
                        AdjustListHeads adjustElements =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.GraphElements,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.IsNode,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustElements);
                    }
                    else if(candidateByIteration.Type == GetCandidateByIterationType.IncidentEdges)
                    {
                        AdjustListHeads adjustIncident =
                            new AdjustListHeads(
                                AdjustListHeadsTypes.IncidentEdges,
                                candidateByIteration.PatternElementName,
                                candidateByIteration.StartingPointNodeName,
                                candidateByIteration.EdgeType,
                                inParallelizedBody);
                        insertionPoint = insertionPoint.Append(adjustIncident);
                    }
                }

                op = op.Previous;
            }
            while (op != null);
        }