/*
 * Copyright © 2016 - 2019 Schlichtherle IT Services
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package global.namespace.neuron.di.internal;

import global.namespace.neuron.di.internal.proxy.Proxies;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

class Reflection8 {

    private static final Unsafe unsafe;

    static {
        try {
            final Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            unsafe = (Unsafe) f.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new AssertionError(e);
        }
    }

    private Reflection8() {
    }

    @SuppressWarnings("unchecked")
    static <C> Class<? extends C> defineSubclass(final Class<C> clazz, final String name, final byte[] b) {
        final ClassLoader loader = clazz.getClassLoader();
        return (Class<? extends C>) unsafe.defineClass(
                name,
                b,
                0,
                b.length,
                null != loader ? loader : Proxies.CLASS_LOADER,
                clazz.getProtectionDomain()
        );
    }
}

@@ -727,351 +727,770 @@
 ort 
-sun.misc.Unsafe;%0A%0Aimport java.lang.reflect.Field;%0A%0Aclass Reflection8 %7B%0A%0A    private static final Unsafe unsafe;%0A%0A    static %7B%0A        try %7B%0A            final Field f = Unsafe.class.getDeclaredField(%22theUnsafe%22);%0A            f.setAccessible(true);%0A            unsafe = (Unsafe) f.get(null);%0A        %7D catch (NoSuchFieldException %7C IllegalAccess
+global.namespace.neuron.di.java.BreedingException;%0A%0Aimport java.lang.reflect.InvocationTargetException;%0Aimport java.lang.reflect.Method;%0A%0Aclass Reflection8 %7B%0A%0A    private Reflection8() %7B%0A    %7D%0A%0A    private static final Method getClassLoadingLock, defineClass;%0A%0A    static %7B%0A        final Class%3CClassLoader%3E classLoaderClass = ClassLoader.class;%0A        try %7B%0A            getClassLoadingLock = classLoaderClass%0A                    .getDeclaredMethod(%22getClassLoadingLock%22, String.class);%0A            getClassLoadingLock.setAccessible(true);%0A            defineClass = classLoaderClass%0A                    .getDeclaredMethod(%22defineClass%22, String.class, byte%5B%5D.class, int.class, int.class);%0A            defineClass.setAccessible(true);%0A        %7D catch (NoSuchMethod
 Exce
@@ -1562,43 +1562,8 @@
  %7D%0A%0A
-    private Reflection8() %7B%0A    %7D%0A%0A
     
@@ -1731,41 +1731,121 @@
 der 
-l
+cl = classL
 oader
- = 
+(
 clazz
-.getClassLoader();%0A
+);%0A        try %7B%0A            synchronized (getClassLoadingLock.invoke(cl, name)) %7B%0A        
     
@@ -1880,15 +1880,8 @@
 C%3E) 
-unsafe.
 defi
@@ -1891,14 +1891,43 @@
 lass
-(%0A    
+.invoke(cl, name, b, 0, b.length);%0A
     
@@ -1934,21 +1934,17 @@
         
-name,
+%7D
 %0A       
@@ -1948,63 +1948,188 @@
     
-        b,%0A                0,%0A                b.length,
+%7D catch (InvocationTargetException e) %7B%0A            throw new BreedingException(e.getCause());%0A        %7D catch (IllegalAccessException e) %7B%0A            throw new AssertionError(e);
 %0A   
@@ -2137,107 +2137,142 @@
     
+%7D%0A
     
+%7D%0A%0A
     
-null != loader ? loader : Proxies.CLASS_LOADER,%0A                clazz.getProtectionDomain
+private static %3CC%3E ClassLoader classLoader(final Class%3CC%3E clazz) %7B%0A        final ClassLoader cl = clazz.getClassLoader
 ()
+;
 %0A   
@@ -2276,17 +2276,61 @@
         
-)
+return null != cl ? cl : Proxies.CLASS_LOADER
 ;%0A    %7D%0A

Revert "Use a less hacky way to define a class for Java 8."