void AddAllDescendants(long startingID, int level, VoxelBinClass voxel0, int shortDimension = -1,
                               int numShortLayers = -1)
        {
            var lowerLevelVoxels = AddAllDescendants(startingID, level, shortDimension, numShortLayers);

            lock (voxel0.InnerVoxels[level])
                voxel0.InnerVoxels[level].AddRange(lowerLevelVoxels);
        }
        private long ChangeEmptyVoxelToPartial(long ID, int level)
        {
            long voxel;

            if (level == 0)
            {
                //adding a new level-0 voxel is fairly straightforward
                var voxelbin = new VoxelBinClass(ID, VoxelRoleTypes.Partial, this);
                lock (voxelDictionaryLevel0)
                    voxelDictionaryLevel0.AddOrReplace(voxelbin);
                voxelbin.ID = Constants.ClearFlagsFromID(ID) + Constants.MakeFlags(level, VoxelRoleTypes.Partial);
                return(voxelbin.ID);
            }
            // for the lower levels, first get or make the level-0 voxel (next7 lines)
            var           thisIDwoFlags = Constants.ClearFlagsFromID(ID);
            var           id0           = MakeParentVoxelID(thisIDwoFlags, 0);
            VoxelBinClass voxel0;

            lock (voxelDictionaryLevel0)
            {
                if (!voxelDictionaryLevel0.Contains(id0))
                {
                    ChangeEmptyVoxelToPartial(id0, 0);
                }
                voxel0 = voxelDictionaryLevel0.GetVoxel(id0);
            }
            // make the new Voxel, and add it to the proper hashset
            voxel = thisIDwoFlags + Constants.MakeFlags(level, VoxelRoleTypes.Partial);
            lock (voxel0.InnerVoxels[level - 1])
                voxel0.InnerVoxels[level - 1].AddOrReplace(voxel);
            // well, we don't need to check if parent is full but we may need to create the parent
            if (level > 1)
            {
                // for the remaining voxellevels, we also need to check if the parent has been created
                var parentID = MakeParentVoxelID(voxel, level - 1);
                lock (voxel0.InnerVoxels[level - 2])
                    parentID = voxel0.InnerVoxels[level - 2].GetVoxel(parentID);
                if (parentID == 0)
                {
                    ChangeEmptyVoxelToPartial(parentID, level - 1);
                }
            }
            return(voxel);
        }
        //public void DeleteLowLevelVoxelCollection(IEnumerable<long> voxels)
        //{
        //    if (numberOfLevels == 1)
        //}

        private long ChangeEmptyVoxelToFull(long ID, int level, bool checkParentFull)
        {
            if (level == 0)
            {   //adding a new level-0 voxel is fairly straightforward
                var voxelBin = new VoxelBinClass(ID, VoxelRoleTypes.Full, this);
                lock (voxelDictionaryLevel0)
                    voxelDictionaryLevel0.AddOrReplace(voxelBin);
                voxelBin.ID = Constants.ClearFlagsFromID(ID) + Constants.MakeFlags(level, VoxelRoleTypes.Full);
                return(voxelBin.ID);
            }
            // for the lower levels, first get or make the level-0 voxel (next7 lines)
            var           thisIDwoFlags = Constants.ClearFlagsFromID(ID);
            var           id0           = MakeParentVoxelID(thisIDwoFlags, 0);
            VoxelBinClass voxel0;

            lock (voxelDictionaryLevel0)
                if (!voxelDictionaryLevel0.Contains(id0))
                {
                    ChangeEmptyVoxelToPartial(id0, 0);
                    voxel0 = voxelDictionaryLevel0.GetVoxel(id0);
                }
                else
                {
                    voxel0 = (VoxelBinClass)voxelDictionaryLevel0.GetVoxel(id0);
                }
            // make the new Voxel, and add it to the proper hashset
            var voxel = thisIDwoFlags + Constants.MakeFlags(level, VoxelRoleTypes.Full);

            lock (voxel0.InnerVoxels[level - 1])
                voxel0.InnerVoxels[level - 1].AddOrReplace(voxel);
            if (level == 1 && checkParentFull)
            {
                //What if this is the last voxel to be added that makes the parent full?
                // This is checked differently for the level-1 than the others. The code could be
                // combined but it would be less efficient.
                var changeToFull = false;
                lock (voxel0.InnerVoxels[0])
                    changeToFull = (voxel0.InnerVoxels[0].Count == voxelsInParent[level]
                                    //the following All statement is slow. First, just
                                    // check if its worth counting to see if all are Full
                                    && voxel0.InnerVoxels[0].All(v => Constants.GetRole(v) == VoxelRoleTypes.Full));
                if (changeToFull)
                {
                    ChangeVoxelToFull(voxel0.ID, checkParentFull);
                }
            }
            else if (level > 1)
            {
                // for the remaining voxellevels, we also need to check if the parent has been created
                var  parentID = MakeParentVoxelID(voxel, level - 1);
                long parentVoxel;
                var  mightBeFull = false;
                lock (voxel0.InnerVoxels[level - 2]) parentVoxel = voxel0.InnerVoxels[level - 2].GetVoxel(parentID);
                if (parentVoxel == 0)
                {
                    ChangeEmptyVoxelToPartial(parentID, level - 1);
                }
                else
                {
                    mightBeFull = true;
                }
                if (checkParentFull && mightBeFull)
                {
                    bool makeParentFull = false;
                    lock (voxel0.InnerVoxels[level - 1])
                    {
                        // since the hashsets are combined we need to count
                        // what is indeed the immediate descendant of the the parent and see if they are all full
                        makeParentFull = voxel0.InnerVoxels[level - 1].Count >= voxelsInParent[level];
                        if (makeParentFull)
                        {
                            makeParentFull = (voxel0.InnerVoxels[level - 1]
                                              .CountDescendants(parentID, level - 1, VoxelRoleTypes.Full) ==
                                              voxelsInParent[level]);
                        }
                    }
                    if (makeParentFull)
                    {
                        ChangeVoxelToFull(parentVoxel, checkParentFull);
                    }
                }
            }
            return(voxel);
        }
 private long CountVoxels(VoxelBinClass voxel0, int level, VoxelRoleTypes role)
 {
     return(voxel0.InnerVoxels[level - 1].Count(v => Constants.GetRole(v) == role));
 }