public MoveNextDriver(IMethodDriver <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Expression, Variable, ILogOptions>
                              driver)
        {
            this.driver = driver;
            MoveNextStateAnalyzer preAnalyzer = new MoveNextStateAnalyzer();

            stateInfo = preAnalyzer.AnalyzeMoveNext("MoveNext", driver);
            // If we are not able
            if (stateInfo.OrderedVisibleStates == null || stateInfo.OrderedVisibleStates.Count() == 0)
            {
                stateInfo = null;
            }
        }
        /// <summary>
        /// Given the state machine information, return the set of entry points for the slices that
        /// do not correspond to "state". The entry point of a slice refers to program point for the case
        /// statements in the switch (this.__state) statement in a MoveNext method.
        /// </summary>
        /// <param name="info"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        Set <APC> GetStateEntriesOtherThan(StateMachineInformation <Local> info, int state)
        {
            Set <APC> result = new Set <APC>();

            foreach (int s in info.StateSliceEntries.Keys)
            {
                if (s == state)
                {
                    continue;
                }
                var set = info.StateSliceEntries[s];
                result = result | set;
            }
            return(result);
        }
        /// <summary>
        /// Given an underlying analysis and generator for a bottom value, this method computes a mapping between a state of
        /// the iterator and fixpoint information computed by the underlying analysis for the slice that corresponds to that
        /// state.
        ///
        /// The analysis runs the underlying analyzer on state 0, the initial state, first. The state from the return point
        /// of this state will be the current value of the invariant candidate.
        /// Then for every continuing state (the state from which a new item is generated for the ienumerable result), we map
        /// the current invariant candidate and map it to the entry of the method, and run the underlying analysis for that
        /// state. Running the underlying analysis for a particular state requires a set of program points, which are the entry
        /// points of other slices. The underlying analysis will mark those program points as unreachable. The exit abstract
        /// state will become the current invariant candidate. This process finishes when a fixedpoint is reached.
        /// </summary>
        /// <typeparam name="MyDomain">The domain of the underlying analysis.</typeparam>
        /// <param name="analysis">The underlying analysis.</param>
        /// <param name="bv">A delegate that generates a bottom value for MyDomain.</param>
        /// <returns></returns>
        public FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > Analyze <MyDomain>(
            IMoveNextOnePassAnalysis <Local, Parameter, Method, Field, Property, Type, Expression, Attribute, Assembly, MyDomain, Variable> analysis,
            StateGenerator <MyDomain> bv)
        {
            // Use a pre-analysis to collect information regarding the state machine.
            MoveNextStateAnalyzer           preAnalyzer = new MoveNextStateAnalyzer();
            StateMachineInformation <Local> stateInfo   = preAnalyzer.AnalyzeMoveNext("MoveNext", driver);

            // If we are not able
            if (stateInfo.OrderedVisibleStates == null || stateInfo.OrderedVisibleStates.Count() == 0)
            {
                throw new ArgumentException("Argument error with MoveNext method: Cannot analyze the state machine.");
            }

            // Fix point computation: fixpoint of the iterator analysis is a mapping: answers.
            bool     fixedpointReached = false;
            MyDomain d = default(MyDomain), oldd = default(MyDomain);
            FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > answers = FunctionalMap <int, IMethodAnalysisFixPoint <Variable> > .Empty;
            MyDomain invariantCandidate   = default(MyDomain);
            Converter <Variable, int> key = driver.KeyNumber;

            int pass = 0;

            while (!fixedpointReached)
            {
                fixedpointReached = true;
                // Going through every state of the state machine, if the final states changes at least once
                // then fixpoint is not reached.
                foreach (int state in stateInfo.OrderedVisibleStates)
                {
                    // The initial state is only analyzed once.
                    if (state < 0)
                    {
                        continue;
                    }
                    if (state == 0 && pass > 0)
                    {
                        continue;
                    }

                    // Initial value for one pass, either TOP, if we analyze it for the first time
                    // or the invariantCandidate.
                    if (invariantCandidate == null || invariantCandidate.Equals(default(MyDomain)))
                    {
                        d = analysis.GetInitialValue(key);
                    }
                    else
                    {
                        d = analysis.MutableVersion(invariantCandidate);
                    }

                    // Call the underlying analysis for one pass
                    Set <APC> cutOffPCs = GetStateEntriesOtherThan(stateInfo, state);
                    driver.CreateForwardForIterator(analysis, bv, cutOffPCs)(d);

                    // Getting the state from the return point of the most recent pass, map it
                    // to the entry point, and join it with the current invariant candidate
                    IFunctionalMap <Variable, FList <Variable> > mapping = GetFieldMapping(driver);
                    var      fakeEdge    = new Pair <APC, APC>(driver.CFG.NormalExit, driver.CFG.Entry);
                    MyDomain returnState = analysis.ReturnState;
                    MyDomain newState    = analysis.ParallelAssign(fakeEdge, mapping, returnState);
                    bool     changed     = false;
                    if (invariantCandidate != null && !invariantCandidate.Equals(default(MyDomain)))
                    {
                        oldd = invariantCandidate;
                        // TODO: use a more sophisticated widenning strategy.
                        bool toWiden = (pass > 2) ? true : false;
                        d = analysis.Join(fakeEdge, newState, oldd, out changed, toWiden);
                        if (changed)
                        {
                            invariantCandidate = d;
                        }
                    }
                    else
                    {
                        changed            = true;
                        invariantCandidate = newState;
                    }
                    if (changed)
                    {
                        fixedpointReached = false;
                    }

                    // Fill the result table with the most recent fixpoint information.
                    answers  = (FunctionalMap <int, IMethodAnalysisFixPoint <Variable> >)answers.Add(state, analysis.ExtractResult());
                    analysis = analysis.Duplicate();
                }
                pass++;
            }
            return(answers);
        }