package net.glowstone.generator.objects;

import java.util.Random;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.material.DoublePlant;
import org.bukkit.material.MaterialData;
import org.bukkit.material.types.DoublePlantSpecies;

public class StoneBoulder implements TerrainObject {

    private static final Material[] GROUND_TYPES = {Material.GRASS, Material.DIRT, Material.STONE};
    private static final Material[] PLANT_TYPES = {Material.LONG_GRASS, Material.YELLOW_FLOWER,
        Material.RED_ROSE, Material.DOUBLE_PLANT, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM};

    @Override
    public boolean generate(World world, Random random, int sourceX, int sourceY, int sourceZ) {
        boolean groundReached = false;
        while (!groundReached && sourceY > 3) {
            Block block = world.getBlockAt(sourceX, sourceY - 1, sourceZ);
            if (!block.isEmpty()) {
                for (Material mat : GROUND_TYPES) {
                    if (mat == block.getType()) {
                        groundReached = true;
                        sourceY++;
                        break;
                    }
                }
            }
            sourceY--;
        }
        if (!groundReached || !world.getBlockAt(sourceX, sourceY, sourceZ).isEmpty()) {
            return false;
        }
        for (int i = 0; i < 3; i++) {
            int radiusX = random.nextInt(2);
            int radiusZ = random.nextInt(2);
            int radiusY = random.nextInt(2);
            float f = (radiusX + radiusZ + radiusY) * 0.333F + 0.5F;
            for (int x = -radiusX; x <= radiusX; x++) {
                for (int z = -radiusZ; z <= radiusZ; z++) {
                    for (int y = -radiusY; y <= radiusY; y++) {
                        if (x * x + z * z + y * y <= f * f) {
                            BlockState state = world
                                    .getBlockAt(sourceX + x, sourceY + y, sourceZ + z).getState();
                            Block blockAbove = state.getBlock().getRelative(BlockFace.UP);
                            for (Material mat : PLANT_TYPES) {
                                if (blockAbove.getType() == mat) {
                                    if (mat == Material.DOUBLE_PLANT && blockAbove.getState()
                                            .getData() instanceof DoublePlant &&
                                            ((DoublePlant) blockAbove.getState().getData())
                                                    .getSpecies()
                                                    == DoublePlantSpecies.PLANT_APEX) {
                                        blockAbove.getRelative(BlockFace.UP)
                                                .setType(Material.AIR);
                                    }
                                    blockAbove.setType(Material.AIR);
                                    break;
                                }
                            }
                            state.setType(Material.MOSSY_COBBLESTONE);
                            state.setData(new MaterialData(Material.MOSSY_COBBLESTONE));
                            state.update(true);
                        }
                    }
                }
            }
            sourceX += random.nextInt(4) - 1;
            sourceZ += random.nextInt(4) - 1;
            sourceY -= random.nextInt(2);
        }
        return true;
    }
}

@@ -46,24 +46,105 @@
 ort 
-java.util.Random
+com.google.common.collect.ImmutableSortedSet;%0Aimport java.util.Random;%0Aimport java.util.SortedSet
 ;%0Aim
@@ -610,24 +610,34 @@
 c final 
+SortedSet%3C
 Material
 %5B%5D PLANT
@@ -628,18 +628,17 @@
 Material
-%5B%5D
+%3E
  PLANT_T
@@ -636,33 +636,67 @@
 %3E PLANT_TYPES = 
-%7B
+ImmutableSortedSet%0A            .of(
 Material.LONG_GR
@@ -723,24 +723,16 @@
 _FLOWER,
-%0A       
  Materia
@@ -742,16 +742,36 @@
 ED_ROSE,
+%0A                   
  Materia
@@ -832,17 +832,17 @@
 MUSHROOM
-%7D
+)
 ;%0A%0A    @
@@ -2042,18 +2042,17 @@
 + y * y 
-%3C=
+%3E
  f * f) 
@@ -2049,32 +2049,92 @@
  %3E f * f) %7B%0A    
+                        continue;%0A                        %7D%0A
                 
@@ -2166,20 +2166,16 @@
 = world%0A
-    
         
@@ -2277,36 +2277,32 @@
                 
-  
-  
 Block blockAbove
@@ -2368,33 +2368,24 @@
             
-    for (
 Material mat
@@ -2389,33 +2389,32 @@
 mat 
-: PLANT_TYPES) %7B%0A        
+= blockAbove.getType();%0A
     
@@ -2441,47 +2441,37 @@
 if (
-blockAbove.getType() == 
+PLANT_TYPES.contains(
 mat)
+)
  %7B%0A
-        
     
@@ -2526,19 +2526,76 @@
 LE_PLANT
- &&
+) %7B%0A                                MaterialData dataAbove =
  blockAb
@@ -2608,16 +2608,27 @@
 tState()
+.getData();
 %0A       
@@ -2656,30 +2656,21 @@
     
-            .getData()
+if (dataAbove
  ins
@@ -2688,19 +2688,16 @@
 blePlant
- &&
 %0A       
@@ -2729,19 +2729,18 @@
         
-   
+&&
  ((Doubl
@@ -2751,93 +2751,18 @@
 nt) 
-blockAbove.getState().getData())%0A                                                    
+dataAbove)
 .get
@@ -2811,28 +2811,16 @@
         
-      
-      
 == Doubl
@@ -2843,28 +2843,24 @@
 ANT_APEX) %7B%0A
-    
             
@@ -2964,20 +2964,16 @@
         
-    
 .setType
@@ -3005,32 +3005,41 @@
                 
+       %7D%0A
            %7D%0A   
@@ -3025,34 +3025,35 @@
    %7D%0A           
-%7D%0A
+   
                 
@@ -3042,32 +3042,34 @@
                 
+%7D%0A
                 
@@ -3066,32 +3066,38 @@
                 
+      
 blockAbove.setTy
@@ -3138,32 +3138,24 @@
             
-        
 break;%0A     
@@ -3177,52 +3177,10 @@
     
- 
-       
 %7D%0A
-                            %7D%0A    
     
@@ -3242,20 +3242,16 @@
 STONE);%0A
-    
         
@@ -3347,28 +3347,24 @@
             
-    
 state.update
@@ -3375,34 +3375,8 @@
 e);%0A
-                        %7D%0A
     

Fix CheckStyle issues in generator/objects/StoneBoulder.java (#740)