/// <summary>
 /// Copies the state of 'other' into this charset
 /// </summary>
 public void CopyStateFrom(CharSet other)
 {
     IsInclusive = other.IsInclusive;
       Chars = new SortedSet<char>(other.Chars);
 }
 public static CharSet OneOf(params char[] chars)
 {
     var cs = new CharSet { IsInclusive = true };
       cs.Chars.AddRange(chars);
       return cs;
 }
 /// <summary>
 /// Epands this charset as necessary so that the given CharSet is included in this one.
 /// </summary>
 /// <returns>this</returns>
 public void Union(CharSet other)
 {
     if (IsInclusive)
       {
     if (other.IsInclusive)
     {
       // [AB] + [BC] = [ABC]
       Chars.AddRange(other.Chars);
     }
     else
     {
       // [ABC] + [^CDE] = [^DE]
       var previouslyIncluded = Chars;
       Chars = new SortedSet<char>(other.Chars);
       IsInclusive = false;
       Chars.RemoveAll(previouslyIncluded);
     }
       }
       else
       {
     if (other.IsInclusive)
     {
       Chars.RemoveAll(other.Chars);
     }
     else
     {
       Chars.IntersectWith(other.Chars);
     }
       }
 }
 public static CharSet AnyExcept(params char[] chars)
 {
     var cs = new CharSet { IsInclusive = false };
       cs.Chars.AddRange(chars);
       return cs;
 }
        /// <summary>
        /// Restricts this charset so that it is no more inclusive than the given one.
        /// </summary>
        /// <returns>
        /// true if any changes were made
        /// </returns>
        /// <exception cref="EmptyIntersectionException">
        /// if the intersection would be empty
        /// </exception>
        public bool Intersect(CharSet other)
        {
            bool changesMade;
              if (IsInclusive)
              {
            if (other.IsInclusive)
            {
              var countBefore = Count;
              Chars.IntersectWith(other.Chars);
              changesMade = Count < countBefore;
            }
            else
            {
              changesMade = Chars.RemoveAll(other.Chars);
            }
              }
              else
              {
            if (other.IsInclusive)
            {
              // [^AB] ^ [BC] = [C]
              var previouslyExcluded = Chars;
              Chars = new SortedSet<char>(other.Chars);
              IsInclusive = true;
              Chars.RemoveAll(previouslyExcluded);
              changesMade = true;
            }
            else
            {
              changesMade = Chars.AddRange(other.Chars);
            }
              }

              if (IsInclusive && Chars.Count == 0)
              {
            throw new EmptyIntersectionException("No chars were found in common");
              }

              return changesMade;
        }