/*
** 2016 March 08
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
 */
package info.ata4.minecraft.dragon.server.entity.breeds;

import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Collectors;
import net.minecraft.util.IStringSerializable;

/**
 *
 * @author Nico Bergemann <barracuda415 at yahoo.de>
 */
public enum EnumDragonBreed implements IStringSerializable {
    
    AIR(0, DragonBreedAir.class),
    END(1, DragonBreedEnd.class),
    FIRE(2, DragonBreedFire.class),
    FOREST(3, DragonBreedForest.class),
    GHOST(4, DragonBreedGhost.class),
    ICE(5, DragonBreedIce.class),
    NETHER(6, DragonBreedNether.class),
    WATER(7, DragonBreedWater.class);
    
    public static final EnumDragonBreed DEFAULT = END;
    
    // create static bimap between enums and meta data for faster and easier
    // lookups
    public static final BiMap<EnumDragonBreed, Integer> META_MAPPING =
        ImmutableBiMap.copyOf(Arrays.asList(values()).stream()
            .collect(Collectors.toMap(Function.identity(), EnumDragonBreed::getMeta)));
    
    private final DragonBreed breed;
    
    // this field is used for block metadata and is technically the same as
    // ordinal(), but it is saved separately to make sure the values stay
    // constant after adding more breeds in unexpected orders
    private final int meta;
    
    private EnumDragonBreed(int meta, Class<? extends DragonBreed> factory) {
        try {
            breed = factory.getDeclaredConstructor(EnumDragonBreed.class).newInstance(this);
        } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalArgumentException ex) {
            throw new RuntimeException("Incompatible breed factory " + factory, ex);
        } catch (SecurityException | IllegalAccessException ex) {
            throw new RuntimeException(ex);
        }
        
        this.meta = meta;
    }
    
    public DragonBreed getBreed() {
        return breed;
    }
    
    public int getMeta() {
        return meta;
    }

    @Override
    public String getName() {
        return name().toLowerCase();
    }
    
}

@@ -438,60 +438,8 @@
 ap;%0A
-import java.lang.reflect.InvocationTargetException;%0A
 impo
@@ -495,16 +495,52 @@
 nction;%0A
+import java.util.function.Supplier;%0A
 import j
@@ -770,22 +770,21 @@
 BreedAir
-.class
+::new
 ),%0A    E
@@ -803,22 +803,21 @@
 BreedEnd
-.class
+::new
 ),%0A    F
@@ -838,22 +838,21 @@
 reedFire
-.class
+::new
 ),%0A    F
@@ -877,22 +877,21 @@
 edForest
-.class
+::new
 ),%0A    G
@@ -914,22 +914,21 @@
 eedGhost
-.class
+::new
 ),%0A    I
@@ -947,22 +947,21 @@
 BreedIce
-.class
+::new
 ),%0A    N
@@ -986,22 +986,21 @@
 edNether
-.class
+::new
 ),%0A    W
@@ -1023,22 +1023,21 @@
 eedWater
-.class
+::new
 );%0A    %0A
@@ -1744,24 +1744,17 @@
 ta, 
-Class%3C? extends 
+Supplier%3C
 Drag
@@ -1786,444 +1786,34 @@
    t
-ry %7B%0A            breed = factory.getDeclaredConstructor(EnumDragonBreed.class).newInstance(this);%0A        %7D catch (NoSuchMethodException %7C InvocationTargetException %7C InstantiationException %7C IllegalArgumentException ex) %7B%0A            throw new RuntimeException(%22Incompatible breed factory %22 + factory, ex);%0A        %7D catch (SecurityException %7C IllegalAccessException ex) %7B%0A            throw new RuntimeException(ex);%0A        %7D%0A        
+his.breed = factory.get();
 %0A   
@@ -2057,15 +2057,10 @@
 ;%0A    %7D%0A
-    %0A
 %7D%0A

Update EnumDragonBreed.java