@SuppressWarnings({"unchecked"}) private <T extends RegionModule> T mirrorRegion(T region) { if (region instanceof PointRegion) { PointRegion rg = (PointRegion) region; int[] v1 = getMirroredValues(rg.getX(), rg.getY(), rg.getZ()); return (T) new PointRegion(null, rg.getX() + v1[0], rg.getY() + v1[1], rg.getZ() + v1[2]); } else if (region instanceof BlockRegion) { BlockRegion rg = (BlockRegion) region; int[] v1 = getMirroredValues(rg.getX(), rg.getY(), rg.getZ()); return (T) new BlockRegion(null, rg.getX() + v1[0], rg.getY() + v1[1], rg.getZ() + v1[2]); } else if (region instanceof CircleRegion) { CircleRegion rg = (CircleRegion) region; int[] v1 = getMirroredValues(rg.getBaseX(), rg.getBaseY(), rg.getBaseZ()); return (T) new CircleRegion(null, rg.getBaseX() + v1[0], rg.getBaseZ() + v1[2], rg.getRadius()); } else if (region instanceof CylinderRegion) { CylinderRegion rg = (CylinderRegion) region; int[] v1 = getMirroredValues(rg.getBaseX(), rg.getBaseY(), rg.getBaseZ()); return (T) new CylinderRegion( null, new Vector(rg.getBaseX() + v1[0], rg.getBaseY() + v1[1], rg.getBaseZ() + v1[2]), rg.getRadius(), rg.getHeight()); } else if (region instanceof RectangleRegion) { RectangleRegion rg = (RectangleRegion) region; int[] v1 = getMirroredValues(rg.getXMin(), rg.getYMin(), rg.getZMin()); int[] v2 = getMirroredValues(rg.getXMax(), rg.getYMax(), rg.getZMax()); return (T) new RectangleRegion( null, rg.getXMin() + v1[0], rg.getZMin() + v1[2], rg.getXMax() + v2[0], rg.getZMax() + v2[2]); } else if (region instanceof CuboidRegion) { CuboidRegion rg = (CuboidRegion) region; int[] v1 = getMirroredValues(rg.getXMin(), rg.getYMin(), rg.getZMin()); int[] v2 = getMirroredValues(rg.getXMax(), rg.getYMax(), rg.getZMax()); return (T) new CuboidRegion( null, rg.getXMin() + v1[0], rg.getYMin() + v1[1], rg.getZMin() + v1[2], rg.getXMax() + v2[0], rg.getYMax() + v2[1], rg.getZMax() + v2[2]); } else if (region instanceof SphereRegion) { SphereRegion rg = (SphereRegion) region; int[] v1 = getMirroredValues(rg.getOriginX(), rg.getOriginY(), rg.getOriginZ()); return (T) new SphereRegion( null, new Vector(rg.getOriginX() + v1[0], rg.getOriginY() + v1[1], rg.getOriginZ() + v1[2]), rg.getRadius()); } else if (region instanceof EmptyRegion) { return (T) new EmptyRegion(""); } else if (region instanceof ComplementRegion) { ComplementRegion rg = (ComplementRegion) region; ModuleCollection<RegionModule> regions = new ModuleCollection<>(); for (RegionModule rg1 : rg.getRegions()) { regions.add(mirrorRegion(rg1)); } return (T) new ComplementRegion(null, regions); } else if (region instanceof IntersectRegion) { IntersectRegion rg = (IntersectRegion) region; ModuleCollection<RegionModule> regions = new ModuleCollection<>(); for (RegionModule rg1 : rg.getRegions()) { regions.add(mirrorRegion(rg1)); } return (T) new IntersectRegion(null, regions); } else if (region instanceof NegativeRegion) { NegativeRegion rg = (NegativeRegion) region; ModuleCollection<RegionModule> regions = new ModuleCollection<>(); for (RegionModule rg1 : rg.getRegions()) { regions.add(mirrorRegion(rg1)); } return (T) new NegativeRegion(null, regions); } else if (region instanceof UnionRegion) { UnionRegion rg = (UnionRegion) region; ModuleCollection<RegionModule> regions = new ModuleCollection<>(); for (RegionModule rg1 : rg.getRegions()) { regions.add(mirrorRegion(rg1)); } return (T) new UnionRegion(null, regions); } else if (region instanceof TranslatedRegion) { TranslatedRegion rg = (TranslatedRegion) region; return (T) new TranslatedRegion(null, mirrorRegion(rg.getRegion())); } else if (region instanceof MirroredRegion) { MirroredRegion rg = (MirroredRegion) region; return (T) new MirroredRegion(null, mirrorRegion(rg.getRegion())); } return null; }