/// <summary>
        /// Initializes a new instance of the <see cref="ScopeValue"/> class.
        /// </summary>
        /// <param name="Size">The Size<see cref="int"/>.</param>
        /// <param name="Scopes">The Scopes<see cref="IDeck{BaseSpectrum}"/>.</param>
        /// <param name="SigmaScopes">The SigmaScopes<see cref="IDeck{BaseSpectrum}"/>.</param>
        /// <param name="Levels">The Levels<see cref="IList{vEBTreeLevel}"/>.</param>
        /// <param name="Level">The Level<see cref="byte"/>.</param>
        /// <param name="NodeIndex">The NodeIndex<see cref="byte"/>.</param>
        /// <param name="DeckIndex">The DeckIndex<see cref="int"/>.</param>
        public ScopeValue(int Size, IDeck <BaseSpectrum> Scopes, IDeck <BaseSpectrum> SigmaScopes, IList <vEBTreeLevel> Levels, byte Level, byte NodeIndex, int DeckIndex)
        {
            this.min       = NULL_KEY;
            this.max       = NULL_KEY;
            this.sigmaNode = null;

            scopes      = Scopes;
            sigmaScopes = SigmaScopes;
            levels      = Levels;

            this.size  = Size;
            parentSqrt = ParentSqrt(size);
            childSqrt  = ChildSqrt(size);

            this.nodeId     = NodeIndex;
            this.level      = Level;
            this.registryId = DeckIndex;
        }
        /// <summary>
        /// The Remove.
        /// </summary>
        /// <param name="x">The x<see cref="int"/>.</param>
        /// <returns>The <see cref="bool"/>.</returns>
        public override bool Remove(int x)
        {
            if (min == max)
            {
                if (min != x)
                {
                    return(true);
                }
                min       = NULL_KEY;
                max       = NULL_KEY;
                sigmaNode = null;
                return(true);
            }

            //--- sigmaScopes common for all sigmaNode scopes ---->
            BaseSpectrum sigmaScopesItem;
            vEBTreeNode  nodeTypeInfo = levels[level].Scopes[nodeId];;
            int          sigmaScopesKey;
            //<-----sigmaNode key --- global
            int x_highest;

            if (min == x)
            {
                int first = sigmaNode.IndexMin;

                //--- sigmaScopes common for all sigmaNode scopes ---->
                sigmaScopesKey = nodeTypeInfo.IndexOffset + nodeTypeInfo.NodeSize * registryId + first;
                sigmaScopes.TryGet(sigmaScopesKey, out sigmaScopesItem);
                x = index(first, sigmaScopesItem.IndexMin);
                //<-----sigmaNode key --- global
                min = x;
            }

            x_highest = highest(x);
            //--- sigmaScopes common for all sigmaNode scopes ---->
            sigmaScopesKey = nodeTypeInfo.IndexOffset + nodeTypeInfo.NodeSize * registryId + x_highest;
            if (!sigmaScopes.TryGet(sigmaScopesKey, out sigmaScopesItem))
            {
                return(false);
            }
            sigmaScopesItem.Remove(lowest(x));
            //<-----sigmaNode key --- global

            if (sigmaScopesItem.IndexMin == NULL_KEY)
            {
                //--- sigmaScopes common for all sigmaNode scopes ---->
                sigmaScopes.Remove(sigmaScopesKey);
                //<-----sigmaNode key --- global

                sigmaNode.Remove(highest(x));

                if (x == max)
                {
                    int sigmaNodeMaximum = sigmaNode.IndexMax;

                    if (sigmaNodeMaximum == NULL_KEY)
                    {
                        max       = min;
                        sigmaNode = null;
                    }
                    else
                    {
                        //--- sigmaScopes common for all sigmaNode scopes ---->
                        sigmaScopesKey = nodeTypeInfo.IndexOffset + nodeTypeInfo.NodeSize * registryId + sigmaNodeMaximum;
                        sigmaScopes.TryGet(sigmaScopesKey, out sigmaScopesItem);
                        int maximumKey = sigmaScopesItem.IndexMax;
                        //<-----sigmaNode key --- global

                        max = index(sigmaNodeMaximum, maximumKey);
                    }
                }
            }
            else if (x == max)
            {
                //--- sigmaScopes common for all sigmaNode scopes ---->
                sigmaScopesKey = nodeTypeInfo.IndexOffset + nodeTypeInfo.NodeSize * registryId + highest(x);
                sigmaScopes.TryGet(sigmaScopesKey, out sigmaScopesItem);
                int maximumKey = sigmaScopesItem.IndexMax;
                //<-----sigmaNode key --- global

                max = index(highest(x), maximumKey);
            }
            return(true);
        }
        /// <summary>
        /// The Remove.
        /// </summary>
        /// <param name="offsetBase">The offsetBase<see cref="int"/>.</param>
        /// <param name="offsetFactor">The offsetFactor<see cref="int"/>.</param>
        /// <param name="indexOffset">The indexOffset<see cref="int"/>.</param>
        /// <param name="x">The x<see cref="int"/>.</param>
        /// <returns>The <see cref="bool"/>.</returns>
        public override bool Remove(int offsetBase, int offsetFactor, int indexOffset, int x)
        {
            if (min == max)
            {
                if (min != x)
                {
                    return(false);
                }
                min       = NULL_KEY;
                max       = NULL_KEY;
                sigmaNode = null;
                return(true);
            }

            BaseSpectrum scopesItem;
            int          x_highest;
            int          scopesKey;

            if (min == x)
            {
                int firstCluster = sigmaNode.IndexMin;

                scopesKey = offsetBase + (indexOffset * parentSqrt) + firstCluster;
                scopes.TryGet(scopesKey, out scopesItem);
                x = index(firstCluster, scopesItem.IndexMin);

                min = x;
            }

            x_highest = highest(x);
            scopesKey = offsetBase + (indexOffset * parentSqrt) + x_highest;

            if (!scopes.TryGet(scopesKey, out scopesItem))
            {
                return(false);
            }

            scopesItem.Remove(offsetBase + (offsetFactor * parentSqrt), (offsetFactor * parentSqrt), (indexOffset * parentSqrt) + x_highest, lowest(x));

            if (scopesItem.IndexMin == NULL_KEY)
            {
                scopes.Remove(scopesKey);

                sigmaNode.Remove(highest(x));

                if (x == max)
                {
                    int sigmaNodeMaximum = sigmaNode.IndexMax;

                    if (sigmaNodeMaximum == NULL_KEY)
                    {
                        max       = min;
                        sigmaNode = null;
                    }
                    else
                    {
                        scopesKey = offsetBase + (indexOffset * parentSqrt) + sigmaNodeMaximum;
                        scopes.TryGet(scopesKey, out scopesItem);

                        int maximumKey = scopesItem.IndexMax;
                        max = index(sigmaNodeMaximum, maximumKey);
                    }
                }
            }
            else if (x == max)
            {
                scopesKey = offsetBase + (indexOffset * parentSqrt) + highest(x);
                scopes.TryGet(scopesKey, out scopesItem);
                int maximumKey = scopesItem.IndexMax;

                max = index(highest(x), maximumKey);
            }
            return(true);
        }
        /// <summary>
        /// The Add.
        /// </summary>
        /// <param name="x">The x<see cref="int"/>.</param>
        public override void Add(int x)
        {
            if ((min == x) || (max == x))
            {
                return;
            }

            if (x < min)
            {
                int tmp = x;
                x   = min;
                min = tmp;
            }

            if (size != MINIMUM_UNIVERSE_SIZE_U4)
            {
                int x_highest = highest(x);

                //--- sigmaScopes common for all sigmaNode scopes ---->
                BaseSpectrum sigmaScopesItem;

                int sigmaScopesKey =
                    levels[level].Scopes[nodeId].IndexOffset
                    + levels[level].Scopes[nodeId].NodeSize
                    * registryId
                    + x_highest;
                //<-----sigmaNode key --- global


                if (!sigmaScopes.TryGet(sigmaScopesKey, out sigmaScopesItem))
                {
                    if (parentSqrt == MINIMUM_UNIVERSE_SIZE_U4)
                    {
                        if (sigmaNode == null)
                        {
                            sigmaNode = new TetraValue(-1);
                            sigmaNode.FirstAdd(x_highest);
                        }
                        else
                        {
                            sigmaNode.Add(x_highest);
                        }

                        //--- sigmaScopes common for all sigmaNode scopes ---->
                        sigmaScopesItem = new TetraValue(-1);
                        sigmaScopes.Add(sigmaScopesKey, sigmaScopesItem);
                        sigmaScopesItem.FirstAdd(lowest(x));
                        //<-----sigmaNode key --- global
                    }
                    else //create new branch
                    {
                        if (sigmaNode == null)
                        {
                            sigmaNode = new ScopeValue(parentSqrt, scopes, sigmaScopes, levels, (byte)(level + 1), (byte)(2 * nodeId), registryId);
                            sigmaNode.FirstAdd(x_highest);
                        }
                        else
                        {
                            sigmaNode.Add(x_highest);
                        }

                        //--- sigmaScopes common for all sigmaNode scopes ---->
                        sigmaScopesItem = new ScopeValue(parentSqrt, scopes, sigmaScopes, levels, (byte)(level + 1), (byte)(2 * nodeId + 1),
                                                         registryId * levels[level].Scopes[nodeId].NodeSize + x_highest);
                        sigmaScopes.Add(sigmaScopesKey, sigmaScopesItem);
                        sigmaScopesItem.FirstAdd(lowest(x));
                        //<-----sigmaNode key --- global
                    }
                }
                else
                {
                    //--- sigmaScopes common for all sigmaNode scopes ---->
                    sigmaScopesItem.Add(lowest(x));
                    //<-----sigmaNode key --- global
                }
            }

            if (max < x)
            {
                max = x;
            }
        }
        /// <summary>
        /// The Add.
        /// </summary>
        /// <param name="offsetBase">The offsetBase<see cref="int"/>.</param>
        /// <param name="offsetFactor">The offsetFactor<see cref="int"/>.</param>
        /// <param name="indexOffset">The indexOffset<see cref="int"/>.</param>
        /// <param name="x">The x<see cref="int"/>.</param>
        public override void Add(int offsetBase, int offsetFactor, int indexOffset, int x)
        {
            if ((min == x) || (max == x))
            {
                return;
            }

            if (min == NULL_KEY)
            {
                FirstAdd(offsetBase + offsetFactor * parentSqrt, offsetFactor * parentSqrt, indexOffset * parentSqrt + highest(x), x);
                return;
            }

            if (x < min)
            {
                int tmp = x;
                x   = min;
                min = tmp;
            }

            if (size != MINIMUM_UNIVERSE_SIZE_U4)
            {
                BaseSpectrum scopesItem;
                int          x_highest = highest(x);

                int scopesKey = offsetBase + indexOffset * parentSqrt + x_highest;

                if (!scopes.TryGet(scopesKey, out scopesItem))
                {
                    if (parentSqrt == MINIMUM_UNIVERSE_SIZE_U4)
                    {
                        if (sigmaNode == null)    //sigmaNode of the current level (u>4, e.g., u=16)
                        {
                            sigmaNode = new TetraValue(-1);
                            sigmaNode.FirstAdd(x_highest);
                        }
                        else
                        {
                            sigmaNode.Add(x_highest); //tutaj zrobic else
                        }
                        scopesItem = new TetraValue(-1);
                        scopes.Add(scopesKey, scopesItem);
                        scopesItem.FirstAdd(lowest(x));
                    }
                    else //create new node (add next level)
                    {
                        if (sigmaNode == null)
                        {
                            sigmaNode = new ScopeValue(parentSqrt, scopes, sigmaScopes, levels, (byte)(level + 1), (byte)(2 * nodeId), registryId);
                            sigmaNode.FirstAdd(x_highest);
                        }
                        else
                        {
                            sigmaNode.Add(x_highest); //tutaj zrobic else
                        }

                        scopesItem = new ScopeValue(parentSqrt, scopes, sigmaScopes, levels, (byte)(level + 1), (byte)(2 * nodeId + 1),
                                                    registryId * levels[level].Scopes[nodeId].NodeSize + x_highest);
                        scopes.Add(scopesKey, scopesItem);
                        scopesItem.FirstAdd(offsetBase + offsetFactor * parentSqrt, offsetFactor * parentSqrt, indexOffset * parentSqrt + x_highest, lowest(x));
                    }
                }
                else
                {
                    scopesItem.Add(offsetBase + offsetFactor * parentSqrt, offsetFactor * parentSqrt, indexOffset * parentSqrt + x_highest, lowest(x));
                }
            }

            if (max < x)
            {
                max = x;
            }
        }