public SegmentLimit <Variable> AssignInParallel <Expression>(Dictionary <Variable, FList <Variable> > sourceToTargets, Converter <Variable, Expression> convert,
                                                                     IExpressionDecoder <Variable, Expression> decoder)
        {
            #region Contracts
            Contract.Requires(sourceToTargets != null);
            Contract.Requires(convert != null);
            Contract.Requires(decoder != null);

            Contract.Ensures(Contract.Result <SegmentLimit <Variable> >() != null);
            #endregion

            var newSet = new Set <NormalizedExpression <Variable> >();

            foreach (var x in expressions)
            {
                Contract.Assume(x != null);

                FList <Variable> targets;

                int      value;
                Variable var;
                if (x.IsConstant(out value))
                {
                    newSet.Add(x);
                }
                else if (x.IsVariable(out var))
                {
                    if (sourceToTargets.TryGetValue(var, out targets))
                    {
                        Contract.Assume(targets != null);

                        foreach (var newName in targets.GetEnumerable())
                        {
                            newSet.Add(NormalizedExpression <Variable> .For(newName));
                        }
                    }
                }
                else if (x.IsAddition(out var, out value))
                {
                    if (sourceToTargets.TryGetValue(var, out targets))
                    {
                        Contract.Assume(targets != null);
                        foreach (var newName in targets.GetEnumerable())
                        {
                            newSet.Add(NormalizedExpression <Variable> .For(newName, value));
                        }
                    }

                    // This is a special case to handle renaming for a[p++] = ...
                    // We have (var + value) --> var
                    Variable source;
                    if (IsATarget(var, sourceToTargets, out source))
                    {
                        Variable v;
                        int      k;
                        if (decoder.TryMatchVarPlusConst(convert(source), out v, out k) && v.Equals(var) && k == value)
                        {
                            newSet.Add(NormalizedExpression <Variable> .For(var));
                        }
                    }
                }
            }

            return(new SegmentLimit <Variable>(newSet, this.IsConditional));
        }