/// <summary>
        /// Return set of flags indicating possible relationships between
        /// this interval and another interval.
        /// </summary>
        /// <param name="other">Interval with which to compare with</param>
        /// <returns>flags indicating possible relationship between this interval and the other interval</returns>
        public virtual int GetRelationFlags(Edu.Stanford.Nlp.Util.Interval <E> other)
        {
            if (other == null)
            {
                return(0);
            }
            int flags  = 0;
            int comp11 = this.first.CompareTo(other.First());

            // 3 choices
            flags |= ToRelFlags(comp11, RelFlagsSsShift);
            int comp22 = this.second.CompareTo(other.Second());

            // 3 choices
            flags |= ToRelFlags(comp22, RelFlagsEeShift);
            int comp12 = this.first.CompareTo(other.Second());

            // 3 choices
            flags |= ToRelFlags(comp12, RelFlagsSeShift);
            int comp21 = this.second.CompareTo(other.First());

            // 3 choices
            flags |= ToRelFlags(comp21, RelFlagsEsShift);
            flags  = AddIntervalRelationFlags(flags, false);
            return(flags);
        }
        /// <summary>Check whether this interval overlaps with the other interval.</summary>
        /// <remarks>
        /// Check whether this interval overlaps with the other interval.
        /// (I.e. the intersect would not be null.)
        /// </remarks>
        /// <param name="other">interval to compare with</param>
        /// <returns>true if this interval overlaps the other interval</returns>
        public virtual bool Overlaps(Edu.Stanford.Nlp.Util.Interval <E> other)
        {
            if (other == null)
            {
                return(false);
            }
            int comp12 = this.first.CompareTo(other.Second());
            int comp21 = this.second.CompareTo(other.First());

            if (comp12 > 0 || comp21 < 0)
            {
                return(false);
            }
            else
            {
                if (comp12 == 0)
                {
                    if (!this.IncludesBegin() || !other.IncludesEnd())
                    {
                        return(false);
                    }
                }
                if (comp21 == 0)
                {
                    if (!this.IncludesEnd() || !other.IncludesBegin())
                    {
                        return(false);
                    }
                }
                return(true);
            }
        }
        public virtual bool Contains(Edu.Stanford.Nlp.Util.Interval <E> other)
        {
            bool containsOtherBegin = (other.IncludesBegin()) ? Contains(other.GetBegin()) : ContainsOpen(other.GetBegin());
            bool containsOtherEnd   = (other.IncludesEnd()) ? Contains(other.GetEnd()) : ContainsOpen(other.GetEnd());

            return(containsOtherBegin && containsOtherEnd);
        }
        /*  // Returns true if end before (start of other)
         * public boolean isEndBeforeBegin(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp21 = this.second.compareTo(other.first());
         * return (comp21 < 0);
         * }
         *
         * // Returns true if end before or eq (start of other)
         * public boolean isEndBeforeEqBegin(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp21 = this.second.compareTo(other.first());
         * return (comp21 <= 0);
         * }
         *
         * // Returns true if end before or eq (start of other)
         * public boolean isEndEqBegin(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp21 = this.second.compareTo(other.first());
         * return (comp21 == 0);
         * }
         *
         * // Returns true if start after (end of other)
         * public boolean isBeginAfterEnd(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp12 = this.first.compareTo(other.second());
         * return (comp12 > 0);
         * }
         *
         * // Returns true if start eq(end of other)
         * public boolean isBeginAfterEqEnd(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp12 = this.first.compareTo(other.second());
         * return (comp12 >= 0);
         * }
         *
         * // Returns true if start eq(end of other)
         * public boolean isBeginEqEnd(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp12 = this.first.compareTo(other.second());
         * return (comp12 >= 0);
         * }
         *
         * // Returns true if start is the same
         * public boolean isBeginSame(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp11 = this.first.compareTo(other.first());
         * return (comp11 == 0);
         * }
         *
         * // Returns true if end is the same
         * public boolean isEndSame(Interval<E> other)
         * {
         * if (other == null) return false;
         * int comp22 = this.second.compareTo(other.second());
         * return (comp22 == 0);
         * } */
        /// <summary>
        /// Checks whether this interval is comparable with another interval
        /// comes before or after
        /// </summary>
        /// <param name="other">interval to compare with</param>
        public virtual bool IsIntervalComparable(Edu.Stanford.Nlp.Util.Interval <E> other)
        {
            int flags = GetRelationFlags(other);

            if (CheckMultipleBitSet(flags & RelFlagsIntervalUnknown))
            {
                return(false);
            }
            return(CheckFlagSet(flags, RelFlagsIntervalBefore) || CheckFlagSet(flags, RelFlagsIntervalAfter));
        }
        /// <summary>
        /// Returns interval that is the intersection of this and the other interval
        /// Returns null if intersect is null
        /// </summary>
        /// <param name="other">interval with which to intersect</param>
        /// <returns>interval that is the intersection of this and the other interval</returns>
        public virtual Edu.Stanford.Nlp.Util.Interval Intersect(Edu.Stanford.Nlp.Util.Interval <E> other)
        {
            if (other == null)
            {
                return(null);
            }
            E a = Max(this.first, other.first);
            E b = Min(this.second, other.second);

            return(ToInterval(a, b));
        }
        /// <summary>Returns order of another interval compared to this one</summary>
        /// <param name="other">Interval to compare with</param>
        /// <returns>
        /// -1 if this interval is before the other interval, 1 if this interval is after
        /// 0 otherwise (may indicate the two intervals are same or not comparable)
        /// </returns>
        public virtual int CompareIntervalOrder(Edu.Stanford.Nlp.Util.Interval <E> other)
        {
            int flags = GetRelationFlags(other);

            if (CheckFlagExclusiveSet(flags, RelFlagsIntervalBefore, RelFlagsIntervalUnknown))
            {
                return(-1);
            }
            else
            {
                if (CheckFlagExclusiveSet(flags, RelFlagsIntervalAfter, RelFlagsIntervalUnknown))
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }
        }
 public override bool Equals(object o)
 {
     if (this == o)
     {
         return(true);
     }
     if (o == null || GetType() != o.GetType())
     {
         return(false);
     }
     if (!base.Equals(o))
     {
         return(false);
     }
     Edu.Stanford.Nlp.Util.Interval interval = (Edu.Stanford.Nlp.Util.Interval)o;
     if (flags != interval.flags)
     {
         return(false);
     }
     return(true);
 }
        /// <summary>
        /// Returns the relationship of this interval to the other interval
        /// The most specific relationship from the following is returned.
        /// </summary>
        /// <remarks>
        /// Returns the relationship of this interval to the other interval
        /// The most specific relationship from the following is returned.
        /// NONE: the other interval is null
        /// EQUAL: this have same endpoints as other
        /// OVERLAP:  this and other overlaps
        /// BEFORE: this ends before other starts
        /// AFTER: this starts after other ends
        /// BEGIN_MEET_END: this begin is the same as the others end
        /// END_MEET_BEGIN: this end is the same as the others begin
        /// CONTAIN: this contains the other
        /// INSIDE: this is inside the other
        /// UNKNOWN: this is returned if for some reason it is not
        /// possible to determine the exact relationship
        /// of the two intervals (possible for fuzzy intervals)
        /// </remarks>
        /// <param name="other">The other interval with which to compare with</param>
        /// <returns>RelType indicating relationship between the two interval</returns>
        public virtual Interval.RelType GetRelation(Edu.Stanford.Nlp.Util.Interval <E> other)
        {
            // TODO: Handle open/closed intervals?
            if (other == null)
            {
                return(Interval.RelType.None);
            }
            int comp11 = this.first.CompareTo(other.First());
            // 3 choices
            int comp22 = this.second.CompareTo(other.Second());

            // 3 choices
            if (comp11 == 0)
            {
                if (comp22 == 0)
                {
                    // |---|  this
                    // |---|   other
                    return(Interval.RelType.Equal);
                }
                if (comp22 < 0)
                {
                    // SAME START - this finishes before other
                    // |---|  this
                    // |------|   other
                    return(Interval.RelType.Inside);
                }
                else
                {
                    // SAME START - this finishes after other
                    // |------|  this
                    // |---|   other
                    return(Interval.RelType.Contain);
                }
            }
            else
            {
                if (comp22 == 0)
                {
                    if (comp11 < 0)
                    {
                        // SAME FINISH - this start before other
                        // |------|  this
                        //    |---|   other
                        return(Interval.RelType.Contain);
                    }
                    else
                    {
                        /*if (comp11 > 0) */
                        // SAME FINISH - this starts after other
                        //    |---|  this
                        // |------|   other
                        return(Interval.RelType.Inside);
                    }
                }
                else
                {
                    if (comp11 > 0 && comp22 < 0)
                    {
                        //    |---|  this
                        // |---------|   other
                        return(Interval.RelType.Inside);
                    }
                    else
                    {
                        if (comp11 < 0 && comp22 > 0)
                        {
                            // |---------|  this
                            //    |---|   other
                            return(Interval.RelType.Contain);
                        }
                        else
                        {
                            int comp12 = this.first.CompareTo(other.Second());
                            int comp21 = this.second.CompareTo(other.First());
                            if (comp12 > 0)
                            {
                                //           |---|  this
                                // |---|   other
                                return(Interval.RelType.After);
                            }
                            else
                            {
                                if (comp21 < 0)
                                {
                                    // |---|  this
                                    //        |---|   other
                                    return(Interval.RelType.Before);
                                }
                                else
                                {
                                    if (comp12 == 0)
                                    {
                                        //     |---|  this
                                        // |---|   other
                                        return(Interval.RelType.BeginMeetEnd);
                                    }
                                    else
                                    {
                                        if (comp21 == 0)
                                        {
                                            // |---|  this
                                            //     |---|   other
                                            return(Interval.RelType.EndMeetBegin);
                                        }
                                        else
                                        {
                                            return(Interval.RelType.Overlap);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
 public static double GetRadius(Edu.Stanford.Nlp.Util.Interval <int> interval)
 {
     return((interval.GetEnd() - interval.GetBegin()) / 2.0);
 }
 public static double GetMidPoint(Edu.Stanford.Nlp.Util.Interval <int> interval)
 {
     return((interval.GetBegin() + interval.GetEnd()) / 2.0);
 }