public override ArrayState Ldelem(
                    APC pc, Type type, Variable dest, Variable array, Variable index, ArrayState data)
                {
                    Contract.Assume(data != null);

                    var mySubState = Select(data);

                    var boxedArray = new BoxedVariable <Variable>(array);
                    var boxedIndex = new BoxedVariable <Variable>(index);

                    var symbolicConditions = SymbolicExpressionTracker <BoxedVariable <Variable>, BoxedExpression> .Unknown;

                    ScalarFromArrayTracking prevInfo;

                    if (mySubState.TryGetValue(new BoxedVariable <Variable>(dest), out prevInfo))
                    {
                        Contract.Assert(prevInfo.Conditions != null);
                        symbolicConditions = symbolicConditions.Meet(prevInfo.Conditions);
                    }

                    var isUnModifiedArrayElement = data.IsUnmodifiedArrayElementFromEntry(boxedArray, ToBoxedExpression(pc, index));

                    var newRelation = new ScalarFromArrayTracking(boxedArray, boxedIndex, isUnModifiedArrayElement, symbolicConditions);

                    mySubState[new BoxedVariable <Variable>(dest)] = newRelation;

                    return(data.UpdatePluginAt(this.Id, mySubState));
                }
                private ArrayState AssumeCheckOfAnArrayElement(APC pc, Variable var, ArrayState data)
                {
                    Contract.Requires(data != null);
                    Contract.Ensures(Contract.Result <ArrayState>() != null);

                    Pair <BoxedVariable <Variable>, BoxedVariable <Variable> > refined;

                    if (data.CanRefineToArrayLoad(new BoxedVariable <Variable>(var), out refined))
                    {
                        var mySubState = Select(data);
                        ArraySegmentation <
                            FlatAbstractDomainOfBoolsWithRenaming <BoxedVariable <Variable> >, BoxedVariable <Variable>, BoxedExpression> segmentation;

                        Contract.Assume(refined.One != null);
                        Contract.Assume(refined.Two != null);

                        // Do we have a segmentation?
                        foreach (var arr in GetEquals(pc, refined.One, data))
                        {
                            if (mySubState.TryGetValue(arr, out segmentation))
                            {
                                // Is it unmodified?
                                if (data.IsUnmodifiedArrayElementFromEntry(arr, ToBoxedExpression(pc, refined.Two)))
                                {
                                    var norm = ToBoxedExpression(pc, refined.Two).ToNormalizedExpression <Variable>();
                                    if (norm != null && segmentation.TrySetAbstractValue(norm, CHECKED, data.Numerical, out segmentation))
                                    {
                                        mySubState.Update(arr, segmentation);
                                    }
                                    else
                                    {
                                        mySubState.RemoveElement(arr);
                                    }

                                    data = data.UpdatePluginAt(this.Id, mySubState);
                                }
                            }
                        }
                    }

                    return(data);
                }
                public override ArrayState Stelem(APC pc, Type type, Variable array, Variable index, Variable value, ArrayState data)
                {
                    Contract.Assume(data != null);

                    var mySubState = Select(data);

                    var boxedArray = new BoxedVariable <Variable>(array);
                    var boxedIndex = new BoxedVariable <Variable>(index);


                    if (mySubState.IsNormal())
                    {
                        var toRemove = new List <BoxedVariable <Variable> >();
                        foreach (var pair in mySubState.Elements)
                        {
                            var el = pair.Value;
                            if (el.IsNormal() && el.Left.IsNormal() && el.Left.Contains(boxedArray) && el.Right.IsNormal() && el.Right.Contains(boxedIndex))
                            {
                                toRemove.Add(pair.Key);
                            }
                        }

                        foreach (var k in toRemove)
                        {
                            mySubState.RemoveElement(k);
                        }
                    }

                    var isUnModifiedArrayElement = data.IsUnmodifiedArrayElementFromEntry(boxedArray, ToBoxedExpression(pc, index));

                    var newRelation = new ScalarFromArrayTracking(boxedArray, boxedIndex, isUnModifiedArrayElement, SymbolicExpressionTracker <BoxedVariable <Variable>, BoxedExpression> .Unknown);

                    mySubState[new BoxedVariable <Variable>(value)] = newRelation;

                    return(data.UpdatePluginAt(this.Id, mySubState));
                }