//This adds the transitions required to make a group trie correspond to the correct quantified regex
        private RegexTrie <T> joinQuantifiedTrie(MinMaxResult result,
                                                 RegexTrie <T> startNodeOfCurrentComponent,
                                                 RegexTrie <T> endNodeOfCurrentComponent,
                                                 RegexTrie <T> endNodeOfPreviousComponent)
        {
            //This is the end node which will be reached by epsilon transition in case of zeroed quantifiers
            //or quantifiers with a number range of more than one, start node is used for zeroing
            RegexTrie <T> epsilonEndNode   = new RegexTrie <T>();
            RegexTrie <T> epsilonStartNode = new RegexTrie <T>();

            //This holds the end node used during the loop
            RegexTrie <T> loopEndNode = endNodeOfCurrentComponent;

            //Loop from 1 (one occurrence already exists) to max occurrences. If loop index is greater than min,
            //add epsilon from iteration trie end to final trie end.

            if (result.minOccurs > 1 || result.maxOccurs > 1)
            {
                //This is used as a model for copying, only needs to be calculated if there's a set number of occurrences
                KeyValuePair <RegexTrie <T>, RegexTrie <T> > trieModel = copyTrie(startNodeOfCurrentComponent, endNodeOfCurrentComponent);
                //Result of trie copy
                KeyValuePair <RegexTrie <T>, RegexTrie <T> > trieCopy;

                for (int index = 2; index <= result.maxOccurs; index++)
                {
                    if (index <= result.maxOccurs)
                    {
                        //Copy the trie and link it to the end of trie
                        trieCopy = copyTrie(trieModel);
                        loopEndNode.AddEpsilonTransition(trieCopy.Key);
                        //If the index is equal or greater than minoccurs, add epsilon to end node
                        if (result.minOccurs <= index)
                        {
                            trieCopy.Value.AddEpsilonTransition(epsilonEndNode);
                        }
                        //Assign the end node of the copy as the end node of the component
                        loopEndNode = trieCopy.Value;
                    }
                }
            }

            //If there's less than two occurrences, connect the end of the first span of the trie to the epsilon end trie
            //Do this after the copy loop in order to not disturb the copying.
            if (result.minOccurs < 2)
            {
                endNodeOfCurrentComponent.AddEpsilonTransition(epsilonEndNode);
            }

            //If the quantifier is starred, add epsilon from end to start
            if (result.starred)
            {
                endNodeOfCurrentComponent.AddEpsilonTransition(startNodeOfCurrentComponent);
            }

            //If the quantifier is zeroed, add an epsilon from epsilon start node
            //newCurrentTrie
            if (result.zeroInclusive)
            {
                epsilonStartNode.AddEpsilonTransition(startNodeOfCurrentComponent);
                epsilonStartNode.AddEpsilonTransition(epsilonEndNode);
                startNodeOfCurrentComponent = epsilonStartNode;
            }

            //Connect trie to previous trie
            endNodeOfPreviousComponent.AddEpsilonTransition(startNodeOfCurrentComponent);

            return(epsilonEndNode);
        }
        //This checks for a quantifier immediately after the character, and joins the current trie to the end of the
        //previous trie. Returns a pair of int (to increment string index) and the node to which further tries will be connected
        private KeyValuePair <int, RegexTrie <T> > checkForQuantifier(
            string sourceTail,
            RegexTrie <T> endNodeOfCurrentComponent,
            RegexTrie <T> startNodeOfCurrentComponent,
            RegexTrie <T> endNodeOfPreviousComponent,
            Stack <RegexTrie <T> > commonDestination)
        {
            char nextChar;

            try
            {
                nextChar = sourceTail[0];
            }
            catch
            {
                //assign a non-special character to trigger the default case
                nextChar = 'n';
            }

            switch (nextChar)
            {
            case '*':
            {
                return(new KeyValuePair <int, RegexTrie <T> >(1, joinQuantifiedTrie(
                                                                  new MinMaxResult(1, 1, true, true),
                                                                  startNodeOfCurrentComponent,
                                                                  endNodeOfCurrentComponent,
                                                                  endNodeOfPreviousComponent)));
            }

            case '+':
            {
                return(new KeyValuePair <int, RegexTrie <T> >(1, joinQuantifiedTrie(
                                                                  new MinMaxResult(1, 1, true, false),
                                                                  startNodeOfCurrentComponent,
                                                                  endNodeOfCurrentComponent,
                                                                  endNodeOfPreviousComponent)));
            }

            case '?':
            {
                return(new KeyValuePair <int, RegexTrie <T> >(1, joinQuantifiedTrie(
                                                                  new MinMaxResult(1, 1, false, true),
                                                                  startNodeOfCurrentComponent,
                                                                  endNodeOfCurrentComponent,
                                                                  endNodeOfPreviousComponent)));
            }

            case '{':
            {
                int          closeBraceIndex = sourceTail.IndexOf('}');
                string       quantString     = sourceTail.Substring(1, closeBraceIndex - 1);
                MinMaxResult minMax          = findMinMax(quantString);
                return(new KeyValuePair <int, RegexTrie <T> >(closeBraceIndex + 1, joinQuantifiedTrie(
                                                                  minMax,
                                                                  startNodeOfCurrentComponent,
                                                                  endNodeOfCurrentComponent,
                                                                  endNodeOfPreviousComponent)));
            }

            default:
            {
                endNodeOfPreviousComponent.AddEpsilonTransition(startNodeOfCurrentComponent);
                return(new KeyValuePair <int, RegexTrie <T> >(0, endNodeOfCurrentComponent));
            }
            }
        }