public static int getScatteredPhraseEntries(string phrase, string text)
        {
            if (String.IsNullOrEmpty(phrase))
                throw new ArgumentException("Phrase is null or empty!");
            if (String.IsNullOrEmpty(text))
                throw new ArgumentException("Text is null or empty!");

            var root = new TreeNode(0, phrase.Length - 1, new PhraseCharSet(phrase));
            for (int symbolIndex = 0; symbolIndex < text.Length; symbolIndex++)
                root.getNextSymbol(text.ElementAt(symbolIndex));

            return root.getVariantsNumber();
        }
        public void getNextSymbol(char nextTextCharacter)
        {
            if (!phraseCharSet.isPhraseContainsChar(nextTextCharacter))
                return;//phrase do not even contain this char, so it is not any interesting for us - return

            //if we face the symbol, which position in phrase match our node's position
            if (phraseCharSet.isCharMatchesPosition(nextTextCharacter, indexOfTheSymbolInPhrase))
            {
                //if we do not have nextSymbolNode yet, it means, that it is only one more same char in a row - simply increment symbolsCollected
                if (nextSymbolNode == null)
                {
                    //fix for phrases with two or more symbols in a row - we need to check matching for a position of next symbol
                    if (symbolsCollected == 1 && phraseCharSet.isCharMatchesPosition(nextTextCharacter, indexOfTheSymbolInPhrase + 1))
                    {
                        //if yes, we must initialize nextSymbolNode as current symbol can be the next, not current symbol as well
                        nextSymbolNode = new TreeNode(indexOfTheSymbolInPhrase + 1, maxIndex, phraseCharSet);
                        nextSymbolNode.getNextSymbol(nextTextCharacter);

                        //and if we now have nextSymbolNode, we can instantiate sameSymbolNode with this symbol as well
                        sameSymbolNode = new TreeNode(indexOfTheSymbolInPhrase, maxIndex, phraseCharSet);
                        sameSymbolNode.getNextSymbol(nextTextCharacter);
                    }
                    else
                    {
                        symbolsCollected++;
                    }
                }
                else
                {
                    //this means that ve already had a set of at least next characters before we reach current symbol
                    //in case there is no sameSymbolNode yet, we will create it as current symbol can create new branch of possibilities
                    if (sameSymbolNode == null)
                        sameSymbolNode = new TreeNode(indexOfTheSymbolInPhrase, maxIndex, phraseCharSet);

                    //and send symbol to it
                    sameSymbolNode.getNextSymbol(nextTextCharacter);

                    //and as symbols in phrase can duplicate, we send symbol to nextSymbolNode as symbol can find a place for him further in the branch
                    nextSymbolNode.getNextSymbol(nextTextCharacter);
                }

                return;
            }

            //if we face the symbol, that match the symbol with position in phrase that is ahead of us by 1
            if (phraseCharSet.isCharMatchesPosition(nextTextCharacter, indexOfTheSymbolInPhrase + 1))
            {
                //if we do not have nextSymbolNode yet, it means it is high time to create it - we faced the symbol, that matches next position in phrase
                if (nextSymbolNode == null)
                    nextSymbolNode = new TreeNode(indexOfTheSymbolInPhrase + 1, maxIndex, phraseCharSet);
                else
                {
                    //and if sameSymbolNode existed, will send symbol there
                    if (sameSymbolNode != null)
                        sameSymbolNode.getNextSymbol(nextTextCharacter);
                }

                //as we already have nextSymbolNode, we just send symbol to it, nextSymbolNode will take care of it
                nextSymbolNode.getNextSymbol(nextTextCharacter);

                return;
            }

            //if symbol does not match any of mentioned conditions, will send it to children anyway
            if (nextSymbolNode != null)
            {
                nextSymbolNode.getNextSymbol(nextTextCharacter);
                if (sameSymbolNode != null)
                    sameSymbolNode.getNextSymbol(nextTextCharacter);
            }
        }