public SplitTreeNode(SplitTreeNode parent, int childNum, int maskOffset, int nodeIndex, long blockOffset, List<Record> records)
        {
            this.parent = parent;
            this.childNum = childNum;
            this.maskOffset = maskOffset;

            this.nodeIndex = nodeIndex;
            this.blockOffset = blockOffset;
            this.records = records;
        }
        private List<SplitTreeNode> UpdateBlock(BlockBatch blockBatch)
        {
            Block block = dictionary.Container.ReadBlock(blockBatch.BlockOffset);

            //todo: review types
            List<Record> records = MergeRecords(block.Records, blockBatch.Records, blockBatch.MaskOffset/8);

            SplitTreeNode splitTreeRoot = new SplitTreeNode(null, -1, blockBatch.MaskOffset, blockBatch.NodeIndex, blockBatch.BlockOffset, records);

            List<SplitTreeNode> updatedTreeNodes = new List<SplitTreeNode>();
            updatedTreeNodes.Add(splitTreeRoot);

            List<SplitTreeNode> unsplitTreeNodes = new List<SplitTreeNode>();
            if (splitTreeRoot.Records.Count > dictionary.Container.RecordsPerBlock)
            {
                unsplitTreeNodes.Add(splitTreeRoot);
            }

            while (unsplitTreeNodes.Count != 0)
            {
                SplitTreeNode nodeToSplit = unsplitTreeNodes[unsplitTreeNodes.Count - 1];
                unsplitTreeNodes.RemoveAt(unsplitTreeNodes.Count - 1);

                List<SplitTreeNode> newNodes = Split(nodeToSplit);
                foreach (SplitTreeNode treeNode in newNodes)
                {
                    updatedTreeNodes.Add(treeNode);
                    if (treeNode.Records.Count > dictionary.Container.RecordsPerBlock)
                    {
                        unsplitTreeNodes.Add(treeNode);
                    }
                }
            }

            return updatedTreeNodes;
        }
        private List<SplitTreeNode> Split(SplitTreeNode node)
        {
            List<Record> records = node.Records;
            node.Records = null;

            int maskByteOffset = node.MaskOffset/8;
            byte mask = (byte) (1 << (7 - node.MaskOffset%8));

            int firstRight = 0;
            for (; firstRight < records.Count; firstRight++)
            {
                bool isLeft = (records[firstRight].Key.GetByteAt(maskByteOffset) & mask) == 0;
                if (!isLeft)
                {
                    break;
                }
            }

            List<SplitTreeNode> newNodes = new List<SplitTreeNode>();
            if (firstRight != 0)
            {
                SplitTreeNode newNode = new SplitTreeNode(node, 0, node.MaskOffset + 1, -1, node.BlockOffset, records.GetRange(0, firstRight));
                node.BlockOffset = -1;
                newNodes.Add(newNode);
            }
            if (firstRight < records.Count)
            {
                SplitTreeNode newNode = new SplitTreeNode(node, 1, node.MaskOffset + 1, -1, node.BlockOffset, records.GetRange(firstRight, records.Count - firstRight));
                node.BlockOffset = -1;
                newNodes.Add(newNode);
            }

            return newNodes;
        }