}//end OuterArrangement

        // inner loop
        private static List <int> InnerArrangement(int index, int data_len, Dictionary <string, int> count_table, AugmentedTrie tree, string word)
        {
            TreeNode   the_leaf   = tree.FindtheLeaf(word);
            List <int> inner_list = new List <int>(the_leaf.GetDataNode());//go through the data first

            bool[] over_arr = new bool[data_len];
            for (int i = 0; i < data_len; i++)
            {
                over_arr[i] = false;
            }

            foreach (int element in inner_list)
            {
                over_arr[element - index] = true;
            }

            List <int> inner_random = new List <int>();
            List <int> inner_first  = new List <int>();

            for (int i = 0; i < data_len; i++)
            {
                if (over_arr[i] == false)
                {
                    inner_random.Add(i);
                }
                else
                {
                    inner_first.Add(i);
                }
            }

            //make random_inner randomly
            inner_random.Shuffle();

            inner_list = inner_first.Concat(inner_random).ToList();

            return(inner_list);
        }//end innerArrangement
        }// end

        public static List <double> candidateHOTSAX(List <int> candidate_list, int index, List <double> norm_data, int N_LENGTH, int W_LENGTH, ref AugmentedTrie tree, ref Dictionary <string, int> count_table, ref Dictionary <int, string> total_table)
        {
            string old_segment_word, new_segment_word;
            //old_segment_word: store the first segment at time t to SAX word.
            //new_segment_word: store the new segment at time t+1 to SAX word.

            List <double> new_segment = norm_data.GetRange(norm_data.Count - N_LENGTH, N_LENGTH);

            old_segment_word = total_table[index - 1];
            new_segment_word = convertSegmentToWord(new_segment, N_LENGTH, W_LENGTH);

            //update Tree, and Tables:
            // first, we  update 'count_table':

            if (count_table.ContainsKey(old_segment_word))
            {
                count_table[old_segment_word]--;
            }
            if (count_table.ContainsKey(new_segment_word))
            {
                count_table[new_segment_word]++;
            }
            else
            {
                count_table.Add(new_segment_word, 1);
            }

            //update 'total_table':
            int len_total_table = norm_data.Count;

            total_table.Remove(index - 1);
            total_table.Add(index + len_total_table - N_LENGTH, new_segment_word);

            //update 'Tree':
            TreeNode old_seg_leaf = tree.FindtheLeaf(old_segment_word);
            TreeNode new_seg_leaf = tree.FindtheLeaf(new_segment_word);

            old_seg_leaf.GetDataNode().Remove(index - 1);
            new_seg_leaf.GetDataNode().Add(index + len_total_table - N_LENGTH);
            //end update

            double best_so_far_dist = 0;
            int    best_so_far_loc  = 0;

            double nearest_neighbor_dist = 0;
            double dist = 0;

            List <int> outer_list, inner_list;

            outer_list = candidate_list;//OuterArrangement(index, total_table, count_table);
            bool break_to_outer_loop = false;

            bool[] is_skip_at_p = new bool[norm_data.Count];
            for (int i = 0; i < norm_data.Count; i++)
            {
                is_skip_at_p[i] = false;
            }

            foreach (int p in outer_list)
            {
                if (is_skip_at_p[p])
                {
                    //p was visited at inner loop before
                    continue;
                }
                else
                {
                    nearest_neighbor_dist = Constants.INFINITE;
                    string word = total_table[p + index];

                    inner_list = InnerArrangement(index, total_table.Count, count_table, tree, word);

                    foreach (int q in inner_list)// inner loop
                    {
                        if (Math.Abs(p - q) < N_LENGTH)
                        {
                            continue;// self-match => skip to the next one
                        }
                        else
                        {
                            //calculate the Distance between p and q
                            dist = MathFuncs.EuDistance(norm_data.GetRange(p, N_LENGTH), norm_data.GetRange(q, N_LENGTH));

                            if (dist < best_so_far_dist)
                            {
                                //skip the element q at oute_loop, 'cuz if (p,q) is not a solution, so does (q,p).
                                is_skip_at_p[q] = true;

                                break_to_outer_loop = true; //break, to the next loop at outer_loop
                                break;                      // break at inner_loop first
                            }

                            if (dist < nearest_neighbor_dist)
                            {
                                nearest_neighbor_dist = dist;
                            }
                        }
                    }//end inner
                    if (break_to_outer_loop)
                    {
                        break_to_outer_loop = false; //reset
                        continue;                    //go to the next p in outer loop
                    }

                    if (nearest_neighbor_dist > best_so_far_dist)
                    {
                        best_so_far_dist = nearest_neighbor_dist;
                        best_so_far_loc  = p;
                    }
                } //end else
            }     //end outter

            List <double> result = new List <double> {
                best_so_far_dist, best_so_far_loc
            };

            //Console.WriteLine("skip = " + number_skip);

            return(result);
        }