public virtual bool Like(SemanticException other)
        {
            Contract.Ensures(other == null
                                 ? Contract.Result<bool>() == false
                                 : true);
            Contract.Ensures(other == this
                                 ? Contract.Result<bool>() == true
                                 : true);
#if EXTRA_CONTRACTS
// pragma to avoid warning, not an error: GetType() isn't Pure
            Contract.Ensures(other != null && GetType() != other.GetType()
                                 ? Contract.Result<bool>() == false
                                 : true);
#endif
            Contract.Ensures(other != null && other.Message != Message
                                 ? Contract.Result<bool>() == false
                                 : true);
            Contract.Ensures(other != null && other.InnerException != InnerException
                                 ? Contract.Result<bool>() == false
                                 : true);

            if (other == null || GetType() != other.GetType())
            {
                return false;
            }
            if (other == this)
            {
                return true;
            }
            return (other.Message == Message) && (other.InnerException == InnerException);
        }
        public override bool Like(SemanticException other)
        {
            Contract.Ensures((base.Like(other)
                              && ((PropertyException)other).Sender == Sender
                              && ((PropertyException)other).PropertyName == PropertyName)
                                 == Contract.Result<bool>());

            if (!base.Like(other))
            {
                return false;
            }

            PropertyException pe = (PropertyException)other;
            return (pe.PropertyName == PropertyName) && (pe.Sender == Sender);
        }
        /// <summary>
        /// This exception is semantically like the <paramref name="other"/>
        /// exception, and contains exceptions that are
        /// <see cref="Like">alike</see>.
        /// </summary>
        public override bool Like(SemanticException other)
        {
            if (!base.Like(other))
            {
                return false;
            }

            CompoundSemanticException ce = (CompoundSemanticException)other;
            return (ce.Elements.Count == Elements.Count)
                   && Elements.All(x => ce.Elements.Any(x.Like))
                   && ce.Elements.All(x => Elements.Any(x.Like));
        }
        public bool ContainsElement(SemanticException exception)
        {
            Contract.Ensures(Contract.Result<bool>() == Elements.Any(x => x.Like(exception)));

            return Set.Any(x => x.Like(exception));
        }
        /// <summary>
        /// Add an element exception to <see cref="Elements"/>.
        /// </summary>
        public void AddElement(SemanticException exception)
        {
            Contract.Requires(exception != null);
            Contract.Requires(!Closed);
            Contract.Ensures(
                exception is CompoundSemanticException
                    ? ((CompoundSemanticException)exception).Elements.All(ContainsElement)
                    : Elements.Contains(exception));

            CompoundSemanticException cse = exception as CompoundSemanticException;
            if (cse == null)
            {
                Set.Add(exception);
            }
            else
            {
                foreach (SemanticException ex in cse.Elements)
                {
                    AddElement(ex);
                }
            }
        }
        public override bool Like(SemanticException other)
        {
            Contract.Ensures((base.Like(other)
                              && object.Equals(((ValueException)other).OldValue, OldValue)
                              && object.Equals(((ValueException)other).NewValue, NewValue))
                                 == Contract.Result<bool>());

            if (!base.Like(other))
            {
                return false;
            }

            ValueException ve = (ValueException)other;
            return object.Equals(ve.OldValue, OldValue) && object.Equals(ve.NewValue, NewValue);
        }