//searches for words in the dictionary that match unique permutations of all subsets
        //of the user input.
        private void searchForWords()
        {
            string input = txtLetters.Text;

            //check for bad input
            if (input.Length == 0)
            {
                MessageBox.Show("You must enter letters in the textbox to get results.");
                return;
            }
            else if (input.Length > 8)
            {
                MessageBox.Show("A maximum of eight characters is allowed due to the time-complexity of this algorithm.");
                return;
            }

            //tree to hold words
            if (!my_dictionary_loaded)
            {
                my_dictionary_loaded = true;
                addDictionary();
            }

            //get characters
            char[] letters = input.ToLower().ToCharArray();

            //get unique permutations
            Subsets s = new Subsets();

            s.addObserver(this);

            lblInfo.Text = "Getting letter permutations...";
            List <List <DSInteger> > permutation_indices = s.getUniquePermutationIndices <DSInteger>(letters.Length);

            lblInfo.Text        = "Building possible words...";
            pbrProgress.Value   = 0;
            pbrProgress.Maximum = permutation_indices.size();

            //get word candidates from the permutation indices
            Set <DSString> word_candidates = new HashSet <DSString>();

            for (int i = 0; i < permutation_indices.size(); i++)
            {
                StringBuilder    builder     = new StringBuilder();
                List <DSInteger> permutation = permutation_indices.get(i);
                for (int j = 0; j < permutation.size(); j++)
                {
                    builder.Append(letters[permutation.get(j).value]);
                }

                DSString possible = new DSString(builder.ToString());
                if (!word_candidates.contains(possible))
                {
                    word_candidates.add(possible);
                }

                //show progress
                updateProgress();
            }

            pbrProgress.Value   = 0;
            pbrProgress.Maximum = word_candidates.size();
            lblInfo.Text        = "Check Search Tree for words...";

            //sort candidates according to length and then alphabetically
            DSString[] sorted = word_candidates.toArray();
            Sorting <DSString> .Sort(Sorts.QuickSort, ref sorted, new StringLengthComparator());

            //clear old lookups
            lstWords.Items.Clear();

            //lookup each word in the bst
            for (int i = sorted.Length - 1; i >= 0; i--)
            {
                DSString current = sorted[i];
                if (my_bst.contains(current))
                {
                    lstWords.Items.Add(current.value);
                }

                //show progress
                updateProgress();
            }

            //show words found
            lblInfo.Text = "Words found: " + lstWords.Items.Count;
        }