/// <summary>
        /// Gets or sets the distance for an entity.
        /// </summary>
        /// <param name="index">The index for the entity</param>
        /// <returns></returns>
        public double this[int index]
        {
            get
            {
                CheckRange("index", 0, Count - 1, index);

                if (index >= InternalCount)
                {
                    return(DefaultDistance);
                }

                TreeTableWithCounterEntry rbEntry = rbTree[index];
                var counter = (TreeTableVisibleCounter)rbTree[index].GetCounterTotal();
                return(counter.GetVisibleCount());
            }
            set
            {
                CheckRange("index", 0, Count - 1, index);

                if (index >= InternalCount)
                {
                    EnsureTreeCount(index + 1);
                }

                TreeTableWithCounterEntry rbEntry = rbTree[index];
                var counter = (TreeTableVisibleCounter)rbTree[index].GetCounterTotal();
                if (counter.GetVisibleCount() != value)
                {
                    rbEntry.Value = new TreeTableVisibleCounterSource(value);
                    rbEntry.InvalidateCounterBottomUp(false);
                }
            }
        }
        void EnsureTreeCount(int count)
        {
            int treeCount = rbTree.GetCount();

            if (treeCount == 0)
            {
                rbTree.BeginInit();
                for (int n = 0; n < count; n++)
                {
                    var rbEntry = new TreeTableWithCounterEntry
                    {
                        Value = new TreeTableVisibleCounterSource(DefaultDistance),
                        Tree  = rbTree
                    };
                    rbTree.Add(rbEntry);
                }
                rbTree.EndInit();
            }
            else if (treeCount < count)
            {
                for (int n = treeCount; n < count; n++)
                {
                    var rbEntry = new TreeTableWithCounterEntry
                    {
                        Value = new TreeTableVisibleCounterSource(DefaultDistance),
                        Tree  = rbTree
                    };
                    rbTree.Add(rbEntry);
                }
            }
        }
        /// <summary>
        /// Assigns a collection with nested entities to an item.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="nestedCollection">The nested collection.</param>
        public void SetNestedDistances(int index, IDistanceCounterCollection nestedCollection)
        {
            CheckRange("index", 0, Count - 1, index);

            EnsureTreeCount(index + 1);

            TreeTableWithCounterEntry rbEntry = rbTree[index];
            var vcs = new NestedTreeTableVisibleCounterSource(this, nestedCollection);

            rbEntry.Value = vcs;
            rbEntry.InvalidateCounterBottomUp(false);
            vcs.Entry = rbEntry;
        }
        /// <summary>
        /// Gets the nested entities at a given index. If the index does not hold
        /// a mested distances collection the method returns null.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <returns>The nested collection or null.</returns>
        public IDistanceCounterCollection GetNestedDistances(int index)
        {
            if (index < rbTree.GetCount())
            {
                TreeTableWithCounterEntry rbEntry = rbTree[index];
                if (rbEntry != null)
                {
                    var vcs = rbEntry.Value as NestedTreeTableVisibleCounterSource;
                    if (vcs != null)
                    {
                        return(vcs.NestedDistances);
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Hides a specified range of entities (lines, rows or colums)
        /// </summary>
        /// <param name="from">The index for the first entity&gt;</param>
        /// <param name="to">The raw index for the last entity</param>
        /// <param name="distance">The distance.</param>
        public void SetRange(int from, int to, double distance)
        {
            CheckRange("from", 0, Count - 1, from);
            CheckRange("to", 0, Count - 1, to);

            EnsureTreeCount(to + 1);

            for (int n = from; n <= to; n++)
            {
                TreeTableWithCounterEntry rbEntry = rbTree[n];
                var counter = (TreeTableVisibleCounter)rbTree[n].GetCounterTotal();
                if (counter.GetVisibleCount() != distance)
                {
                    rbEntry.Value = new TreeTableVisibleCounterSource(distance);
                    rbEntry.InvalidateCounterBottomUp(true);
                }
            }
        }
        /// <summary>
        /// Resets the range by restoring the default distance
        /// for all entries in the specified range.
        /// </summary>
        /// <param name="from">From.</param>
        /// <param name="to">To.</param>
        public void ResetRange(int from, int to)
        {
            CheckRange("from", 0, Count - 1, from);
            CheckRange("to", 0, Count - 1, to);

            if (from >= rbTree.GetCount())
            {
                return;
            }

            if (to >= rbTree.GetCount())
            {
                // TODO: Review if should check for rbTree.GetCount()-1
                if (from == 0)
                {
                    Clear();
                }

                to = rbTree.GetCount() - 1;
                for (int n = from; n <= to; n++)
                {
                    TreeTableWithCounterEntry rbEntry = rbTree[n];
                    var counter = (TreeTableVisibleCounter)rbTree[n].GetCounterTotal();
                    if (counter.GetVisibleCount() != DefaultDistance)
                    {
                        rbEntry.InvalidateCounterBottomUp(false);
                    }
                    rbTree.Remove(rbEntry);
                }
            }
            else
            {
                for (int n = from; n <= to; n++)
                {
                    TreeTableWithCounterEntry rbEntry = rbTree[n];
                    var counter = (TreeTableVisibleCounter)rbTree[n].GetCounterTotal();
                    if (counter.GetVisibleCount() != DefaultDistance)
                    {
                        rbEntry.Value = DefaultDistance;
                        rbEntry.InvalidateCounterBottomUp(false);
                    }
                }
            }
        }
        /// <summary>
        /// Removes enities from the collection.
        /// </summary>
        /// <param name="removeAt">Index of the first entity to be removed.</param>
        /// <param name="count">The number of entities to be removed.</param>
        public void Remove(int removeAt, int count)
        {
            Count -= count;

            if (removeAt >= InternalCount)
            {
                return;
            }

            for (int n = count - 1; n >= 0; n--)
            {
                int index = removeAt + n;
                if (index < InternalCount)
                {
                    TreeTableWithCounterEntry rbEntry = rbTree[index];
                    rbEntry.InvalidateCounterBottomUp(false);
                    rbTree.Remove(rbEntry);
                }
            }
        }
        /// <summary>
        /// Insert entities in the collection.
        /// </summary>
        /// <param name="insertAt">Insert position.</param>
        /// <param name="count">The number of entities to be inserted.</param>
        public void Insert(int insertAt, int count)
        {
            Count += count;

            if (insertAt >= InternalCount)
            {
                return;
            }

            for (int n = 0; n < count; n++)
            {
                var rbEntry = new TreeTableWithCounterEntry
                {
                    Value = new TreeTableVisibleCounterSource(DefaultDistance),
                    Tree  = rbTree
                };
                rbTree.Insert(n + insertAt, rbEntry);
                rbEntry.InvalidateCounterBottomUp(false);
            }
        }
        /// <summary>
        /// Skip subsequent entities for which the distance is 0.0 and return the next entity.
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public int GetNextVisibleIndex(int index)
        {
            CheckRange("index", 0, Count - 1, index);

            if (index >= InternalCount)
            {
                return(index + 1);
            }

            TreeTableWithCounterEntry rbEntry = rbTree[index];

            rbEntry = rbTree.GetNextVisibleEntry(rbEntry);
            if (rbEntry == null)
            {
                if (InternalCount < Count)
                {
                    return(InternalCount);
                }
                return(-1);
            }
            return(rbTree.IndexOf(rbEntry));
        }