public static RegexExpression Create(RegexExpression left, RegexExpression right)
        {
            var leftMatch = left as RegexMatchSet;

            if (leftMatch != null)
            {
                var rightMatch = right as RegexMatchSet;
                if (rightMatch != null)
                {
                    var handle = new RangeSetHandle.Union(false);
                    handle.Add(leftMatch.Handle);
                    handle.Add(rightMatch.Handle);
                    return(new RegexMatchSet(leftMatch.Text + '|' + rightMatch.Text, handle));
                }
            }
            return(new RegexAlternation(left, right));
        }
        public static RegexMatchSet FromSet(string set)
        {
            var match = rxSet.Match(set);

            if (!match.Success)
            {
                throw new ArgumentException("Set is invalid", "set");
            }
            var handle = new RangeSetHandle.Union(match.Groups["neg"].Success);

            foreach (Capture capture in match.Groups["letter"].Captures)
            {
                handle.Add((capture.Value[0] == '\\') ? ParseEscape(capture.Value) : new RangeSetHandle.Static(capture.Value.ToCodepoints().Single()));
            }
            var from = match.Groups["from"].Captures;
            var to   = match.Groups["to"].Captures;

            Debug.Assert(from.Count == to.Count);
            for (var i = 0; i < from.Count; i++)
            {
                handle.Add(new RangeSetHandle.Static(ParseSingleLetter(from[i].Value), ParseSingleLetter(to[i].Value)));
            }
            return(new RegexMatchSet(set, handle.Simplify()));
        }