private EntityUpdates Convert(long[] labelsBefore, long[] labelsAfter, params Command.PropertyCommand[] changes)
        {
            long nodeId = 0;

            EntityUpdates.Builder updates = EntityUpdates.ForEntity(( long )0, false).withTokens(labelsBefore).withTokensAfter(labelsAfter);
            EntityCommandGrouper  grouper = new EntityCommandGrouper <>(typeof(Command.NodeCommand), 8);

            grouper.add(new Command.NodeCommand(new NodeRecord(nodeId), new NodeRecord(nodeId)));
            foreach (Command.PropertyCommand change in changes)
            {
                grouper.add(change);
            }
            EntityCommandGrouper.Cursor cursor = grouper.sortAndAccessGroups();
            assertTrue(cursor.NextEntity());
            _converter.convertPropertyRecord(cursor, updates);
            return(updates.Build());
        }
        /// <summary>
        /// Converts physical changes to PropertyRecords for a entity into logical updates
        /// </summary>
        public virtual void ConvertPropertyRecord <T1>(EntityCommandGrouper <T1> changes, EntityUpdates.Builder properties)
        {
            MapBlocks(changes);

            int bc = 0;
            int ac = 0;

            while (bc < _beforeBlocksCursor || ac < _afterBlocksCursor)
            {
                PropertyBlock beforeBlock = null;
                PropertyBlock afterBlock  = null;

                int beforeKey = int.MaxValue;
                int afterKey  = int.MaxValue;
                int key;
                if (bc < _beforeBlocksCursor)
                {
                    beforeBlock = _beforeBlocks[bc];
                    beforeKey   = beforeBlock.KeyIndexId;
                }
                if (ac < _afterBlocksCursor)
                {
                    afterBlock = _afterBlocks[ac];
                    afterKey   = afterBlock.KeyIndexId;
                }

                if (beforeKey < afterKey)
                {
                    afterBlock = null;
                    key        = beforeKey;
                    bc++;
                }
                else if (beforeKey > afterKey)
                {
                    beforeBlock = null;
                    key         = afterKey;
                    ac++;
                }
                else
                {
                    // They are the same
                    key = afterKey;
                    bc++;
                    ac++;
                }

                if (beforeBlock != null && afterBlock != null)
                {
                    // CHANGE
                    if (!beforeBlock.HasSameContentsAs(afterBlock))
                    {
                        Value beforeVal = ValueOf(beforeBlock);
                        Value afterVal  = ValueOf(afterBlock);
                        properties.Changed(key, beforeVal, afterVal);
                    }
                }
                else
                {
                    // ADD/REMOVE
                    if (afterBlock != null)
                    {
                        properties.Added(key, ValueOf(afterBlock));
                    }
                    else
                    {
                        properties.Removed(key, ValueOf(beforeBlock));
                    }
                }
            }
        }