@Override
    public boolean shouldKeepLeft(ServiceUnitStateData from, ServiceUnitStateData to) {
        if (to == null) {
            return false;
        }

        if (from != null) {
            if (from.versionId() == Long.MAX_VALUE && to.versionId() == Long.MIN_VALUE) { // overflow
            } else if (from.versionId() >= to.versionId()) {
                return true;
            } else if (from.versionId() < to.versionId() - 1) { // Compacted
                return false;
            } // else from.versionId() == to.versionId() - 1 // continue to check further
        }

        if (to.force()) {
            return false;
        }

        ServiceUnitState prevState = state(from);
        ServiceUnitState state = state(to);
        if (!ServiceUnitState.isValidTransition(prevState, state)) {
            return true;
        }

        if (checkBrokers) {
            switch (prevState) {
                case Owned:
                    switch (state) {
                        case Splitting:
                            return isNotBlank(to.dstBroker())
                                    || !from.dstBroker().equals(to.sourceBroker());
                        case Releasing:
                            return invalidUnload(from, to);
                    }
                case Assigning:
                    switch (state) {
                        case Owned:
                            return notEquals(from, to);
                    }
                case Releasing:
                    switch (state) {
                        case Assigning:
                            return isBlank(to.dstBroker()) || notEquals(from, to);
                        case Free:
                            return notEquals(from, to);
                    }
                case Splitting:
                    switch (state) {
                        case Deleted:
                            return notEquals(from, to);
                    }
                case Free:
                    switch (state) {
                        case Assigning:
                            return isNotBlank(to.sourceBroker()) || isBlank(to.dstBroker());
                    }
            }
        }
        return false;
    }
@Test
    public void testVersionId(){
        assertTrue(strategy.shouldKeepLeft(
                new ServiceUnitStateData(Assigning, dst, 1),
                new ServiceUnitStateData(Assigning, dst, 1)));

        assertTrue(strategy.shouldKeepLeft(
                new ServiceUnitStateData(Assigning, dst, 1),
                new ServiceUnitStateData(Assigning, dst, 2)));

        assertFalse(strategy.shouldKeepLeft(
                new ServiceUnitStateData(Owned, dst, src, 10),
                new ServiceUnitStateData(Releasing, "broker2", dst, 11)));

        assertFalse(strategy.shouldKeepLeft(
                new ServiceUnitStateData(Owned, dst, src, Long.MAX_VALUE),
                new ServiceUnitStateData(Releasing, "broker2", dst, Long.MAX_VALUE + 1)));

        assertFalse(strategy.shouldKeepLeft(
                new ServiceUnitStateData(Owned, dst, src, Long.MAX_VALUE + 1),
                new ServiceUnitStateData(Releasing, "broker2", dst, Long.MAX_VALUE + 2)));

        assertTrue(strategy.shouldKeepLeft(
                new ServiceUnitStateData(Owned, dst, src, 10),
                new ServiceUnitStateData(Releasing, "broker2", dst, 5)));

        assertFalse(strategy.shouldKeepLeft(
                new ServiceUnitStateData(Owned, dst, src, 10),
                new ServiceUnitStateData(Owned, "broker2", dst, 12)));

    }