public Preconditions Ldelem(APC pc, Type type, Variable dest, Variable array, Variable index, Preconditions pre)
                {
                    BreakHere(pc, pre);

                    if (pre != null)
                    {
                        var result = new Preconditions();

                        var ldElemExp = new BoxedExpression.ArrayIndexExpression <Type>(BoxedExpression.Var(array), BoxedExpression.Var(index), type);
                        var destExp   = BoxedExpression.Var(dest);

                        foreach (var p in pre)
                        {
                            if (p != null)
                            {
                                result.AddIfNotNull(p.Substitute(destExp, ldElemExp));
                            }
                        }
                        return(result);
                    }
                    else
                    {
                        return(pre);
                    }
                }
                private BoxedExpression GenerateTheExists(APC exitPC, BoxedExpression variable, Type arrayType, BoxedExpression array)
                {
                    Contract.Requires(variable != null);
                    Contract.Requires(array != null);

                    BoxedExpression newPost = null;

                    var boundedVariable = BoxedExpression.Var("__j__");

                    var      lowerBound = BoxedExpression.Const(0, this.DecoderForMetaData.System_Int32, this.DecoderForMetaData);
                    Variable arrayVar, arrayLength;

                    if (array.TryGetFrameworkVariable(out arrayVar) &&
                        this.Context.ValueContext.TryGetArrayLength(exitPC, arrayVar, out arrayLength))
                    {
                        var upperBound = BoxedExpression.Var(arrayLength, this.Context.ValueContext.VisibleAccessPathListFromPost(exitPC, arrayLength));

                        // arr[boundedVariable] == variable
                        var arrayLoad = new BoxedExpression.ArrayIndexExpression <Type>(array, boundedVariable, arrayType);

                        var eq = BoxedExpression.Binary(BinaryOperator.Ceq, arrayLoad, variable);

                        newPost = new ExistsIndexedExpression(null, boundedVariable, lowerBound, upperBound, eq);
                    }

                    return(newPost);
                }
                private List <BoxedExpression> GetForAllVisibleOutsideOfTheMethod(
                    BoxedVariable <Variable> array,
                    ArraySegmentation <FlatAbstractDomainOfBoolsWithRenaming <BoxedVariable <Variable> >, BoxedVariable <Variable>, BoxedExpression> segmentation)
                {
                    Contract.Requires(array != null);
                    Contract.Requires(segmentation != null);

                    var result = new List <BoxedExpression>();

                    var arrayBE = ReadVariableInPreStateForRequires(this.Context.MethodContext.CFG.EntryAfterRequires, array);

                    if (arrayBE != null)
                    {
                        var boundVar   = BoxedExpression.Var("i");
                        var arrayindex = new BoxedExpression.ArrayIndexExpression <Type>(arrayBE, boundVar, this.DecoderForMetaData.System_Object);
                        var factory    = new BoxedExpressionFactory <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly, Variable>(
                            boundVar, arrayindex,
                            (v => ReadVariableInPreStateForRequires(this.Context.MethodContext.CFG.EntryAfterRequires, v)),
                            this.DecoderForMetaData, null);
                        var formula = segmentation.To(factory);
                        if (formula != null)
                        {
                            result.AddRange(factory.SplitAnd(formula));
                        }
                    }

                    return(result);
                }
                public override bool SuggestAnalysisSpecificPostconditions(
                    ContractInferenceManager inferenceManager,
                    IFixpointInfo <APC, ArrayState> fixpointInfo, List <BoxedExpression> postconditions)
                {
                    Contract.Assert(this.MethodDriver.CFG != null);
                    var exitPC = this.MethodDriver.CFG.NormalExit;

                    ArrayState exitState;

                    if (fixpointInfo.PostState(exitPC, out exitState))
                    {
                        var mySubState = Select(exitState);
                        foreach (var pair in mySubState.Elements)
                        {
                            // Try to get a variable name for it
                            var variable = ReadVariableInPostState(exitPC, pair.Key);

                            if (variable == null)
                            {
                                // we fail to get a name in the post state, let us see if it is a constant
                                Int64 k;
                                var   intv = exitState.Numerical.BoundsFor(pair.Key);
                                if (intv.IsSingleton && intv.LowerBound.TryInt64(out k))
                                {
                                    variable = BoxedExpression.Const(k, this.DecoderForMetaData.System_Int64, this.DecoderForMetaData);
                                }
                                else
                                {
                                    continue;
                                }
                            }

                            Contract.Assert(variable != null);

                            Contract.Assume(pair.Value != null);

                            if (pair.Value.IsNormal() && pair.Value.IsUnmodifiedFromEntry.IsTrue())
                            {
                                foreach (var arrayBoxed in pair.Value.Left.Values)
                                {
                                    Contract.Assume(arrayBoxed != null);

                                    var arrayType = GetTypeOrObject(exitPC, arrayBoxed);

                                    var array = ReadVariableInPostState(exitPC, arrayBoxed);
                                    if (array != null)
                                    {
                                        // If we have one or more definite values for the index expression, we use them
                                        if (pair.Value.Right.IsNormal())
                                        {
                                            foreach (var indexBoxed in pair.Value.Right.Values)
                                            {
                                                BoxedExpression newPost = null;

                                                Contract.Assume(indexBoxed != null);
                                                var index = ReadVariableInPostState(exitPC, indexBoxed);

                                                if (index == null)
                                                {
                                                    newPost = GenerateTheExists(exitPC, variable, arrayType, array);
                                                }
                                                else
                                                {
                                                    #region Generate arr[index] == variable
                                                    var arrayLoad = new BoxedExpression.ArrayIndexExpression <Type>(array, index, arrayType);

                                                    newPost = BoxedExpression.Binary(BinaryOperator.Ceq, arrayLoad, variable);
                                                    #endregion
                                                }

                                                postconditions.AddIfNotNull(newPost);
                                            }
                                        }
                                        // else, if we know it is top, we can simp,y project over it
                                        else if (pair.Value.Right.IsTop)
                                        {
                                            postconditions.AddIfNotNull(GenerateTheExists(exitPC, variable, arrayType, array));
                                        }
                                    }
                                }
                            }
                        }
                    }

                    return(false);
                }