// package: net.minecraft.world.level.World;

// If the entity is not inside the World Border, call the normal Block Collision handler
// This bypasses our custom collision handler
// This is done so that all this World Border collision logic does not have to be in BKCommonLib
// return instance.a(voxelshape, voxelshape1, flag, flag1);

// Notes:
// flag = always false
// flag1 = inWorldBorder

public java.util.stream.Stream<VoxelShape> getBlockCollisions(com.bergerkiller.bukkit.common.internal.logic.EntityMoveHandler handler, VoxelShape voxelshape, VoxelShape voxelshape1, boolean flag, boolean flag1) {
    int i = MathUtil.floor(voxelshape.b(EnumDirection$EnumAxis.X)) - 1;
    int j = MathUtil.ceil(voxelshape.c(EnumDirection$EnumAxis.X)) + 1;
    int k = MathUtil.floor(voxelshape.b(EnumDirection$EnumAxis.Y)) - 1;
    int l = MathUtil.ceil(voxelshape.c(EnumDirection$EnumAxis.Y)) + 1;
    int i1 = MathUtil.floor(voxelshape.b(EnumDirection$EnumAxis.Z)) - 1;
    int j1 = MathUtil.ceil(voxelshape.c(EnumDirection$EnumAxis.Z)) + 1;
    WorldBorder worldborder = this.getWorldBorder();
    VoxelShape voxelshape2 = VoxelShapes.a();
    VoxelShapeBitSet voxelshapebitset = new VoxelShapeBitSet(j - i, l - k, j1 - i1);
#if classexists net.minecraft.core.BlockPosition$PooledBlockPosition
    BlockPosition.PooledBlockPosition blockposition_b = BlockPosition.PooledBlockPosition.r();
#else
    BlockPosition.b blockposition_b = BlockPosition.b.r();
#endif
    Throwable throwable = null;

    try {
        for (int k1 = i; k1 < j; ++k1) {
            VoxelShape voxelshape3 = VoxelShapes.a();

            for (int l1 = i1; l1 < j1; ++l1) {
                boolean flag2 = k1 == i || k1 == j - 1;
                boolean flag3 = l1 == i1 || l1 == j1 - 1;

                if (flag2 && flag3) {
                    continue;
                }

                blockposition_b.c(k1, 64, l1);

                if (this.isLoaded((BlockPosition) blockposition_b)) {
                    VoxelShape voxelshape4 = VoxelShapes.a();

                    for (int i2 = k; i2 < l; ++i2) {
                        if (!flag2 && !flag3 || i2 != l - 1) {
                            blockposition_b.c(k1, i2, l1);
                            VoxelShape voxelshape5;

                            if (flag1 && !worldborder.a((BlockPosition) blockposition_b)) {
                                voxelshape5 = VoxelShapes.b();
                            } else {
#if version >= 1.13.2
                                voxelshape5 = this.getType((BlockPosition) blockposition_b).getCollisionShape((IBlockAccess) this, blockposition_b);
#else
                                voxelshape5 = this.getType((BlockPosition) blockposition_b).h((IBlockAccess) this, blockposition_b);
#endif
                            }

#if version >= 1.13.2
                            if (!voxelshape5.isEmpty()) {
#else
                            if (!voxelshape5.b()) {
#endif
                                VoxelShape voxelshape6;
                                VoxelShape voxelshape7;

                                // BKCommonLib start: check actually colliding + Block Collision event handler
                                voxelshape6 = voxelshape5.a((double) k1, (double) i2, (double) l1);
                                if (!VoxelShapes.c(voxelshape, voxelshape6, OperatorBoolean.AND)) {
                                    continue;
                                }
                                org.bukkit.craftbukkit.block.CraftBlock cb_block = new org.bukkit.craftbukkit.block.CraftBlock(instance, blockposition_b.h());
                                if (!handler.onBlockCollided(cb_block)) {
                                    continue;
                                }
                                // BKCommonLib end

                                if (voxelshape5 == VoxelShapes.b()) {
                                    if (flag) {
                                        // voxelshape6 = voxelshape5.a((double) k1, (double) i2, (double) l1);
                                        if (!VoxelShapes.c(voxelshape1, voxelshape6, OperatorBoolean.AND) && VoxelShapes.c(voxelshape, voxelshape6, OperatorBoolean.AND)) {
                                            voxelshape7 = VoxelShapes.b();
                                            return voxelshape7;
                                        }
                                    } else {
                                        voxelshapebitset.a(k1 - i, i2 - k, l1 - i1, true, true);
                                    }
                                } else {
                                    // voxelshape6 = voxelshape5.a((double) k1, (double) i2, (double) l1);
                                    if (!VoxelShapes.c(voxelshape1, voxelshape6, OperatorBoolean.AND) && VoxelShapes.c(voxelshape, voxelshape6, OperatorBoolean.AND)) {
                                        if (flag) {
                                            voxelshape7 = VoxelShapes.b();
                                            return voxelshape7;
                                        }

                                        voxelshape4 = VoxelShapes.b(voxelshape4, voxelshape6, OperatorBoolean.OR);
                                    }
                                }
                            }
                        }
                    }

                    voxelshape3 = VoxelShapes.b(voxelshape3, voxelshape4, OperatorBoolean.OR);
                }
            }

            voxelshape2 = VoxelShapes.b(voxelshape2, voxelshape3, OperatorBoolean.OR);
        }
    } catch (Throwable throwable1) {
        throwable = throwable1;
        throw throwable1;
    } finally {
        if (blockposition_b != null) {
            if (throwable != null) {
                try {
                    blockposition_b.close();
                } catch (Throwable throwable2) {
                    throwable.addSuppressed(throwable2);
                }
            } else {
                blockposition_b.close();
            }
        }

    }

    if (flag) {
        return java.util.stream.Stream.empty();
    } else {
        voxelshape2 = voxelshape2.c();
        VoxelShapeWorldRegion voxelshapeworldregion = new VoxelShapeWorldRegion(voxelshapebitset, i, k, i1);

        voxelshape2 = VoxelShapes.b(voxelshape2, voxelshapeworldregion, OperatorBoolean.OR);
        return com.bergerkiller.mountiplex.MountiplexUtil.toStream(voxelshape2);
    }
}
