private void BuildExecuteAndCompareAsyncCall(Dictionary<string, ReadOnlyCollection<QueryExpression>> freeVariableValues, CodeExpression continuationExpression, CodeExpressionWithFreeVariables generatedCode, int maxValueCount, Dictionary<string, QueryExpression> freeVariableAssignments, CodeExpression queryVariable)
        {
            var listVariable = this.CodeBuilder.Declare(
                "actionList",
                Code.New(Code.TypeRef<List<Action<IAsyncContinuation>>>()));

            for (int j = 0; j < maxValueCount; ++j)
            {
                if (j > 0)
                {
                    // for anything but the first value, set the new value of each free variable
                    var lambda = Code.Lambda().WithParameter("c");

                    this.CodeBuilder.BeginLambda(lambda);

                    foreach (var freeVar in generatedCode.FreeVariables)
                    {
                        this.CodeBuilder.Add(Code.Variable(freeVar.Name).Assign(freeVar.PossibleValues[j % freeVar.PossibleValues.Count]));
                    }

                    this.CodeBuilder.Add(Code.Argument("c").Call("Continue"));
                    this.CodeBuilder.EndLambda();
                    this.CodeBuilder.Add(listVariable.Call("Add", lambda));
                }

                foreach (var free in generatedCode.FreeVariables)
                {
                    freeVariableAssignments[free.Name] = freeVariableValues[free.Name][j % freeVariableValues[free.Name].Count];
                }

                var lambdaBody = this.BuildQueryExecuteCallAndVariables(Code.Argument("c"), queryVariable, freeVariableAssignments);

                // add the lambda body to the list
                this.CodeBuilder.Add(listVariable.Call("Add", Code.Lambda().WithParameter("c").WithBody(lambdaBody)));
            }

            // add code to run all lambdas accumulated so far
            this.CodeBuilder.Add(Code.Type(typeof(AsyncHelpers).Name).Call("RunActionSequence", continuationExpression, listVariable));
        }
        private void BuildExecuteAndCompareSync(Dictionary<string, ReadOnlyCollection<QueryExpression>> freeVariableValues, CodeExpression continuationExpression, CodeExpressionWithFreeVariables generatedCode, int maxValueCount, Dictionary<string, QueryExpression> freeVariableAssignments, CodeExpression queryVariable)
        {
            for (int j = 0; j < maxValueCount; ++j)
            {
                foreach (var free in generatedCode.FreeVariables)
                {
                    freeVariableAssignments[free.Name] = freeVariableValues[free.Name][j % freeVariableValues[free.Name].Count];
                }

                this.CodeBuilder.Add(this.BuildQueryExecuteCallAndVariables(continuationExpression, queryVariable, freeVariableAssignments));
            }
        }      
        private void BuildClientExecuteCode(CodeExpression continuationExpression, CodeExpressionWithFreeVariables generatedCode)
        {
            var freeVariableValues = this.ClientQueryFreeVariableAssignmentsExtractingVisitor.ExtractFreeVariableAssignments(this.QueryExpression);

            // find the number of possible values for all free variables in the expression
            var maxValueCount = 0;

            if (generatedCode.FreeVariables.Any())
            {
                maxValueCount = generatedCode.FreeVariables.Max(fv => fv.PossibleValues.Count);
            }

            var freeVariableAssignments = new Dictionary<string, QueryExpression>();

            // declare free variables and assign their first values
            foreach (var free in generatedCode.FreeVariables)
            {
                this.CodeBuilder.Add(Code.DeclareVariable(free.VariableType, free.Name, free.PossibleValues.First()));
                freeVariableAssignments[free.Name] = freeVariableValues[free.Name][0];
            }

            // var expression = ... generatedQuery
            var queryVariable = this.CodeBuilder.Declare("query", generatedCode.Expression);

            // simple case with 0 or 1 values for free variables
            if (maxValueCount <= 1)
            {
                this.CodeBuilder.Add(this.BuildQueryExecuteCallAndVariables(continuationExpression, queryVariable, freeVariableAssignments));
            }
            else
            {
                // create actionList variable which will hold all verification calls
                // since verification is asynchronous this will let us serialize the calls by doing RunActionSequence
                if (this.IsAsync)
                {
                    this.BuildExecuteAndCompareAsyncCall(freeVariableValues, continuationExpression, generatedCode, maxValueCount, freeVariableAssignments, queryVariable);
                }
                else
                {
                    this.BuildExecuteAndCompareSync(freeVariableValues, continuationExpression, generatedCode, maxValueCount, freeVariableAssignments, queryVariable);
                }
            }
        }