protected bool TryCreateArraySegment(BoxedExpression low, BoxedExpression upp, Variable arrayLen,
                                                     AbstractDomain intv,
                                                     INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression> numDom,
                                                     out ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression> arraySegmentation)
                {
                    #region Contracts

                    Contract.Requires(low != null);
                    Contract.Requires(upp != null);
                    Contract.Requires(intv != null);
                    Contract.Requires(arrayLen != null);
                    Contract.Requires(numDom != null);

                    Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out arraySegmentation) != null);

                    #endregion

                    var lowerBounds = new Set <NormalizedExpression <BoxedVariable <Variable> > >();

                    lowerBounds.AddIfNotNull(low.ToNormalizedExpression <Variable>());

                    var upperBounds = new Set <NormalizedExpression <BoxedVariable <Variable> > >();

                    upperBounds.AddIfNotNull(upp.ToNormalizedExpression <Variable>());
                    upperBounds.AddIfNotNull(upp.ToNormalizedExpression <Variable>(true));
                    upperBounds.AddIfNotNull(upp.Simplify(this.DecoderForMetaData).ToNormalizedExpression <Variable>());
                    upperBounds.AddIfNotNull(this.Decoder.Stripped(upp).ToNormalizedExpression <Variable>());

                    if (lowerBounds.Count == 0 || upperBounds.Count == 0)
                    {
                        arraySegmentation = null;
                        return(false);
                    }

                    var segments = new NonNullList <SegmentLimit <BoxedVariable <Variable> > >();

                    var elements = new NonNullList <AbstractDomain>();

                    #region Build the prefix

                    // Check if low is zero
                    int lowValue;
                    if (low.IsConstantInt(out lowValue))
                    {
                        if (lowValue < 0)
                        {
                            arraySegmentation = default(ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>);
                            return(false);
                        }

                        // { 0 } Top { lowValue }
                        if (lowValue > 0)
                        {
                            segments.Add(new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(0), false));
                            elements.Add((AbstractDomain)intv.Top);
                        }

                        //  .. { lowValue } intv
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(lowerBounds, false));
                        elements.Add(intv);
                    }
                    else if (numDom.CheckIfGreaterEqualThanZero(low).IsTrue())
                    {
                        // { 0 } Top { low }?
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(0), false));
                        elements.Add((AbstractDomain)intv.Top);

                        // intv { upp }?
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(lowerBounds, true)); // F: we can improve precision by asking if low != 0
                        elements.Add(intv);
                    }
                    else
                    {
                        arraySegmentation = default(ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>);
                        return(false);
                    }

                    #endregion

                    #region Build the suffix
                    // ... { upperBounds }
                    if (arrayLen.Equals(upp.UnderlyingVariable) || arrayLen.Equals(this.Decoder.Stripped(upp).UnderlyingVariable))
                    {
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(upperBounds, false));
                    }
                    else // ... { upperBounds } Top { arrayLen }?
                    {
                        segments.Add(new SegmentLimit <BoxedVariable <Variable> >(upperBounds, false));
                        elements.Add((AbstractDomain)intv.Top);
                        segments.Add(
                            new SegmentLimit <BoxedVariable <Variable> >(
                                NormalizedExpression <BoxedVariable <Variable> > .For(new BoxedVariable <Variable>(arrayLen)), true));
                    }
                    #endregion

                    arraySegmentation = new ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>(
                        segments, elements,
                        (AbstractDomain)intv.Bottom, this.ExpressionManager);

                    return(true);
                }