    @Test
    @SuppressWarnings("SpellCheckingInspection")
    public void testDisclaim() throws Exception
    {

        BlockPos spawn = new BlockPos(test.overWorld, 200,64,100);
        ChunkPos spawnChunk = spawn.getChunk();
        City city = new City(test.mineCity, "Disclaim", test.joserobjr, spawn, 0);
        Island spawnIsland = city.islands().iterator().next();

        assertThrown(()-> city.disclaim(spawnChunk, false))
                .isInstanceOf(IllegalStateException.class)
                .hasMessageContaining("last");


        ChunkPos chunk = spawnChunk.add(Direction.NORTH);
        assertEquals(spawnIsland, city.claim(chunk, false));

        assertThrown(()-> city.disclaim(spawnChunk, false))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("spawn");

        assertThrown(()-> city.claim(spawnChunk, false))
                .hasMessageContaining("reserved")
                .isInstanceOf(IllegalArgumentException.class);

        assertEquals(Collections.singleton(spawnIsland), city.disclaim(chunk, false));
        assertEquals(1, city.getSizeX());
        assertEquals(1, city.getSizeZ());
        assertEquals(1, city.getChunkCount());

        chunk = spawnChunk.add(Direction.SOUTH, 5);
        Island islandA = city.claim(chunk, true);
        assertNotEquals(spawnIsland, islandA);
        assertEquals(2, city.getSizeX());
        assertEquals(2, city.getSizeZ());
        assertEquals(2, city.getChunkCount());
        assertEquals(Arrays.asList(spawnIsland, islandA), new ArrayList<>(city.islands()));

        assertEquals(Collections.singleton(islandA), city.disclaim(chunk, false));
        assertEquals(1, city.getSizeX());
        assertEquals(1, city.getSizeZ());
        assertEquals(1, city.getChunkCount());
        assertEquals(Collections.singletonList(spawnIsland), new ArrayList<>(city.islands()));

        Island islandB = city.claim(chunk, true);
        assertNotEquals(islandA, islandB);
        assertEquals(2, city.getSizeX());
        assertEquals(2, city.getSizeZ());
        assertEquals(2, city.getChunkCount());
        assertEquals(Arrays.asList(spawnIsland, islandB), new ArrayList<>(city.islands()));

        assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false));
        assertEquals(3, city.getSizeX());
        assertEquals(2, city.getSizeZ());
        assertEquals(3, city.getChunkCount());
        assertEquals(Collections.singleton(islandB), city.disclaim(chunk.add(Direction.EAST), false));
        assertEquals(2, city.getSizeX());
        assertEquals(2, city.getSizeZ());
        assertEquals(2, city.getChunkCount());

        /*
         *     X →
         *     123456789
         * Z-1|   X     |
         * ↓ 0|   XX    |
         *   1| XXDXXXX |
         *   4|   X     |
         *   5|   XX    |
         *   6|   X     |
         */
        assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false));
        chunk = chunk.add(Direction.EAST, 2);
        assertEquals(islandB, city.claim(chunk, false));
        assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 2), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 3), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 4), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.NORTH), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.NORTH, 2), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.NORTH_EAST), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 2), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 2).add(Direction.EAST), false));
        assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 3), false));
        assertEquals(14, islandB.getChunkCount());
        assertEquals(7, islandB.getSizeX());
        assertEquals(6, islandB.getSizeZ());
        assertEquals(15, city.getChunkCount());
        assertEquals(8, city.getSizeX());
        assertEquals(7, city.getSizeZ());
        assertEquals(2, city.islands().size());

        /*
         *     X →
         *     123456789
         * Z-1|   B     |
         * ↓ 0|   BB    |
         *   1| XX BBBB |
         *   4|   Y     |
         *   5|   YY    |
         *   6|   Y     |
         */
        ChunkPos pos = chunk;
        assertThrown(()-> city.disclaim(pos, false))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("required");

        Collection<Island> islands = city.disclaim(pos, true);
        assertEquals(2, islands.size());
        Island islandX = islands.stream().min((a,b)-> a.getChunkCount()-b.getChunkCount()).get();
        Island islandY = islands.stream().filter(i-> i != islandX).findAny().get();
        assertEquals(2, islandX.getChunkCount());
        assertEquals(4, islandY.getChunkCount());
        assertEquals(7, islandB.getChunkCount());
        assertEquals(5, islandB.getSizeX());
        assertEquals(3, islandB.getSizeZ());
        assertEquals(14, city.getChunkCount());
        assertEquals(10, city.getSizeX());
        assertEquals(8, city.getSizeZ());
        assertEquals(4, city.islands().size());

        city.islands().forEach(island -> assertEquals(island, city.getIsland(island.getId())));
    }