Class, containing data for building tree of variants.
        /// <summary>
        /// Initializes a new instance of the <see cref="TreeNode"/> class.
        /// </summary>
        /// <param name="parent">
        /// Parent node.
        /// </param>
        /// <param name="content">
        /// Content of the this node.
        /// </param>
        /// <param name="table">
        /// Parameters table.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Thrown if parent is null.
        /// </exception>
        public TreeNode(AbstractNode parent, IBaseObject content, PhantomTable table)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent", "Parent node is null");
            }

            this.parent = parent;
            Level = this.parent.Level + 1;
            Volume = table[Level + 1].Volume;
            id = content;
            StartPosition = table.StartPositions[Level];
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TreeTop"/> class,
        /// representing root element of the tree.
        /// </summary>
        /// <param name="source">
        /// The input chain.
        /// </param>
        /// <param name="generator">
        /// The gen.
        /// </param>
        public TreeTop(BaseChain source, IGenerator generator)
        {
            table = new PhantomTable(source);
            this.generator = generator;
            StartPosition = 0;
            Volume = table[0].Volume;
            Level = -1;
            if ((table[1].Content[0] is ValueString) || (table[1].Content[0] is BaseChain))
            {
                isString = true;
            }

            if ((source != null) && (source.GetLength() != 0))
            {
                var temp = (ValuePhantom)source[0];
                for (int i = 0; i < temp.Cardinality; i++)
                {
                    Children.Add(new TreeNode(this, temp[i], table));
                }
            }
        }
 /// <summary>
 /// Choosing which child will generate next element of sequence.
 /// </summary>
 /// <param name="result">
 /// Intermediate result.
 /// </param>
 /// <param name="generator">
 /// Random numbers generator.
 /// </param>
 /// <param name="table">
 /// Phantom sequence parameters table.
 /// </param>
 protected void Find(BaseChain result, IGenerator generator, PhantomTable table)
 {
     // if not leaf node
     if (Children.Count != 0)
     {
         double val = generator.Next();
         ulong curVal = 0;
         foreach (TreeNode child in Children)
         {
             curVal += child.Volume;
             if (val <= ((double)curVal / Volume))
             {
                 child.FillChain(result, generator, table);
                 return;
             }
         }
     }
     else
     {
         // if there is no children nodes then generation is done and decrement procedure is started
         Decrement();
     }
 }
        /// <summary>
        /// Method adds new element into generated sequence.
        /// And calls the same method of one of the children if sequence is incomplete.
        /// </summary>
        /// <param name="result">
        /// Generated sequence.
        /// </param>
        /// <param name="generator">
        /// Random number generator.
        /// </param>
        /// <param name="table">
        /// Parameters table.
        /// </param>
        public void FillChain(BaseChain result, IGenerator generator, PhantomTable table)
        {
            if ((table.Length != (Level + 2)) && (Children.Count == 0))
            {
                ValuePhantom temp = table[Level + 2].Content;
                for (int i = 0; i < temp.Cardinality; i++)
                {
                    Children.Add(new TreeNode(this, temp[i], table));
                }
            }

            if ((id is BaseChain) || (id is ValueString))
            {
                string amino = id.ToString();
                for (int k = 0; k < amino.Length; k++)
                {
                    result[StartPosition + k] = new ValueString(amino[k]);
                }
            }
            else
            {
                result[StartPosition] = id;
            }

            Find(result, generator, table);
        }