--- a/net/minecraft/server/BlockSapling.java
+++ b/net/minecraft/server/BlockSapling.java
@@ -2,11 +2,21 @@
 
 import java.util.Random;
 
+// CraftBukkit start
+import java.util.List;
+
+import org.bukkit.Location;
+import org.bukkit.TreeType;
+import org.bukkit.block.BlockState;
+import org.bukkit.event.world.StructureGrowEvent;
+// CraftBukkit end
+
 public class BlockSapling extends BlockPlant implements IBlockFragilePlantElement {
 
     public static final BlockStateInteger STAGE = BlockProperties.at;
     protected static final VoxelShape b = Block.a(2.0D, 0.0D, 2.0D, 14.0D, 12.0D, 14.0D);
     private final WorldGenTreeProvider c;
+    public static TreeType treeType; // CraftBukkit
 
     protected BlockSapling(WorldGenTreeProvider worldgentreeprovider, Block.Info block_info) {
         super(block_info);
@@ -23,7 +33,30 @@
     public void tick(IBlockData iblockdata, World world, BlockPosition blockposition, Random random) {
         super.tick(iblockdata, world, blockposition, random);
         if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(7) == 0) {
+            // CraftBukkit start
+            world.captureTreeGeneration = true;
+            // CraftBukkit end
             this.grow(world, blockposition, iblockdata, random);
+            // CraftBukkit start
+            world.captureTreeGeneration = false;
+            if (world.capturedBlockStates.size() > 0) {
+                TreeType treeType = BlockSapling.treeType;
+                BlockSapling.treeType = null;
+                Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ());
+                List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone();
+                world.capturedBlockStates.clear();
+                StructureGrowEvent event = null;
+                if (treeType != null) {
+                    event = new StructureGrowEvent(location, treeType, false, null, blocks);
+                    org.bukkit.Bukkit.getPluginManager().callEvent(event);
+                }
+                if (event == null || !event.isCancelled()) {
+                    for (BlockState blockstate : blocks) {
+                        blockstate.update(true);
+                    }
+                }
+            }
+            // CraftBukkit end
         }
 
     }