    public void populate(MetropolisGenerator generator,Chunk chunk) {
        ClipboardProviderWorldEdit clips = generator.getClipboardProvider();
        grid = generator.getGridProvider().getGrid(chunkX,chunkZ);
        GridRandom random = grid.getRandom();
        ContextProvider context = generator.getContextProvider();
        if(random.getChance(60)){
            List<Clipboard> schems = clips.getFit(chunkSizeX,chunkSizeZ, findRoad(),context.getContext(chunkX,chunkZ)); 
            if(schems!=null&&schems.size()>0){
                generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                parcel.populate(generator,chunk);
                return;
            }else {
                generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ) + "going over to fallback");
                schems = clips.getFit(chunkSizeX,chunkSizeZ, Direction.NORTH,context.getContext(chunkX,chunkZ)); 
                if(schems!=null&&schems.size()>0){
                    generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                    parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                    parcel.populate(generator,chunk);
                    return;
                }else {
                    generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ));
                }
            }
        }
        if((chunkSizeX<=2)&&(chunkSizeZ<=2)){ 
            List<Clipboard> schems = clips.getFit(chunkSizeX,chunkSizeZ, findRoad(),context.getContext(chunkX,chunkZ)); 
            if(schems!=null&&schems.size()>0){
                generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                parcel.populate(generator,chunk);
                return;
            }else {
                generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ) + "going over to fallback");
                schems = clips.getFit(chunkSizeX,chunkSizeZ, Direction.NORTH,context.getContext(chunkX,chunkZ)); 
                if(schems!=null&&schems.size()>0){
                    generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                    parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                    parcel.populate(generator,chunk);
                    return;
                }else {
                    parcel = new EmptyParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ);
                    generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ));
                }
            }
            return; 
        }
        if(chunkSizeX>chunkSizeZ){
            int cut = random.getRandomInt(1,chunkSizeX-1);
            partitionX(grid,cut);
        }else {
            int cut = random.getRandomInt(1,chunkSizeZ-1);
            partitionZ(grid,cut);
        }
        partition1.populate(generator,chunk);
        partition2.populate(generator,chunk);
    }
    private Direction findRoad(){
        for(int i=0;i<chunkSizeX;i++){
            Parcel p = grid.getParcel(chunkX+i,chunkZ-1); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.NORTH;
            }
            p = grid.getParcel(chunkX+i,chunkZ+chunkSizeZ); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.SOUTH;
            }
        }
        for(int i=0;i<chunkSizeZ;i++){
            Parcel p = grid.getParcel(chunkX-1,chunkZ+i); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.WEST;
            }
            p = grid.getParcel(chunkX+chunkSizeX,chunkZ); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.EAST;
            }
        }
        return Direction.NONE; 
    }
    private void partitionXwithRoads(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,cut,chunkSizeZ);
        for(int i=chunkZ;i<chunkZ+chunkSizeZ;i++){
            grid.setParcel(chunkX,i,new RoadParcel(grid,chunkX,i));
        }
        partition2 = new DistrictParcel(grid,chunkX+cut+1,chunkZ,chunkSizeX-cut-1,chunkSizeZ);
    }
    private void partitionX(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,cut,chunkSizeZ);
        partition2 = new DistrictParcel(grid,chunkX+cut,chunkZ,chunkSizeX-cut,chunkSizeZ);
    }
    private void partitionZwithRoads(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,chunkSizeX,cut);
        for(int i=chunkX;i<chunkX+chunkSizeX;i++){
            grid.setParcel(i,chunkZ+cut,new RoadParcel(grid,i,chunkZ));
        }
        partition2 = new DistrictParcel(grid,chunkX,chunkZ+cut+1,chunkSizeX,chunkSizeZ-cut-1);
    }
    private void partitionZ(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,chunkSizeX,cut);
        partition2 = new DistrictParcel(grid,chunkX,chunkZ+cut,chunkSizeX,chunkSizeZ-cut);
    }
}

    public void populate(MetropolisGenerator generator,Chunk chunk) {
        ClipboardProviderWorldEdit clips = generator.getClipboardProvider();
        grid = generator.getGridProvider().getGrid(chunkX,chunkZ);
        GridRandom random = grid.getRandom();
        ContextProvider context = generator.getContextProvider();
        if(random.getChance(60)){
            List<Clipboard> schems = clips.getFit(chunkSizeX,chunkSizeZ, findRoad(),context.getContext(chunkX,chunkZ)); 
            if(schems!=null&&schems.size()>0){
                generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                parcel.populate(generator,chunk);
                return;
            }else {
                generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ) + "going over to fallback");
                schems = clips.getFit(chunkSizeX,chunkSizeZ, Direction.NORTH,context.getContext(chunkX,chunkZ)); 
                if(schems!=null&&schems.size()>0){
                    generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                    parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                    parcel.populate(generator,chunk);
                    return;
                }else {
                    generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ));
                }
            }
        }
        if((chunkSizeX<=2)&&(chunkSizeZ<=2)){ 
            List<Clipboard> schems = clips.getFit(chunkSizeX,chunkSizeZ, findRoad(),context.getContext(chunkX,chunkZ)); 
            if(schems!=null&&schems.size()>0){
                generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                parcel.populate(generator,chunk);
                return;
            }else {
                generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ) + "going over to fallback");
                schems = clips.getFit(chunkSizeX,chunkSizeZ, Direction.NORTH,context.getContext(chunkX,chunkZ)); 
                if(schems!=null&&schems.size()>0){
                    generator.reportDebug("Found "+schems.size()+" schematics for this spot, placing one");
                    parcel = new ClipboardParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ,schems.get(random.getRandomInt(schems.size())),context.getContext(chunkX,chunkZ));
                    parcel.populate(generator,chunk);
                    return;
                }else {
                    parcel = new EmptyParcel(grid,chunkX,chunkZ,chunkSizeX,chunkSizeZ);
                    generator.reportDebug("No schems found for size "+chunkSizeX+"x"+chunkSizeZ + " , context=" + context.getContext(chunkX,chunkZ));
                }
            }
            return; 
        }
        if(chunkSizeX>chunkSizeZ){
            int cut = random.getRandomInt(1,chunkSizeX-1);
            partitionX(grid,cut);
        }else {
            int cut = random.getRandomInt(1,chunkSizeZ-1);
            partitionZ(grid,cut);
        }
        partition1.populate(generator,chunk);
        partition2.populate(generator,chunk);
    }
    private Direction findRoad(){
        for(int i=0;i<chunkSizeX;i++){
            Parcel p = grid.getParcel(chunkX+i,chunkZ-1); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.NORTH;
            }
            p = grid.getParcel(chunkX+i,chunkZ+chunkSizeZ); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.SOUTH;
            }
        }
        for(int i=0;i<chunkSizeZ;i++){
            Parcel p = grid.getParcel(chunkX-1,chunkZ+i); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.WEST;
            }
            p = grid.getParcel(chunkX+chunkSizeX,chunkZ); 
            if(p!=null && p.getContextType().equals(ContextType.ROAD)){
                return Direction.EAST;
            }
        }
        return Direction.NONE; 
    }
    private void partitionXwithRoads(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,cut,chunkSizeZ);
        for(int i=chunkZ;i<chunkZ+chunkSizeZ;i++){
            grid.setParcel(chunkX+cut,i,new RoadParcel(grid,chunkX+cut,i));
        }
        partition2 = new DistrictParcel(grid,chunkX+cut+1,chunkZ,chunkSizeX-cut-1,chunkSizeZ);
    }
    private void partitionX(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,cut,chunkSizeZ);
        partition2 = new DistrictParcel(grid,chunkX+cut,chunkZ,chunkSizeX-cut,chunkSizeZ);
    }
    private void partitionZwithRoads(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,chunkSizeX,cut);
        for(int i=chunkX;i<chunkX+chunkSizeX;i++){
            grid.setParcel(i,chunkZ+cut,new RoadParcel(grid,i,chunkZ+cut));
        }
        partition2 = new DistrictParcel(grid,chunkX,chunkZ+cut+1,chunkSizeX,chunkSizeZ-cut-1);
    }
    private void partitionZ(Grid grid,int cut){
        partition1 = new DistrictParcel(grid,chunkX,chunkZ,chunkSizeX,cut);
        partition2 = new DistrictParcel(grid,chunkX,chunkZ+cut,chunkSizeX,chunkSizeZ-cut);
    }
}
