diff --git a/HFunction.java b/HFunction.java
deleted file mode 100644
--- a/HFunction.java
+++ /dev/null
@@ -1,50 +0,0 @@
-import java.lang.reflect.*;
-
-/**
- * An HFunction can be used as a invocation handler which actually
- * handles the invocation by calling a Haskell function.
- *
- * @author Julian Fleischer
- */
-public class HFunction implements InvocationHandler {
-
-    private final long hFunction;
-
-    static native void release(long func);
-    static native Object call(long func, Method self, Object[] args);
-
-    /**
-     * Creates an HFunction from a function pointer.
-     *
-     * @param func
-     */
-    public HFunction(long func) {
-        hFunction = func;
-    }
-
-    public Object invoke(Object proxy, Method method, Object[] args) {
-        return call(hFunction, method, args);
-    }
-
-    protected void finalize() {
-        release(hFunction);
-    }
-
-    /**
-     * Make an HFunction for a given iface from a function pointer.
-     *
-     * @param iface
-     * @param func
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> T makeFunction(Class<T> iface, long func) {
-        InvocationHandler handler = new HFunction(func);
-        return (T) Proxy.newProxyInstance(
-                            iface.getClassLoader(),
-                            new Class<?>[] { iface },
-                            handler);
-    }
-}
-
-
-
diff --git a/ReadClass.java b/ReadClass.java
deleted file mode 100644
--- a/ReadClass.java
+++ /dev/null
@@ -1,33 +0,0 @@
-import java.io.*;
-
-public class ReadClass {
-
-    public static void main(String... args) throws Exception {
-
-        File file = new File("HFunction.class");
-        int size = (int) file.length();
-                
-        FileInputStream stream = new FileInputStream(file);
-        PrintStream out = new PrintStream("src/hfunction.h");
-
-        byte[] bytes = new byte[size];
-
-        stream.read(bytes);
-
-        out.printf("\n#define FFIJNI_HFUNCTION_LENGTH %d\n\n", size);
-        out.print("static jbyte hFunctionClass[FFIJNI_HFUNCTION_LENGTH] = {");
-        for (int i = 0; i < size; i++) {
-            if (i % 16 == 0) {
-                out.println();
-                out.print("  ");
-            }
-            out.print(bytes[i]);
-            if (i+1 < size) {
-                out.print(", ");
-            }
-        }
-        out.println("\n};");
-    }
-}
-
-
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -11,9 +11,6 @@
 import Prelude
 import qualified Prelude as P
 
-import qualified Control.Exception as Exc
-import Control.Monad (when)
-
 import Data.List
 
 import Distribution.PackageDescription
@@ -25,7 +22,6 @@
 import Distribution.Verbosity
 
 import System.Environment
-import System.Exit (ExitCode (..))
 import System.Directory
 import System.FilePath
 
@@ -38,23 +34,11 @@
 #endif
 
 main = do
-    let verb = verbose
 
     args <- getArgs
 
     args' <- case args of
-        "configure" : _ -> do
-            notice verb ("OS=" ++ show buildOS)
-            notice verb ("ARCH=" ++ show buildArch)
-            args_ <- Exc.catch (configure verb args buildOS) $ \exc -> do
-                warn verb $
-                    "Could not find a JDK. Continuing anyway.\n"
-                 ++ "The error is: "
-                 ++ ((show :: Exc.SomeException -> String) exc)
-                return $
-                    args ++ ["--extra-include-dirs=./include",
-                             "--ghc-option=-optc-DFFIJNI_LIBJVM=!404!"]
-            return args_
+        "configure" : _ -> configure args buildOS
         _ -> return args
 
     let hooks = simpleUserHooks {
@@ -186,12 +170,12 @@
             "" -> ""
 
     
-configure verb args OSX = do
+configure args OSX = do
     -- In Mac OS X there is the tool /usr/libexec/java_home which tells
     -- us where JRE and JDK are installed.
 
     javaHome <- findFirstFile id ["/usr/libexec/java_home"]
-        >>= maybe (fail "Could not determine JAVA_HOME using /usr/libexec/java_home - is there a JDK installed?")
+        >>= maybe (die "Could not determine JAVA_HOME using /usr/libexec/java_home - is there a JDK installed?")
                   return
         >>= (\cmd -> rawSystemStdout silent cmd [])
         >>= return . head . lines
@@ -199,58 +183,37 @@
     libjvmPath <- getEnvironment >>= return . lookup "FFIJNI_LIBJVM"
         >>= maybe (return $ javaHome ++ "/jre/lib/server/libjvm.dylib") return
 
-    notice verb $ "JAVA_HOME=" ++ javaHome
-    notice verb $ "FFIJNI_LIBJVM=" ++ libjvmPath
+    notice normal $ "JAVA_HOME=" ++ javaHome
+    notice normal $ "FFIJNI_LIBJVM=" ++ libjvmPath
 
     return $ args ++ ["--extra-include-dirs=" ++ javaHome ++ "/include",
                       "--extra-include-dirs=" ++ javaHome ++ "/include/darwin",
                       "--ghc-option=-optc-DFFIJNI_LIBJVM=" ++ libjvmPath]
 
-
-configure verb args Linux = do
+configure args Linux = do
     -- In Linux we find out where javac lives and resolve all
     -- symlinks until we find the JDK home.
 
-    let lookupJavac = findExecutable "javac"
-            >>= maybe (fail "Could not determine path to javac. Try setting JAVA_HOME.") return
-            >>= resolve >>= return . takeDirectory . takeDirectory
-
-    javaHome <- getEnvironment >>= return . lookup "JAVA_HOME"
-        >>= maybe lookupJavac return
-
-    when (verb >= deafening) $ do
-        getDirectoryContentsRecursive javaHome >>= mapM_ (debug verb)
-
-    rawSystemExitCode normal (javaHome ++ "/bin/javac") ["GetProperty.java"]
-        >>= (\exit -> case exit of
-                ExitSuccess -> return ()
-                ExitFailure code -> fail $ "javac exited with ExitCode " ++ show code)
+    javaHome <- findExecutable "javac"
+        >>= maybe (die "Could not determine path to javac.") return
+        >>= resolve >>= return . takeDirectory . takeDirectory
 
-    javaArch <- rawSystemStdout normal (javaHome ++ "/bin/java") ["GetProperty", "os.arch"]
-	    >>= return . head . lines
+    rawSystemExit normal "javac" ["GetProperty.java"]
 
-    notice verb $ "os.arch=" ++ javaArch
+    javaArch <- rawSystemStdout normal "java" ["GetProperty", "os.arch"]
+	>>= return . head . lines
 
     libjvmPath <- getEnvironment >>= return . lookup "FFIJNI_LIBJVM"
         >>= maybe (return $ javaHome ++ "/jre/lib/" ++ javaArch ++ "/server/libjvm.so") return
 
-    notice verb $ "JAVA_HOME=" ++ javaHome
-    notice verb $ "FFIJNI_LIBJVM=" ++ libjvmPath
-
-    findFirstFile id [javaHome ++ "/include/jni.h"]
-        >>= maybe (fail $ "jni.h was not found in " ++ javaHome ++ "/include")
-                  (return . const ())
-
-    findFirstFile id [javaHome ++ "/include/linux/jni_md.h"]
-        >>= maybe (fail $ "jni_md.h was not found in " ++ javaHome ++ "/include/linux")
-                  (return . const ())
+    notice normal $ "JAVA_HOME=" ++ javaHome
+    notice normal $ "FFIJNI_LIBJVM=" ++ libjvmPath
 
     return $ args ++ ["--extra-include-dirs=" ++ javaHome ++ "/include",
                       "--extra-include-dirs=" ++ javaHome ++ "/include/linux",
                       "--ghc-option=-optc-DFFIJNI_LIBJVM=" ++ libjvmPath]
 
-
-configure verb args Windows = do
+configure args Windows = do
     -- The strategy for finding a JDK in Windows is rather simplistic.
     -- Typically the JDK is installed in %ProgramFiles%/Java, so we look
     -- into that directory for directories starting with @jdk@. We choose
@@ -265,20 +228,15 @@
         >>= maybe (return $ javaHome ++ "\\jre\\bin\\server\\jvm.dll") return
         >>= return . replace '\\' '/'
 
-    notice verb $ "JAVA_HOME=" ++ javaHome
-    notice verb $ "FFIJNI_LIBJVM=" ++ libjvmPath
-
-    findFirstFile id [javaHome ++ "/include/jni.h"]
-        >>= maybe (fail $ "jni.h was not found in " ++ javaHome ++ "/include")
-                  (return . const ())
+    notice normal $ "JAVA_HOME=" ++ javaHome
+    notice normal $ "FFIJNI_LIBJVM=" ++ libjvmPath
 
     return $ args ++ ["--extra-include-dirs=" ++ javaHome ++ "/include",
                       "--extra-include-dirs=" ++ javaHome ++ "/include/win32",
                       "--ghc-option=-optc-DFFIJNI_LIBJVM=" ++ libjvmPath]
 
-configure verb args os = do
-    warn verb $ "Unknown platform: " ++ show os
-    -- default, nothing
+configure args _ = do
+
     return args
 
 replace :: Char -> Char -> String -> String
diff --git a/dist/build/Foreign/Java.hs b/dist/build/Foreign/Java.hs
--- a/dist/build/Foreign/Java.hs
+++ b/dist/build/Foreign/Java.hs
@@ -213,10 +213,7 @@
     asObject :: a -> Java JObject
 
     -- | Returns a reference to the Class of the given object.
-    classOf :: a -> Java JClass
-
-    -- | Returns a string representation of the type.
-    jtypeOf :: a -> Java String
+    classOf  :: a -> Java JClass
 
     -- | Checks two objects for equality using their @equals@ methods.
     equals   :: JavaObject b => a -> b -> Java Bool
@@ -224,10 +221,6 @@
     toString obj = asObject obj >>= toString
     hashCode obj = asObject obj >>= hashCode
     classOf obj  = asObject obj >>= classOf
-    jtypeOf obj  = do
-        (Just clazz) <- getClass "java.lang.Class"
-        getName <- clazz `bindMethod` "getName" ::= string
-        classOf obj >>= asObject >>= getName >>= return . maybe "" id
 
     equals this obj = do
         this'  <- asObject this
diff --git a/dist/build/Foreign/Java/Bindings.hs b/dist/build/Foreign/Java/Bindings.hs
--- a/dist/build/Foreign/Java/Bindings.hs
+++ b/dist/build/Foreign/Java/Bindings.hs
@@ -1,385 +1,177 @@
-#line 1 "src/Foreign/Java/Bindings.cpphs"
-{-# LANGUAGE Haskell2010
-    , TypeFamilies
-    , FlexibleContexts
-    , FlexibleInstances
-    , TypeSynonymInstances
-    , MultiParamTypeClasses
-    , ScopedTypeVariables
-    , NoImplicitPrelude
- #-}
-{-# OPTIONS
-    -Wall
- #-}
-
--- |
--- Module       : Foreign.Java.Bindings.Support
--- Copyright    : (c) Julian Fleischer 2013
--- License      : MIT (See LICENSE file in cabal package)
---
--- Maintainer   : julian.fleischer@fu-berlin.de
--- Stability    : experimental
--- Portability  : non-portable (TypeFamilies)
---
--- This module provides type classes and instances for
--- supporting the high level bindings. This module should
--- not be imported directly.
-module Foreign.Java.Bindings where
-
-import Haskell.X.Prelude hiding (toList, arr)
-
-import Control.Monad.State hiding (void)
-
-import Foreign
-import Foreign.C
-
-import Foreign.Java
-import Foreign.Java.JavaMonad
-import Foreign.Java.Types as T
-import qualified Foreign.Java.JNI.Safe as JNI
-import qualified Foreign.Java.JNI.Types as Core
-
-
----------------
--- Utilities --
----------------
-
-
-object' :: [Char] -> Q
-object' = T.object'
-
-
-------------------------------
--- Primitive argument types --
-------------------------------
-
-class JBoolean a  where toBoolean :: a -> Java Bool
-class JChar a     where toChar    :: a -> Java Word16
-class JByte a     where toByte    :: a -> Java Int8
-class JShort a    where toShort   :: a -> Java Int16
-class JInt a      where toInt     :: a -> Java Int32
-class JLong a     where toLong    :: a -> Java Int64
-class JFloat a    where toFloat   :: a -> Java Float
-class JDouble a   where toDouble  :: a -> Java Double
-
-
-instance JBoolean Bool   where toBoolean = return
-
-instance JChar Char      where toChar = return . fromIntegral . fromEnum
-instance JChar Int8      where toChar = return . fromIntegral
-instance JChar Word16    where toChar = return
-
-instance JByte Int8      where toByte = return
-
-instance JShort Int8     where toShort = return . fromIntegral
-instance JShort Word8    where toShort = return . fromIntegral
-instance JShort Int16    where toShort = return
-
-instance JInt Int        where toInt = return . fromIntegral
-instance JInt Int8       where toInt = return . fromIntegral
-instance JInt Word8      where toInt = return . fromIntegral
-instance JInt Int16      where toInt = return . fromIntegral
-instance JInt Word16     where toInt = return . fromIntegral
-instance JInt Int32      where toInt = return
-
-instance JLong Int       where toLong = return . fromIntegral
-instance JLong Int8      where toLong = return . fromIntegral
-instance JLong Word8     where toLong = return . fromIntegral
-instance JLong Int16     where toLong = return . fromIntegral
-instance JLong Word16    where toLong = return . fromIntegral
-instance JLong Int32     where toLong = return . fromIntegral
-instance JLong Word32    where toLong = return . fromIntegral
-instance JLong Int64     where toLong = return
-
-instance JFloat CFloat   where toFloat = return . realToFrac
-instance JFloat Float    where toFloat = return
-
-instance JDouble CDouble where toDouble = return . realToFrac
-instance JDouble Double  where toDouble = return
-
-
---------------------------
--- Array argument types --
---------------------------
-
-class Array a where
-    asMaybeArrayObject :: a -> Java (Maybe JObject)
-
-
-----------------------------
--- Primitive result types --
-----------------------------
-
-
-
+{-# LANGUAGE Haskell2010 #-}
+{-# OPTIONS -Wall #-}
 
+-- | Functions for generating glue code between Haskell and Java.
+module Foreign.Java.Bindings (
 
+    -- * Create Haskell glue code from Java definitions
+    printJavaPackageModule,
+    printJavaClassModule,
+    printJavaClassBootfile,
+    printJavaClassModule',
+    printJavaClassBootfile',
 
+    -- * Reflect Java classes
+    reflectJavaClasses,
+    findJavaClasses,
 
+    -- ** A priori known information about Java
+    javaClassesSE6
 
+  ) where
 
+import Foreign.Java
+import Foreign.Java.Utils
+import qualified Foreign.Java.Bindings.JavaSE6
 
+import Foreign.Java.Bindings.JavaTypes
+import qualified Foreign.Java.Bindings.Java2Haskell as Java2Haskell
+import qualified Foreign.Java.Bindings.ReflectJava  as ReflectJava
 
--- | The result of a function call that is of type @boolean@.
-class BooleanResult m where {        toBooleanResult :: Either JThrowable Bool -> Java m }    ;    instance BooleanResult Bool where {        toBooleanResult = either (\exc -> toString exc >>= fail) return }    ;    instance BooleanResult (Either JThrowable Bool) where {        toBooleanResult = return }
--- | The result of a function call that is of type @char@.
-class CharResult m where {        toCharResult :: Either JThrowable Word16 -> Java m }    ;    instance CharResult Word16 where {        toCharResult = either (\exc -> toString exc >>= fail) return }    ;    instance CharResult (Either JThrowable Word16) where {        toCharResult = return }
--- | The result of a function call that is of type @byte@.
-class ByteResult m where {        toByteResult :: Either JThrowable Int8 -> Java m }    ;    instance ByteResult Int8 where {        toByteResult = either (\exc -> toString exc >>= fail) return }    ;    instance ByteResult (Either JThrowable Int8) where {        toByteResult = return }
--- | The result of a function call that is of type @short@.
-class ShortResult m where {        toShortResult :: Either JThrowable Int16 -> Java m }    ;    instance ShortResult Int16 where {        toShortResult = either (\exc -> toString exc >>= fail) return }    ;    instance ShortResult (Either JThrowable Int16) where {        toShortResult = return }
--- | The result of a function call that is of type @int@.
-class IntResult m where {        toIntResult :: Either JThrowable Int32 -> Java m }    ;    instance IntResult Int32 where {        toIntResult = either (\exc -> toString exc >>= fail) return }    ;    instance IntResult (Either JThrowable Int32) where {        toIntResult = return }
--- | The result of a function call that is of type @long@.
-class LongResult m where {        toLongResult :: Either JThrowable Int64 -> Java m }    ;    instance LongResult Int64 where {        toLongResult = either (\exc -> toString exc >>= fail) return }    ;    instance LongResult (Either JThrowable Int64) where {        toLongResult = return }
--- | The result of a function call that is of type @float@.
-class FloatResult m where {        toFloatResult :: Either JThrowable Float -> Java m }    ;    instance FloatResult Float where {        toFloatResult = either (\exc -> toString exc >>= fail) return }    ;    instance FloatResult (Either JThrowable Float) where {        toFloatResult = return }
--- | The result of a function call that is of type @double@.
-class DoubleResult m where {        toDoubleResult :: Either JThrowable Double -> Java m }    ;    instance DoubleResult Double where {        toDoubleResult = either (\exc -> toString exc >>= fail) return }    ;    instance DoubleResult (Either JThrowable Double) where {        toDoubleResult = return }
+import Foreign.Java.Bindings.HaskellTypes
+import qualified Foreign.Java.Bindings.Haskell2Java   as Haskell2Java
+import qualified Foreign.Java.Bindings.ReflectHaskell as ReflectHaskell
 
--- | The result of a function call that is of type @void@.
-class VoidResult m where
-    toVoidResult :: Either JThrowable () -> Java m
-    
-instance VoidResult () where
-    toVoidResult = either (\exc -> toString exc >>= fail) return
+import Data.Word
 
-instance VoidResult (Either JThrowable ()) where
-    toVoidResult = return
-    
-instance VoidResult (Maybe JThrowable) where
-    toVoidResult = return . either Just (const Nothing)
+import Data.Map (Map)
+import qualified Data.List as List
+import qualified Data.Map  as Map
 
 
-------------------------
--- Array result types --
-------------------------
-
--- | An array result of a function call.
-class JavaArray (ArrayResultType m) (ArrayResultComponent m) => ArrayResult m where
-    -- | The JVM machine type of the components of the array.
-    type ArrayResultType m
-
-    -- | The type of the component of the array as returned by
-    -- the low level JNI call.
-    type ArrayResultComponent m
-
-    -- | Convert the array to a sophisticated type.
-    toArrayResult :: Either JThrowable (Maybe (JArray (ArrayResultType m))) -> Java m
-
-instance ArrayResult a => ArrayResult (Either JThrowable a) where
-    type ArrayResultType (Either JThrowable a) = ArrayResultType a
-    type ArrayResultComponent (Either JThrowable a) = ArrayResultComponent a
-
-    toArrayResult = either (return . Left) (toArrayResult . Right)
+javaClassesSE6 :: [String]
+-- ^ The names of all Java Classes part of Java SE 6.
+javaClassesSE6 = Foreign.Java.Bindings.JavaSE6.javaClassesSE6
 
+imports :: String
+-- ^ Imports of all auto generated java code files.
+imports  = ((\_ -> let { __ = 
+{-# LINE 48 "Foreign/Java/Bindings.hss" #-}
+concat ["import qualified Foreign.Java as JNI\nimport Foreign.Java ((-->))\nimport qualified Prelude as Prelude\nimport Prelude ((.), ($), (>>=), (>>), return)\nimport qualified Foreign.Java.Bindings.Support as JNIS\nimport Data.Functor ((<$>))\n"]
+{-# LINE 55 "Foreign/Java/Bindings.hss" #-}
+} in __) undefined)
 
+classInfoSignature :: String
+-- ^ 
+classInfoSignature = "Prelude.String"
 
+classInfo' :: JavaClass -> String
+-- ^ 
+classInfo' clazz = className clazz
 
+packageInfo' packageName classes = packageName
 
+printJavaPackageModule :: String      -- The Java package name
+                       -> String      -- The Haskell module name of the Java package
+                       -> Map String JavaClass -- Info about all other classes
+                       -> [JavaClass] -- The Java classes contained in the Java package
+                       -> String
+-- ^ 
+printJavaPackageModule packageName modName classInfo classes = ((\_ -> let { __ = 
+{-# LINE 73 "Foreign/Java/Bindings.hss" #-}
+concat ["{-# LANGUAGE Haskell2010 #-}\n-- | Package @", (packageName), "@\nmodule ", (modName), " (\n", (moduleExports), "    info'\n) where\n", (imports), "\n", (moduleImports), "\n-- Information about this package.\ninfo' = ", (show $ packageInfo' packageName classes), "\n", (moduleDeclarations), "\n"]
+{-# LINE 85 "Foreign/Java/Bindings.hss" #-}
+} in __) undefined)
+  where moduleDeclarations   = Java2Haskell.pkgModDecl     classInfo classes
+        moduleImports        = Java2Haskell.pkgModImports  classInfo classes
+        moduleExports        = Java2Haskell.pkgModExports  classInfo classes
 
 
+printJavaClassModule :: JavaClass -- The Java class
+                     -> String    -- The Haskell module name of the Java class
+                     -> Map String JavaClass -- Info about all classes
+                     -> String
+-- ^ 
+printJavaClassModule clazz modName classInfo = ((\_ -> let { __ = 
+{-# LINE 96 "Foreign/Java/Bindings.hss" #-}
+concat ["{-# LANGUAGE Haskell2010 #-}\n-- | ", (show $ classType clazz), " @", (classFullName clazz), "@\nmodule ", (modName), " (\n", (moduleExports), "    -- * Information about this class.\n    info'\n) where\n", (imports), "\n", (bootfileImports), "\n", (moduleImports), "\ninfo' = ", (show $ classInfo' clazz), "\n", (bootfileDeclarations), "\n", (moduleDeclarations), "\n"]
+{-# LINE 110 "Foreign/Java/Bindings.hss" #-}
+} in __) undefined)
+  where bootfileDeclarations = Java2Haskell.classBootDecl    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports classInfo clazz
+        moduleDeclarations   = Java2Haskell.classModDecl     classInfo clazz
+        moduleImports        = Java2Haskell.classModImports  classInfo clazz
+        moduleExports        = Java2Haskell.classModExports  classInfo clazz
 
 
-instance ArrayResult [Bool] where {        type ArrayResultType [Bool] = T.Z ;        type ArrayResultComponent [Bool] = Bool ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
-instance ArrayResult [Word16] where {        type ArrayResultType [Word16] = T.C ;        type ArrayResultComponent [Word16] = Word16 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
-instance ArrayResult [Int8] where {        type ArrayResultType [Int8] = T.B ;        type ArrayResultComponent [Int8] = Int8 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
-instance ArrayResult [Int16] where {        type ArrayResultType [Int16] = T.S ;        type ArrayResultComponent [Int16] = Int16 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
-instance ArrayResult [Int32] where {        type ArrayResultType [Int32] = T.I ;        type ArrayResultComponent [Int32] = Int32 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
-instance ArrayResult [Int64] where {        type ArrayResultType [Int64] = T.J ;        type ArrayResultComponent [Int64] = Int64 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
-instance ArrayResult [Float] where {        type ArrayResultType [Float] = T.F ;        type ArrayResultComponent [Float] = Float ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
-instance ArrayResult [Double] where {        type ArrayResultType [Double] = T.D ;        type ArrayResultComponent [Double] = Double ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+printJavaClassBootfile :: JavaClass -- The Java class
+                       -> String    -- The Haskell module name of the Java class
+                       -> Map String JavaClass -- Info about all classes
+                       -> String
+-- ^ 
+printJavaClassBootfile clazz modName classInfo = ((\_ -> let { __ = 
+{-# LINE 123 "Foreign/Java/Bindings.hss" #-}
+concat ["{-# LANGUAGE Haskell2010 #-}\n-- Bootfile for class ", (className clazz), "\nmodule ", (modName), " (\n", (bootfileExports), "    info'\n) where\n", (imports), "\n", (bootfileImports), "\ninfo' :: ", (classInfoSignature), "\n", (bootfileDeclarations), "\n"]
+{-# LINE 134 "Foreign/Java/Bindings.hss" #-}
+} in __) undefined)
+  where bootfileDeclarations = Java2Haskell.classBootDecl    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports classInfo clazz
+        bootfileExports      = Java2Haskell.classBootExports classInfo clazz
 
 
-instance ArrayResult [Char] where
-    type ArrayResultType [Char] = T.C
-    type ArrayResultComponent [Char] = Word16
-
-    toArrayResult = either (\exc -> toString exc >>= fail)
-                           (maybe (return [])
-                                  (fmap (map (toEnum . fromIntegral)) . toList))
-
-instance ArrayResult [[Char]] where
-    type ArrayResultType [[Char]] = T.L
-    type ArrayResultComponent [[Char]] = Maybe JObject
-
-    toArrayResult =
-        either (\exc -> toString exc >>= fail)
-               (maybe (return [])
-                      (\arr -> toList arr >>= mapM (maybe (return "") toString)))
-
+printJavaClassModule' :: JavaClass -- The Java class
+                      -> String    -- The Haskell module name of the Java class
+                      -> Map String JavaClass -- Info about all classes
+                      -> String
+-- ^ 
+printJavaClassModule' clazz modName classInfo = ((\_ -> let { __ = 
+{-# LINE 145 "Foreign/Java/Bindings.hss" #-}
+concat ["{-# LANGUAGE Haskell2010, TypeFamilies #-}\n-- hidden @", (className clazz), "@\nmodule ", (modName), "__ (\n", (moduleExports), "    info'\n) where\n", (imports), "\n", (bootfileImports), "\n", (moduleImports), "\ninfo' = ", (show $ classInfo' clazz), "\n", (bootfileDeclarations), "\n", (moduleDeclarations), "\n"]
+{-# LINE 158 "Foreign/Java/Bindings.hss" #-}
+} in __) undefined)
+  where bootfileDeclarations = Java2Haskell.classBootDecl'    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports' classInfo clazz
+        moduleDeclarations   = Java2Haskell.classModDecl'     classInfo clazz
+        moduleImports        = Java2Haskell.classModImports'  classInfo clazz
+        moduleExports        = Java2Haskell.classModExports'  classInfo clazz
 
 
------------------------
--- All other objects --
------------------------
-
-newtype AsString o = AsString [Char]
-    deriving (Eq, Show, Ord)
-
-newtype AsList a o = AsList [a]
-    deriving (Eq, Show, Ord)
-
-class ObjectToList o e where
-    objectToList :: o -> JObject -> Java [e]
-
--- | The result of a function call that is of type @object@.
-class ObjectResult m where
-    -- | 
-    toObjectResult :: Either JThrowable (Maybe JObject) -> Java m
-
-instance ObjectResult (AsString a) where
-    toObjectResult = fmap AsString . either (\exc -> toString exc >>= fail)
-                                            (maybe (return "null") toString)
-
-instance ObjectToList o e => ObjectResult (AsList e o) where
-    toObjectResult = fmap AsList . either (\exc -> toString exc >>= fail)
-                                          (maybe (return []) (objectToList (undefined :: o)))
-
-instance UnsafeCast a => ObjectResult (Value a) where
-    toObjectResult = either (return . Fail)
-                            (maybe (return NoValue)
-                                   (fmap Value . unsafeFromJObject))
-
-instance UnsafeCast a => ObjectResult (Either JThrowable a) where
-    toObjectResult = either (return . Left)
-                            (maybe (fmap Left nullPointer)
-                                   (fmap Right . unsafeFromJObject))
-      where
-        nullPointer :: Java JThrowable
-        nullPointer = do
-            (Just clazz) <- getClass "java.lang.NullPointerException"
-            (Just (Core.JObject obj)) <- newObject clazz
-            return $ Core.JThrowable (castForeignPtr obj)
-
-instance UnsafeCast a => ObjectResult (Either (Maybe JThrowable) a) where
-    toObjectResult = either (return . Left . Just)
-                            (maybe (return (Left Nothing))
-                                   (fmap Right . unsafeFromJObject))
-
-instance UnsafeCast a => ObjectResult (Maybe a) where
-    toObjectResult = either (\exc -> toString exc >>= fail)
-                            (maybe (return Nothing)
-                                   (fmap Just . unsafeFromJObject))
+printJavaClassBootfile' :: JavaClass -- The Java class
+                        -> String    -- The Haskell module name of the Java class
+                        -> Map String JavaClass -- Info about all classes
+                        -> String
+-- ^ 
+printJavaClassBootfile' clazz modName classInfo = ((\_ -> let { __ = 
+{-# LINE 171 "Foreign/Java/Bindings.hss" #-}
+concat ["{-# LANGUAGE Haskell2010 #-}\n-- hidden Bootfile for class ", (className clazz), "\nmodule ", (modName), "__ (\n", (bootfileExports), "    info'\n) where\n", (imports), "\n", (bootfileImports), "\ninfo' :: ", (classInfoSignature), "\n", (bootfileDeclarations), "\n"]
+{-# LINE 182 "Foreign/Java/Bindings.hss" #-}
+} in __) undefined)
+  where bootfileDeclarations = Java2Haskell.classBootDecl'    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports' classInfo clazz
+        bootfileExports      = Java2Haskell.classBootExports' classInfo clazz
 
 
----------------------------------------------------
--- Advanced features (Callbacks, Subtyping, ...) --
----------------------------------------------------
+reflectJavaClasses :: [String]
+                   -> Java [JavaClass]
+-- ^ Retrieve information about the given Java classes
+-- from the Java Virtual Machine.
+reflectJavaClasses = ReflectJava.reflectClasses
 
 
--- | A convenient alternative to 'isInstanceOf'.
+findJavaClasses :: Word32 -- Maximum depth for following dependencies.
+                -> [String]
+                -> Java [String]
+-- ^ Find all classes that the given classes depend on.
 --
--- Minimal complete definition: 'coerce' or 'whenInstanceOf'.
-class InstanceOf a where
-    type CoercedType a
+-- In order to provide proper bindings for a class, bindings
+-- for all classes which a class depends on need to exist too.
+-- A class depends on all classes which it inherits from or
+-- which are used as arguments, return types, or parameters.
+--
+-- This functions returns all the class names of the classes
+-- on which the given classes depend on. No duplicates are
+-- reported and the resulting list is sorted.
+findJavaClasses = ReflectJava.findClasses
 
-    -- | Check if the object of type @a@ is an instance
-    -- of the type represented by @b@. 
-    instanceOf :: JavaObject o => o -> a -> Java Bool
 
-    -- | Check if the object of type @a@ is an instance
-    -- of the type @c@, represented by @b@. If so, it will coerce
-    -- the object of type @a@ and pass it to the given action.
-    --
-    -- If @a@ was an instance of @c@ (where @c@ is represented
-    -- by @b@) this function will return @'Just' d@, where @d@ is
-    -- the result of the optional computation. If not, 'Nothing'
-    -- is returned.
-    whenInstanceOf :: JavaObject o => o -> a -> (CoercedType a -> Java d) -> Java (Maybe d)
 
-    -- | Coerces the given object of type @a@ to an object of
-    -- @c@, where @c@ is represented by a value of type @b@.
-    -- Returns @'Nothing'@ if this is not possible.
-    coerce :: JavaObject o => o -> a -> Java (Maybe (CoercedType a))
 
-    instanceOf o t =
-        whenInstanceOf o t (return . const ())
-            >>= return . maybe False (const True)
 
-    whenInstanceOf o t a =
-        coerce o t >>= maybe (return Nothing) (fmap Just . a)
 
-    coerce o t = whenInstanceOf o t return
 
--- | For INTERNAL use only. Is however not in a hidden module,
--- so that other libraries can link against it.
-class UnsafeCast a where
-    -- | For INTERNAL use only. Do not use yourself.
-    unsafeFromJObject :: JObject -> Java a
 
 
 
----------------
--- Callbacks --
----------------
-
-
-registerCallbacks :: Core.JClass -> Java Bool
--- ^ Yepp. Register callbacks. Do it.
-registerCallbacks (Core.JClass ptr) = do
-    vm <- getVM
-    io $ withForeignPtr ptr $ \clazz -> JNI.registerCallbacks vm clazz
-
-
--- | A wrapped function can be used as a callback from the
--- JVM into the Haskell runtime environment.
-type WrappedFunc = Ptr Core.JVM -- Ptr to JEnv
-               -> Ptr Core.JObjectRef -- Ptr to this, a proxy
-               -> Ptr Core.JObjectRef -- Ptr to method, the requested method
-               -> Ptr Core.JObjectRef -- Ptr to a JObject-Array (Object[]), the arguments
-               -> IO (Ptr Core.JObjectRef) -- Returns a pointer to the result
-
-type InterfaceFunc = JObject -> JObject -> JObject -> Java (Maybe JObject)
-
-runJava_ :: Ptr Core.JVM -> Java a -> IO a
-runJava_ vm f = runStateT (_runJava f) (newJVMState vm) >>= return . fst
-
-foreign import ccall safe "wrapper"
-    wrap_ :: WrappedFunc -> IO (FunPtr WrappedFunc)
-
-foreign export ccall freeFunPtr :: FunPtr WrappedFunc -> IO ()
-
-
-freeFunPtr :: FunPtr WrappedFunc -> IO ()
-freeFunPtr ptr = freeHaskellFunPtr ptr
-
-
-implementInterfaceBy :: [Char] -> InterfaceFunc -> Java JObject
-implementInterfaceBy ifaceName func = do
-    iface <- getClass ifaceName >>= asObject . fromJust
-    (Just clazz) <- getClass "HFunction"
-    _success <- registerCallbacks clazz
-    makeFunction <- clazz `bindStaticMethod` "makeFunction"
-        ::= object "java.lang.Class" --> long --> object "java.lang.Object"
-    (Just impl) <- io (intify func) >>= makeFunction (Just iface)
-    return impl
-  where
-    wrap :: InterfaceFunc -> IO (FunPtr WrappedFunc)
-    wrap f = do
-
-        let proxyFunc vm self method args = do
-                self'   <- Core.JObject <$> newForeignPtr JNI.release self
-                method' <- Core.JObject <$> newForeignPtr JNI.release method
-                args'   <- Core.JObject <$> newForeignPtr JNI.release args
-
-                jobj <- runJava_ vm (f self' method' args')
-
-                case jobj of
-                    Nothing -> return nullPtr
-                    Just (Core.JObject ptr) -> withForeignPtr ptr return
-
-        wrappedFunc <- wrap_ proxyFunc
-
-        return wrappedFunc
-
-    intify :: InterfaceFunc -> IO Int64
-    intify = fmap (fromIntegral . ptrToIntPtr . castFunPtrToPtr) . wrap
-
-
-delete :: Core.JObject -> Java ()
-delete (Core.JObject ptr) = io $ do
-    finalizeForeignPtr ptr
 
 
 
diff --git a/dist/build/Foreign/Java/Bindings/Haskell2Java.hs b/dist/build/Foreign/Java/Bindings/Haskell2Java.hs
new file mode 100644
--- /dev/null
+++ b/dist/build/Foreign/Java/Bindings/Haskell2Java.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE Haskell2010
+ #-}
+
+module Foreign.Java.Bindings.Haskell2Java where
+
+
+
diff --git a/dist/build/Foreign/Java/Bindings/Java2Haskell.hs b/dist/build/Foreign/Java/Bindings/Java2Haskell.hs
new file mode 100644
--- /dev/null
+++ b/dist/build/Foreign/Java/Bindings/Java2Haskell.hs
@@ -0,0 +1,342 @@
+{-# LANGUAGE Haskell2010 #-}
+
+module Foreign.Java.Bindings.Java2Haskell where
+
+import Foreign.Java.Util
+import Foreign.Java.Utils
+import Foreign.Java.Bindings.JavaTypes
+import Foreign.Java.Bindings.Typomatic
+import Data.Map (Map)
+
+import Data.Function
+
+import qualified Data.Char as Char
+import qualified Data.List as List
+import qualified Data.Set  as Set
+import qualified Data.Map  as Map
+
+import qualified Data.List.HIUtils as HI
+
+import Control.Arrow
+
+pkgModExports :: Map String JavaClass -> [JavaClass] -> String
+pkgModExports info classes = concatMap (\(t, b) -> ((\_ -> let { __ = 
+{-# LINE 23 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["    -- * ", (show t), "s\n", (b), ""]
+{-# LINE 23 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined))
+        $ map (second $ concatMap format)
+        $ HI.aggregateAL
+        $ zip (map classType classes) classes
+  where
+    format clazz =
+        let haskName  = takeClassName $ classModName clazz
+            javaName  = className clazz
+            dataDecl  = if classIface clazz then "" else
+                ((\_ -> let { __ = 
+{-# LINE 32 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["    ", (dataTName haskName), " (..),\n"]
+{-# LINE 32 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+        in ((\_ -> let { __ = 
+{-# LINE 33 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["    -- ** ", (show $ classType clazz), " ", (javaName), "\n    -- | For constructors, methods, and so on, see: \"", (classModName clazz), "\".\n    ", (tyclTName haskName), ",\n", (dataDecl), "    ", (newtTName haskName), " ", (if classEnum clazz then "(..)" else ""), ",\n"]
+{-# LINE 39 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+
+
+pkgModImports :: Map String JavaClass -> [JavaClass] -> String
+pkgModImports info classes = concatMap (format . classModName) classes
+  where format modName = ((\_ -> let { __ = 
+{-# LINE 44 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["import ", (modName), "__ hiding (info')\n"]
+{-# LINE 44 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+
+
+pkgModDecl :: Map String JavaClass -> [JavaClass] -> String
+pkgModDecl info classes = ""
+
+
+-- Modules and Boot files
+  
+classBootExports :: Map String JavaClass -> JavaClass -> String
+classBootExports info clazz = ""
+
+
+classBootImports :: Map String JavaClass -> JavaClass -> String
+classBootImports info clazz = ""
+
+
+classModImports :: Map String JavaClass -> JavaClass -> String
+classModImports info clazz = concatMap format references
+  where
+    format package = ((\_ -> let { __ = 
+{-# LINE 64 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["import qualified ", (package), "\n"]
+{-# LINE 64 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+    references = Set.toList
+        $ Set.map (fst . splitClassName . classModName . check . flip Map.lookup info)
+        $ Set.fromList (classFullName clazz : dependencies)
+    dependencies = classDependencies clazz
+    check = maybe (error ((\_ -> let { __ = 
+{-# LINE 69 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["classModImports in Foreign.Java.Bindings.Java2Haskell - class definition not found"]
+{-# LINE 71 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)) id
+
+
+classBootDecl :: Map String JavaClass -> JavaClass -> String
+classBootDecl info clazz = ((\_ -> let { __ = 
+{-# LINE 75 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat [""]
+{-# LINE 76 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+
+classModExports :: Map String JavaClass -> JavaClass -> String
+classModExports info clazz = "    -- * Methods\n" ++ concatMap methodExport methodNames
+  where
+    methods = List.sortBy (compare `on` methodName) (classMethods clazz)
+    methodNames = mkMethodNames methods
+    methodExport name = name ++ ",    \n"
+
+
+classModDecl :: Map String JavaClass -> JavaClass -> String
+classModDecl info clazz = concatMap methodDecl $ zip methodNames methods
+  where
+    methods = List.sortBy (compare `on` methodName) (classMethods clazz)
+    methodNames = mkMethodNames methods
+    methodDecl (name, method)
+        | arrayTypes = ((\_ -> let { __ = 
+{-# LINE 92 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), " :: ", (signature), "\n", (name), " = Prelude.undefined\n"]
+{-# LINE 95 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+        | otherwise = ((\_ -> let { __ = 
+{-# LINE 96 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (haddock), "\n", (name), " :: ", (signature), "\n", (name), "", (argsDecl), " = do\n    (Prelude.Just clazz) <- JNI.getClass \"", (classFullName clazz), "\"\n    (Prelude.Just method) <- clazz `JNI.", (getMethod), "` ", (jniSignature), "\n", (thisArg), "", (readArgs), "    result <- JNI.", (callMethod), " method ", (argsRefs), "\n    ", (convertResult), " result\n"]
+{-# LINE 106 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+      where
+        arrayTypes
+--            | any isArrayType (methodParams method) = True
+            | (Just ret) <- methodReturnType method = isArrayType ret
+            | otherwise = False
+        isArrayType x = case x of JArr _ -> True ; _ -> False
+        isStatic = methodStatic method
+        javaSignature = fJavaSignature argsInfo
+        javaReturnType = fJavaReturnType argsInfo
+        jniSignature = fJniSignature argsInfo
+        signature = fSignature argsInfo
+        getMethod = if isStatic then "getStaticMethod" else "getMethod"
+        callMethod = if isStatic then "callStaticMethodE" else "callMethodE"
+        args = fArgNames argsInfo
+        argsNotThis = (if isStatic then id else tail) args
+        argsInfo = runTypomatic info (typomatic clazz method)
+        argsDecl = concatMap (' ':) args
+        argsRefs = concatMap (++ "' ") args
+        haddock = ((\_ -> let { __ = 
+{-# LINE 125 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["-- | @", (if isStatic then "static " else "virtual "), "", (if methodSynchronized method then "synchronized " else ""), "", (if methodNative method then "native " else ""), "", (if methodFinal method then "final " else ""), "", (javaSignature), " -> ", (javaReturnType), "@"]
+{-# LINE 130 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+        thisArg = if isStatic then "" else ((\_ -> let { __ = 
+{-# LINE 131 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["    ", (head args), "' <- JNI.asObject ", (head args), "\n"]
+{-# LINE 131 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+        readArgs = concatMap (("    " ++). uncurry readArg) (zip argsNotThis (methodParams method))
+        readArg name jtype = case jtype of
+            JBoolean -> ((\_ -> let { __ = 
+{-# LINE 134 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toBoolean ", (name), "\n"]
+{-# LINE 134 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JChar    -> ((\_ -> let { __ = 
+{-# LINE 135 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toChar ", (name), "\n"]
+{-# LINE 135 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JByte    -> ((\_ -> let { __ = 
+{-# LINE 136 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toByte ", (name), "\n"]
+{-# LINE 136 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JShort   -> ((\_ -> let { __ = 
+{-# LINE 137 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toShort ", (name), "\n"]
+{-# LINE 137 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JInt     -> ((\_ -> let { __ = 
+{-# LINE 138 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toInt ", (name), "\n"]
+{-# LINE 138 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JLong    -> ((\_ -> let { __ = 
+{-# LINE 139 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toLong ", (name), "\n"]
+{-# LINE 139 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JFloat   -> ((\_ -> let { __ = 
+{-# LINE 140 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toFloat ", (name), "\n"]
+{-# LINE 140 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JDouble  -> ((\_ -> let { __ = 
+{-# LINE 141 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.toDouble ", (name), "\n"]
+{-# LINE 141 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JObj _   -> ((\_ -> let { __ = 
+{-# LINE 142 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- Prelude.Just <$> JNI.asObject ", (name), "\n"]
+{-# LINE 142 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+            JArr _   -> ((\_ -> let { __ = 
+{-# LINE 143 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["", (name), "' <- JNIS.asMaybeArrayObject ", (name), "\n"]
+{-# LINE 143 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+        convertResult = ("JNIS." ++) $ case methodReturnType method of
+            Nothing -> "toVoidResult"
+            Just t -> case t of
+                JBoolean -> "toBooleanResult"
+                JChar    -> "toCharResult"
+                JByte    -> "toByteResult"
+                JShort   -> "toShortResult"
+                JInt     -> "toIntResult"
+                JLong    -> "toLongResult"
+                JFloat   -> "toFloatResult"
+                JDouble  -> "toDoubleResult"
+                JObj n   -> "toObjectResult"
+                JArr c   -> "toArrayResult"
+
+        
+
+mkMethodNames :: [JavaMethod] -> [String]
+mkMethodNames = concatMap (zipWith (flip (++)) (iterate (++"'") ""))
+                . List.group . map sanitize . map methodName
+  where
+    sanitize name
+        | Char.isUpper (head name) = '_' : name
+        | name `elem` haskellKeywords = name ++ "'"
+        | otherwise = name
+
+
+-- Hidden Modules and Boot files
+
+
+classModExports' :: Map String JavaClass -> JavaClass -> String
+classModExports' info clazz = ((\_ -> let { __ = 
+{-# LINE 174 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["    ", (tyclTName haskName), ",\n    ", (dataTName haskName), " (..),\n    ", (newtTName haskName), " ", (if classEnum clazz then "(..)" else ""), ",\n"]
+{-# LINE 178 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+  where
+    haskName = takeClassName $ classModName clazz
+    javaName = className clazz
+
+
+classBootExports' :: Map String JavaClass -> JavaClass -> String
+classBootExports' info clazz = ((\_ -> let { __ = 
+{-# LINE 185 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["    ", (tyclTName haskName), ",\n    ", (dataTName haskName), " (..),\n    ", (newtTName haskName), ",\n"]
+{-# LINE 189 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+  where
+    haskName = takeClassName $ classModName clazz
+    javaName = className clazz
+
+
+classBootImports' :: Map String JavaClass -> JavaClass -> String
+classBootImports' info clazz
+    = concatMap (format . classModName) supertypes
+  where
+    format modName = ((\_ -> let { __ = 
+{-# LINE 199 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["import qualified ", (modName), "__\n"]
+{-# LINE 199 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+    supertypes = map (check . flip Map.lookup info)
+               $ Set.toList
+               $ Set.fromList (classParents clazz ++ classIfaces clazz)
+    check = maybe (error ((\_ -> let { __ = 
+{-# LINE 203 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["classBootImports' in Foreign.Java.Bindings.Java2Haskell - class definition not found"]
+{-# LINE 205 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)) id
+
+
+classModImports' :: Map String JavaClass -> JavaClass -> String
+classModImports' info clazz = ""
+
+
+classBootDecl' :: Map String JavaClass -> JavaClass -> String
+classBootDecl' info clazz
+    | classEnum clazz = ((\_ -> let { __ = 
+{-# LINE 214 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["class ", (tyclTDecl), "\ndata ", (newtTDecl), " = ", (enumConstants), "\ndata ", (dataTDecl), " = ", (dataCDecl), "\n"]
+{-# LINE 218 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+    | otherwise = ((\_ -> let { __ = 
+{-# LINE 219 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["class ", (tyclTDecl), "\nnewtype ", (newtTDecl), " = ", (newtCDecl), " JNI.JObject\ndata ", (dataTDecl), " = ", (dataCDecl), "\n"]
+{-# LINE 223 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+  where baseName  = takeClassName $ classModName clazz
+        params    = concatMap (\(p:ps) -> ' ' : Char.toLower p : ps)
+                      $ map (tyVarName . paramName) $ classTypeParams clazz
+        newtTDecl = newtTName baseName ++ params
+        newtCDecl = newtCName baseName
+        dataTDecl = dataTName baseName ++ params
+        dataCDecl = dataCName baseName ++ params
+        tyclTDecl = ((\_ -> let { __ = 
+{-# LINE 231 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["(JNI.JavaObject this", (context), ") => ", (tyclTName baseName), " this"]
+{-# LINE 231 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+        context = concatMap parentContext (classParents clazz)
+        parentContext parent = ((\_ -> let { __ = 
+{-# LINE 233 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat [", ", (qualifiedName), " this"]
+{-# LINE 233 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+          where parentClass = info Map.! parent
+                modName = classModName parentClass
+                qualifiedName = modName ++ "__." ++ (tyclTName $ takeClassName modName)
+        enumConstants = concat $ List.intersperse " | " $ map sanitize $ map snd $ classEnumConstants clazz
+          where sanitize (x:xs) = Char.toUpper x : xs
+
+
+classModDecl' :: Map String JavaClass -> JavaClass -> String
+classModDecl' info clazz
+    | classEnum clazz = ((\_ -> let { __ = 
+{-# LINE 243 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["instance JNI.JavaObject (", (newtTDecl), ") where\n    asObject = Prelude.undefined\ninstance ", (tyclTName baseName), " (", (newtTDecl), ")\ninstance JNIS.InstanceOf (", (dataTDecl), ") where\n    type CoercedType (", (dataTDecl), ") = (", (newtTDecl), ")\n", (instances), "\n"]
+{-# LINE 250 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+    | otherwise = ((\_ -> let { __ = 
+{-# LINE 251 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["instance JNI.JavaObject (", (newtTDecl), ") where\n    asObject (", (newtCName baseName), " obj) = return obj\ninstance JNIS.UnsafeCast (", (newtTDecl), ") where\n    unsafeFromJObject obj = return (", (newtCDecl), " obj)\ninstance ", (tyclTName baseName), " (", (newtTDecl), ")\ninstance JNIS.InstanceOf (", (dataTDecl), ") where\n    type CoercedType (", (dataTDecl), ") = (", (newtTDecl), ")\n    coerce o t = do\n        obj <- JNI.asObject o\n        (Prelude.Just clazz) <- JNI.getClass \"", (fullClassName), "\"\n        isInstanceOf <- obj `JNI.isInstanceOf` clazz\n        if isInstanceOf\n            then Prelude.Just <$> (JNIS.unsafeFromJObject obj)\n            else return Prelude.Nothing\n", (instances), "\n"]
+{-# LINE 267 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+  where fullClassName = classFullName clazz
+        baseName  = takeClassName $ classModName clazz
+        params    = concatMap (\(p:ps) -> ' ' : Char.toLower p : ps)
+                      $ map (tyVarName . paramName) $ classTypeParams clazz
+        newtTDecl = newtTName baseName ++ params
+        newtCDecl = newtCName baseName
+        dataTDecl = dataTName baseName ++ params
+        dataCDecl = dataCName baseName ++ params
+        instances = concatMap parentInstance (classParents clazz)
+        parentInstance parent = ((\_ -> let { __ = 
+{-# LINE 277 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+concat ["instance ", (qualifiedName), " (", (newtTDecl), ")\n"]
+{-# LINE 279 "Foreign/Java/Bindings/Java2Haskell.hss" #-}
+} in __) undefined)
+          where parentClass = info Map.! parent
+                modName = classModName parentClass
+                qualifiedName = modName ++ "__." ++ (tyclTName $ takeClassName modName)
+
+
diff --git a/dist/build/Foreign/Java/Bindings/Support.hs b/dist/build/Foreign/Java/Bindings/Support.hs
new file mode 100644
--- /dev/null
+++ b/dist/build/Foreign/Java/Bindings/Support.hs
@@ -0,0 +1,357 @@
+#line 1 "src/Foreign/Java/Bindings/Support.cpphs"
+{-# LANGUAGE Haskell2010
+    , TypeFamilies
+    , FlexibleContexts
+    , FlexibleInstances
+    , TypeSynonymInstances
+ #-}
+{-# OPTIONS
+    -Wall
+ #-}
+
+-- |
+-- Module       : Foreign.Java.Bindings.Support
+-- Copyright    : (c) Julian Fleischer 2013
+-- License      : MIT (See LICENSE file in cabal package)
+--
+-- Maintainer   : julian.fleischer@fu-berlin.de
+-- Stability    : experimental
+-- Portability  : non-portable (TypeFamilies)
+--
+-- This module provides type classes and instances for
+-- supporting the high level bindings. This module should
+-- not be imported directly.
+module Foreign.Java.Bindings.Support where
+
+import Control.Monad.State hiding (void)
+
+import Data.Int
+import Data.Word
+import Data.Maybe
+
+import Foreign.Ptr
+import Foreign.ForeignPtr
+import Foreign.C.Types
+
+import Foreign.Java
+import Foreign.Java.JavaMonad
+import Foreign.Java.Types as T
+import qualified Foreign.Java.JNI.Safe as JNI
+import qualified Foreign.Java.JNI.Types as Core
+
+
+---------------
+-- Utilities --
+---------------
+
+
+object' :: String -> Q
+object' = T.object'
+
+
+------------------------------
+-- Primitive argument types --
+------------------------------
+
+class JBoolean a  where toBoolean :: a -> Java Bool
+class JChar a     where toChar    :: a -> Java Word16
+class JByte a     where toByte    :: a -> Java Int8
+class JShort a    where toShort   :: a -> Java Int16
+class JInt a      where toInt     :: a -> Java Int32
+class JLong a     where toLong    :: a -> Java Int64
+class JFloat a    where toFloat   :: a -> Java Float
+class JDouble a   where toDouble  :: a -> Java Double
+
+
+instance JBoolean Bool   where toBoolean = return
+
+instance JChar Char      where toChar = return . fromIntegral . fromEnum
+instance JChar Int8      where toChar = return . fromIntegral
+instance JChar Word16    where toChar = return
+
+instance JByte Int8      where toByte = return
+
+instance JShort Int8     where toShort = return . fromIntegral
+instance JShort Word8    where toShort = return . fromIntegral
+instance JShort Int16    where toShort = return
+
+instance JInt Int        where toInt = return . fromIntegral
+instance JInt Int8       where toInt = return . fromIntegral
+instance JInt Word8      where toInt = return . fromIntegral
+instance JInt Int16      where toInt = return . fromIntegral
+instance JInt Word16     where toInt = return . fromIntegral
+instance JInt Int32      where toInt = return
+
+instance JLong Int       where toLong = return . fromIntegral
+instance JLong Int8      where toLong = return . fromIntegral
+instance JLong Word8     where toLong = return . fromIntegral
+instance JLong Int16     where toLong = return . fromIntegral
+instance JLong Word16    where toLong = return . fromIntegral
+instance JLong Int32     where toLong = return . fromIntegral
+instance JLong Word32    where toLong = return . fromIntegral
+instance JLong Int64     where toLong = return
+
+instance JFloat CFloat   where toFloat = return . realToFrac
+instance JFloat Float    where toFloat = return
+
+instance JDouble CDouble where toDouble = return . realToFrac
+instance JDouble Double  where toDouble = return
+
+
+--------------------------
+-- Array argument types --
+--------------------------
+
+class Array a where
+    asMaybeArrayObject :: a -> Java (Maybe JObject)
+
+
+----------------------------
+-- Primitive result types --
+----------------------------
+
+
+
+
+
+
+
+
+
+
+
+-- | The result of a function call that is of type @boolean@.
+class BooleanResult m where {        toBooleanResult :: Either JThrowable Bool -> Java m }    ;    instance BooleanResult Bool where {        toBooleanResult = either (\exc -> toString exc >>= fail) return }    ;    instance BooleanResult (Either JThrowable Bool) where {        toBooleanResult = return }
+-- | The result of a function call that is of type @char@.
+class CharResult m where {        toCharResult :: Either JThrowable Word16 -> Java m }    ;    instance CharResult Word16 where {        toCharResult = either (\exc -> toString exc >>= fail) return }    ;    instance CharResult (Either JThrowable Word16) where {        toCharResult = return }
+-- | The result of a function call that is of type @byte@.
+class ByteResult m where {        toByteResult :: Either JThrowable Int8 -> Java m }    ;    instance ByteResult Int8 where {        toByteResult = either (\exc -> toString exc >>= fail) return }    ;    instance ByteResult (Either JThrowable Int8) where {        toByteResult = return }
+-- | The result of a function call that is of type @short@.
+class ShortResult m where {        toShortResult :: Either JThrowable Int16 -> Java m }    ;    instance ShortResult Int16 where {        toShortResult = either (\exc -> toString exc >>= fail) return }    ;    instance ShortResult (Either JThrowable Int16) where {        toShortResult = return }
+-- | The result of a function call that is of type @int@.
+class IntResult m where {        toIntResult :: Either JThrowable Int32 -> Java m }    ;    instance IntResult Int32 where {        toIntResult = either (\exc -> toString exc >>= fail) return }    ;    instance IntResult (Either JThrowable Int32) where {        toIntResult = return }
+-- | The result of a function call that is of type @long@.
+class LongResult m where {        toLongResult :: Either JThrowable Int64 -> Java m }    ;    instance LongResult Int64 where {        toLongResult = either (\exc -> toString exc >>= fail) return }    ;    instance LongResult (Either JThrowable Int64) where {        toLongResult = return }
+-- | The result of a function call that is of type @float@.
+class FloatResult m where {        toFloatResult :: Either JThrowable Float -> Java m }    ;    instance FloatResult Float where {        toFloatResult = either (\exc -> toString exc >>= fail) return }    ;    instance FloatResult (Either JThrowable Float) where {        toFloatResult = return }
+-- | The result of a function call that is of type @double@.
+class DoubleResult m where {        toDoubleResult :: Either JThrowable Double -> Java m }    ;    instance DoubleResult Double where {        toDoubleResult = either (\exc -> toString exc >>= fail) return }    ;    instance DoubleResult (Either JThrowable Double) where {        toDoubleResult = return }
+
+-- | The result of a function call that is of type @void@.
+class VoidResult m where
+    toVoidResult :: Either JThrowable () -> Java m
+    
+instance VoidResult () where
+    toVoidResult = either (\exc -> toString exc >>= fail) return
+
+instance VoidResult (Either JThrowable ()) where
+    toVoidResult = return
+    
+instance VoidResult (Maybe JThrowable) where
+    toVoidResult = return . either Just (const Nothing)
+
+
+------------------------
+-- Array result types --
+------------------------
+
+-- | An array result of a function call.
+class JavaArray (ArrayResultType m) (ArrayResultComponent m) => ArrayResult m where
+    -- | The JVM machine type of the components of the array.
+    type ArrayResultType m
+
+    -- | The type of the component of the array as returned by
+    -- the low level JNI call.
+    type ArrayResultComponent m
+
+    -- | Convert the array to a sophisticated type.
+    toArrayResult :: Either JThrowable (Maybe (JArray (ArrayResultType m))) -> Java m
+
+instance ArrayResult a => ArrayResult (Either JThrowable a) where
+    type ArrayResultType (Either JThrowable a) = ArrayResultType a
+    type ArrayResultComponent (Either JThrowable a) = ArrayResultComponent a
+
+    toArrayResult = either (return . Left) (toArrayResult . Right)
+
+
+
+
+
+
+
+
+
+instance ArrayResult [Bool] where {        type ArrayResultType [Bool] = T.Z ;        type ArrayResultComponent [Bool] = Bool ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+instance ArrayResult [Word16] where {        type ArrayResultType [Word16] = T.C ;        type ArrayResultComponent [Word16] = Word16 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+instance ArrayResult [Int8] where {        type ArrayResultType [Int8] = T.B ;        type ArrayResultComponent [Int8] = Int8 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+instance ArrayResult [Int16] where {        type ArrayResultType [Int16] = T.S ;        type ArrayResultComponent [Int16] = Int16 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+instance ArrayResult [Int32] where {        type ArrayResultType [Int32] = T.I ;        type ArrayResultComponent [Int32] = Int32 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+instance ArrayResult [Int64] where {        type ArrayResultType [Int64] = T.J ;        type ArrayResultComponent [Int64] = Int64 ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+instance ArrayResult [Float] where {        type ArrayResultType [Float] = T.F ;        type ArrayResultComponent [Float] = Float ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+instance ArrayResult [Double] where {        type ArrayResultType [Double] = T.D ;        type ArrayResultComponent [Double] = Double ;                toArrayResult = either (\exc -> toString exc >>= fail)                                (maybe (return []) toList) }
+
+
+instance ArrayResult [Char] where
+    type ArrayResultType [Char] = T.C
+    type ArrayResultComponent [Char] = Word16
+
+    toArrayResult = either (\exc -> toString exc >>= fail)
+                           (maybe (return [])
+                                  (fmap (map (toEnum . fromIntegral)) . toList))
+
+instance ArrayResult [String] where
+    type ArrayResultType [String] = T.L
+    type ArrayResultComponent [String] = Maybe JObject
+
+    toArrayResult =
+        either (\exc -> toString exc >>= fail)
+               (maybe (return [])
+                      (\arr -> toList arr >>= mapM (maybe (return "") toString)))
+
+
+
+-----------------------
+-- All other objects --
+-----------------------
+
+
+-- | The result of a function call that is of type @object@.
+class ObjectResult m where
+    -- | 
+    toObjectResult :: Either JThrowable (Maybe JObject) -> Java m
+
+instance UnsafeCast a => ObjectResult (Value JThrowable a) where
+    toObjectResult = either (return . Fail)
+                            (maybe (return NoValue)
+                                   (fmap Value . unsafeFromJObject))
+
+instance UnsafeCast a => ObjectResult (Either (Maybe JThrowable) a) where
+    toObjectResult = either (return . Left . Just)
+                            (maybe (return (Left Nothing))
+                                   (fmap Right . unsafeFromJObject))
+
+instance UnsafeCast a => ObjectResult (Either JThrowable (Maybe a)) where
+    toObjectResult = either (return . Left)
+                            (fmap Right . maybe (return Nothing)
+                                                (fmap Just . unsafeFromJObject))
+
+instance UnsafeCast a => ObjectResult (Maybe a) where
+    toObjectResult = either (\exc -> toString exc >>= fail)
+                            (maybe (return Nothing)
+                                   (fmap Just . unsafeFromJObject))
+
+instance ObjectResult [Char] where
+    toObjectResult = either (\exc -> toString exc >>= fail)
+                            (maybe (return "null") toString)
+
+
+---------------------------------------------------
+-- Advanced features (Callbacks, Subtyping, ...) --
+---------------------------------------------------
+
+
+-- | A convenient alternative to 'isInstanceOf'.
+--
+-- Minimal complete definition: 'coerce' or 'whenInstanceOf'.
+class InstanceOf a where
+    type CoercedType a
+
+    -- | Check if the object of type @a@ is an instance
+    -- of the type represented by @b@. 
+    instanceOf :: JavaObject o => o -> a -> Java Bool
+
+    -- | Check if the object of type @a@ is an instance
+    -- of the type @c@, represented by @b@. If so, it will coerce
+    -- the object of type @a@ and pass it to the given action.
+    --
+    -- If @a@ was an instance of @c@ (where @c@ is represented
+    -- by @b@) this function will return @'Just' d@, where @d@ is
+    -- the result of the optional computation. If not, 'Nothing'
+    -- is returned.
+    whenInstanceOf :: JavaObject o => o -> a -> (CoercedType a -> Java d) -> Java (Maybe d)
+
+    -- | Coerces the given object of type @a@ to an object of
+    -- @c@, where @c@ is represented by a value of type @b@.
+    -- Returns @'Nothing'@ if this is not possible.
+    coerce :: JavaObject o => o -> a -> Java (Maybe (CoercedType a))
+
+    instanceOf o t =
+        whenInstanceOf o t (return . const ())
+            >>= return . maybe False (const True)
+
+    whenInstanceOf o t a =
+        coerce o t >>= maybe (return Nothing) (fmap Just . a)
+
+    coerce o t = whenInstanceOf o t return
+
+-- | For INTERNAL use only. Is however not in a hidden module,
+-- so that other libraries can link against it.
+class UnsafeCast a where
+    -- | For INTERNAL use only. Do not use yourself.
+    unsafeFromJObject :: JObject -> Java a
+
+
+
+---------------
+-- Callbacks --
+---------------
+
+
+registerCallbacks :: Core.JClass -> Java Bool
+-- ^ Yepp. Register callbacks. Do it.
+registerCallbacks (Core.JClass ptr) = do
+    vm <- getVM
+    io $ withForeignPtr ptr $ \clazz -> JNI.registerCallbacks vm clazz
+
+
+type WrappedFun = Ptr Core.JVM
+               -> Ptr Core.JObjectRef
+               -> Ptr Core.JObjectRef
+               -> Ptr Core.JObjectRef
+               -> IO (Ptr Core.JObjectRef)
+
+
+runJava_ :: Ptr Core.JVM -> Java a -> IO a
+runJava_ vm f = runStateT (_runJava f) (newJVMState vm) >>= return . fst
+
+foreign import ccall safe "wrapper"
+    wrap_ :: WrappedFun -> IO (FunPtr WrappedFun)
+
+foreign export ccall freeFunPtr :: FunPtr WrappedFun -> IO ()
+
+freeFunPtr :: FunPtr WrappedFun -> IO ()
+freeFunPtr ptr = freeHaskellFunPtr ptr
+
+
+wrap :: Java () -> IO (FunPtr WrappedFun)
+wrap f = do
+
+    let func vm _self _method _args = do
+            runJava_ vm f
+            return nullPtr
+            
+    func' <- wrap_ func
+
+    return func'
+
+intify :: Java () -> IO Int64
+intify = fmap (fromIntegral . ptrToIntPtr . castFunPtrToPtr) . wrap
+
+
+sushimaki :: String -> Java () -> Java JObject
+sushimaki ifaceName func = do
+    iface <- getClass ifaceName >>= asObject . fromJust
+    (Just clazz) <- getClass "HFunction"
+    _success <- registerCallbacks clazz
+    makeFunction <- clazz `bindStaticMethod` "makeFunction"
+        ::= object "java.lang.Class" --> long --> object "java.lang.Object"
+    (Just impl) <- io (intify func) >>= makeFunction (Just iface)
+    return impl
+
+
+delete :: Core.JObject -> Java ()
+delete (Core.JObject ptr) = io $ do
+    finalizeForeignPtr ptr
+
+
+
diff --git a/dist/build/Foreign/Java/JNI/Safe.hs b/dist/build/Foreign/Java/JNI/Safe.hs
--- a/dist/build/Foreign/Java/JNI/Safe.hs
+++ b/dist/build/Foreign/Java/JNI/Safe.hs
@@ -47,18 +47,6 @@
 getConstructorID,
 newObject,
 
--- ** Array creation
-
-newBooleanArray,
-newCharArray,
-newLongArray,
-newIntArray,
-newShortArray,
-newByteArray,
-newFloatArray,
-newDoubleArray,
-newObjectArray,
-
 -- * Method access
 
 JStaticMethodID,
@@ -224,11 +212,6 @@
 setLibjvmPath,
 registerCallbacks,
 
--- * Primitive types
-
-Z (Z), C (C), B (B), S (S), I (I), J (J),
-D (D), F (F), L (L), V (V), A (A), X (X),
-
 -- * Workarounds for certain platforms
 
 runCocoaMain
@@ -534,33 +517,6 @@
 foreign import ccall safe "ffijni.h setJValueString"
     setJValueString :: Ptr JVM -> Ptr JValues -> CInt -> CString -> IO ()
 
-foreign import ccall safe "ffijni.h newBooleanArray"
-    newBooleanArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newCharArray"
-    newCharArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newLongArray"
-    newLongArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newIntArray"
-    newIntArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newShortArray"
-    newShortArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newByteArray"
-    newByteArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newFloatArray"
-    newFloatArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newDoubleArray"
-    newDoubleArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall safe "ffijni.h newObjectArray"
-    newObjectArray :: Ptr JVM -> Int32 -> Ptr JClass -> Ptr JObjectRef
-
 foreign import ccall safe "ffijni.h newJString"
     newJString :: Ptr JVM -> CString -> IO (Ptr JObjectRef)
 
@@ -675,7 +631,7 @@
 foreign import ccall safe "ffijni.h getDebugStatus"
     getDebugStatus :: IO Bool
 
-foreign import ccall safe "ffijni.h setDebugStatus"
+foreign import ccall safe "ffijni.g setDebugStatus"
     setDebugStatus :: Bool -> IO ()
 
 foreign import ccall safe "ffijni.h runCocoaMain"
diff --git a/dist/build/Foreign/Java/JNI/Unsafe.hs b/dist/build/Foreign/Java/JNI/Unsafe.hs
--- a/dist/build/Foreign/Java/JNI/Unsafe.hs
+++ b/dist/build/Foreign/Java/JNI/Unsafe.hs
@@ -47,18 +47,6 @@
 getConstructorID,
 newObject,
 
--- ** Array creation
-
-newBooleanArray,
-newCharArray,
-newLongArray,
-newIntArray,
-newShortArray,
-newByteArray,
-newFloatArray,
-newDoubleArray,
-newObjectArray,
-
 -- * Method access
 
 JStaticMethodID,
@@ -224,11 +212,6 @@
 setLibjvmPath,
 registerCallbacks,
 
--- * Primitive types
-
-Z (Z), C (C), B (B), S (S), I (I), J (J),
-D (D), F (F), L (L), V (V), A (A), X (X),
-
 -- * Workarounds for certain platforms
 
 runCocoaMain
@@ -534,33 +517,6 @@
 foreign import ccall unsafe "ffijni.h setJValueString"
     setJValueString :: Ptr JVM -> Ptr JValues -> CInt -> CString -> IO ()
 
-foreign import ccall unsafe "ffijni.h newBooleanArray"
-    newBooleanArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newCharArray"
-    newCharArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newLongArray"
-    newLongArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newIntArray"
-    newIntArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newShortArray"
-    newShortArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newByteArray"
-    newByteArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newFloatArray"
-    newFloatArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newDoubleArray"
-    newDoubleArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall unsafe "ffijni.h newObjectArray"
-    newObjectArray :: Ptr JVM -> Int32 -> Ptr JClass -> Ptr JObjectRef
-
 foreign import ccall unsafe "ffijni.h newJString"
     newJString :: Ptr JVM -> CString -> IO (Ptr JObjectRef)
 
@@ -675,7 +631,7 @@
 foreign import ccall unsafe "ffijni.h getDebugStatus"
     getDebugStatus :: IO Bool
 
-foreign import ccall unsafe "ffijni.h setDebugStatus"
+foreign import ccall unsafe "ffijni.g setDebugStatus"
     setDebugStatus :: Bool -> IO ()
 
 foreign import ccall unsafe "ffijni.h runCocoaMain"
diff --git a/dist/build/h2js/h2js-tmp/Main.hs b/dist/build/h2js/h2js-tmp/Main.hs
new file mode 100644
--- /dev/null
+++ b/dist/build/h2js/h2js-tmp/Main.hs
@@ -0,0 +1,97 @@
+{-# LANGUAGE Haskell2010
+ #-}
+
+module Main where
+
+import Options
+import Haskell2Java
+
+import Foreign.Java.Bindings
+
+import System.Console.GetOpt
+import System.Environment (getArgs, getProgName)
+
+import Data.Maybe
+import Data.NamedRecord
+import Data.List
+import Data.List.Split
+import Data.Word
+
+import Text.Printf
+
+versionInfo = "Java <-> Haskell Bindings Generator"
+
+-- | The flags (needed for the options list / GetOpt).
+data Flag = Help
+          | Version
+          | Classpath [String]
+          | SearchDepth Word32
+          | TargetDirectory String
+          | CompleteSE6
+          | Verbose
+
+-- | The Command line options as fed to the GetOpt parser.
+options = [
+    Option "h" ["help"] (NoArg Help)
+        "Print this help text.",
+
+    Option "V" ["version"] (NoArg Version)
+        "Print version information.",
+
+    Option "c" ["classpath"] (ReqArg readClasspath "")
+        "The Java classpath to be used.",
+
+    Option "d" ["search-depth"] (ReqArg readSearchDepth "")
+        "The maximum search depth for dependent Java classes.",
+
+    Option "v" ["--verbose"] (NoArg Verbose)
+        "Verbose output, prints extra diagnostic information.",
+
+    Option "X" [] (NoArg CompleteSE6)
+        "Completely translate Java SE 6"
+
+ ] where
+    readClasspath = Classpath . splitOneOf ":;,"
+    readSearchDepth = SearchDepth . read
+
+parseArgs :: IO (Either (Options, [String]) [String])
+-- ^ Parse command line arguments with the help of the GetOpt library.
+parseArgs = do
+    (opts, args, errs) <- getArgs >>= return . getOpt Permute options
+    if null errs
+        then return $ Left  (parseOpts newOptions opts, args)
+        else return $ Right errs
+  where
+    parseOpts opts [] = opts
+    parseOpts opts (x:xs) = flip parseOpts xs $
+        case x of
+            Help ->          opts `set` optShowHelp    := True
+            Version ->       opts `set` optShowVersion := True
+            Verbose ->       opts `set` optVerbose     := True
+            CompleteSE6 ->   opts `set` optCompleteSE6 := True
+            Classpath cp ->  opts `set` optClasspath   := cp
+            SearchDepth d -> opts `set` optSearchDepth := d
+
+main :: IO ()
+-- ^ main: parseArgs and either 'run' or show errors.
+main = parseArgs >>= either (uncurry run) (mapM_ putStr)
+
+run :: Options -> [String] -> IO ()
+-- ^ The actual main function.
+run opts args
+    | opts `get` optShowHelp = do
+        progName <- getProgName
+        putStrLn (usageInfo ((\_ -> let { __ = 
+{-# LINE 84 "Main.hss" #-}
+concat ["", (versionInfo), "\n\nUsage: ", (progName), " [options] command [files...]\n\nUse `", (progName), " help' for information about commands.\n"]
+{-# LINE 90 "Main.hss" #-}
+} in __) undefined) options)
+
+    | opts `get` optShowVersion = putStrLn versionInfo
+
+    | otherwise = getProgName >>= \progName -> putStr ((\_ -> let { __ = 
+{-# LINE 94 "Main.hss" #-}
+concat ["No command given. Use `", (progName), " help' for help.\n"]
+{-# LINE 96 "Main.hss" #-}
+} in __) undefined)
+
diff --git a/dist/build/j2hs/j2hs-tmp/Java2Haskell.hs b/dist/build/j2hs/j2hs-tmp/Java2Haskell.hs
new file mode 100644
--- /dev/null
+++ b/dist/build/j2hs/j2hs-tmp/Java2Haskell.hs
@@ -0,0 +1,238 @@
+{-# LANGUAGE Haskell2010
+ #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-missing-signatures
+    -fno-warn-name-shadowing
+ #-}
+
+{- | The @j2hs@ command - create Haskell bindings for Java classes.
+    
+-}
+module Java2Haskell where
+
+import Prelude hiding (print)
+
+import Options
+--import Common
+
+import Foreign.Java
+import Foreign.Java.Bindings
+import Foreign.Java.Bindings.JavaTypes
+import Foreign.Java.Utils
+import Foreign.Java.IO
+
+import Data.NamedRecord
+import qualified Data.List as L
+import Data.Strings
+
+import Data.Generics
+
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+import qualified Data.MultiMap as MultiMap
+import qualified Data.Bimap as Bimap
+
+import Control.Monad
+
+import System.Directory
+import System.FilePath
+import System.IO hiding (print)
+import System.Exit
+
+
+-- Following 20 lines: Functions for managing a Bimap
+-- such that it works with case insensitive string.
+--
+-- TODO: Factor this out `plus` use the case-insensitive package.
+--       Those functions x... should be made into their own
+--       datatype (Something like CISBimap or
+--       BimapWithGenericComparisonFunction or ...)
+
+newtype CaseInsensitiveString = CIS String
+
+instance Eq CaseInsensitiveString where
+    (CIS a) == (CIS b) = strToLower a == strToLower b
+
+instance Ord CaseInsensitiveString where
+    (CIS a) <= (CIS b) = strToLower a <= strToLower b
+
+xToString (CIS s) = s
+
+xEmpty      = Bimap.empty
+xInsert k v = Bimap.insert (CIS k) (CIS v)
+xMemberR k  = Bimap.memberR (CIS k)
+xGet m      = xToString . (Bimap.!) m . CIS
+xFromList   = Bimap.fromList . map (\(a, b) -> (CIS a, CIS b))
+xToList     = map (\(a, b) -> (xToString a, xToString b)) . Bimap.toList
+xKeysR      = map xToString . Bimap.keysR
+xKeys       = map xToString . Bimap.keys
+xSize       = Bimap.size
+
+-- end todo
+
+
+ifVerbose opts = when (opts `get` optVerbose) . liftIO . putStr
+
+j2hs :: Options -> [String] -> IO ()
+j2hs opts args = do
+
+    classpath <- mapM canonicalizePath $ opts `get` optClasspath
+    targetDir <- return (opts `get` optTargetDirectory)
+
+    let classpath' = concat $ L.intersperse ":" classpath
+        indent     = ("  " ++)
+
+    ifVerbose opts ((\_ -> let { __ = 
+{-# LINE 86 "Java2Haskell.hss" #-}
+concat ["Classpath:\n", (concatMap (\x -> "  " ++ x ++ "\n") (classpath)), ""]
+{-# LINE 88 "Java2Haskell.hss" #-}
+} in __) undefined)
+    print "Initializing JVM..."
+    initJava [((\_ -> let { __ = 
+{-# LINE 90 "Java2Haskell.hss" #-}
+concat ["-Djava.class.path=", (classpath'), ""]
+{-# LINE 90 "Java2Haskell.hss" #-}
+} in __) undefined)]
+    println " Done."
+    
+    unless (null args) $ runJava $ do
+        io $ do
+            ifVerbose opts ((\_ -> let { __ = 
+{-# LINE 95 "Java2Haskell.hss" #-}
+concat ["Target Directory:\n  ", (targetDir), "\n"]
+{-# LINE 98 "Java2Haskell.hss" #-}
+} in __) undefined)
+            createDirectoryIfMissing True targetDir
+            setCurrentDirectory targetDir
+            
+        ifVerbose opts ((\_ -> let { __ = 
+{-# LINE 102 "Java2Haskell.hss" #-}
+concat ["Looking for Java classes:\n", (concatMap (\x -> "  " ++ x ++ "\n") args), ""]
+{-# LINE 104 "Java2Haskell.hss" #-}
+} in __) undefined)
+
+        -- Gather all classes that need to be translated
+        print "Looking up classes..."
+        classes  <- findJavaClasses (opts `get` optSearchDepth) args
+
+        println ((\_ -> let { __ = 
+{-# LINE 110 "Java2Haskell.hss" #-}
+concat [" ", (show $ length classes), " found."]
+{-# LINE 110 "Java2Haskell.hss" #-}
+} in __) undefined)
+        ifVerbose opts $
+            unlines (map indent classes)
+
+        -- Calculate the Haskell module names for packages and classes
+        let packages = Set.toList $ Set.fromList
+                     $ map (maybe "" id . takePackageName) classes
+
+            -- temporary class names
+            classModules_ = foldr (uncurry g) xEmpty $ map f classes
+              where f x = (x, makeClassModuleName x)
+                    g clazzName modName all = xInsert clazzName newName all
+                      where newName = head $ dropWhile (`xMemberR` all)
+                                           $ iterate (++ "_") modName
+
+            -- package names.
+            -- This func keeps in mind that package names must not clash with class names.
+            packageModules = foldr (uncurry g) xEmpty $ map f packages
+              where f x = (x, makePackageModuleName x)
+                    g pkgName modName all = xInsert pkgName newName all
+                      where newName = head $ dropWhile (\n -> n `xMemberR` classModules_
+                                                           || n `xMemberR` all)
+                                           $ iterate (++ "Package") modName
+
+            -- finally the class names.
+            -- This func keeps in mind that the package names might have been augmented
+            -- before. i.e. the package java.awt.image will be Java.Awt.ImagePackage now,
+            -- thus all classes inside the package have their full name changed too.
+            classModules = Map.fromList $ map f $ xToList classModules_
+              where f (clazzName, moduleName)
+                        = (clazzName, joinClassName (newPackageName, classModuleName))
+                      where classModuleName = takeClassName moduleName
+                            packageName = maybe "" id $ takePackageName clazzName
+                            newPackageName = packageModules `xGet` packageName
+
+            -- A mapping form packages to classes
+            classesByPackage = MultiMap.fromList
+                             $ map (\clazz -> (fst $ splitClassName clazz, clazz)) classes
+
+            -- A list of all modules
+            allModules = xKeysR packageModules ++ Map.elems classModules
+
+            -- The list of hidden modules
+            hiddenModules = map (++ "__") $ Map.elems classModules
+
+        -- Gather information about classes via Reflection
+        print ((\_ -> let { __ = 
+{-# LINE 156 "Java2Haskell.hss" #-}
+concat ["Gathering refection information..."]
+{-# LINE 156 "Java2Haskell.hss" #-}
+} in __) undefined)
+        let classNames = Map.keys classModules
+            updName name clazz = (name, clazz { classModName = classModules Map.! name })
+        classInfo <- Map.fromList `fmap` map (uncurry updName)
+                                  `fmap` zip classNames
+                                  `fmap` everywhere (mkT (\(TyVar v) -> TyVar ('_':v)))
+                                  `fmap` reflectJavaClasses classNames
+        println " Done."
+
+        when (opts `get` optOnlyReflect) $ io $ do
+            mapM_ println $ Map.elems classInfo
+            exitSuccess
+
+        println ((\_ -> let { __ = 
+{-# LINE 169 "Java2Haskell.hss" #-}
+concat ["Generating modules for ", (show $ Map.size classModules), " classes in ", (show $ xSize packageModules), " packages..."]
+{-# LINE 170 "Java2Haskell.hss" #-}
+} in __) undefined)
+
+        -- Create all the package files.
+        -- These contain the Java classes as Haskell types.
+        forM_ (xToList packageModules) $ \(packageName, packageMod) -> do
+            let dirName = strJoin [pathSeparator] (strSplitAll "." packageMod)
+
+            -- Create the directory for the package
+            io $ do 
+                createDirectoryIfMissing True dirName
+
+                let classes = map (classInfo Map.!)
+                                  (MultiMap.lookup packageName classesByPackage)
+
+                -- Create the Haskell module file for the Java package
+                file <- openFile (dirName ++ ".hs") WriteMode
+                hPutStrLn file
+                  $ printJavaPackageModule packageName packageMod classInfo classes
+                hClose file
+
+        -- Create all the class files.
+        -- These contain the java methods as Haskell functions.
+        forM_ (Map.toList classModules) $ \(clazzName, clazzMod) -> do
+            let fileName = strJoin [pathSeparator] (strSplitAll "." clazzMod)
+                clazz = classInfo Map.! clazzName
+
+            io $ do
+                -- Create the Haskell module file for the Java class.
+                file <- openFile (fileName ++ ".hs") WriteMode
+                hPutStrLn file $ printJavaClassModule clazz clazzMod classInfo
+                hClose file
+
+                -- Create the *hidden* Haskell module file for the Java class.
+                file <- openFile (fileName ++ "__.hs") WriteMode
+                hPutStrLn file $ printJavaClassModule' clazz clazzMod classInfo
+                hClose file
+
+        -- write Cabal file
+        when (opts `get` optCabalProject) $ io $ do
+            cabalFile <- openFile ((opts `get` optProjectName) ++ ".cabal") WriteMode
+            hPutStrLn cabalFile ((\_ -> let { __ = 
+{-# LINE 210 "Java2Haskell.hss" #-}
+concat ["name:           ", (opts `get` optProjectName), "\nversion:        ", (opts `get` optProjectVersion), "\ncabal-version:  >= 1.8\nbuild-type:     Simple\n\nLibrary {\n build-depends:\n  base >= 4 && < 5,\n  java-bridge\n exposed-modules:\n  ", (strJoin ",\n  " allModules), "\n other-modules:\n  ", (strJoin ",\n  " hiddenModules), " }\n"]
+{-# LINE 224 "Java2Haskell.hss" #-}
+} in __) undefined)
+            hClose cabalFile
+
+    return ()
+
diff --git a/dist/build/j2hs/j2hs-tmp/Main.hs b/dist/build/j2hs/j2hs-tmp/Main.hs
new file mode 100644
--- /dev/null
+++ b/dist/build/j2hs/j2hs-tmp/Main.hs
@@ -0,0 +1,131 @@
+{-# LANGUAGE Haskell2010
+ #-}
+
+module Main where
+
+import Options
+import Java2Haskell
+
+import Foreign.Java.Bindings
+import Foreign.Java.Utils
+import Foreign.Java.JNI (javaBridgeVersion)
+
+import System.Console.GetOpt
+import System.Environment (getArgs, getProgName)
+
+import Data.Maybe
+import Data.NamedRecord
+import Data.List
+import Data.List.Split
+import Data.Word
+
+import Text.Printf
+
+versionInfo = ((\_ -> let { __ = 
+{-# LINE 24 "Main.hss" #-}
+concat ["Java <-> Haskell Bindings Generator (using java-bridge ", (javaBridgeVersion), ")"]
+{-# LINE 25 "Main.hss" #-}
+} in __) undefined)
+
+-- | The flags (needed for the options list / GetOpt).
+data Flag = Help
+          | Version
+          | Packages [String]
+          | Classpath [String]
+          | SearchDepth Word32
+          | TargetDirectory String
+          | CompleteSE6
+          | OnlyReflect
+          | Filtered
+          | Verbose
+
+-- | The Command line options as fed to the GetOpt parser.
+options = [
+    Option "h" ["help"] (NoArg Help)
+        "Print this help text.",
+
+    Option "V" ["version"] (NoArg Version)
+        "Print version information.",
+
+    Option "c" ["classpath"] (ReqArg readClasspath "")
+        "The Java classpath to be used.",
+
+    Option "P" ["packages"] (ReqArg readPackages "")
+        "The packages to translate.",
+
+    Option "d" ["search-depth"] (ReqArg readSearchDepth "")
+        "The maximum search depth for dependent Java classes.",
+
+    Option "v" ["verbose"] (NoArg Verbose)
+        "Verbose output, prints extra diagnostic information.",
+
+    Option "R" ["reflect"] (NoArg OnlyReflect)
+        "Only reflect the given java files (mainly for debugging purposes).",
+
+    Option "X" [] (NoArg CompleteSE6)
+        "Completely translate Java SE.",
+
+    Option "F" [] (NoArg Filtered)
+        "Only translate a subset of the Java SE.",
+
+    Option "t" ["target-directory"] (ReqArg TargetDirectory "")
+        "The target directory for generated source files."
+
+ ] where
+    readPackages = Packages . splitOneOf ":;,"
+    readClasspath = Classpath . splitOneOf ":;,"
+    readSearchDepth = SearchDepth . read
+
+parseArgs :: IO (Either (Options, [String]) [String])
+-- ^ Parse command line arguments with the help of the GetOpt library.
+parseArgs = do
+    (opts, args, errs) <- getArgs >>= return . getOpt Permute options
+    if null errs
+        then return $ Left  (parseOpts newOptions opts, args)
+        else return $ Right errs
+  where
+    parseOpts opts [] = opts
+    parseOpts opts (x:xs) = flip parseOpts xs $
+        case x of
+            Help              -> opts `set` optShowHelp        := True
+            Version           -> opts `set` optShowVersion     := True
+            Verbose           -> opts `set` optVerbose         := True
+            Filtered          -> opts `set` optFiltered        := True
+            CompleteSE6       -> opts `set` optCompleteSE6     := True
+            OnlyReflect       -> opts `set` optOnlyReflect     := True
+            Classpath cp      -> opts `set` optClasspath       := cp
+            Packages pkgs     -> opts `set` optPackages        := pkgs
+            SearchDepth d     -> opts `set` optSearchDepth     := d
+            TargetDirectory t -> opts `set` optTargetDirectory := t
+
+main :: IO ()
+-- ^ main: parseArgs and either 'run' or show errors.
+main = parseArgs >>= either (uncurry run) (mapM_ putStr)
+
+run :: Options -> [String] -> IO ()
+-- ^ The actual main function.
+run opts args
+    | opts `get` optShowHelp = do
+        progName <- getProgName
+        putStrLn (usageInfo ((\_ -> let { __ = 
+{-# LINE 107 "Main.hss" #-}
+concat ["", (versionInfo), "\n\nUsage: ", (progName), " [options] command [files...]\n\nUse `", (progName), " help' for information about commands.\n"]
+{-# LINE 113 "Main.hss" #-}
+} in __) undefined) options)
+
+    | opts `get` optShowVersion = putStrLn versionInfo
+    | opts `get` optCompleteSE6 =
+        if opts `get` optFiltered then j2hs opts (filter minimal  javaClassesSE6)
+                                  else j2hs opts (filter justJava javaClassesSE6)
+
+    | otherwise = getProgName >>= \progName -> putStr ((\_ -> let { __ = 
+{-# LINE 120 "Main.hss" #-}
+concat ["No command given. Use `", (progName), " help' for help.\n"]
+{-# LINE 122 "Main.hss" #-}
+} in __) undefined)
+  where
+    justJava = ("java" `isPrefixOf`)
+    minimal name = pkg `elem` (opts `get` optPackages)
+        where (pkg, _) = splitClassName name
+
+
diff --git a/examples/calculator/calculator.cabal b/examples/calculator/calculator.cabal
new file mode 100644
--- /dev/null
+++ b/examples/calculator/calculator.cabal
@@ -0,0 +1,22 @@
+Name:               calculator
+Version:            1.0
+Synopsis:           A simple calculator demoing the usage of Java/Swing from within Haskell
+Description:        A simple calculator demoing the usage of Java/Swing from within Haskell
+
+Category:           LaTeX
+Stability:          provisional
+License:            MIT
+License-File:       LICENSE
+Author:             Julian Fleischer <julian.fleischer@fu-berlin.de>
+Maintainer:         Julian Fleischer <julian.fleischer@fu-berlin.de>
+Build-Type:         Simple
+Cabal-Version:      >= 1.8
+
+Executable calculator
+    Hs-Source-Dirs:     src
+    Main-is:            calculator.hs
+
+    Build-Depends:      base >= 4.5 && < 5.0
+                        , java-bridge >= 0.20130507
+
+    Ghc-Options:        -threaded
diff --git a/examples/calculator/src/calculator.hs b/examples/calculator/src/calculator.hs
new file mode 100644
--- /dev/null
+++ b/examples/calculator/src/calculator.hs
@@ -0,0 +1,60 @@
+import Foreign.Java
+import Data.Maybe
+
+import Foreign.Java.Bindings.Support
+
+
+main :: IO ()
+main = runJavaGui $ do
+    
+    (Just jFrameClass)  <- getClass "javax.swing.JFrame"
+    (Just jButtonClass) <- getClass "javax.swing.JButton"
+    (Just jGridLayoutClass) <- getClass "java.awt.GridLayout"
+
+    setVisible   <- jFrameClass `bindMethod` "setVisible" ::= boolean --> void
+    addComponent <- jFrameClass `bindMethod` "add" ::= object "java.awt.Component"
+                                                   --> object "java.awt.Component"
+    setLocation  <- jFrameClass `bindMethod` "setLocationRelativeTo" ::= object "java.awt.Component"
+                                                                     --> void
+    setSize'     <- jFrameClass `bindMethod` "setSize" ::= int --> int --> void
+    let setSize obj (a, b) = setSize' obj a b
+    setLayout    <- jFrameClass `bindMethod` "setLayout" ::= object "java.awt.LayoutManager"
+                                                         --> void
+
+    addActionListener <- jButtonClass
+        `bindMethod` "addActionListener" ::= object "java.awt.event.ActionListener" --> void
+
+    (Just jButtonConstr)     <- getConstructor jButtonClass $ string
+    (Just jGridLayoutConstr) <- getConstructor jGridLayoutClass $ int --> int
+    
+    (Just jFrame) <- newObject jFrameClass
+    
+    newObjectFrom jGridLayoutConstr 4 4 >>= setLayout jFrame
+
+    buttons <- mapM (newObjectFrom jButtonConstr)
+                    [ "1", "2", "3", "*"
+                    , "4", "5", "6", "-"
+                    , "7", "8", "9", "·"
+                    , "C", "0", "=", "÷" ]
+    
+    mapM_ (addComponent jFrame) buttons
+
+    let action = do
+            io $ putStrLn "Let's have some fun!"
+
+    listener <- sushimaki "java.awt.event.ActionListener" action
+
+    mapM_ (flip addActionListener (Just listener) . fromJust) buttons
+
+    jFrame `setSize` (400, 300)
+    jFrame `setLocation` Nothing
+    jFrame `setVisible` True
+
+
+
+
+
+
+
+
+
diff --git a/examples/system-properties/Makefile b/examples/system-properties/Makefile
new file mode 100644
--- /dev/null
+++ b/examples/system-properties/Makefile
@@ -0,0 +1,9 @@
+all:
+	mkdir -p build
+	ghc --make system-properties.hs -odir build -hidir build -o system-properties
+
+clean:
+	rm -rf build system-properties
+
+.PHONY: clean all
+
diff --git a/examples/system-properties/system-properties.hs b/examples/system-properties/system-properties.hs
new file mode 100644
--- /dev/null
+++ b/examples/system-properties/system-properties.hs
@@ -0,0 +1,24 @@
+import Foreign.Java
+import Foreign.Java.Maybe
+import qualified Foreign.Java.JNI.Safe as JNI
+import Data.Maybe
+
+main = do
+    JNI.setDebugStatus True
+    runJava $ do
+        (Just system) <- getClass "java.lang.System"
+        getProperties <- system `bindStaticMethod` "getProperties" ::= object "java.util.Properties"
+
+        (Just hashtableClass) <- getClass "java.util.Hashtable"    
+        getEntrySet <- hashtableClass `bindMethod` "entrySet" ::= object "java.util.Set"
+
+        (Just setClass) <- getClass "java.util.Set"
+        toArray <- setClass `bindMethod` "toArray" ::= array (object "java.lang.Object")
+
+        (Just properties) <- getProperties
+        (Just entrySet) <- getEntrySet properties
+        toArray entrySet
+            >>= toList . fromJust
+            >>= mapM toString
+            >>= mapM (io . putStrLn)
+
diff --git a/hs2j/Common.hs b/hs2j/Common.hs
new file mode 100644
--- /dev/null
+++ b/hs2j/Common.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE Haskell2010 #-}
+
+module Common where
+
+import Options
+
+
diff --git a/hs2j/Haskell2Java.hs b/hs2j/Haskell2Java.hs
new file mode 100644
--- /dev/null
+++ b/hs2j/Haskell2Java.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE Haskell2010
+ #-}
+
+module Haskell2Java where
+
+import Options
+import Common
+
+hs2j :: Options -> [String] -> IO ()
+hs2j opts args = putStrLn "hs2j"
+
+
diff --git a/hs2j/Main.hss b/hs2j/Main.hss
new file mode 100644
--- /dev/null
+++ b/hs2j/Main.hss
@@ -0,0 +1,97 @@
+{-# LANGUAGE Haskell2010
+ #-}
+
+module Main where
+
+import Options
+import Haskell2Java
+
+import Foreign.Java.Bindings
+
+import System.Console.GetOpt
+import System.Environment (getArgs, getProgName)
+
+import Data.Maybe
+import Data.NamedRecord
+import Data.List
+import Data.List.Split
+import Data.Word
+
+import Text.Printf
+
+versionInfo = "Java <-> Haskell Bindings Generator"
+
+-- | The flags (needed for the options list / GetOpt).
+data Flag = Help
+          | Version
+          | Classpath [String]
+          | SearchDepth Word32
+          | TargetDirectory String
+          | CompleteSE6
+          | Verbose
+
+-- | The Command line options as fed to the GetOpt parser.
+options = [
+    Option "h" ["help"] (NoArg Help)
+        "Print this help text.",
+
+    Option "V" ["version"] (NoArg Version)
+        "Print version information.",
+
+    Option "c" ["classpath"] (ReqArg readClasspath "")
+        "The Java classpath to be used.",
+
+    Option "d" ["search-depth"] (ReqArg readSearchDepth "")
+        "The maximum search depth for dependent Java classes.",
+
+    Option "v" ["--verbose"] (NoArg Verbose)
+        "Verbose output, prints extra diagnostic information.",
+
+    Option "X" [] (NoArg CompleteSE6)
+        "Completely translate Java SE 6"
+
+ ] where
+    readClasspath = Classpath . splitOneOf ":;,"
+    readSearchDepth = SearchDepth . read
+
+parseArgs :: IO (Either (Options, [String]) [String])
+-- ^ Parse command line arguments with the help of the GetOpt library.
+parseArgs = do
+    (opts, args, errs) <- getArgs >>= return . getOpt Permute options
+    if null errs
+        then return $ Left  (parseOpts newOptions opts, args)
+        else return $ Right errs
+  where
+    parseOpts opts [] = opts
+    parseOpts opts (x:xs) = flip parseOpts xs $
+        case x of
+            Help ->          opts `set` optShowHelp    := True
+            Version ->       opts `set` optShowVersion := True
+            Verbose ->       opts `set` optVerbose     := True
+            CompleteSE6 ->   opts `set` optCompleteSE6 := True
+            Classpath cp ->  opts `set` optClasspath   := cp
+            SearchDepth d -> opts `set` optSearchDepth := d
+
+main :: IO ()
+-- ^ main: parseArgs and either 'run' or show errors.
+main = parseArgs >>= either (uncurry run) (mapM_ putStr)
+
+run :: Options -> [String] -> IO ()
+-- ^ The actual main function.
+run opts args
+    | opts `get` optShowHelp = do
+        progName <- getProgName
+        putStrLn (usageInfo """
+            #{versionInfo}
+            
+            Usage: #{progName} [options] command [files...]
+            
+            Use `#{progName} help' for information about commands.
+            """ options)
+
+    | opts `get` optShowVersion = putStrLn versionInfo
+
+    | otherwise = getProgName >>= \progName -> putStr """
+        No command given. Use `#{progName} help' for help.
+        """
+
diff --git a/hs2j/Options.hs b/hs2j/Options.hs
new file mode 100644
--- /dev/null
+++ b/hs2j/Options.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE Haskell2010
+    , TemplateHaskell
+ #-}
+
+module Options where
+
+import Data.Name
+import Data.NamedRecord
+import Data.Word
+
+-- The options as used in the application later on.
+-- This is a named record, see Data.NamedRecord for
+-- more information.
+record' "Options"
+    `has` "optShowHelp" := False
+    `has` "optShowVersion" := False
+    `has` "optClasspath" := ["."]
+    `has` "optSearchDepth" := (100 :: Word32)
+    `has` "optTargetDirectory" := "bindings"
+    `has` "optVerbose" := False
+    `has` "optCompleteSE6" := False
+
+
diff --git a/include/jni.h b/include/jni.h
deleted file mode 100644
--- a/include/jni.h
+++ /dev/null
@@ -1,714 +0,0 @@
-#ifndef _JNI_H_
-#define _JNI_H_
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdint.h>
-
-#define JNI_VERSION_1_1 0x00010001
-#define JNI_VERSION_1_2 0x00010002
-#define JNI_VERSION_1_4 0x00010004
-#define JNI_VERSION_1_6 0x00010006
-
-#define JNICALL
-
-#define JNI_FALSE 0
-#define JNI_TRUE  1
-
-#define JNI_OK        0
-#define JNI_ERR       (-1)
-#define JNI_EDETACHED (-2)
-#define JNI_EVERSION  (-3)
-#define JNI_ENOMEM    (-4)
-#define JNI_EEXIST    (-5)
-#define JNI_EINVAL    (-6)
-
-#define JNI_COMMIT 1
-#define JNI_ABORT  2
-
-
-typedef int8_t  jbyte;
-typedef int32_t jint;
-typedef int64_t jlong;
-
-typedef uint8_t  jboolean;
-typedef uint16_t jchar;
-typedef int16_t  jshort;
-typedef float    jfloat;
-typedef double   jdouble;
-
-typedef jint     jsize;
-
-
-struct _jobject;
-
-typedef struct _jobject *jobject;
-typedef jobject jclass;
-typedef jobject jthrowable;
-typedef jobject jstring;
-typedef jobject jarray;
-typedef jarray jbooleanArray;
-typedef jarray jbyteArray;
-typedef jarray jcharArray;
-typedef jarray jshortArray;
-typedef jarray jintArray;
-typedef jarray jlongArray;
-typedef jarray jfloatArray;
-typedef jarray jdoubleArray;
-typedef jarray jobjectArray;
-
-
-typedef jobject jweak;
-
-typedef union jvalue {
-    jboolean z;
-    jbyte    b;
-    jchar    c;
-    jshort   s;
-    jint     i;
-    jlong    j;
-    jfloat   f;
-    jdouble  d;
-    jobject  l;
-} jvalue;
-
-struct _jfieldID;
-typedef struct _jfieldID *jfieldID;
-
-struct _jmethodID;
-typedef struct _jmethodID *jmethodID;
-
-typedef enum _jobjectType {
-     JNIInvalidRefType    = 0,
-     JNILocalRefType      = 1,
-     JNIGlobalRefType     = 2,
-     JNIWeakGlobalRefType = 3
-} jobjectRefType;
-
-
-typedef struct {
-    char *name;
-    char *signature;
-    void *fnPtr;
-} JNINativeMethod;
-
-
-struct JNINativeInterface_;
-
-struct JNIEnv_;
-
-typedef const struct JNINativeInterface_ *JNIEnv;
-
-
-struct JNIInvokeInterface_;
-
-struct JavaVM_;
-
-typedef const struct JNIInvokeInterface_ *JavaVM;
-
-
-
-struct JNINativeInterface_ {
-    void *reserved0;
-    void *reserved1;
-    void *reserved2;
-
-    void *reserved3;
-    jint (JNICALL *GetVersion)(JNIEnv *env);
-
-    jclass (JNICALL *DefineClass)
-      (JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
-       jsize len);
-    jclass (JNICALL *FindClass)
-      (JNIEnv *env, const char *name);
-
-    jmethodID (JNICALL *FromReflectedMethod)
-      (JNIEnv *env, jobject method);
-    jfieldID (JNICALL *FromReflectedField)
-      (JNIEnv *env, jobject field);
-
-    jobject (JNICALL *ToReflectedMethod)
-      (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic);
-
-    jclass (JNICALL *GetSuperclass)
-      (JNIEnv *env, jclass sub);
-    jboolean (JNICALL *IsAssignableFrom)
-      (JNIEnv *env, jclass sub, jclass sup);
-
-    jobject (JNICALL *ToReflectedField)
-      (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic);
-
-    jint (JNICALL *Throw)
-      (JNIEnv *env, jthrowable obj);
-    jint (JNICALL *ThrowNew)
-      (JNIEnv *env, jclass clazz, const char *msg);
-    jthrowable (JNICALL *ExceptionOccurred)
-      (JNIEnv *env);
-    void (JNICALL *ExceptionDescribe)
-      (JNIEnv *env);
-    void (JNICALL *ExceptionClear)
-      (JNIEnv *env);
-    void (JNICALL *FatalError)
-      (JNIEnv *env, const char *msg);
-
-    jint (JNICALL *PushLocalFrame)
-      (JNIEnv *env, jint capacity);
-    jobject (JNICALL *PopLocalFrame)
-      (JNIEnv *env, jobject result);
-
-    jobject (JNICALL *NewGlobalRef)
-      (JNIEnv *env, jobject lobj);
-    void (JNICALL *DeleteGlobalRef)
-      (JNIEnv *env, jobject gref);
-    void (JNICALL *DeleteLocalRef)
-      (JNIEnv *env, jobject obj);
-    jboolean (JNICALL *IsSameObject)
-      (JNIEnv *env, jobject obj1, jobject obj2);
-    jobject (JNICALL *NewLocalRef)
-      (JNIEnv *env, jobject ref);
-    jint (JNICALL *EnsureLocalCapacity)
-      (JNIEnv *env, jint capacity);
-
-    jobject (JNICALL *AllocObject)
-      (JNIEnv *env, jclass clazz);
-    jobject (JNICALL *NewObject)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jobject (JNICALL *NewObjectV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jobject (JNICALL *NewObjectA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jclass (JNICALL *GetObjectClass)
-      (JNIEnv *env, jobject obj);
-    jboolean (JNICALL *IsInstanceOf)
-      (JNIEnv *env, jobject obj, jclass clazz);
-
-    jmethodID (JNICALL *GetMethodID)
-      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
-
-    jobject (JNICALL *CallObjectMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jobject (JNICALL *CallObjectMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jobject (JNICALL *CallObjectMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
-
-    jboolean (JNICALL *CallBooleanMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jboolean (JNICALL *CallBooleanMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jboolean (JNICALL *CallBooleanMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
-
-    jbyte (JNICALL *CallByteMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jbyte (JNICALL *CallByteMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jbyte (JNICALL *CallByteMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
-
-    jchar (JNICALL *CallCharMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jchar (JNICALL *CallCharMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jchar (JNICALL *CallCharMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
-
-    jshort (JNICALL *CallShortMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jshort (JNICALL *CallShortMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jshort (JNICALL *CallShortMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
-
-    jint (JNICALL *CallIntMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jint (JNICALL *CallIntMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jint (JNICALL *CallIntMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
-
-    jlong (JNICALL *CallLongMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jlong (JNICALL *CallLongMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jlong (JNICALL *CallLongMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
-
-    jfloat (JNICALL *CallFloatMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jfloat (JNICALL *CallFloatMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jfloat (JNICALL *CallFloatMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
-
-    jdouble (JNICALL *CallDoubleMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    jdouble (JNICALL *CallDoubleMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    jdouble (JNICALL *CallDoubleMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
-
-    void (JNICALL *CallVoidMethod)
-      (JNIEnv *env, jobject obj, jmethodID methodID, ...);
-    void (JNICALL *CallVoidMethodV)
-      (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
-    void (JNICALL *CallVoidMethodA)
-      (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args);
-
-    jobject (JNICALL *CallNonvirtualObjectMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jobject (JNICALL *CallNonvirtualObjectMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jobject (JNICALL *CallNonvirtualObjectMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue * args);
-
-    jboolean (JNICALL *CallNonvirtualBooleanMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jboolean (JNICALL *CallNonvirtualBooleanMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jboolean (JNICALL *CallNonvirtualBooleanMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue * args);
-
-    jbyte (JNICALL *CallNonvirtualByteMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jbyte (JNICALL *CallNonvirtualByteMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jbyte (JNICALL *CallNonvirtualByteMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue *args);
-
-    jchar (JNICALL *CallNonvirtualCharMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jchar (JNICALL *CallNonvirtualCharMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jchar (JNICALL *CallNonvirtualCharMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue *args);
-
-    jshort (JNICALL *CallNonvirtualShortMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jshort (JNICALL *CallNonvirtualShortMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jshort (JNICALL *CallNonvirtualShortMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue *args);
-
-    jint (JNICALL *CallNonvirtualIntMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jint (JNICALL *CallNonvirtualIntMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jint (JNICALL *CallNonvirtualIntMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue *args);
-
-    jlong (JNICALL *CallNonvirtualLongMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jlong (JNICALL *CallNonvirtualLongMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jlong (JNICALL *CallNonvirtualLongMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue *args);
-
-    jfloat (JNICALL *CallNonvirtualFloatMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jfloat (JNICALL *CallNonvirtualFloatMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jfloat (JNICALL *CallNonvirtualFloatMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue *args);
-
-    jdouble (JNICALL *CallNonvirtualDoubleMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    jdouble (JNICALL *CallNonvirtualDoubleMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    jdouble (JNICALL *CallNonvirtualDoubleMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue *args);
-
-    void (JNICALL *CallNonvirtualVoidMethod)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
-    void (JNICALL *CallNonvirtualVoidMethodV)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       va_list args);
-    void (JNICALL *CallNonvirtualVoidMethodA)
-      (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
-       const jvalue * args);
-
-    jfieldID (JNICALL *GetFieldID)
-      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
-
-    jobject (JNICALL *GetObjectField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jboolean (JNICALL *GetBooleanField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jbyte (JNICALL *GetByteField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jchar (JNICALL *GetCharField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jshort (JNICALL *GetShortField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jint (JNICALL *GetIntField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jlong (JNICALL *GetLongField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jfloat (JNICALL *GetFloatField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-    jdouble (JNICALL *GetDoubleField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID);
-
-    void (JNICALL *SetObjectField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val);
-    void (JNICALL *SetBooleanField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val);
-    void (JNICALL *SetByteField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val);
-    void (JNICALL *SetCharField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val);
-    void (JNICALL *SetShortField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val);
-    void (JNICALL *SetIntField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
-    void (JNICALL *SetLongField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val);
-    void (JNICALL *SetFloatField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val);
-    void (JNICALL *SetDoubleField)
-      (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val);
-
-    jmethodID (JNICALL *GetStaticMethodID)
-      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
-
-    jobject (JNICALL *CallStaticObjectMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jobject (JNICALL *CallStaticObjectMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jobject (JNICALL *CallStaticObjectMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jboolean (JNICALL *CallStaticBooleanMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jboolean (JNICALL *CallStaticBooleanMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jboolean (JNICALL *CallStaticBooleanMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jbyte (JNICALL *CallStaticByteMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jbyte (JNICALL *CallStaticByteMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jbyte (JNICALL *CallStaticByteMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jchar (JNICALL *CallStaticCharMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jchar (JNICALL *CallStaticCharMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jchar (JNICALL *CallStaticCharMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jshort (JNICALL *CallStaticShortMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jshort (JNICALL *CallStaticShortMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jshort (JNICALL *CallStaticShortMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jint (JNICALL *CallStaticIntMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jint (JNICALL *CallStaticIntMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jint (JNICALL *CallStaticIntMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jlong (JNICALL *CallStaticLongMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jlong (JNICALL *CallStaticLongMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jlong (JNICALL *CallStaticLongMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jfloat (JNICALL *CallStaticFloatMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jfloat (JNICALL *CallStaticFloatMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jfloat (JNICALL *CallStaticFloatMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    jdouble (JNICALL *CallStaticDoubleMethod)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
-    jdouble (JNICALL *CallStaticDoubleMethodV)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
-    jdouble (JNICALL *CallStaticDoubleMethodA)
-      (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
-
-    void (JNICALL *CallStaticVoidMethod)
-      (JNIEnv *env, jclass cls, jmethodID methodID, ...);
-    void (JNICALL *CallStaticVoidMethodV)
-      (JNIEnv *env, jclass cls, jmethodID methodID, va_list args);
-    void (JNICALL *CallStaticVoidMethodA)
-      (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args);
-
-    jfieldID (JNICALL *GetStaticFieldID)
-      (JNIEnv *env, jclass clazz, const char *name, const char *sig);
-    jobject (JNICALL *GetStaticObjectField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jboolean (JNICALL *GetStaticBooleanField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jbyte (JNICALL *GetStaticByteField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jchar (JNICALL *GetStaticCharField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jshort (JNICALL *GetStaticShortField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jint (JNICALL *GetStaticIntField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jlong (JNICALL *GetStaticLongField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jfloat (JNICALL *GetStaticFloatField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-    jdouble (JNICALL *GetStaticDoubleField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID);
-
-    void (JNICALL *SetStaticObjectField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value);
-    void (JNICALL *SetStaticBooleanField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value);
-    void (JNICALL *SetStaticByteField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value);
-    void (JNICALL *SetStaticCharField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value);
-    void (JNICALL *SetStaticShortField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value);
-    void (JNICALL *SetStaticIntField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
-    void (JNICALL *SetStaticLongField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value);
-    void (JNICALL *SetStaticFloatField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value);
-    void (JNICALL *SetStaticDoubleField)
-      (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value);
-
-    jstring (JNICALL *NewString)
-      (JNIEnv *env, const jchar *unicode, jsize len);
-    jsize (JNICALL *GetStringLength)
-      (JNIEnv *env, jstring str);
-    const jchar *(JNICALL *GetStringChars)
-      (JNIEnv *env, jstring str, jboolean *isCopy);
-    void (JNICALL *ReleaseStringChars)
-      (JNIEnv *env, jstring str, const jchar *chars);
-
-    jstring (JNICALL *NewStringUTF)
-      (JNIEnv *env, const char *utf);
-    jsize (JNICALL *GetStringUTFLength)
-      (JNIEnv *env, jstring str);
-    const char* (JNICALL *GetStringUTFChars)
-      (JNIEnv *env, jstring str, jboolean *isCopy);
-    void (JNICALL *ReleaseStringUTFChars)
-      (JNIEnv *env, jstring str, const char* chars);
-
-
-    jsize (JNICALL *GetArrayLength)
-      (JNIEnv *env, jarray array);
-
-    jobjectArray (JNICALL *NewObjectArray)
-      (JNIEnv *env, jsize len, jclass clazz, jobject init);
-    jobject (JNICALL *GetObjectArrayElement)
-      (JNIEnv *env, jobjectArray array, jsize index);
-    void (JNICALL *SetObjectArrayElement)
-      (JNIEnv *env, jobjectArray array, jsize index, jobject val);
-
-    jbooleanArray (JNICALL *NewBooleanArray)
-      (JNIEnv *env, jsize len);
-    jbyteArray (JNICALL *NewByteArray)
-      (JNIEnv *env, jsize len);
-    jcharArray (JNICALL *NewCharArray)
-      (JNIEnv *env, jsize len);
-    jshortArray (JNICALL *NewShortArray)
-      (JNIEnv *env, jsize len);
-    jintArray (JNICALL *NewIntArray)
-      (JNIEnv *env, jsize len);
-    jlongArray (JNICALL *NewLongArray)
-      (JNIEnv *env, jsize len);
-    jfloatArray (JNICALL *NewFloatArray)
-      (JNIEnv *env, jsize len);
-    jdoubleArray (JNICALL *NewDoubleArray)
-      (JNIEnv *env, jsize len);
-
-    jboolean * (JNICALL *GetBooleanArrayElements)
-      (JNIEnv *env, jbooleanArray array, jboolean *isCopy);
-    jbyte * (JNICALL *GetByteArrayElements)
-      (JNIEnv *env, jbyteArray array, jboolean *isCopy);
-    jchar * (JNICALL *GetCharArrayElements)
-      (JNIEnv *env, jcharArray array, jboolean *isCopy);
-    jshort * (JNICALL *GetShortArrayElements)
-      (JNIEnv *env, jshortArray array, jboolean *isCopy);
-    jint * (JNICALL *GetIntArrayElements)
-      (JNIEnv *env, jintArray array, jboolean *isCopy);
-    jlong * (JNICALL *GetLongArrayElements)
-      (JNIEnv *env, jlongArray array, jboolean *isCopy);
-    jfloat * (JNICALL *GetFloatArrayElements)
-      (JNIEnv *env, jfloatArray array, jboolean *isCopy);
-    jdouble * (JNICALL *GetDoubleArrayElements)
-      (JNIEnv *env, jdoubleArray array, jboolean *isCopy);
-
-    void (JNICALL *ReleaseBooleanArrayElements)
-      (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode);
-    void (JNICALL *ReleaseByteArrayElements)
-      (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode);
-    void (JNICALL *ReleaseCharArrayElements)
-      (JNIEnv *env, jcharArray array, jchar *elems, jint mode);
-    void (JNICALL *ReleaseShortArrayElements)
-      (JNIEnv *env, jshortArray array, jshort *elems, jint mode);
-    void (JNICALL *ReleaseIntArrayElements)
-      (JNIEnv *env, jintArray array, jint *elems, jint mode);
-    void (JNICALL *ReleaseLongArrayElements)
-      (JNIEnv *env, jlongArray array, jlong *elems, jint mode);
-    void (JNICALL *ReleaseFloatArrayElements)
-      (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode);
-    void (JNICALL *ReleaseDoubleArrayElements)
-      (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode);
-
-    void (JNICALL *GetBooleanArrayRegion)
-      (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf);
-    void (JNICALL *GetByteArrayRegion)
-      (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf);
-    void (JNICALL *GetCharArrayRegion)
-      (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf);
-    void (JNICALL *GetShortArrayRegion)
-      (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf);
-    void (JNICALL *GetIntArrayRegion)
-      (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf);
-    void (JNICALL *GetLongArrayRegion)
-      (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf);
-    void (JNICALL *GetFloatArrayRegion)
-      (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf);
-    void (JNICALL *GetDoubleArrayRegion)
-      (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf);
-
-    void (JNICALL *SetBooleanArrayRegion)
-      (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf);
-    void (JNICALL *SetByteArrayRegion)
-      (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf);
-    void (JNICALL *SetCharArrayRegion)
-      (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf);
-    void (JNICALL *SetShortArrayRegion)
-      (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf);
-    void (JNICALL *SetIntArrayRegion)
-      (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf);
-    void (JNICALL *SetLongArrayRegion)
-      (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf);
-    void (JNICALL *SetFloatArrayRegion)
-      (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf);
-    void (JNICALL *SetDoubleArrayRegion)
-      (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf);
-
-    jint (JNICALL *RegisterNatives)
-      (JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
-       jint nMethods);
-    jint (JNICALL *UnregisterNatives)
-      (JNIEnv *env, jclass clazz);
-
-    jint (JNICALL *MonitorEnter)
-      (JNIEnv *env, jobject obj);
-    jint (JNICALL *MonitorExit)
-      (JNIEnv *env, jobject obj);
-
-    jint (JNICALL *GetJavaVM)
-      (JNIEnv *env, JavaVM **vm);
-
-    void (JNICALL *GetStringRegion)
-      (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);
-    void (JNICALL *GetStringUTFRegion)
-      (JNIEnv *env, jstring str, jsize start, jsize len, char *buf);
-
-    void * (JNICALL *GetPrimitiveArrayCritical)
-      (JNIEnv *env, jarray array, jboolean *isCopy);
-    void (JNICALL *ReleasePrimitiveArrayCritical)
-      (JNIEnv *env, jarray array, void *carray, jint mode);
-
-    const jchar * (JNICALL *GetStringCritical)
-      (JNIEnv *env, jstring string, jboolean *isCopy);
-    void (JNICALL *ReleaseStringCritical)
-      (JNIEnv *env, jstring string, const jchar *cstring);
-
-    jweak (JNICALL *NewWeakGlobalRef)
-       (JNIEnv *env, jobject obj);
-    void (JNICALL *DeleteWeakGlobalRef)
-       (JNIEnv *env, jweak ref);
-
-    jboolean (JNICALL *ExceptionCheck)
-       (JNIEnv *env);
-
-    jobject (JNICALL *NewDirectByteBuffer)
-       (JNIEnv* env, void* address, jlong capacity);
-    void* (JNICALL *GetDirectBufferAddress)
-       (JNIEnv* env, jobject buf);
-    jlong (JNICALL *GetDirectBufferCapacity)
-       (JNIEnv* env, jobject buf);
-
-    jobjectRefType (JNICALL *GetObjectRefType)
-        (JNIEnv* env, jobject obj);
-};
-
-
-struct JNIEnv_ {
-    const struct JNINativeInterface_ *functions;
-};
-
-
-typedef struct JavaVMOption {
-    char *optionString;
-    void *extraInfo;
-} JavaVMOption;
-
-typedef struct JavaVMInitArgs {
-    jint version;
-
-    jint nOptions;
-    JavaVMOption *options;
-    jboolean ignoreUnrecognized;
-} JavaVMInitArgs;
-
-typedef struct JavaVMAttachArgs {
-    jint version;
-
-    char *name;
-    jobject group;
-} JavaVMAttachArgs;
-
-
-struct JNIInvokeInterface_ {
-    void *reserved0;
-    void *reserved1;
-    void *reserved2;
-
-    jint (JNICALL *DestroyJavaVM)(JavaVM *vm);
-
-    jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args);
-
-    jint (JNICALL *DetachCurrentThread)(JavaVM *vm);
-
-    jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version);
-
-    jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args);
-};
-
-struct JavaVM_ {
-    const struct JNIInvokeInterface_ *functions;
-};
-
-#endif /*_JNI_H_*/
-
-
diff --git a/j2hs/Common.hs b/j2hs/Common.hs
new file mode 100644
--- /dev/null
+++ b/j2hs/Common.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE Haskell2010 #-}
+
+module Common where
+
+import Options
+
+
diff --git a/j2hs/Java2Haskell.hss b/j2hs/Java2Haskell.hss
new file mode 100644
--- /dev/null
+++ b/j2hs/Java2Haskell.hss
@@ -0,0 +1,228 @@
+{-# LANGUAGE Haskell2010
+ #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-missing-signatures
+    -fno-warn-name-shadowing
+ #-}
+
+{- | The @j2hs@ command - create Haskell bindings for Java classes.
+    
+-}
+module Java2Haskell where
+
+import Prelude hiding (print)
+
+import Options
+--import Common
+
+import Foreign.Java
+import Foreign.Java.Bindings
+import Foreign.Java.Bindings.JavaTypes
+import Foreign.Java.Utils
+import Foreign.Java.IO
+
+import Data.NamedRecord
+import qualified Data.List as L
+import Data.Strings
+
+import Data.Generics
+
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+import qualified Data.MultiMap as MultiMap
+import qualified Data.Bimap as Bimap
+
+import Control.Monad
+
+import System.Directory
+import System.FilePath
+import System.IO hiding (print)
+import System.Exit
+
+
+-- Following 20 lines: Functions for managing a Bimap
+-- such that it works with case insensitive string.
+--
+-- TODO: Factor this out `plus` use the case-insensitive package.
+--       Those functions x... should be made into their own
+--       datatype (Something like CISBimap or
+--       BimapWithGenericComparisonFunction or ...)
+
+newtype CaseInsensitiveString = CIS String
+
+instance Eq CaseInsensitiveString where
+    (CIS a) == (CIS b) = strToLower a == strToLower b
+
+instance Ord CaseInsensitiveString where
+    (CIS a) <= (CIS b) = strToLower a <= strToLower b
+
+xToString (CIS s) = s
+
+xEmpty      = Bimap.empty
+xInsert k v = Bimap.insert (CIS k) (CIS v)
+xMemberR k  = Bimap.memberR (CIS k)
+xGet m      = xToString . (Bimap.!) m . CIS
+xFromList   = Bimap.fromList . map (\(a, b) -> (CIS a, CIS b))
+xToList     = map (\(a, b) -> (xToString a, xToString b)) . Bimap.toList
+xKeysR      = map xToString . Bimap.keysR
+xKeys       = map xToString . Bimap.keys
+xSize       = Bimap.size
+
+-- end todo
+
+
+ifVerbose opts = when (opts `get` optVerbose) . liftIO . putStr
+
+j2hs :: Options -> [String] -> IO ()
+j2hs opts args = do
+
+    classpath <- mapM canonicalizePath $ opts `get` optClasspath
+    targetDir <- return (opts `get` optTargetDirectory)
+
+    let classpath' = concat $ L.intersperse ":" classpath
+        indent     = ("  " ++)
+
+    ifVerbose opts """
+        Classpath:
+        #{concatMap (\x -> "  " ++ x ++ "\n") (classpath)}"""
+    print "Initializing JVM..."
+    initJava ["""-Djava.class.path=#{classpath'}"""]
+    println " Done."
+    
+    unless (null args) $ runJava $ do
+        io $ do
+            ifVerbose opts """
+                Target Directory:
+                  #{targetDir}
+                """
+            createDirectoryIfMissing True targetDir
+            setCurrentDirectory targetDir
+            
+        ifVerbose opts """
+            Looking for Java classes:
+            #{concatMap (\x -> "  " ++ x ++ "\n") args}"""
+
+        -- Gather all classes that need to be translated
+        print "Looking up classes..."
+        classes  <- findJavaClasses (opts `get` optSearchDepth) args
+
+        println """ #{show $ length classes} found."""
+        ifVerbose opts $
+            unlines (map indent classes)
+
+        -- Calculate the Haskell module names for packages and classes
+        let packages = Set.toList $ Set.fromList
+                     $ map (maybe "" id . takePackageName) classes
+
+            -- temporary class names
+            classModules_ = foldr (uncurry g) xEmpty $ map f classes
+              where f x = (x, makeClassModuleName x)
+                    g clazzName modName all = xInsert clazzName newName all
+                      where newName = head $ dropWhile (`xMemberR` all)
+                                           $ iterate (++ "_") modName
+
+            -- package names.
+            -- This func keeps in mind that package names must not clash with class names.
+            packageModules = foldr (uncurry g) xEmpty $ map f packages
+              where f x = (x, makePackageModuleName x)
+                    g pkgName modName all = xInsert pkgName newName all
+                      where newName = head $ dropWhile (\n -> n `xMemberR` classModules_
+                                                           || n `xMemberR` all)
+                                           $ iterate (++ "Package") modName
+
+            -- finally the class names.
+            -- This func keeps in mind that the package names might have been augmented
+            -- before. i.e. the package java.awt.image will be Java.Awt.ImagePackage now,
+            -- thus all classes inside the package have their full name changed too.
+            classModules = Map.fromList $ map f $ xToList classModules_
+              where f (clazzName, moduleName)
+                        = (clazzName, joinClassName (newPackageName, classModuleName))
+                      where classModuleName = takeClassName moduleName
+                            packageName = maybe "" id $ takePackageName clazzName
+                            newPackageName = packageModules `xGet` packageName
+
+            -- A mapping form packages to classes
+            classesByPackage = MultiMap.fromList
+                             $ map (\clazz -> (fst $ splitClassName clazz, clazz)) classes
+
+            -- A list of all modules
+            allModules = xKeysR packageModules ++ Map.elems classModules
+
+            -- The list of hidden modules
+            hiddenModules = map (++ "__") $ Map.elems classModules
+
+        -- Gather information about classes via Reflection
+        print """Gathering refection information..."""
+        let classNames = Map.keys classModules
+            updName name clazz = (name, clazz { classModName = classModules Map.! name })
+        classInfo <- Map.fromList `fmap` map (uncurry updName)
+                                  `fmap` zip classNames
+                                  `fmap` everywhere (mkT (\(TyVar v) -> TyVar ('_':v)))
+                                  `fmap` reflectJavaClasses classNames
+        println " Done."
+
+        when (opts `get` optOnlyReflect) $ io $ do
+            mapM_ println $ Map.elems classInfo
+            exitSuccess
+
+        println """Generating modules for #{show $ Map.size classModules} classes in \
+                   #{show $ xSize packageModules} packages..."""
+
+        -- Create all the package files.
+        -- These contain the Java classes as Haskell types.
+        forM_ (xToList packageModules) $ \(packageName, packageMod) -> do
+            let dirName = strJoin [pathSeparator] (strSplitAll "." packageMod)
+
+            -- Create the directory for the package
+            io $ do 
+                createDirectoryIfMissing True dirName
+
+                let classes = map (classInfo Map.!)
+                                  (MultiMap.lookup packageName classesByPackage)
+
+                -- Create the Haskell module file for the Java package
+                file <- openFile (dirName ++ ".hs") WriteMode
+                hPutStrLn file
+                  $ printJavaPackageModule packageName packageMod classInfo classes
+                hClose file
+
+        -- Create all the class files.
+        -- These contain the java methods as Haskell functions.
+        forM_ (Map.toList classModules) $ \(clazzName, clazzMod) -> do
+            let fileName = strJoin [pathSeparator] (strSplitAll "." clazzMod)
+                clazz = classInfo Map.! clazzName
+
+            io $ do
+                -- Create the Haskell module file for the Java class.
+                file <- openFile (fileName ++ ".hs") WriteMode
+                hPutStrLn file $ printJavaClassModule clazz clazzMod classInfo
+                hClose file
+
+                -- Create the *hidden* Haskell module file for the Java class.
+                file <- openFile (fileName ++ "__.hs") WriteMode
+                hPutStrLn file $ printJavaClassModule' clazz clazzMod classInfo
+                hClose file
+
+        -- write Cabal file
+        when (opts `get` optCabalProject) $ io $ do
+            cabalFile <- openFile ((opts `get` optProjectName) ++ ".cabal") WriteMode
+            hPutStrLn cabalFile """
+                name:           #{opts `get` optProjectName}
+                version:        #{opts `get` optProjectVersion}
+                cabal-version:  >= 1.8
+                build-type:     Simple
+                
+                Library {
+                 build-depends:
+                  base >= 4 && < 5,
+                  java-bridge
+                 exposed-modules:
+                  #{strJoin ",\n  " allModules}
+                 other-modules:
+                  #{strJoin ",\n  " hiddenModules} }
+                """
+            hClose cabalFile
+
+    return ()
+
diff --git a/j2hs/Main.hss b/j2hs/Main.hss
new file mode 100644
--- /dev/null
+++ b/j2hs/Main.hss
@@ -0,0 +1,128 @@
+{-# LANGUAGE Haskell2010
+ #-}
+
+module Main where
+
+import Options
+import Java2Haskell
+
+import Foreign.Java.Bindings
+import Foreign.Java.Utils
+import Foreign.Java.JNI (javaBridgeVersion)
+
+import System.Console.GetOpt
+import System.Environment (getArgs, getProgName)
+
+import Data.Maybe
+import Data.NamedRecord
+import Data.List
+import Data.List.Split
+import Data.Word
+
+import Text.Printf
+
+versionInfo = """
+    Java <-> Haskell Bindings Generator (using java-bridge #{javaBridgeVersion})"""
+
+-- | The flags (needed for the options list / GetOpt).
+data Flag = Help
+          | Version
+          | Packages [String]
+          | Classpath [String]
+          | SearchDepth Word32
+          | TargetDirectory String
+          | CompleteSE6
+          | OnlyReflect
+          | Filtered
+          | Verbose
+
+-- | The Command line options as fed to the GetOpt parser.
+options = [
+    Option "h" ["help"] (NoArg Help)
+        "Print this help text.",
+
+    Option "V" ["version"] (NoArg Version)
+        "Print version information.",
+
+    Option "c" ["classpath"] (ReqArg readClasspath "")
+        "The Java classpath to be used.",
+
+    Option "P" ["packages"] (ReqArg readPackages "")
+        "The packages to translate.",
+
+    Option "d" ["search-depth"] (ReqArg readSearchDepth "")
+        "The maximum search depth for dependent Java classes.",
+
+    Option "v" ["verbose"] (NoArg Verbose)
+        "Verbose output, prints extra diagnostic information.",
+
+    Option "R" ["reflect"] (NoArg OnlyReflect)
+        "Only reflect the given java files (mainly for debugging purposes).",
+
+    Option "X" [] (NoArg CompleteSE6)
+        "Completely translate Java SE.",
+
+    Option "F" [] (NoArg Filtered)
+        "Only translate a subset of the Java SE.",
+
+    Option "t" ["target-directory"] (ReqArg TargetDirectory "")
+        "The target directory for generated source files."
+
+ ] where
+    readPackages = Packages . splitOneOf ":;,"
+    readClasspath = Classpath . splitOneOf ":;,"
+    readSearchDepth = SearchDepth . read
+
+parseArgs :: IO (Either (Options, [String]) [String])
+-- ^ Parse command line arguments with the help of the GetOpt library.
+parseArgs = do
+    (opts, args, errs) <- getArgs >>= return . getOpt Permute options
+    if null errs
+        then return $ Left  (parseOpts newOptions opts, args)
+        else return $ Right errs
+  where
+    parseOpts opts [] = opts
+    parseOpts opts (x:xs) = flip parseOpts xs $
+        case x of
+            Help              -> opts `set` optShowHelp        := True
+            Version           -> opts `set` optShowVersion     := True
+            Verbose           -> opts `set` optVerbose         := True
+            Filtered          -> opts `set` optFiltered        := True
+            CompleteSE6       -> opts `set` optCompleteSE6     := True
+            OnlyReflect       -> opts `set` optOnlyReflect     := True
+            Classpath cp      -> opts `set` optClasspath       := cp
+            Packages pkgs     -> opts `set` optPackages        := pkgs
+            SearchDepth d     -> opts `set` optSearchDepth     := d
+            TargetDirectory t -> opts `set` optTargetDirectory := t
+
+main :: IO ()
+-- ^ main: parseArgs and either 'run' or show errors.
+main = parseArgs >>= either (uncurry run) (mapM_ putStr)
+
+run :: Options -> [String] -> IO ()
+-- ^ The actual main function.
+run opts args
+    | opts `get` optShowHelp = do
+        progName <- getProgName
+        putStrLn (usageInfo """
+            #{versionInfo}
+            
+            Usage: #{progName} [options] command [files...]
+            
+            Use `#{progName} help' for information about commands.
+            """ options)
+
+    | opts `get` optShowVersion = putStrLn versionInfo
+    | opts `get` optCompleteSE6 =
+        if opts `get` optFiltered then j2hs opts (filter minimal  javaClassesSE6)
+                                  else j2hs opts (filter justJava javaClassesSE6)
+
+    | otherwise = getProgName >>= \progName -> putStr """
+        No command given. Use `#{progName} help' for help.
+        """
+  where
+    justJava = ("java" `isPrefixOf`)
+    minimal name = pkg `elem` (opts `get` optPackages)
+        where (pkg, _) = splitClassName name
+
+
diff --git a/j2hs/Options.hs b/j2hs/Options.hs
new file mode 100644
--- /dev/null
+++ b/j2hs/Options.hs
@@ -0,0 +1,29 @@
+{-# LANGUAGE Haskell2010
+    , TemplateHaskell
+ #-}
+
+module Options where
+
+import Data.Name
+import Data.NamedRecord
+import Data.Word
+
+-- The options as used in the application later on.
+-- This is a named record, see Data.NamedRecord for
+-- more information.
+record' "Options"
+    `has` "optShowHelp"         := False
+    `has` "optShowVersion"      := False
+    `has` "optPackages"         := ["java.lang"]
+    `has` "optClasspath"        := ["."]
+    `has` "optSearchDepth"      := (100 :: Word32)
+    `has` "optVerbose"          := False
+    `has` "optCompleteSE6"      := False
+    `has` "optFiltered"         := False
+    `has` "optOnlyReflect"      := False
+    `has` "optTargetDirectory"  := "bindings"
+    `has` "optProjectName"      := "java-bindings"
+    `has` "optProjectVersion"   := "1.0"
+    `has` "optCabalProject"     := True
+
+
diff --git a/java-bridge.cabal b/java-bridge.cabal
--- a/java-bridge.cabal
+++ b/java-bridge.cabal
@@ -1,5 +1,5 @@
 name:           java-bridge
-version:        0.99
+version:        0.20130602
 
 license:        MIT
 license-file:   LICENSE
@@ -13,65 +13,71 @@
 cabal-version:  >= 1.8
 
 synopsis:       Bindings to the JNI and a high level interface generator.
-description:    This package offers bindings to the
-                /Java Native Interface/ and a high level interface
-                generator.
+description:    This package offers bindings to the /Java Native Interface/
+                and a high level interface generator.
                 .
                 [@low level bindings to the JNI@]
-                    The low level bindings are located in
-                    "Foreign.Java.JNI.Safe" and "Foreign.Java.JNI.Unsafe".
-                    When using these bindings you will have to deal with
-                    pointers and manage global references manually.
+                    The low level bindings are located in "Foreign.Java.JNI.Safe"
+                    and "Foreign.Java.JNI.Unsafe". When using these bindings you
+                    will have to deal with pointers and manage global references
+                    manually.
                 .
                 [@medium level interface@]
-                    The medium level interface is located in
-                    "Foreign.Java". It offers an abstraction over the JNI,
-                    i.e. you will not have to deal with pointers
-                    explicitly nor do you need to manually do conversions
-                    between native types and Haskell types.
-                    Also references will automatically be released by
-                    the Haskell runtime when no longer needed. You will
-                    still need to manually lookup classes and methods in
-                    order to use them.
+                    The medium level interface is located in "Foreign.Java".
+                    It offers an abstraction over the JNI, i.e. you will not
+                    have to deal with pointers explicitly nor do you need to
+                    manually do conversions between native types and Haskell
+                    types. Also references will automatically be released by
+                    the Haskell runtime when no longer needed. You will still
+                    need to manually lookup classes and methods in order to use
+                    them.
                 .
+                [@high level bindings generator@]
+                    You can also generate high level bindings using the tools
+                    @j2hs@ and @hs2j@ that come along with this package. The tools
+                    works in both directions, i.e. you can generate glue code to use
+                    existing Java libraries from within Haskell as well as to use
+                    Haskell from within Java. This is the most convenient way
+                    to deal with a Java library.
                 .
+                .
                 >>> INSTALLATION / USAGE
                 .
                 It should suffice to do @cabal install@ (or
-                @cabal install java-bridge@ when installing from
-                hackageDB). /You need to have a JDK installed prior to
-                installing this library/.
+                @cabal install java-bridge@ when installing from hackageDB).
+                /You need to have a JDK installed prior to installing this library/.
                 .
-                Setup will try to find the location of your java
-                installation automatically. This is needed in order to
-                load @libjvm@. Note that this library is loaded
-                dynamically, which  means that linking errors might not
-                show up during installation.
+                Setup will try to find the location of your java installation
+                automatically. This is needed in order to load @libjvm@.
+                Note that this library is loaded dynamically, which
+                means that linking errors might not show up during installation.
                 .
-                You can specify the location of @libjvm@ manually using
-                the environment variable @FFIJNI_LIBJVM@. This
-                environment variable is consulted by @Setup.hs@ as well
-                as by the library each time @libjvm@ is loaded - which
-                means that you can override the path to @libjvm@ at any
-                time. The function @getCompiledLibjvmPath@ in
-                "Foreign.Java.JNI.Safe" will tell you what path to
-                @libjvm@ has been set during compilation of the library.
+                You can specify the location of @libjvm@ manually using the
+                environment variable @FFIJNI_LIBJVM@. This environment variable
+                is consulted by @Setup.hs@ as well as by the library each time
+                @libjvm@ is loaded - which means that you can override the path to
+                @libjvm@ at any time. The function @getCompiledLibjvmPath@ in
+                "Foreign.Java.JNI.Safe" will tell you what path to @libjvm@ has
+                been set during compilation of the library.
                 .
                 .
                 >>> FUN WITH (cabal-) FLAGS
                 .
-                The following cabal flags are available to you for
-                configuring your installation:
+                The following cabal flags are available to you for configuring
+                your installation:
                 .
                 [@ONLY_CORE@]
                     Build only the Core Modules which offer a
                     direct binding to the Java Native Interface.
                     The core modules are "Foreign.Java.JNI",
-                    "Foreign.Java.JNI.Safe",
-                    and "Foreign.Java.JNI.Unsafe".
+                    "Foreign.Java.JNI.Safe", and "Foreign.Java.JNI.Unsafe".
                     This implies @NO_TOOLS@.
                     Defaults to @False@.
                 .
+                [@NO_TOOLS@]
+                    Do not build the @j2hs@ and @hs2j@ executables.
+                    Defaults to @False@.
+                .
                 [@DEBUG@]
                     Enable a debug build. Defaults to @False@.
                 .
@@ -87,19 +93,26 @@
                     @False@. Enable this flag if building on your
                     OS X machine fails. Defaults to @False@.
                 .
-                Use for example
-                @cabal install -f OSX_FRAMEWORK -f EXAMPLES@
+                [@EXAMPLES@]
+                    Build a set of examples. They are prefixed
+                    with @java-@ and located along your haskell
+                    executables. Defaults to @False@.
+                .
+                Use for example @cabal install -f OSX_FRAMEWORK -f EXAMPLES@
                 or @cabal configure -f DEBUG@.
+                .
+                .
+                >>> HACKING
+                .
+                See @HACKING.txt@ and @ISSUES.txt@ in the tar.gz-package.
                 
 build-type:     Custom
 
-extra-source-files: include/jni.h,
-                    src/Foreign/Java/JNI/core.hs,
+extra-source-files: src/Foreign/Java/JNI/core.hs,
                     src/ffijni.h,
-                    src/hfunction.h,
                     GetProperty.java,
-                    HFunction.java,
-                    ReadClass.java,
+                    examples/calculator/calculator.cabal,
+                    examples/system-properties/Makefile,
                     HACKING.txt,
                     ISSUES.txt,
                     README.md
@@ -109,6 +122,10 @@
                     direct binding to the Java Native Interface.
     Default:        False
 
+flag NO_TOOLS
+    Description:    Do not build the `j2hs' and `hs2j' executables.
+    Default:        False
+
 flag DEBUG
     Description:    Enable a debug build.
     Default:        False
@@ -123,10 +140,14 @@
                     of loading the dynamic library.
     Default:        False
 
+flag EXAMPLES
+    Description:    Build a set of sample executables.
+    Default:        False
 
+
 Library
-    cc-options:         -DFFIJNI_BRIDGE_VERSION="1.0"
-    cpp-options:        -DFFIJNI_BRIDGE_VERSION="1.0"
+    cc-options:         -DFFIJNI_BRIDGE_VERSION="0.20130602"
+    cpp-options:        -DFFIJNI_BRIDGE_VERSION="0.20130602"
 
     build-depends:      base >= 4.5 && < 5
                         , directory >= 1.1.0.2
@@ -147,18 +168,35 @@
     else
         exposed-modules:    Foreign.Java
                             , Foreign.Java.Bindings
+                            , Foreign.Java.Bindings.JavaTypes
+                            , Foreign.Java.Bindings.HaskellTypes
+                            , Foreign.Java.Bindings.Support
+                            , Foreign.Java.Control
+                            , Foreign.Java.IO
+                            , Foreign.Java.Maybe
                             , Foreign.Java.Utils
                             , Foreign.Java.Value
+                            , Foreign.Java.Tutorial
 
-        build-depends:      cpphs >= 1.16
+        build-depends:      hinduce-missingh
+                            , cpphs >= 1.16
                             , strings >= 1.1
+                            , multimap >= 1.2
+                            -- the following are part of the Haskell Platform
                             , mtl >= 2.1.1
+                            , syb >= 0.3.6.1
                             , transformers >= 0.3
-                            , hx >= 0.4
+                            , containers >= 0.4.2.1
 
         other-modules:      Foreign.Java.Types
                             , Foreign.Java.JavaMonad
                             , Foreign.Java.Util
+                            , Foreign.Java.Bindings.ReflectJava
+                            , Foreign.Java.Bindings.ReflectHaskell
+                            , Foreign.Java.Bindings.Java2Haskell
+                            , Foreign.Java.Bindings.Haskell2Java
+                            , Foreign.Java.Bindings.JavaSE6
+                            , Foreign.Java.Bindings.Typomatic
 
     if flag(DEBUG)
         cc-options:         -DFFIJNI_DEBUG
@@ -194,4 +232,111 @@
                 cpp-options: -DFFIJNI_WINDOWS
             else
                 buildable: False
+
+
+Executable j2hs
+    if flag(ONLY_CORE)
+        buildable: False
+    else
+        if flag(NO_TOOLS)
+            buildable: False
+        else
+            buildable: True
+
+    hs-source-dirs: j2hs
+    main-is: Main.hs
+
+    other-modules:  Common
+                    , Options
+                    , Java2Haskell
+
+    build-depends:  base >= 4.5 && < 5
+                    , java-bridge
+                    -- The following are part of the GHC core packages:
+                    , containers >= 0.4.2.1
+                    , directory >= 1.1.0.2
+                    , filepath >= 1.3
+                    -- These are part of the Haskell Platform:
+                    , syb >= 0.3.6.1
+                    , split >= 0.2.1.1
+                    -- These are available from HackageDB:
+                    , strings >= 1.1
+                    , multimap >= 1.2
+                    , names >= 0.3.1 && < 0.4
+                    , named-records >= 0.5
+                    -- These are also available form HackageDB but from
+                    -- another maintainer than this package:
+                    , bimap >= 0.2.4
+                    , hint >= 0.3.3.4
+
+
+Executable h2js
+    if flag(ONLY_CORE)
+        buildable: False
+    else
+        if flag(NO_TOOLS)
+            buildable: False
+        else
+            buildable: True
+
+    hs-source-dirs: hs2j
+    main-is: Main.hs
+
+    other-modules:  Common
+                    , Options
+                    , Haskell2Java
+
+    build-depends:  base >= 4.5 && < 5
+                    , java-bridge
+                    -- The following are part of the GHC core packages:
+                    , containers >= 0.4.2.1
+                    , directory >= 1.1.0.2
+                    , filepath >= 1.3
+                    -- These are part of the Haskell Platform:
+                    , syb >= 0.3.6.1
+                    , split >= 0.2.1.1
+                    -- These are available from HackageDB:
+                    , strings >= 1.1
+                    , multimap >= 1.1
+                    , names >= 0.3.1 && < 0.4
+                    , named-records >= 0.5
+                    -- These are also available form HackageDB but from
+                    -- another maintainer than this package:
+                    , bimap >= 0.2.4
+                    , hint >= 0.3.3.4
+
+
+Executable java-calculator
+    if flag(EXAMPLES)
+        if os(darwin)
+            if flag(OSX_GUI)
+                buildable: True
+            else
+                buildable: False
+        else
+            buildable: True
+    else
+        buildable: False
+
+    build-depends:  base >= 4 && < 5
+                    , java-bridge
+
+    hs-source-dirs: examples/calculator/src
+    main-is: calculator.hs
+
+    ghc-options: -threaded
+
+
+Executable java-system-properties
+    if flag(EXAMPLES)
+        buildable: True
+    else
+        buildable: False
+
+    build-depends:  base >= 4 && < 5
+                    , java-bridge
+
+    hs-source-dirs: examples/system-properties
+    main-is: system-properties.hs
+
 
diff --git a/src/Foreign/Java.cpphs b/src/Foreign/Java.cpphs
--- a/src/Foreign/Java.cpphs
+++ b/src/Foreign/Java.cpphs
@@ -212,10 +212,7 @@
     asObject :: a -> Java JObject
 
     -- | Returns a reference to the Class of the given object.
-    classOf :: a -> Java JClass
-
-    -- | Returns a string representation of the type.
-    jtypeOf :: a -> Java String
+    classOf  :: a -> Java JClass
 
     -- | Checks two objects for equality using their @equals@ methods.
     equals   :: JavaObject b => a -> b -> Java Bool
@@ -223,10 +220,6 @@
     toString obj = asObject obj >>= toString
     hashCode obj = asObject obj >>= hashCode
     classOf obj  = asObject obj >>= classOf
-    jtypeOf obj  = do
-        (Just clazz) <- getClass "java.lang.Class"
-        getName <- clazz `bindMethod` "getName" ::= string
-        classOf obj >>= asObject >>= getName >>= return . maybe "" id
 
     equals this obj = do
         this'  <- asObject this
diff --git a/src/Foreign/Java/Bindings.cpphs b/src/Foreign/Java/Bindings.cpphs
deleted file mode 100644
--- a/src/Foreign/Java/Bindings.cpphs
+++ /dev/null
@@ -1,384 +0,0 @@
-{-# LANGUAGE Haskell2010
-    , TypeFamilies
-    , FlexibleContexts
-    , FlexibleInstances
-    , TypeSynonymInstances
-    , MultiParamTypeClasses
-    , ScopedTypeVariables
-    , NoImplicitPrelude
- #-}
-{-# OPTIONS
-    -Wall
- #-}
-
--- |
--- Module       : Foreign.Java.Bindings.Support
--- Copyright    : (c) Julian Fleischer 2013
--- License      : MIT (See LICENSE file in cabal package)
---
--- Maintainer   : julian.fleischer@fu-berlin.de
--- Stability    : experimental
--- Portability  : non-portable (TypeFamilies)
---
--- This module provides type classes and instances for
--- supporting the high level bindings. This module should
--- not be imported directly.
-module Foreign.Java.Bindings where
-
-import Haskell.X.Prelude hiding (toList, arr)
-
-import Control.Monad.State hiding (void)
-
-import Foreign
-import Foreign.C
-
-import Foreign.Java
-import Foreign.Java.JavaMonad
-import Foreign.Java.Types as T
-import qualified Foreign.Java.JNI.Safe as JNI
-import qualified Foreign.Java.JNI.Types as Core
-
-
----------------
--- Utilities --
----------------
-
-
-object' :: [Char] -> Q
-object' = T.object'
-
-
-------------------------------
--- Primitive argument types --
-------------------------------
-
-class JBoolean a  where toBoolean :: a -> Java Bool
-class JChar a     where toChar    :: a -> Java Word16
-class JByte a     where toByte    :: a -> Java Int8
-class JShort a    where toShort   :: a -> Java Int16
-class JInt a      where toInt     :: a -> Java Int32
-class JLong a     where toLong    :: a -> Java Int64
-class JFloat a    where toFloat   :: a -> Java Float
-class JDouble a   where toDouble  :: a -> Java Double
-
-
-instance JBoolean Bool   where toBoolean = return
-
-instance JChar Char      where toChar = return . fromIntegral . fromEnum
-instance JChar Int8      where toChar = return . fromIntegral
-instance JChar Word16    where toChar = return
-
-instance JByte Int8      where toByte = return
-
-instance JShort Int8     where toShort = return . fromIntegral
-instance JShort Word8    where toShort = return . fromIntegral
-instance JShort Int16    where toShort = return
-
-instance JInt Int        where toInt = return . fromIntegral
-instance JInt Int8       where toInt = return . fromIntegral
-instance JInt Word8      where toInt = return . fromIntegral
-instance JInt Int16      where toInt = return . fromIntegral
-instance JInt Word16     where toInt = return . fromIntegral
-instance JInt Int32      where toInt = return
-
-instance JLong Int       where toLong = return . fromIntegral
-instance JLong Int8      where toLong = return . fromIntegral
-instance JLong Word8     where toLong = return . fromIntegral
-instance JLong Int16     where toLong = return . fromIntegral
-instance JLong Word16    where toLong = return . fromIntegral
-instance JLong Int32     where toLong = return . fromIntegral
-instance JLong Word32    where toLong = return . fromIntegral
-instance JLong Int64     where toLong = return
-
-instance JFloat CFloat   where toFloat = return . realToFrac
-instance JFloat Float    where toFloat = return
-
-instance JDouble CDouble where toDouble = return . realToFrac
-instance JDouble Double  where toDouble = return
-
-
---------------------------
--- Array argument types --
---------------------------
-
-class Array a where
-    asMaybeArrayObject :: a -> Java (Maybe JObject)
-
-
-----------------------------
--- Primitive result types --
-----------------------------
-
-#define PRIMITIVE_RESULT(NAME, TYPE) \
-    class NAME ## Result m where {\
-        to ## NAME ## Result :: Either JThrowable TYPE -> Java m }\
-    ;\
-    instance NAME ## Result TYPE where {\
-        to ## NAME ## Result = either (\exc -> toString exc >>= fail) return }\
-    ;\
-    instance NAME ## Result (Either JThrowable TYPE) where {\
-        to ## NAME ## Result = return }
-
--- | The result of a function call that is of type @boolean@.
-PRIMITIVE_RESULT(Boolean, Bool)
--- | The result of a function call that is of type @char@.
-PRIMITIVE_RESULT(Char, Word16)
--- | The result of a function call that is of type @byte@.
-PRIMITIVE_RESULT(Byte, Int8)
--- | The result of a function call that is of type @short@.
-PRIMITIVE_RESULT(Short, Int16)
--- | The result of a function call that is of type @int@.
-PRIMITIVE_RESULT(Int, Int32)
--- | The result of a function call that is of type @long@.
-PRIMITIVE_RESULT(Long, Int64)
--- | The result of a function call that is of type @float@.
-PRIMITIVE_RESULT(Float, Float)
--- | The result of a function call that is of type @double@.
-PRIMITIVE_RESULT(Double, Double)
-
--- | The result of a function call that is of type @void@.
-class VoidResult m where
-    toVoidResult :: Either JThrowable () -> Java m
-    
-instance VoidResult () where
-    toVoidResult = either (\exc -> toString exc >>= fail) return
-
-instance VoidResult (Either JThrowable ()) where
-    toVoidResult = return
-    
-instance VoidResult (Maybe JThrowable) where
-    toVoidResult = return . either Just (const Nothing)
-
-
-------------------------
--- Array result types --
-------------------------
-
--- | An array result of a function call.
-class JavaArray (ArrayResultType m) (ArrayResultComponent m) => ArrayResult m where
-    -- | The JVM machine type of the components of the array.
-    type ArrayResultType m
-
-    -- | The type of the component of the array as returned by
-    -- the low level JNI call.
-    type ArrayResultComponent m
-
-    -- | Convert the array to a sophisticated type.
-    toArrayResult :: Either JThrowable (Maybe (JArray (ArrayResultType m))) -> Java m
-
-instance ArrayResult a => ArrayResult (Either JThrowable a) where
-    type ArrayResultType (Either JThrowable a) = ArrayResultType a
-    type ArrayResultComponent (Either JThrowable a) = ArrayResultComponent a
-
-    toArrayResult = either (return . Left) (toArrayResult . Right)
-
-#define ARRAY_RESULT(TYPE, PRIM) \
-    instance ArrayResult [TYPE] where {\
-        type ArrayResultType [TYPE] = T.PRIM ;\
-        type ArrayResultComponent [TYPE] = TYPE ;\
-        \
-        toArrayResult = either (\exc -> toString exc >>= fail) \
-                               (maybe (return []) toList) }
-
-ARRAY_RESULT(Bool,   Z)
-ARRAY_RESULT(Word16, C)
-ARRAY_RESULT(Int8,   B)
-ARRAY_RESULT(Int16,  S)
-ARRAY_RESULT(Int32,  I)
-ARRAY_RESULT(Int64,  J)
-ARRAY_RESULT(Float,  F)
-ARRAY_RESULT(Double, D)
-
-
-instance ArrayResult [Char] where
-    type ArrayResultType [Char] = T.C
-    type ArrayResultComponent [Char] = Word16
-
-    toArrayResult = either (\exc -> toString exc >>= fail)
-                           (maybe (return [])
-                                  (fmap (map (toEnum . fromIntegral)) . toList))
-
-instance ArrayResult [[Char]] where
-    type ArrayResultType [[Char]] = T.L
-    type ArrayResultComponent [[Char]] = Maybe JObject
-
-    toArrayResult =
-        either (\exc -> toString exc >>= fail)
-               (maybe (return [])
-                      (\arr -> toList arr >>= mapM (maybe (return "") toString)))
-
-
-
------------------------
--- All other objects --
------------------------
-
-newtype AsString o = AsString [Char]
-    deriving (Eq, Show, Ord)
-
-newtype AsList a o = AsList [a]
-    deriving (Eq, Show, Ord)
-
-class ObjectToList o e where
-    objectToList :: o -> JObject -> Java [e]
-
--- | The result of a function call that is of type @object@.
-class ObjectResult m where
-    -- | 
-    toObjectResult :: Either JThrowable (Maybe JObject) -> Java m
-
-instance ObjectResult (AsString a) where
-    toObjectResult = fmap AsString . either (\exc -> toString exc >>= fail)
-                                            (maybe (return "null") toString)
-
-instance ObjectToList o e => ObjectResult (AsList e o) where
-    toObjectResult = fmap AsList . either (\exc -> toString exc >>= fail)
-                                          (maybe (return []) (objectToList (undefined :: o)))
-
-instance UnsafeCast a => ObjectResult (Value a) where
-    toObjectResult = either (return . Fail)
-                            (maybe (return NoValue)
-                                   (fmap Value . unsafeFromJObject))
-
-instance UnsafeCast a => ObjectResult (Either JThrowable a) where
-    toObjectResult = either (return . Left)
-                            (maybe (fmap Left nullPointer)
-                                   (fmap Right . unsafeFromJObject))
-      where
-        nullPointer :: Java JThrowable
-        nullPointer = do
-            (Just clazz) <- getClass "java.lang.NullPointerException"
-            (Just (Core.JObject obj)) <- newObject clazz
-            return $ Core.JThrowable (castForeignPtr obj)
-
-instance UnsafeCast a => ObjectResult (Either (Maybe JThrowable) a) where
-    toObjectResult = either (return . Left . Just)
-                            (maybe (return (Left Nothing))
-                                   (fmap Right . unsafeFromJObject))
-
-instance UnsafeCast a => ObjectResult (Maybe a) where
-    toObjectResult = either (\exc -> toString exc >>= fail)
-                            (maybe (return Nothing)
-                                   (fmap Just . unsafeFromJObject))
-
-
----------------------------------------------------
--- Advanced features (Callbacks, Subtyping, ...) --
----------------------------------------------------
-
-
--- | A convenient alternative to 'isInstanceOf'.
---
--- Minimal complete definition: 'coerce' or 'whenInstanceOf'.
-class InstanceOf a where
-    type CoercedType a
-
-    -- | Check if the object of type @a@ is an instance
-    -- of the type represented by @b@. 
-    instanceOf :: JavaObject o => o -> a -> Java Bool
-
-    -- | Check if the object of type @a@ is an instance
-    -- of the type @c@, represented by @b@. If so, it will coerce
-    -- the object of type @a@ and pass it to the given action.
-    --
-    -- If @a@ was an instance of @c@ (where @c@ is represented
-    -- by @b@) this function will return @'Just' d@, where @d@ is
-    -- the result of the optional computation. If not, 'Nothing'
-    -- is returned.
-    whenInstanceOf :: JavaObject o => o -> a -> (CoercedType a -> Java d) -> Java (Maybe d)
-
-    -- | Coerces the given object of type @a@ to an object of
-    -- @c@, where @c@ is represented by a value of type @b@.
-    -- Returns @'Nothing'@ if this is not possible.
-    coerce :: JavaObject o => o -> a -> Java (Maybe (CoercedType a))
-
-    instanceOf o t =
-        whenInstanceOf o t (return . const ())
-            >>= return . maybe False (const True)
-
-    whenInstanceOf o t a =
-        coerce o t >>= maybe (return Nothing) (fmap Just . a)
-
-    coerce o t = whenInstanceOf o t return
-
--- | For INTERNAL use only. Is however not in a hidden module,
--- so that other libraries can link against it.
-class UnsafeCast a where
-    -- | For INTERNAL use only. Do not use yourself.
-    unsafeFromJObject :: JObject -> Java a
-
-
-
----------------
--- Callbacks --
----------------
-
-
-registerCallbacks :: Core.JClass -> Java Bool
--- ^ Yepp. Register callbacks. Do it.
-registerCallbacks (Core.JClass ptr) = do
-    vm <- getVM
-    io $ withForeignPtr ptr $ \clazz -> JNI.registerCallbacks vm clazz
-
-
--- | A wrapped function can be used as a callback from the
--- JVM into the Haskell runtime environment.
-type WrappedFunc = Ptr Core.JVM -- Ptr to JEnv
-               -> Ptr Core.JObjectRef -- Ptr to this, a proxy
-               -> Ptr Core.JObjectRef -- Ptr to method, the requested method
-               -> Ptr Core.JObjectRef -- Ptr to a JObject-Array (Object[]), the arguments
-               -> IO (Ptr Core.JObjectRef) -- Returns a pointer to the result
-
-type InterfaceFunc = JObject -> JObject -> JObject -> Java (Maybe JObject)
-
-runJava_ :: Ptr Core.JVM -> Java a -> IO a
-runJava_ vm f = runStateT (_runJava f) (newJVMState vm) >>= return . fst
-
-foreign import ccall safe "wrapper"
-    wrap_ :: WrappedFunc -> IO (FunPtr WrappedFunc)
-
-foreign export ccall freeFunPtr :: FunPtr WrappedFunc -> IO ()
-
-
-freeFunPtr :: FunPtr WrappedFunc -> IO ()
-freeFunPtr ptr = freeHaskellFunPtr ptr
-
-
-implementInterfaceBy :: [Char] -> InterfaceFunc -> Java JObject
-implementInterfaceBy ifaceName func = do
-    iface <- getClass ifaceName >>= asObject . fromJust
-    (Just clazz) <- getClass "HFunction"
-    _success <- registerCallbacks clazz
-    makeFunction <- clazz `bindStaticMethod` "makeFunction"
-        ::= object "java.lang.Class" --> long --> object "java.lang.Object"
-    (Just impl) <- io (intify func) >>= makeFunction (Just iface)
-    return impl
-  where
-    wrap :: InterfaceFunc -> IO (FunPtr WrappedFunc)
-    wrap f = do
-
-        let proxyFunc vm self method args = do
-                self'   <- Core.JObject <$> newForeignPtr JNI.release self
-                method' <- Core.JObject <$> newForeignPtr JNI.release method
-                args'   <- Core.JObject <$> newForeignPtr JNI.release args
-
-                jobj <- runJava_ vm (f self' method' args')
-
-                case jobj of
-                    Nothing -> return nullPtr
-                    Just (Core.JObject ptr) -> withForeignPtr ptr return
-
-        wrappedFunc <- wrap_ proxyFunc
-
-        return wrappedFunc
-
-    intify :: InterfaceFunc -> IO Int64
-    intify = fmap (fromIntegral . ptrToIntPtr . castFunPtrToPtr) . wrap
-
-
-delete :: Core.JObject -> Java ()
-delete (Core.JObject ptr) = io $ do
-    finalizeForeignPtr ptr
-
-
-
diff --git a/src/Foreign/Java/Bindings.hss b/src/Foreign/Java/Bindings.hss
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings.hss
@@ -0,0 +1,221 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# OPTIONS -Wall #-}
+
+-- | Functions for generating glue code between Haskell and Java.
+module Foreign.Java.Bindings (
+
+    -- * Create Haskell glue code from Java definitions
+    printJavaPackageModule,
+    printJavaClassModule,
+    printJavaClassBootfile,
+    printJavaClassModule',
+    printJavaClassBootfile',
+
+    -- * Reflect Java classes
+    reflectJavaClasses,
+    findJavaClasses,
+
+    -- ** A priori known information about Java
+    javaClassesSE6
+
+  ) where
+
+import Foreign.Java
+import Foreign.Java.Utils
+import qualified Foreign.Java.Bindings.JavaSE6
+
+import Foreign.Java.Bindings.JavaTypes
+import qualified Foreign.Java.Bindings.Java2Haskell as Java2Haskell
+import qualified Foreign.Java.Bindings.ReflectJava  as ReflectJava
+
+import Foreign.Java.Bindings.HaskellTypes
+import qualified Foreign.Java.Bindings.Haskell2Java   as Haskell2Java
+import qualified Foreign.Java.Bindings.ReflectHaskell as ReflectHaskell
+
+import Data.Word
+
+import Data.Map (Map)
+import qualified Data.List as List
+import qualified Data.Map  as Map
+
+
+javaClassesSE6 :: [String]
+-- ^ The names of all Java Classes part of Java SE 6.
+javaClassesSE6 = Foreign.Java.Bindings.JavaSE6.javaClassesSE6
+
+imports :: String
+-- ^ Imports of all auto generated java code files.
+imports  = """
+    import qualified Foreign.Java as JNI
+    import Foreign.Java ((-->))
+    import qualified Prelude as Prelude
+    import Prelude ((.), ($), (>>=), (>>), return)
+    import qualified Foreign.Java.Bindings.Support as JNIS
+    import Data.Functor ((<$>))
+    """
+
+classInfoSignature :: String
+-- ^ 
+classInfoSignature = "Prelude.String"
+
+classInfo' :: JavaClass -> String
+-- ^ 
+classInfo' clazz = className clazz
+
+packageInfo' packageName classes = packageName
+
+printJavaPackageModule :: String      -- The Java package name
+                       -> String      -- The Haskell module name of the Java package
+                       -> Map String JavaClass -- Info about all other classes
+                       -> [JavaClass] -- The Java classes contained in the Java package
+                       -> String
+-- ^ 
+printJavaPackageModule packageName modName classInfo classes = """
+    {-# LANGUAGE Haskell2010 #-}
+    -- | Package @#{packageName}@
+    module #{modName} (
+    #{moduleExports}\
+        info'
+    ) where
+    #{imports}
+    #{moduleImports}
+    -- Information about this package.
+    info' = #{show $ packageInfo' packageName classes}
+    #{moduleDeclarations}
+    """
+  where moduleDeclarations   = Java2Haskell.pkgModDecl     classInfo classes
+        moduleImports        = Java2Haskell.pkgModImports  classInfo classes
+        moduleExports        = Java2Haskell.pkgModExports  classInfo classes
+
+
+printJavaClassModule :: JavaClass -- The Java class
+                     -> String    -- The Haskell module name of the Java class
+                     -> Map String JavaClass -- Info about all classes
+                     -> String
+-- ^ 
+printJavaClassModule clazz modName classInfo = """
+    {-# LANGUAGE Haskell2010 #-}
+    -- | #{show $ classType clazz} @#{classFullName clazz}@
+    module #{modName} (
+    #{moduleExports}\
+        -- * Information about this class.
+        info'
+    ) where
+    #{imports}
+    #{bootfileImports}
+    #{moduleImports}
+    info' = #{show $ classInfo' clazz}
+    #{bootfileDeclarations}
+    #{moduleDeclarations}
+    """
+  where bootfileDeclarations = Java2Haskell.classBootDecl    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports classInfo clazz
+        moduleDeclarations   = Java2Haskell.classModDecl     classInfo clazz
+        moduleImports        = Java2Haskell.classModImports  classInfo clazz
+        moduleExports        = Java2Haskell.classModExports  classInfo clazz
+
+
+printJavaClassBootfile :: JavaClass -- The Java class
+                       -> String    -- The Haskell module name of the Java class
+                       -> Map String JavaClass -- Info about all classes
+                       -> String
+-- ^ 
+printJavaClassBootfile clazz modName classInfo = """
+    {-# LANGUAGE Haskell2010 #-}
+    -- Bootfile for class #{className clazz}
+    module #{modName} (
+    #{bootfileExports}\
+        info'
+    ) where
+    #{imports}
+    #{bootfileImports}
+    info' :: #{classInfoSignature}
+    #{bootfileDeclarations}
+    """
+  where bootfileDeclarations = Java2Haskell.classBootDecl    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports classInfo clazz
+        bootfileExports      = Java2Haskell.classBootExports classInfo clazz
+
+
+printJavaClassModule' :: JavaClass -- The Java class
+                      -> String    -- The Haskell module name of the Java class
+                      -> Map String JavaClass -- Info about all classes
+                      -> String
+-- ^ 
+printJavaClassModule' clazz modName classInfo = """
+    {-# LANGUAGE Haskell2010, TypeFamilies #-}
+    -- hidden @#{className clazz}@
+    module #{modName}__ (
+    #{moduleExports}\
+        info'
+    ) where
+    #{imports}
+    #{bootfileImports}
+    #{moduleImports}
+    info' = #{show $ classInfo' clazz}
+    #{bootfileDeclarations}
+    #{moduleDeclarations}
+    """
+  where bootfileDeclarations = Java2Haskell.classBootDecl'    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports' classInfo clazz
+        moduleDeclarations   = Java2Haskell.classModDecl'     classInfo clazz
+        moduleImports        = Java2Haskell.classModImports'  classInfo clazz
+        moduleExports        = Java2Haskell.classModExports'  classInfo clazz
+
+
+printJavaClassBootfile' :: JavaClass -- The Java class
+                        -> String    -- The Haskell module name of the Java class
+                        -> Map String JavaClass -- Info about all classes
+                        -> String
+-- ^ 
+printJavaClassBootfile' clazz modName classInfo = """
+    {-# LANGUAGE Haskell2010 #-}
+    -- hidden Bootfile for class #{className clazz}
+    module #{modName}__ (
+    #{bootfileExports}\
+        info'
+    ) where
+    #{imports}
+    #{bootfileImports}
+    info' :: #{classInfoSignature}
+    #{bootfileDeclarations}
+    """
+  where bootfileDeclarations = Java2Haskell.classBootDecl'    classInfo clazz
+        bootfileImports      = Java2Haskell.classBootImports' classInfo clazz
+        bootfileExports      = Java2Haskell.classBootExports' classInfo clazz
+
+
+reflectJavaClasses :: [String]
+                   -> Java [JavaClass]
+-- ^ Retrieve information about the given Java classes
+-- from the Java Virtual Machine.
+reflectJavaClasses = ReflectJava.reflectClasses
+
+
+findJavaClasses :: Word32 -- Maximum depth for following dependencies.
+                -> [String]
+                -> Java [String]
+-- ^ Find all classes that the given classes depend on.
+--
+-- In order to provide proper bindings for a class, bindings
+-- for all classes which a class depends on need to exist too.
+-- A class depends on all classes which it inherits from or
+-- which are used as arguments, return types, or parameters.
+--
+-- This functions returns all the class names of the classes
+-- on which the given classes depend on. No duplicates are
+-- reported and the resulting list is sorted.
+findJavaClasses = ReflectJava.findClasses
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Foreign/Java/Bindings/Haskell2Java.hss b/src/Foreign/Java/Bindings/Haskell2Java.hss
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/Haskell2Java.hss
@@ -0,0 +1,7 @@
+{-# LANGUAGE Haskell2010
+ #-}
+
+module Foreign.Java.Bindings.Haskell2Java where
+
+
+
diff --git a/src/Foreign/Java/Bindings/HaskellTypes.hs b/src/Foreign/Java/Bindings/HaskellTypes.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/HaskellTypes.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE Haskell2010 #-}
+
+
+module Foreign.Java.Bindings.HaskellTypes where
+
+
+data HaskellModule = HaskellModule {
+    moduleName :: String,
+    moduleFunctions :: [HaskellFunction],
+    moduleData :: [HaskellData]
+    
+  } deriving (Show, Eq)
+
+
+data HaskellData = HaskellData {
+    dataName :: String,
+    dataConstructors :: [HaskellConstructor]
+    
+    
+  } deriving (Show, Eq)
+
+
+data HaskellFunction = HaskellFunction {
+    functionName :: String,
+    functionArgs :: [HaskellType],
+    functionReturn :: HaskellType
+    
+  } deriving (Show, Eq)
+
+
+data HaskellConstructor = HaskellConstructor {
+    constructorName :: String,
+    constructorField :: (String, HaskellType)
+    
+  } deriving (Show, Eq)
+
+
+data HaskellType = HaskellType {
+
+  } deriving (Show, Eq)
+
+
+
diff --git a/src/Foreign/Java/Bindings/Java2Haskell.hss b/src/Foreign/Java/Bindings/Java2Haskell.hss
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/Java2Haskell.hss
@@ -0,0 +1,284 @@
+{-# LANGUAGE Haskell2010 #-}
+
+module Foreign.Java.Bindings.Java2Haskell where
+
+import Foreign.Java.Util
+import Foreign.Java.Utils
+import Foreign.Java.Bindings.JavaTypes
+import Foreign.Java.Bindings.Typomatic
+import Data.Map (Map)
+
+import Data.Function
+
+import qualified Data.Char as Char
+import qualified Data.List as List
+import qualified Data.Set  as Set
+import qualified Data.Map  as Map
+
+import qualified Data.List.HIUtils as HI
+
+import Control.Arrow
+
+pkgModExports :: Map String JavaClass -> [JavaClass] -> String
+pkgModExports info classes = concatMap (\(t, b) -> """    -- * #{show t}s\n#{b}""")
+        $ map (second $ concatMap format)
+        $ HI.aggregateAL
+        $ zip (map classType classes) classes
+  where
+    format clazz =
+        let haskName  = takeClassName $ classModName clazz
+            javaName  = className clazz
+            dataDecl  = if classIface clazz then "" else
+                """    #{dataTName haskName} (..),\n"""
+        in """
+            -- ** #{show $ classType clazz} #{javaName}
+            -- | For constructors, methods, and so on, see: "#{classModName clazz}".
+            #{tyclTName haskName},
+        #{dataDecl}\
+            #{newtTName haskName} #{if classEnum clazz then "(..)" else ""},
+        """
+
+
+pkgModImports :: Map String JavaClass -> [JavaClass] -> String
+pkgModImports info classes = concatMap (format . classModName) classes
+  where format modName = """import #{modName}__ hiding (info')\n"""
+
+
+pkgModDecl :: Map String JavaClass -> [JavaClass] -> String
+pkgModDecl info classes = ""
+
+
+-- Modules and Boot files
+  
+classBootExports :: Map String JavaClass -> JavaClass -> String
+classBootExports info clazz = ""
+
+
+classBootImports :: Map String JavaClass -> JavaClass -> String
+classBootImports info clazz = ""
+
+
+classModImports :: Map String JavaClass -> JavaClass -> String
+classModImports info clazz = concatMap format references
+  where
+    format package = """import qualified #{package}\n"""
+    references = Set.toList
+        $ Set.map (fst . splitClassName . classModName . check . flip Map.lookup info)
+        $ Set.fromList (classFullName clazz : dependencies)
+    dependencies = classDependencies clazz
+    check = maybe (error """
+        classModImports in Foreign.Java.Bindings.Java2Haskell \
+        - class definition not found""") id
+
+
+classBootDecl :: Map String JavaClass -> JavaClass -> String
+classBootDecl info clazz = """
+    """
+
+classModExports :: Map String JavaClass -> JavaClass -> String
+classModExports info clazz = "    -- * Methods\n" ++ concatMap methodExport methodNames
+  where
+    methods = List.sortBy (compare `on` methodName) (classMethods clazz)
+    methodNames = mkMethodNames methods
+    methodExport name = name ++ ",    \n"
+
+
+classModDecl :: Map String JavaClass -> JavaClass -> String
+classModDecl info clazz = concatMap methodDecl $ zip methodNames methods
+  where
+    methods = List.sortBy (compare `on` methodName) (classMethods clazz)
+    methodNames = mkMethodNames methods
+    methodDecl (name, method)
+        | arrayTypes = """
+            #{name} :: #{signature}
+            #{name} = Prelude.undefined
+            """
+        | otherwise = """
+            #{haddock}
+            #{name} :: #{signature}
+            #{name}#{argsDecl} = do
+                (Prelude.Just clazz) <- JNI.getClass "#{classFullName clazz}"
+                (Prelude.Just method) <- clazz `JNI.#{getMethod}` #{jniSignature}
+            #{thisArg}\
+            #{readArgs}\
+                result <- JNI.#{callMethod} method #{argsRefs}
+                #{convertResult} result
+            """
+      where
+        arrayTypes
+--            | any isArrayType (methodParams method) = True
+            | (Just ret) <- methodReturnType method = isArrayType ret
+            | otherwise = False
+        isArrayType x = case x of JArr _ -> True ; _ -> False
+        isStatic = methodStatic method
+        javaSignature = fJavaSignature argsInfo
+        javaReturnType = fJavaReturnType argsInfo
+        jniSignature = fJniSignature argsInfo
+        signature = fSignature argsInfo
+        getMethod = if isStatic then "getStaticMethod" else "getMethod"
+        callMethod = if isStatic then "callStaticMethodE" else "callMethodE"
+        args = fArgNames argsInfo
+        argsNotThis = (if isStatic then id else tail) args
+        argsInfo = runTypomatic info (typomatic clazz method)
+        argsDecl = concatMap (' ':) args
+        argsRefs = concatMap (++ "' ") args
+        haddock = """
+            -- | @#{if isStatic then "static " else "virtual "}\
+            #{if methodSynchronized method then "synchronized " else ""}\
+            #{if methodNative method then "native " else ""}\
+            #{if methodFinal method then "final " else ""}\
+            #{javaSignature} -> #{javaReturnType}@"""
+        thisArg = if isStatic then "" else """    #{head args}' <- JNI.asObject #{head args}\n"""
+        readArgs = concatMap (("    " ++). uncurry readArg) (zip argsNotThis (methodParams method))
+        readArg name jtype = case jtype of
+            JBoolean -> """#{name}' <- JNIS.toBoolean #{name}\n"""
+            JChar    -> """#{name}' <- JNIS.toChar #{name}\n"""
+            JByte    -> """#{name}' <- JNIS.toByte #{name}\n"""
+            JShort   -> """#{name}' <- JNIS.toShort #{name}\n"""
+            JInt     -> """#{name}' <- JNIS.toInt #{name}\n"""
+            JLong    -> """#{name}' <- JNIS.toLong #{name}\n"""
+            JFloat   -> """#{name}' <- JNIS.toFloat #{name}\n"""
+            JDouble  -> """#{name}' <- JNIS.toDouble #{name}\n"""
+            JObj _   -> """#{name}' <- Prelude.Just <$> JNI.asObject #{name}\n"""
+            JArr _   -> """#{name}' <- JNIS.asMaybeArrayObject #{name}\n"""
+        convertResult = ("JNIS." ++) $ case methodReturnType method of
+            Nothing -> "toVoidResult"
+            Just t -> case t of
+                JBoolean -> "toBooleanResult"
+                JChar    -> "toCharResult"
+                JByte    -> "toByteResult"
+                JShort   -> "toShortResult"
+                JInt     -> "toIntResult"
+                JLong    -> "toLongResult"
+                JFloat   -> "toFloatResult"
+                JDouble  -> "toDoubleResult"
+                JObj n   -> "toObjectResult"
+                JArr c   -> "toArrayResult"
+
+        
+
+mkMethodNames :: [JavaMethod] -> [String]
+mkMethodNames = concatMap (zipWith (flip (++)) (iterate (++"'") ""))
+                . List.group . map sanitize . map methodName
+  where
+    sanitize name
+        | Char.isUpper (head name) = '_' : name
+        | name `elem` haskellKeywords = name ++ "'"
+        | otherwise = name
+
+
+-- Hidden Modules and Boot files
+
+
+classModExports' :: Map String JavaClass -> JavaClass -> String
+classModExports' info clazz = """
+        #{tyclTName haskName},
+        #{dataTName haskName} (..),
+        #{newtTName haskName} #{if classEnum clazz then "(..)" else ""},
+    """
+  where
+    haskName = takeClassName $ classModName clazz
+    javaName = className clazz
+
+
+classBootExports' :: Map String JavaClass -> JavaClass -> String
+classBootExports' info clazz = """
+        #{tyclTName haskName},
+        #{dataTName haskName} (..),
+        #{newtTName haskName},
+    """
+  where
+    haskName = takeClassName $ classModName clazz
+    javaName = className clazz
+
+
+classBootImports' :: Map String JavaClass -> JavaClass -> String
+classBootImports' info clazz
+    = concatMap (format . classModName) supertypes
+  where
+    format modName = """import qualified #{modName}__\n"""
+    supertypes = map (check . flip Map.lookup info)
+               $ Set.toList
+               $ Set.fromList (classParents clazz ++ classIfaces clazz)
+    check = maybe (error """
+        classBootImports' in Foreign.Java.Bindings.Java2Haskell \
+        - class definition not found""") id
+
+
+classModImports' :: Map String JavaClass -> JavaClass -> String
+classModImports' info clazz = ""
+
+
+classBootDecl' :: Map String JavaClass -> JavaClass -> String
+classBootDecl' info clazz
+    | classEnum clazz = """
+        class #{tyclTDecl}
+        data #{newtTDecl} = #{enumConstants}
+        data #{dataTDecl} = #{dataCDecl}
+        """
+    | otherwise = """
+        class #{tyclTDecl}
+        newtype #{newtTDecl} = #{newtCDecl} JNI.JObject
+        data #{dataTDecl} = #{dataCDecl}
+        """
+  where baseName  = takeClassName $ classModName clazz
+        params    = concatMap (\(p:ps) -> ' ' : Char.toLower p : ps)
+                      $ map (tyVarName . paramName) $ classTypeParams clazz
+        newtTDecl = newtTName baseName ++ params
+        newtCDecl = newtCName baseName
+        dataTDecl = dataTName baseName ++ params
+        dataCDecl = dataCName baseName ++ params
+        tyclTDecl = """(JNI.JavaObject this#{context}) => #{tyclTName baseName} this"""
+        context = concatMap parentContext (classParents clazz)
+        parentContext parent = """, #{qualifiedName} this"""
+          where parentClass = info Map.! parent
+                modName = classModName parentClass
+                qualifiedName = modName ++ "__." ++ (tyclTName $ takeClassName modName)
+        enumConstants = concat $ List.intersperse " | " $ map sanitize $ map snd $ classEnumConstants clazz
+          where sanitize (x:xs) = Char.toUpper x : xs
+
+
+classModDecl' :: Map String JavaClass -> JavaClass -> String
+classModDecl' info clazz
+    | classEnum clazz = """
+        instance JNI.JavaObject (#{newtTDecl}) where
+            asObject = Prelude.undefined
+        instance #{tyclTName baseName} (#{newtTDecl})
+        instance JNIS.InstanceOf (#{dataTDecl}) where
+            type CoercedType (#{dataTDecl}) = (#{newtTDecl})
+        #{instances}
+        """
+    | otherwise = """
+        instance JNI.JavaObject (#{newtTDecl}) where
+            asObject (#{newtCName baseName} obj) = return obj
+        instance JNIS.UnsafeCast (#{newtTDecl}) where
+            unsafeFromJObject obj = return (#{newtCDecl} obj)
+        instance #{tyclTName baseName} (#{newtTDecl})
+        instance JNIS.InstanceOf (#{dataTDecl}) where
+            type CoercedType (#{dataTDecl}) = (#{newtTDecl})
+            coerce o t = do
+                obj <- JNI.asObject o
+                (Prelude.Just clazz) <- JNI.getClass "#{fullClassName}"
+                isInstanceOf <- obj `JNI.isInstanceOf` clazz
+                if isInstanceOf
+                    then Prelude.Just <$> (JNIS.unsafeFromJObject obj)
+                    else return Prelude.Nothing
+        #{instances}
+        """
+  where fullClassName = classFullName clazz
+        baseName  = takeClassName $ classModName clazz
+        params    = concatMap (\(p:ps) -> ' ' : Char.toLower p : ps)
+                      $ map (tyVarName . paramName) $ classTypeParams clazz
+        newtTDecl = newtTName baseName ++ params
+        newtCDecl = newtCName baseName
+        dataTDecl = dataTName baseName ++ params
+        dataCDecl = dataCName baseName ++ params
+        instances = concatMap parentInstance (classParents clazz)
+        parentInstance parent = """
+            instance #{qualifiedName} (#{newtTDecl})
+            """
+          where parentClass = info Map.! parent
+                modName = classModName parentClass
+                qualifiedName = modName ++ "__." ++ (tyclTName $ takeClassName modName)
+
+
diff --git a/src/Foreign/Java/Bindings/JavaSE6.hs b/src/Foreign/Java/Bindings/JavaSE6.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/JavaSE6.hs
@@ -0,0 +1,3800 @@
+{-# LANGUAGE Haskell2010 #-}
+
+module Foreign.Java.Bindings.JavaSE6 where
+
+javaClassesSE6
+  = [ "java.applet.Applet"
+    , "java.applet.AppletContext"
+    , "java.applet.AppletStub"
+    , "java.applet.AudioClip"
+    , "java.awt.AWTError"
+    , "java.awt.AWTEvent"
+    , "java.awt.AWTEventMulticaster"
+    , "java.awt.AWTException"
+    , "java.awt.AWTKeyStroke"
+    , "java.awt.AWTPermission"
+    , "java.awt.ActiveEvent"
+    , "java.awt.Adjustable"
+    , "java.awt.AlphaComposite"
+    , "java.awt.BasicStroke"
+    , "java.awt.BorderLayout"
+    , "java.awt.BufferCapabilities"
+    , "java.awt.BufferCapabilities$FlipContents"
+    , "java.awt.Button"
+    , "java.awt.Canvas"
+    , "java.awt.CardLayout"
+    , "java.awt.Checkbox"
+    , "java.awt.CheckboxGroup"
+    , "java.awt.CheckboxMenuItem"
+    , "java.awt.Choice"
+    , "java.awt.Color"
+    , "java.awt.Component"
+    , "java.awt.Component$BaselineResizeBehavior"
+    , "java.awt.ComponentOrientation"
+    , "java.awt.Composite"
+    , "java.awt.CompositeContext"
+    , "java.awt.Container"
+    , "java.awt.ContainerOrderFocusTraversalPolicy"
+    , "java.awt.Cursor"
+    , "java.awt.DefaultFocusTraversalPolicy"
+    , "java.awt.DefaultKeyboardFocusManager"
+    , "java.awt.Desktop"
+    , "java.awt.Desktop$Action"
+    , "java.awt.Dialog"
+    , "java.awt.Dialog$ModalExclusionType"
+    , "java.awt.Dialog$ModalityType"
+    , "java.awt.Dimension"
+    , "java.awt.DisplayMode"
+    , "java.awt.Event"
+    , "java.awt.EventQueue"
+    , "java.awt.FileDialog"
+    , "java.awt.FlowLayout"
+    , "java.awt.FocusTraversalPolicy"
+    , "java.awt.Font"
+    , "java.awt.FontFormatException"
+    , "java.awt.FontMetrics"
+    , "java.awt.Frame"
+    , "java.awt.GradientPaint"
+    , "java.awt.Graphics"
+    , "java.awt.Graphics2D"
+    , "java.awt.GraphicsConfigTemplate"
+    , "java.awt.GraphicsConfiguration"
+    , "java.awt.GraphicsDevice"
+    , "java.awt.GraphicsEnvironment"
+    , "java.awt.GridBagConstraints"
+    , "java.awt.GridBagLayout"
+    , "java.awt.GridBagLayoutInfo"
+    , "java.awt.GridLayout"
+    , "java.awt.HeadlessException"
+    , "java.awt.IllegalComponentStateException"
+    , "java.awt.Image"
+    , "java.awt.ImageCapabilities"
+    , "java.awt.Insets"
+    , "java.awt.ItemSelectable"
+    , "java.awt.JobAttributes"
+    , "java.awt.JobAttributes$DefaultSelectionType"
+    , "java.awt.JobAttributes$DestinationType"
+    , "java.awt.JobAttributes$DialogType"
+    , "java.awt.JobAttributes$MultipleDocumentHandlingType"
+    , "java.awt.JobAttributes$SidesType"
+    , "java.awt.KeyEventDispatcher"
+    , "java.awt.KeyEventPostProcessor"
+    , "java.awt.KeyboardFocusManager"
+    , "java.awt.Label"
+    , "java.awt.LayoutManager"
+    , "java.awt.LayoutManager2"
+    , "java.awt.LinearGradientPaint"
+    , "java.awt.List"
+    , "java.awt.MediaTracker"
+    , "java.awt.Menu"
+    , "java.awt.MenuBar"
+    , "java.awt.MenuComponent"
+    , "java.awt.MenuContainer"
+    , "java.awt.MenuItem"
+    , "java.awt.MenuShortcut"
+    , "java.awt.MouseInfo"
+    , "java.awt.MultipleGradientPaint"
+    , "java.awt.MultipleGradientPaint$ColorSpaceType"
+    , "java.awt.MultipleGradientPaint$CycleMethod"
+    , "java.awt.PageAttributes"
+    , "java.awt.PageAttributes$ColorType"
+    , "java.awt.PageAttributes$MediaType"
+    , "java.awt.PageAttributes$OrientationRequestedType"
+    , "java.awt.PageAttributes$OriginType"
+    , "java.awt.PageAttributes$PrintQualityType"
+    , "java.awt.Paint"
+    , "java.awt.PaintContext"
+    , "java.awt.Panel"
+    , "java.awt.Point"
+    , "java.awt.PointerInfo"
+    , "java.awt.Polygon"
+    , "java.awt.PopupMenu"
+    , "java.awt.PrintGraphics"
+    , "java.awt.PrintJob"
+    , "java.awt.RadialGradientPaint"
+    , "java.awt.Rectangle"
+    , "java.awt.RenderingHints"
+    , "java.awt.RenderingHints$Key"
+    , "java.awt.Robot"
+    , "java.awt.ScrollPane"
+    , "java.awt.ScrollPaneAdjustable"
+    , "java.awt.Scrollbar"
+    , "java.awt.Shape"
+    , "java.awt.SplashScreen"
+    , "java.awt.Stroke"
+    , "java.awt.SystemColor"
+    , "java.awt.SystemTray"
+    , "java.awt.TextArea"
+    , "java.awt.TextComponent"
+    , "java.awt.TextField"
+    , "java.awt.TexturePaint"
+    , "java.awt.Toolkit"
+    , "java.awt.Transparency"
+    , "java.awt.TrayIcon"
+    , "java.awt.TrayIcon$MessageType"
+    , "java.awt.Window"
+    , "java.awt.color.CMMException"
+    , "java.awt.color.ColorSpace"
+    , "java.awt.color.ICC_ColorSpace"
+    , "java.awt.color.ICC_Profile"
+    , "java.awt.color.ICC_ProfileGray"
+    , "java.awt.color.ICC_ProfileRGB"
+    , "java.awt.color.ProfileDataException"
+    , "java.awt.datatransfer.Clipboard"
+    , "java.awt.datatransfer.ClipboardOwner"
+    , "java.awt.datatransfer.DataFlavor"
+    , "java.awt.datatransfer.FlavorEvent"
+    , "java.awt.datatransfer.FlavorListener"
+    , "java.awt.datatransfer.FlavorMap"
+    , "java.awt.datatransfer.FlavorTable"
+    , "java.awt.datatransfer.MimeTypeParseException"
+    , "java.awt.datatransfer.StringSelection"
+    , "java.awt.datatransfer.SystemFlavorMap"
+    , "java.awt.datatransfer.Transferable"
+    , "java.awt.datatransfer.UnsupportedFlavorException"
+    , "java.awt.dnd.Autoscroll"
+    , "java.awt.dnd.DnDConstants"
+    , "java.awt.dnd.DragGestureEvent"
+    , "java.awt.dnd.DragGestureListener"
+    , "java.awt.dnd.DragGestureRecognizer"
+    , "java.awt.dnd.DragSource"
+    , "java.awt.dnd.DragSourceAdapter"
+    , "java.awt.dnd.DragSourceContext"
+    , "java.awt.dnd.DragSourceDragEvent"
+    , "java.awt.dnd.DragSourceDropEvent"
+    , "java.awt.dnd.DragSourceEvent"
+    , "java.awt.dnd.DragSourceListener"
+    , "java.awt.dnd.DragSourceMotionListener"
+    , "java.awt.dnd.DropTarget"
+    , "java.awt.dnd.DropTarget$DropTargetAutoScroller"
+    , "java.awt.dnd.DropTargetAdapter"
+    , "java.awt.dnd.DropTargetContext"
+    , "java.awt.dnd.DropTargetDragEvent"
+    , "java.awt.dnd.DropTargetDropEvent"
+    , "java.awt.dnd.DropTargetEvent"
+    , "java.awt.dnd.DropTargetListener"
+    , "java.awt.dnd.InvalidDnDOperationException"
+    , "java.awt.dnd.MouseDragGestureRecognizer"
+    , "java.awt.event.AWTEventListener"
+    , "java.awt.event.AWTEventListenerProxy"
+    , "java.awt.event.ActionEvent"
+    , "java.awt.event.ActionListener"
+    , "java.awt.event.AdjustmentEvent"
+    , "java.awt.event.AdjustmentListener"
+    , "java.awt.event.ComponentAdapter"
+    , "java.awt.event.ComponentEvent"
+    , "java.awt.event.ComponentListener"
+    , "java.awt.event.ContainerAdapter"
+    , "java.awt.event.ContainerEvent"
+    , "java.awt.event.ContainerListener"
+    , "java.awt.event.FocusAdapter"
+    , "java.awt.event.FocusEvent"
+    , "java.awt.event.FocusListener"
+    , "java.awt.event.HierarchyBoundsAdapter"
+    , "java.awt.event.HierarchyBoundsListener"
+    , "java.awt.event.HierarchyEvent"
+    , "java.awt.event.HierarchyListener"
+    , "java.awt.event.InputEvent"
+    , "java.awt.event.InputMethodEvent"
+    , "java.awt.event.InputMethodListener"
+    , "java.awt.event.InvocationEvent"
+    , "java.awt.event.ItemEvent"
+    , "java.awt.event.ItemListener"
+    , "java.awt.event.KeyAdapter"
+    , "java.awt.event.KeyEvent"
+    , "java.awt.event.KeyListener"
+    , "java.awt.event.MouseAdapter"
+    , "java.awt.event.MouseEvent"
+    , "java.awt.event.MouseListener"
+    , "java.awt.event.MouseMotionAdapter"
+    , "java.awt.event.MouseMotionListener"
+    , "java.awt.event.MouseWheelEvent"
+    , "java.awt.event.MouseWheelListener"
+    , "java.awt.event.PaintEvent"
+    , "java.awt.event.TextEvent"
+    , "java.awt.event.TextListener"
+    , "java.awt.event.WindowAdapter"
+    , "java.awt.event.WindowEvent"
+    , "java.awt.event.WindowFocusListener"
+    , "java.awt.event.WindowListener"
+    , "java.awt.event.WindowStateListener"
+    , "java.awt.font.FontRenderContext"
+    , "java.awt.font.GlyphJustificationInfo"
+    , "java.awt.font.GlyphMetrics"
+    , "java.awt.font.GlyphVector"
+    , "java.awt.font.GraphicAttribute"
+    , "java.awt.font.ImageGraphicAttribute"
+    , "java.awt.font.LayoutPath"
+    , "java.awt.font.LineBreakMeasurer"
+    , "java.awt.font.LineMetrics"
+    , "java.awt.font.MultipleMaster"
+    , "java.awt.font.NumericShaper"
+    , "java.awt.font.OpenType"
+    , "java.awt.font.ShapeGraphicAttribute"
+    , "java.awt.font.TextAttribute"
+    , "java.awt.font.TextHitInfo"
+    , "java.awt.font.TextLayout"
+    , "java.awt.font.TextLayout$CaretPolicy"
+    , "java.awt.font.TextMeasurer"
+    , "java.awt.font.TransformAttribute"
+    , "java.awt.geom.AffineTransform"
+    , "java.awt.geom.Arc2D"
+    , "java.awt.geom.Arc2D$Double"
+    , "java.awt.geom.Arc2D$Float"
+    , "java.awt.geom.Area"
+    , "java.awt.geom.CubicCurve2D"
+    , "java.awt.geom.CubicCurve2D$Double"
+    , "java.awt.geom.CubicCurve2D$Float"
+    , "java.awt.geom.Dimension2D"
+    , "java.awt.geom.Ellipse2D"
+    , "java.awt.geom.Ellipse2D$Double"
+    , "java.awt.geom.Ellipse2D$Float"
+    , "java.awt.geom.FlatteningPathIterator"
+    , "java.awt.geom.GeneralPath"
+    , "java.awt.geom.IllegalPathStateException"
+    , "java.awt.geom.Line2D"
+    , "java.awt.geom.Line2D$Double"
+    , "java.awt.geom.Line2D$Float"
+    , "java.awt.geom.NoninvertibleTransformException"
+    , "java.awt.geom.Path2D"
+    , "java.awt.geom.Path2D$Double"
+    , "java.awt.geom.Path2D$Float"
+    , "java.awt.geom.PathIterator"
+    , "java.awt.geom.Point2D"
+    , "java.awt.geom.Point2D$Double"
+    , "java.awt.geom.Point2D$Float"
+    , "java.awt.geom.QuadCurve2D"
+    , "java.awt.geom.QuadCurve2D$Double"
+    , "java.awt.geom.QuadCurve2D$Float"
+    , "java.awt.geom.Rectangle2D"
+    , "java.awt.geom.Rectangle2D$Double"
+    , "java.awt.geom.Rectangle2D$Float"
+    , "java.awt.geom.RectangularShape"
+    , "java.awt.geom.RoundRectangle2D"
+    , "java.awt.geom.RoundRectangle2D$Double"
+    , "java.awt.geom.RoundRectangle2D$Float"
+    , "java.awt.im.InputContext"
+    , "java.awt.im.InputMethodHighlight"
+    , "java.awt.im.InputMethodRequests"
+    , "java.awt.im.InputSubset"
+    , "java.awt.im.spi.InputMethod"
+    , "java.awt.im.spi.InputMethodContext"
+    , "java.awt.im.spi.InputMethodDescriptor"
+    , "java.awt.image.AffineTransformOp"
+    , "java.awt.image.AreaAveragingScaleFilter"
+    , "java.awt.image.BandCombineOp"
+    , "java.awt.image.BandedSampleModel"
+    , "java.awt.image.BufferStrategy"
+    , "java.awt.image.BufferedImage"
+    , "java.awt.image.BufferedImageFilter"
+    , "java.awt.image.BufferedImageOp"
+    , "java.awt.image.ByteLookupTable"
+    , "java.awt.image.ColorConvertOp"
+    , "java.awt.image.ColorModel"
+    , "java.awt.image.ComponentColorModel"
+    , "java.awt.image.ComponentSampleModel"
+    , "java.awt.image.ConvolveOp"
+    , "java.awt.image.CropImageFilter"
+    , "java.awt.image.DataBuffer"
+    , "java.awt.image.DataBufferByte"
+    , "java.awt.image.DataBufferDouble"
+    , "java.awt.image.DataBufferFloat"
+    , "java.awt.image.DataBufferInt"
+    , "java.awt.image.DataBufferShort"
+    , "java.awt.image.DataBufferUShort"
+    , "java.awt.image.DirectColorModel"
+    , "java.awt.image.FilteredImageSource"
+    , "java.awt.image.ImageConsumer"
+    , "java.awt.image.ImageFilter"
+    , "java.awt.image.ImageObserver"
+    , "java.awt.image.ImageProducer"
+    , "java.awt.image.ImagingOpException"
+    , "java.awt.image.IndexColorModel"
+    , "java.awt.image.Kernel"
+    , "java.awt.image.LookupOp"
+    , "java.awt.image.LookupTable"
+    , "java.awt.image.MemoryImageSource"
+    , "java.awt.image.MultiPixelPackedSampleModel"
+    , "java.awt.image.PackedColorModel"
+    , "java.awt.image.PixelGrabber"
+    , "java.awt.image.PixelInterleavedSampleModel"
+    , "java.awt.image.RGBImageFilter"
+    , "java.awt.image.Raster"
+    , "java.awt.image.RasterFormatException"
+    , "java.awt.image.RasterOp"
+    , "java.awt.image.RenderedImage"
+    , "java.awt.image.ReplicateScaleFilter"
+    , "java.awt.image.RescaleOp"
+    , "java.awt.image.SampleModel"
+    , "java.awt.image.ShortLookupTable"
+    , "java.awt.image.SinglePixelPackedSampleModel"
+    , "java.awt.image.TileObserver"
+    , "java.awt.image.VolatileImage"
+    , "java.awt.image.WritableRaster"
+    , "java.awt.image.WritableRenderedImage"
+    , "java.awt.image.renderable.ContextualRenderedImageFactory"
+    , "java.awt.image.renderable.ParameterBlock"
+    , "java.awt.image.renderable.RenderContext"
+    , "java.awt.image.renderable.RenderableImage"
+    , "java.awt.image.renderable.RenderableImageOp"
+    , "java.awt.image.renderable.RenderableImageProducer"
+    , "java.awt.image.renderable.RenderedImageFactory"
+    , "java.awt.print.Book"
+    , "java.awt.print.PageFormat"
+    , "java.awt.print.Pageable"
+    , "java.awt.print.Paper"
+    , "java.awt.print.Printable"
+    , "java.awt.print.PrinterAbortException"
+    , "java.awt.print.PrinterException"
+    , "java.awt.print.PrinterGraphics"
+    , "java.awt.print.PrinterIOException"
+    , "java.awt.print.PrinterJob"
+    , "java.beans.AppletInitializer"
+    , "java.beans.BeanDescriptor"
+    , "java.beans.BeanInfo"
+    , "java.beans.Beans"
+    , "java.beans.ConstructorProperties"
+    , "java.beans.Customizer"
+    , "java.beans.DefaultPersistenceDelegate"
+    , "java.beans.DesignMode"
+    , "java.beans.Encoder"
+    , "java.beans.EventHandler"
+    , "java.beans.EventSetDescriptor"
+    , "java.beans.ExceptionListener"
+    , "java.beans.Expression"
+    , "java.beans.FeatureDescriptor"
+    , "java.beans.IndexedPropertyChangeEvent"
+    , "java.beans.IndexedPropertyDescriptor"
+    , "java.beans.IntrospectionException"
+    , "java.beans.Introspector"
+    , "java.beans.MethodDescriptor"
+    , "java.beans.ParameterDescriptor"
+    , "java.beans.PersistenceDelegate"
+    , "java.beans.PropertyChangeEvent"
+    , "java.beans.PropertyChangeListener"
+    , "java.beans.PropertyChangeListenerProxy"
+    , "java.beans.PropertyChangeSupport"
+    , "java.beans.PropertyDescriptor"
+    , "java.beans.PropertyEditor"
+    , "java.beans.PropertyEditorManager"
+    , "java.beans.PropertyEditorSupport"
+    , "java.beans.PropertyVetoException"
+    , "java.beans.SimpleBeanInfo"
+    , "java.beans.Statement"
+    , "java.beans.VetoableChangeListener"
+    , "java.beans.VetoableChangeListenerProxy"
+    , "java.beans.VetoableChangeSupport"
+    , "java.beans.Visibility"
+    , "java.beans.XMLDecoder"
+    , "java.beans.XMLEncoder"
+    , "java.beans.beancontext.BeanContext"
+    , "java.beans.beancontext.BeanContextChild"
+    , "java.beans.beancontext.BeanContextChildComponentProxy"
+    , "java.beans.beancontext.BeanContextChildSupport"
+    , "java.beans.beancontext.BeanContextContainerProxy"
+    , "java.beans.beancontext.BeanContextEvent"
+    , "java.beans.beancontext.BeanContextMembershipEvent"
+    , "java.beans.beancontext.BeanContextMembershipListener"
+    , "java.beans.beancontext.BeanContextProxy"
+    , "java.beans.beancontext.BeanContextServiceAvailableEvent"
+    , "java.beans.beancontext.BeanContextServiceProvider"
+    , "java.beans.beancontext.BeanContextServiceProviderBeanInfo"
+    , "java.beans.beancontext.BeanContextServiceRevokedEvent"
+    , "java.beans.beancontext.BeanContextServiceRevokedListener"
+    , "java.beans.beancontext.BeanContextServices"
+    , "java.beans.beancontext.BeanContextServicesListener"
+    , "java.beans.beancontext.BeanContextServicesSupport"
+    , "java.beans.beancontext.BeanContextServicesSupport$BCSSServiceProvider"
+    , "java.beans.beancontext.BeanContextSupport"
+    , "java.beans.beancontext.BeanContextSupport$BCSIterator"
+    , "java.io.BufferedInputStream"
+    , "java.io.BufferedOutputStream"
+    , "java.io.BufferedReader"
+    , "java.io.BufferedWriter"
+    , "java.io.ByteArrayInputStream"
+    , "java.io.ByteArrayOutputStream"
+    , "java.io.CharArrayReader"
+    , "java.io.CharArrayWriter"
+    , "java.io.CharConversionException"
+    , "java.io.Closeable"
+    , "java.io.Console"
+    , "java.io.DataInput"
+    , "java.io.DataInputStream"
+    , "java.io.DataOutput"
+    , "java.io.DataOutputStream"
+    , "java.io.EOFException"
+    , "java.io.Externalizable"
+    , "java.io.File"
+    , "java.io.FileDescriptor"
+    , "java.io.FileFilter"
+    , "java.io.FileInputStream"
+    , "java.io.FileNotFoundException"
+    , "java.io.FileOutputStream"
+    , "java.io.FilePermission"
+    , "java.io.FileReader"
+    , "java.io.FileWriter"
+    , "java.io.FilenameFilter"
+    , "java.io.FilterInputStream"
+    , "java.io.FilterOutputStream"
+    , "java.io.FilterReader"
+    , "java.io.FilterWriter"
+    , "java.io.Flushable"
+    , "java.io.IOError"
+    , "java.io.IOException"
+    , "java.io.InputStream"
+    , "java.io.InputStreamReader"
+    , "java.io.InterruptedIOException"
+    , "java.io.InvalidClassException"
+    , "java.io.InvalidObjectException"
+    , "java.io.LineNumberInputStream"
+    , "java.io.LineNumberReader"
+    , "java.io.NotActiveException"
+    , "java.io.NotSerializableException"
+    , "java.io.ObjectInput"
+    , "java.io.ObjectInputStream"
+    , "java.io.ObjectInputStream$GetField"
+    , "java.io.ObjectInputValidation"
+    , "java.io.ObjectOutput"
+    , "java.io.ObjectOutputStream"
+    , "java.io.ObjectOutputStream$PutField"
+    , "java.io.ObjectStreamClass"
+    , "java.io.ObjectStreamConstants"
+    , "java.io.ObjectStreamException"
+    , "java.io.ObjectStreamField"
+    , "java.io.OptionalDataException"
+    , "java.io.OutputStream"
+    , "java.io.OutputStreamWriter"
+    , "java.io.PipedInputStream"
+    , "java.io.PipedOutputStream"
+    , "java.io.PipedReader"
+    , "java.io.PipedWriter"
+    , "java.io.PrintStream"
+    , "java.io.PrintWriter"
+    , "java.io.PushbackInputStream"
+    , "java.io.PushbackReader"
+    , "java.io.RandomAccessFile"
+    , "java.io.Reader"
+    , "java.io.SequenceInputStream"
+    , "java.io.Serializable"
+    , "java.io.SerializablePermission"
+    , "java.io.StreamCorruptedException"
+    , "java.io.StreamTokenizer"
+    , "java.io.StringBufferInputStream"
+    , "java.io.StringReader"
+    , "java.io.StringWriter"
+    , "java.io.SyncFailedException"
+    , "java.io.UTFDataFormatException"
+    , "java.io.UnsupportedEncodingException"
+    , "java.io.WriteAbortedException"
+    , "java.io.Writer"
+    , "java.lang.AbstractMethodError"
+    , "java.lang.Appendable"
+    , "java.lang.ArithmeticException"
+    , "java.lang.ArrayIndexOutOfBoundsException"
+    , "java.lang.ArrayStoreException"
+    , "java.lang.AssertionError"
+    , "java.lang.Boolean"
+    , "java.lang.Byte"
+    , "java.lang.CharSequence"
+    , "java.lang.Character"
+    , "java.lang.Character$Subset"
+    , "java.lang.Character$UnicodeBlock"
+    , "java.lang.Class"
+    , "java.lang.ClassCastException"
+    , "java.lang.ClassCircularityError"
+    , "java.lang.ClassFormatError"
+    , "java.lang.ClassLoader"
+    , "java.lang.ClassNotFoundException"
+    , "java.lang.CloneNotSupportedException"
+    , "java.lang.Cloneable"
+    , "java.lang.Comparable"
+    , "java.lang.Compiler"
+    , "java.lang.Deprecated"
+    , "java.lang.Double"
+    , "java.lang.Enum"
+    , "java.lang.EnumConstantNotPresentException"
+    , "java.lang.Error"
+    , "java.lang.Exception"
+    , "java.lang.ExceptionInInitializerError"
+    , "java.lang.Float"
+    , "java.lang.IllegalAccessError"
+    , "java.lang.IllegalAccessException"
+    , "java.lang.IllegalArgumentException"
+    , "java.lang.IllegalMonitorStateException"
+    , "java.lang.IllegalStateException"
+    , "java.lang.IllegalThreadStateException"
+    , "java.lang.IncompatibleClassChangeError"
+    , "java.lang.IndexOutOfBoundsException"
+    , "java.lang.InheritableThreadLocal"
+    , "java.lang.InstantiationError"
+    , "java.lang.InstantiationException"
+    , "java.lang.Integer"
+    , "java.lang.InternalError"
+    , "java.lang.InterruptedException"
+    , "java.lang.Iterable"
+    , "java.lang.LinkageError"
+    , "java.lang.Long"
+    , "java.lang.Math"
+    , "java.lang.NegativeArraySizeException"
+    , "java.lang.NoClassDefFoundError"
+    , "java.lang.NoSuchFieldError"
+    , "java.lang.NoSuchFieldException"
+    , "java.lang.NoSuchMethodError"
+    , "java.lang.NoSuchMethodException"
+    , "java.lang.NullPointerException"
+    , "java.lang.Number"
+    , "java.lang.NumberFormatException"
+    , "java.lang.Object"
+    , "java.lang.OutOfMemoryError"
+    , "java.lang.Override"
+    , "java.lang.Package"
+    , "java.lang.Process"
+    , "java.lang.ProcessBuilder"
+    , "java.lang.Readable"
+    , "java.lang.Runnable"
+    , "java.lang.Runtime"
+    , "java.lang.RuntimeException"
+    , "java.lang.RuntimePermission"
+    , "java.lang.SecurityException"
+    , "java.lang.SecurityManager"
+    , "java.lang.Short"
+    , "java.lang.StackOverflowError"
+    , "java.lang.StackTraceElement"
+    , "java.lang.StrictMath"
+    , "java.lang.String"
+    , "java.lang.StringBuffer"
+    , "java.lang.StringBuilder"
+    , "java.lang.StringIndexOutOfBoundsException"
+    , "java.lang.SuppressWarnings"
+    , "java.lang.System"
+    , "java.lang.Thread"
+    , "java.lang.Thread$State"
+    , "java.lang.Thread$UncaughtExceptionHandler"
+    , "java.lang.ThreadDeath"
+    , "java.lang.ThreadGroup"
+    , "java.lang.ThreadLocal"
+    , "java.lang.Throwable"
+    , "java.lang.TypeNotPresentException"
+    , "java.lang.UnknownError"
+    , "java.lang.UnsatisfiedLinkError"
+    , "java.lang.UnsupportedClassVersionError"
+    , "java.lang.UnsupportedOperationException"
+    , "java.lang.VerifyError"
+    , "java.lang.VirtualMachineError"
+    , "java.lang.Void"
+    , "java.lang.annotation.Annotation"
+    , "java.lang.annotation.AnnotationFormatError"
+    , "java.lang.annotation.AnnotationTypeMismatchException"
+    , "java.lang.annotation.Documented"
+    , "java.lang.annotation.ElementType"
+    , "java.lang.annotation.IncompleteAnnotationException"
+    , "java.lang.annotation.Inherited"
+    , "java.lang.annotation.Retention"
+    , "java.lang.annotation.RetentionPolicy"
+    , "java.lang.annotation.Target"
+    , "java.lang.instrument.ClassDefinition"
+    , "java.lang.instrument.ClassFileTransformer"
+    , "java.lang.instrument.IllegalClassFormatException"
+    , "java.lang.instrument.Instrumentation"
+    , "java.lang.instrument.UnmodifiableClassException"
+    , "java.lang.management.ClassLoadingMXBean"
+    , "java.lang.management.CompilationMXBean"
+    , "java.lang.management.GarbageCollectorMXBean"
+    , "java.lang.management.LockInfo"
+    , "java.lang.management.ManagementFactory"
+    , "java.lang.management.ManagementPermission"
+    , "java.lang.management.MemoryMXBean"
+    , "java.lang.management.MemoryManagerMXBean"
+    , "java.lang.management.MemoryNotificationInfo"
+    , "java.lang.management.MemoryPoolMXBean"
+    , "java.lang.management.MemoryType"
+    , "java.lang.management.MemoryUsage"
+    , "java.lang.management.MonitorInfo"
+    , "java.lang.management.OperatingSystemMXBean"
+    , "java.lang.management.RuntimeMXBean"
+    , "java.lang.management.ThreadInfo"
+    , "java.lang.management.ThreadMXBean"
+    , "java.lang.ref.PhantomReference"
+    , "java.lang.ref.Reference"
+    , "java.lang.ref.ReferenceQueue"
+    , "java.lang.ref.SoftReference"
+    , "java.lang.ref.WeakReference"
+    , "java.lang.reflect.AccessibleObject"
+    , "java.lang.reflect.AnnotatedElement"
+    , "java.lang.reflect.Array"
+    , "java.lang.reflect.Constructor"
+    , "java.lang.reflect.Field"
+    , "java.lang.reflect.GenericArrayType"
+    , "java.lang.reflect.GenericDeclaration"
+    , "java.lang.reflect.GenericSignatureFormatError"
+    , "java.lang.reflect.InvocationHandler"
+    , "java.lang.reflect.InvocationTargetException"
+    , "java.lang.reflect.MalformedParameterizedTypeException"
+    , "java.lang.reflect.Member"
+    , "java.lang.reflect.Method"
+    , "java.lang.reflect.Modifier"
+    , "java.lang.reflect.ParameterizedType"
+    , "java.lang.reflect.Proxy"
+    , "java.lang.reflect.ReflectPermission"
+    , "java.lang.reflect.Type"
+    , "java.lang.reflect.TypeVariable"
+    , "java.lang.reflect.UndeclaredThrowableException"
+    , "java.lang.reflect.WildcardType"
+    , "java.math.BigDecimal"
+    , "java.math.BigInteger"
+    , "java.math.MathContext"
+    , "java.math.RoundingMode"
+    , "java.net.Authenticator"
+    , "java.net.Authenticator$RequestorType"
+    , "java.net.BindException"
+    , "java.net.CacheRequest"
+    , "java.net.CacheResponse"
+    , "java.net.ConnectException"
+    , "java.net.ContentHandler"
+    , "java.net.ContentHandlerFactory"
+    , "java.net.CookieHandler"
+    , "java.net.CookieManager"
+    , "java.net.CookiePolicy"
+    , "java.net.CookieStore"
+    , "java.net.DatagramPacket"
+    , "java.net.DatagramSocket"
+    , "java.net.DatagramSocketImpl"
+    , "java.net.DatagramSocketImplFactory"
+    , "java.net.FileNameMap"
+    , "java.net.HttpCookie"
+    , "java.net.HttpRetryException"
+    , "java.net.HttpURLConnection"
+    , "java.net.IDN"
+    , "java.net.Inet4Address"
+    , "java.net.Inet6Address"
+    , "java.net.InetAddress"
+    , "java.net.InetSocketAddress"
+    , "java.net.InterfaceAddress"
+    , "java.net.JarURLConnection"
+    , "java.net.MalformedURLException"
+    , "java.net.MulticastSocket"
+    , "java.net.NetPermission"
+    , "java.net.NetworkInterface"
+    , "java.net.NoRouteToHostException"
+    , "java.net.PasswordAuthentication"
+    , "java.net.PortUnreachableException"
+    , "java.net.ProtocolException"
+    , "java.net.Proxy"
+    , "java.net.Proxy$Type"
+    , "java.net.ProxySelector"
+    , "java.net.ResponseCache"
+    , "java.net.SecureCacheResponse"
+    , "java.net.ServerSocket"
+    , "java.net.Socket"
+    , "java.net.SocketAddress"
+    , "java.net.SocketException"
+    , "java.net.SocketImpl"
+    , "java.net.SocketImplFactory"
+    , "java.net.SocketOptions"
+    , "java.net.SocketPermission"
+    , "java.net.SocketTimeoutException"
+    , "java.net.URI"
+    , "java.net.URISyntaxException"
+    , "java.net.URL"
+    , "java.net.URLClassLoader"
+    , "java.net.URLConnection"
+    , "java.net.URLDecoder"
+    , "java.net.URLEncoder"
+    , "java.net.URLStreamHandler"
+    , "java.net.URLStreamHandlerFactory"
+    , "java.net.UnknownHostException"
+    , "java.net.UnknownServiceException"
+    , "java.nio.Buffer"
+    , "java.nio.BufferOverflowException"
+    , "java.nio.BufferUnderflowException"
+    , "java.nio.ByteBuffer"
+    , "java.nio.ByteOrder"
+    , "java.nio.CharBuffer"
+    , "java.nio.DoubleBuffer"
+    , "java.nio.FloatBuffer"
+    , "java.nio.IntBuffer"
+    , "java.nio.InvalidMarkException"
+    , "java.nio.LongBuffer"
+    , "java.nio.MappedByteBuffer"
+    , "java.nio.ReadOnlyBufferException"
+    , "java.nio.ShortBuffer"
+    , "java.nio.channels.AlreadyConnectedException"
+    , "java.nio.channels.AsynchronousCloseException"
+    , "java.nio.channels.ByteChannel"
+    , "java.nio.channels.CancelledKeyException"
+    , "java.nio.channels.Channel"
+    , "java.nio.channels.Channels"
+    , "java.nio.channels.ClosedByInterruptException"
+    , "java.nio.channels.ClosedChannelException"
+    , "java.nio.channels.ClosedSelectorException"
+    , "java.nio.channels.ConnectionPendingException"
+    , "java.nio.channels.DatagramChannel"
+    , "java.nio.channels.FileChannel"
+    , "java.nio.channels.FileChannel$MapMode"
+    , "java.nio.channels.FileLock"
+    , "java.nio.channels.FileLockInterruptionException"
+    , "java.nio.channels.GatheringByteChannel"
+    , "java.nio.channels.IllegalBlockingModeException"
+    , "java.nio.channels.IllegalSelectorException"
+    , "java.nio.channels.InterruptibleChannel"
+    , "java.nio.channels.NoConnectionPendingException"
+    , "java.nio.channels.NonReadableChannelException"
+    , "java.nio.channels.NonWritableChannelException"
+    , "java.nio.channels.NotYetBoundException"
+    , "java.nio.channels.NotYetConnectedException"
+    , "java.nio.channels.OverlappingFileLockException"
+    , "java.nio.channels.Pipe"
+    , "java.nio.channels.Pipe$SinkChannel"
+    , "java.nio.channels.Pipe$SourceChannel"
+    , "java.nio.channels.ReadableByteChannel"
+    , "java.nio.channels.ScatteringByteChannel"
+    , "java.nio.channels.SelectableChannel"
+    , "java.nio.channels.SelectionKey"
+    , "java.nio.channels.Selector"
+    , "java.nio.channels.ServerSocketChannel"
+    , "java.nio.channels.SocketChannel"
+    , "java.nio.channels.UnresolvedAddressException"
+    , "java.nio.channels.UnsupportedAddressTypeException"
+    , "java.nio.channels.WritableByteChannel"
+    , "java.nio.channels.spi.AbstractInterruptibleChannel"
+    , "java.nio.channels.spi.AbstractSelectableChannel"
+    , "java.nio.channels.spi.AbstractSelectionKey"
+    , "java.nio.channels.spi.AbstractSelector"
+    , "java.nio.channels.spi.SelectorProvider"
+    , "java.nio.charset.CharacterCodingException"
+    , "java.nio.charset.Charset"
+    , "java.nio.charset.CharsetDecoder"
+    , "java.nio.charset.CharsetEncoder"
+    , "java.nio.charset.CoderMalfunctionError"
+    , "java.nio.charset.CoderResult"
+    , "java.nio.charset.CodingErrorAction"
+    , "java.nio.charset.IllegalCharsetNameException"
+    , "java.nio.charset.MalformedInputException"
+    , "java.nio.charset.UnmappableCharacterException"
+    , "java.nio.charset.UnsupportedCharsetException"
+    , "java.nio.charset.spi.CharsetProvider"
+    , "java.rmi.AccessException"
+    , "java.rmi.AlreadyBoundException"
+    , "java.rmi.ConnectException"
+    , "java.rmi.ConnectIOException"
+    , "java.rmi.MarshalException"
+    , "java.rmi.MarshalledObject"
+    , "java.rmi.Naming"
+    , "java.rmi.NoSuchObjectException"
+    , "java.rmi.NotBoundException"
+    , "java.rmi.RMISecurityException"
+    , "java.rmi.RMISecurityManager"
+    , "java.rmi.Remote"
+    , "java.rmi.RemoteException"
+    , "java.rmi.ServerError"
+    , "java.rmi.ServerException"
+    , "java.rmi.ServerRuntimeException"
+    , "java.rmi.StubNotFoundException"
+    , "java.rmi.UnexpectedException"
+    , "java.rmi.UnknownHostException"
+    , "java.rmi.UnmarshalException"
+    , "java.rmi.activation.Activatable"
+    , "java.rmi.activation.ActivateFailedException"
+    , "java.rmi.activation.ActivationDesc"
+    , "java.rmi.activation.ActivationException"
+    , "java.rmi.activation.ActivationGroup"
+    , "java.rmi.activation.ActivationGroupDesc"
+    , "java.rmi.activation.ActivationGroupDesc$CommandEnvironment"
+    , "java.rmi.activation.ActivationGroupID"
+    , "java.rmi.activation.ActivationGroup_Stub"
+    , "java.rmi.activation.ActivationID"
+    , "java.rmi.activation.ActivationInstantiator"
+    , "java.rmi.activation.ActivationMonitor"
+    , "java.rmi.activation.ActivationSystem"
+    , "java.rmi.activation.Activator"
+    , "java.rmi.activation.UnknownGroupException"
+    , "java.rmi.activation.UnknownObjectException"
+    , "java.rmi.dgc.DGC"
+    , "java.rmi.dgc.Lease"
+    , "java.rmi.dgc.VMID"
+    , "java.rmi.registry.LocateRegistry"
+    , "java.rmi.registry.Registry"
+    , "java.rmi.registry.RegistryHandler"
+    , "java.rmi.server.ExportException"
+    , "java.rmi.server.LoaderHandler"
+    , "java.rmi.server.LogStream"
+    , "java.rmi.server.ObjID"
+    , "java.rmi.server.Operation"
+    , "java.rmi.server.RMIClassLoader"
+    , "java.rmi.server.RMIClassLoaderSpi"
+    , "java.rmi.server.RMIClientSocketFactory"
+    , "java.rmi.server.RMIFailureHandler"
+    , "java.rmi.server.RMIServerSocketFactory"
+    , "java.rmi.server.RMISocketFactory"
+    , "java.rmi.server.RemoteCall"
+    , "java.rmi.server.RemoteObject"
+    , "java.rmi.server.RemoteObjectInvocationHandler"
+    , "java.rmi.server.RemoteRef"
+    , "java.rmi.server.RemoteServer"
+    , "java.rmi.server.RemoteStub"
+    , "java.rmi.server.ServerCloneException"
+    , "java.rmi.server.ServerNotActiveException"
+    , "java.rmi.server.ServerRef"
+    , "java.rmi.server.Skeleton"
+    , "java.rmi.server.SkeletonMismatchException"
+    , "java.rmi.server.SkeletonNotFoundException"
+    , "java.rmi.server.SocketSecurityException"
+    , "java.rmi.server.UID"
+    , "java.rmi.server.UnicastRemoteObject"
+    , "java.rmi.server.Unreferenced"
+    , "java.security.AccessControlContext"
+    , "java.security.AccessControlException"
+    , "java.security.AccessController"
+    , "java.security.AlgorithmParameterGenerator"
+    , "java.security.AlgorithmParameterGeneratorSpi"
+    , "java.security.AlgorithmParameters"
+    , "java.security.AlgorithmParametersSpi"
+    , "java.security.AllPermission"
+    , "java.security.AuthProvider"
+    , "java.security.BasicPermission"
+    , "java.security.Certificate"
+    , "java.security.CodeSigner"
+    , "java.security.CodeSource"
+    , "java.security.DigestException"
+    , "java.security.DigestInputStream"
+    , "java.security.DigestOutputStream"
+    , "java.security.DomainCombiner"
+    , "java.security.GeneralSecurityException"
+    , "java.security.Guard"
+    , "java.security.GuardedObject"
+    , "java.security.Identity"
+    , "java.security.IdentityScope"
+    , "java.security.InvalidAlgorithmParameterException"
+    , "java.security.InvalidKeyException"
+    , "java.security.InvalidParameterException"
+    , "java.security.Key"
+    , "java.security.KeyException"
+    , "java.security.KeyFactory"
+    , "java.security.KeyFactorySpi"
+    , "java.security.KeyManagementException"
+    , "java.security.KeyPair"
+    , "java.security.KeyPairGenerator"
+    , "java.security.KeyPairGeneratorSpi"
+    , "java.security.KeyRep"
+    , "java.security.KeyRep$Type"
+    , "java.security.KeyStore"
+    , "java.security.KeyStore$Builder"
+    , "java.security.KeyStore$CallbackHandlerProtection"
+    , "java.security.KeyStore$Entry"
+    , "java.security.KeyStore$LoadStoreParameter"
+    , "java.security.KeyStore$PasswordProtection"
+    , "java.security.KeyStore$PrivateKeyEntry"
+    , "java.security.KeyStore$ProtectionParameter"
+    , "java.security.KeyStore$SecretKeyEntry"
+    , "java.security.KeyStore$TrustedCertificateEntry"
+    , "java.security.KeyStoreException"
+    , "java.security.KeyStoreSpi"
+    , "java.security.MessageDigest"
+    , "java.security.MessageDigestSpi"
+    , "java.security.NoSuchAlgorithmException"
+    , "java.security.NoSuchProviderException"
+    , "java.security.Permission"
+    , "java.security.PermissionCollection"
+    , "java.security.Permissions"
+    , "java.security.Policy"
+    , "java.security.Policy$Parameters"
+    , "java.security.PolicySpi"
+    , "java.security.Principal"
+    , "java.security.PrivateKey"
+    , "java.security.PrivilegedAction"
+    , "java.security.PrivilegedActionException"
+    , "java.security.PrivilegedExceptionAction"
+    , "java.security.ProtectionDomain"
+    , "java.security.Provider"
+    , "java.security.Provider$Service"
+    , "java.security.ProviderException"
+    , "java.security.PublicKey"
+    , "java.security.SecureClassLoader"
+    , "java.security.SecureRandom"
+    , "java.security.SecureRandomSpi"
+    , "java.security.Security"
+    , "java.security.SecurityPermission"
+    , "java.security.Signature"
+    , "java.security.SignatureException"
+    , "java.security.SignatureSpi"
+    , "java.security.SignedObject"
+    , "java.security.Signer"
+    , "java.security.Timestamp"
+    , "java.security.URIParameter"
+    , "java.security.UnrecoverableEntryException"
+    , "java.security.UnrecoverableKeyException"
+    , "java.security.UnresolvedPermission"
+    , "java.security.acl.Acl"
+    , "java.security.acl.AclEntry"
+    , "java.security.acl.AclNotFoundException"
+    , "java.security.acl.Group"
+    , "java.security.acl.LastOwnerException"
+    , "java.security.acl.NotOwnerException"
+    , "java.security.acl.Owner"
+    , "java.security.acl.Permission"
+    , "java.security.cert.CRL"
+    , "java.security.cert.CRLException"
+    , "java.security.cert.CRLSelector"
+    , "java.security.cert.CertPath"
+    , "java.security.cert.CertPath$CertPathRep"
+    , "java.security.cert.CertPathBuilder"
+    , "java.security.cert.CertPathBuilderException"
+    , "java.security.cert.CertPathBuilderResult"
+    , "java.security.cert.CertPathBuilderSpi"
+    , "java.security.cert.CertPathParameters"
+    , "java.security.cert.CertPathValidator"
+    , "java.security.cert.CertPathValidatorException"
+    , "java.security.cert.CertPathValidatorResult"
+    , "java.security.cert.CertPathValidatorSpi"
+    , "java.security.cert.CertSelector"
+    , "java.security.cert.CertStore"
+    , "java.security.cert.CertStoreException"
+    , "java.security.cert.CertStoreParameters"
+    , "java.security.cert.CertStoreSpi"
+    , "java.security.cert.Certificate"
+    , "java.security.cert.Certificate$CertificateRep"
+    , "java.security.cert.CertificateEncodingException"
+    , "java.security.cert.CertificateException"
+    , "java.security.cert.CertificateExpiredException"
+    , "java.security.cert.CertificateFactory"
+    , "java.security.cert.CertificateFactorySpi"
+    , "java.security.cert.CertificateNotYetValidException"
+    , "java.security.cert.CertificateParsingException"
+    , "java.security.cert.CollectionCertStoreParameters"
+    , "java.security.cert.LDAPCertStoreParameters"
+    , "java.security.cert.PKIXBuilderParameters"
+    , "java.security.cert.PKIXCertPathBuilderResult"
+    , "java.security.cert.PKIXCertPathChecker"
+    , "java.security.cert.PKIXCertPathValidatorResult"
+    , "java.security.cert.PKIXParameters"
+    , "java.security.cert.PolicyNode"
+    , "java.security.cert.PolicyQualifierInfo"
+    , "java.security.cert.TrustAnchor"
+    , "java.security.cert.X509CRL"
+    , "java.security.cert.X509CRLEntry"
+    , "java.security.cert.X509CRLSelector"
+    , "java.security.cert.X509CertSelector"
+    , "java.security.cert.X509Certificate"
+    , "java.security.cert.X509Extension"
+    , "java.security.interfaces.DSAKey"
+    , "java.security.interfaces.DSAKeyPairGenerator"
+    , "java.security.interfaces.DSAParams"
+    , "java.security.interfaces.DSAPrivateKey"
+    , "java.security.interfaces.DSAPublicKey"
+    , "java.security.interfaces.ECKey"
+    , "java.security.interfaces.ECPrivateKey"
+    , "java.security.interfaces.ECPublicKey"
+    , "java.security.interfaces.RSAKey"
+    , "java.security.interfaces.RSAMultiPrimePrivateCrtKey"
+    , "java.security.interfaces.RSAPrivateCrtKey"
+    , "java.security.interfaces.RSAPrivateKey"
+    , "java.security.interfaces.RSAPublicKey"
+    , "java.security.spec.AlgorithmParameterSpec"
+    , "java.security.spec.DSAParameterSpec"
+    , "java.security.spec.DSAPrivateKeySpec"
+    , "java.security.spec.DSAPublicKeySpec"
+    , "java.security.spec.ECField"
+    , "java.security.spec.ECFieldF2m"
+    , "java.security.spec.ECFieldFp"
+    , "java.security.spec.ECGenParameterSpec"
+    , "java.security.spec.ECParameterSpec"
+    , "java.security.spec.ECPoint"
+    , "java.security.spec.ECPrivateKeySpec"
+    , "java.security.spec.ECPublicKeySpec"
+    , "java.security.spec.EllipticCurve"
+    , "java.security.spec.EncodedKeySpec"
+    , "java.security.spec.InvalidKeySpecException"
+    , "java.security.spec.InvalidParameterSpecException"
+    , "java.security.spec.KeySpec"
+    , "java.security.spec.MGF1ParameterSpec"
+    , "java.security.spec.PKCS8EncodedKeySpec"
+    , "java.security.spec.PSSParameterSpec"
+    , "java.security.spec.RSAKeyGenParameterSpec"
+    , "java.security.spec.RSAMultiPrimePrivateCrtKeySpec"
+    , "java.security.spec.RSAOtherPrimeInfo"
+    , "java.security.spec.RSAPrivateCrtKeySpec"
+    , "java.security.spec.RSAPrivateKeySpec"
+    , "java.security.spec.RSAPublicKeySpec"
+    , "java.security.spec.X509EncodedKeySpec"
+    , "java.sql.Array"
+    , "java.sql.BatchUpdateException"
+    , "java.sql.Blob"
+    , "java.sql.CallableStatement"
+    , "java.sql.ClientInfoStatus"
+    , "java.sql.Clob"
+    , "java.sql.Connection"
+    , "java.sql.DataTruncation"
+    , "java.sql.DatabaseMetaData"
+    , "java.sql.Date"
+    , "java.sql.Driver"
+    , "java.sql.DriverManager"
+    , "java.sql.DriverPropertyInfo"
+    , "java.sql.NClob"
+    , "java.sql.ParameterMetaData"
+    , "java.sql.PreparedStatement"
+    , "java.sql.Ref"
+    , "java.sql.ResultSet"
+    , "java.sql.ResultSetMetaData"
+    , "java.sql.RowId"
+    , "java.sql.RowIdLifetime"
+    , "java.sql.SQLClientInfoException"
+    , "java.sql.SQLData"
+    , "java.sql.SQLDataException"
+    , "java.sql.SQLException"
+    , "java.sql.SQLFeatureNotSupportedException"
+    , "java.sql.SQLInput"
+    , "java.sql.SQLIntegrityConstraintViolationException"
+    , "java.sql.SQLInvalidAuthorizationSpecException"
+    , "java.sql.SQLNonTransientConnectionException"
+    , "java.sql.SQLNonTransientException"
+    , "java.sql.SQLOutput"
+    , "java.sql.SQLPermission"
+    , "java.sql.SQLRecoverableException"
+    , "java.sql.SQLSyntaxErrorException"
+    , "java.sql.SQLTimeoutException"
+    , "java.sql.SQLTransactionRollbackException"
+    , "java.sql.SQLTransientConnectionException"
+    , "java.sql.SQLTransientException"
+    , "java.sql.SQLWarning"
+    , "java.sql.SQLXML"
+    , "java.sql.Savepoint"
+    , "java.sql.Statement"
+    , "java.sql.Struct"
+    , "java.sql.Time"
+    , "java.sql.Timestamp"
+    , "java.sql.Types"
+    , "java.sql.Wrapper"
+    , "java.text.Annotation"
+    , "java.text.AttributedCharacterIterator"
+    , "java.text.AttributedCharacterIterator$Attribute"
+    , "java.text.AttributedString"
+    , "java.text.Bidi"
+    , "java.text.BreakIterator"
+    , "java.text.CharacterIterator"
+    , "java.text.ChoiceFormat"
+    , "java.text.CollationElementIterator"
+    , "java.text.CollationKey"
+    , "java.text.Collator"
+    , "java.text.DateFormat"
+    , "java.text.DateFormat$Field"
+    , "java.text.DateFormatSymbols"
+    , "java.text.DecimalFormat"
+    , "java.text.DecimalFormatSymbols"
+    , "java.text.FieldPosition"
+    , "java.text.Format"
+    , "java.text.Format$Field"
+    , "java.text.MessageFormat"
+    , "java.text.MessageFormat$Field"
+    , "java.text.Normalizer"
+    , "java.text.Normalizer$Form"
+    , "java.text.NumberFormat"
+    , "java.text.NumberFormat$Field"
+    , "java.text.ParseException"
+    , "java.text.ParsePosition"
+    , "java.text.RuleBasedCollator"
+    , "java.text.SimpleDateFormat"
+    , "java.text.StringCharacterIterator"
+    , "java.text.spi.BreakIteratorProvider"
+    , "java.text.spi.CollatorProvider"
+    , "java.text.spi.DateFormatProvider"
+    , "java.text.spi.DateFormatSymbolsProvider"
+    , "java.text.spi.DecimalFormatSymbolsProvider"
+    , "java.text.spi.NumberFormatProvider"
+    , "java.util.AbstractCollection"
+    , "java.util.AbstractList"
+    , "java.util.AbstractMap"
+    , "java.util.AbstractMap$SimpleEntry"
+    , "java.util.AbstractMap$SimpleImmutableEntry"
+    , "java.util.AbstractQueue"
+    , "java.util.AbstractSequentialList"
+    , "java.util.AbstractSet"
+    , "java.util.ArrayDeque"
+    , "java.util.ArrayList"
+    , "java.util.Arrays"
+    , "java.util.BitSet"
+    , "java.util.Calendar"
+    , "java.util.Collection"
+    , "java.util.Collections"
+    , "java.util.Comparator"
+    , "java.util.ConcurrentModificationException"
+    , "java.util.Currency"
+    , "java.util.Date"
+    , "java.util.Deque"
+    , "java.util.Dictionary"
+    , "java.util.DuplicateFormatFlagsException"
+    , "java.util.EmptyStackException"
+    , "java.util.EnumMap"
+    , "java.util.EnumSet"
+    , "java.util.Enumeration"
+    , "java.util.EventListener"
+    , "java.util.EventListenerProxy"
+    , "java.util.EventObject"
+    , "java.util.FormatFlagsConversionMismatchException"
+    , "java.util.Formattable"
+    , "java.util.FormattableFlags"
+    , "java.util.Formatter"
+    , "java.util.Formatter$BigDecimalLayoutForm"
+    , "java.util.FormatterClosedException"
+    , "java.util.GregorianCalendar"
+    , "java.util.HashMap"
+    , "java.util.HashSet"
+    , "java.util.Hashtable"
+    , "java.util.IdentityHashMap"
+    , "java.util.IllegalFormatCodePointException"
+    , "java.util.IllegalFormatConversionException"
+    , "java.util.IllegalFormatException"
+    , "java.util.IllegalFormatFlagsException"
+    , "java.util.IllegalFormatPrecisionException"
+    , "java.util.IllegalFormatWidthException"
+    , "java.util.InputMismatchException"
+    , "java.util.InvalidPropertiesFormatException"
+    , "java.util.Iterator"
+    , "java.util.LinkedHashMap"
+    , "java.util.LinkedHashSet"
+    , "java.util.LinkedList"
+    , "java.util.List"
+    , "java.util.ListIterator"
+    , "java.util.ListResourceBundle"
+    , "java.util.Locale"
+    , "java.util.Map"
+    , "java.util.Map$Entry"
+    , "java.util.MissingFormatArgumentException"
+    , "java.util.MissingFormatWidthException"
+    , "java.util.MissingResourceException"
+    , "java.util.NavigableMap"
+    , "java.util.NavigableSet"
+    , "java.util.NoSuchElementException"
+    , "java.util.Observable"
+    , "java.util.Observer"
+    , "java.util.PriorityQueue"
+    , "java.util.Properties"
+    , "java.util.PropertyPermission"
+    , "java.util.PropertyResourceBundle"
+    , "java.util.Queue"
+    , "java.util.Random"
+    , "java.util.RandomAccess"
+    , "java.util.ResourceBundle"
+    , "java.util.ResourceBundle$Control"
+    , "java.util.Scanner"
+    , "java.util.ServiceConfigurationError"
+    , "java.util.ServiceLoader"
+    , "java.util.Set"
+    , "java.util.SimpleTimeZone"
+    , "java.util.SortedMap"
+    , "java.util.SortedSet"
+    , "java.util.Stack"
+    , "java.util.StringTokenizer"
+    , "java.util.TimeZone"
+    , "java.util.Timer"
+    , "java.util.TimerTask"
+    , "java.util.TooManyListenersException"
+    , "java.util.TreeMap"
+    , "java.util.TreeSet"
+    , "java.util.UUID"
+    , "java.util.UnknownFormatConversionException"
+    , "java.util.UnknownFormatFlagsException"
+    , "java.util.Vector"
+    , "java.util.WeakHashMap"
+    , "java.util.concurrent.AbstractExecutorService"
+    , "java.util.concurrent.ArrayBlockingQueue"
+    , "java.util.concurrent.BlockingDeque"
+    , "java.util.concurrent.BlockingQueue"
+    , "java.util.concurrent.BrokenBarrierException"
+    , "java.util.concurrent.Callable"
+    , "java.util.concurrent.CancellationException"
+    , "java.util.concurrent.CompletionService"
+    , "java.util.concurrent.ConcurrentHashMap"
+    , "java.util.concurrent.ConcurrentLinkedQueue"
+    , "java.util.concurrent.ConcurrentMap"
+    , "java.util.concurrent.ConcurrentNavigableMap"
+    , "java.util.concurrent.ConcurrentSkipListMap"
+    , "java.util.concurrent.ConcurrentSkipListSet"
+    , "java.util.concurrent.CopyOnWriteArrayList"
+    , "java.util.concurrent.CopyOnWriteArraySet"
+    , "java.util.concurrent.CountDownLatch"
+    , "java.util.concurrent.CyclicBarrier"
+    , "java.util.concurrent.DelayQueue"
+    , "java.util.concurrent.Delayed"
+    , "java.util.concurrent.Exchanger"
+    , "java.util.concurrent.ExecutionException"
+    , "java.util.concurrent.Executor"
+    , "java.util.concurrent.ExecutorCompletionService"
+    , "java.util.concurrent.ExecutorService"
+    , "java.util.concurrent.Executors"
+    , "java.util.concurrent.Future"
+    , "java.util.concurrent.FutureTask"
+    , "java.util.concurrent.LinkedBlockingDeque"
+    , "java.util.concurrent.LinkedBlockingQueue"
+    , "java.util.concurrent.PriorityBlockingQueue"
+    , "java.util.concurrent.RejectedExecutionException"
+    , "java.util.concurrent.RejectedExecutionHandler"
+    , "java.util.concurrent.RunnableFuture"
+    , "java.util.concurrent.RunnableScheduledFuture"
+    , "java.util.concurrent.ScheduledExecutorService"
+    , "java.util.concurrent.ScheduledFuture"
+    , "java.util.concurrent.ScheduledThreadPoolExecutor"
+    , "java.util.concurrent.Semaphore"
+    , "java.util.concurrent.SynchronousQueue"
+    , "java.util.concurrent.ThreadFactory"
+    , "java.util.concurrent.ThreadPoolExecutor"
+    , "java.util.concurrent.ThreadPoolExecutor$AbortPolicy"
+    , "java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"
+    , "java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy"
+    , "java.util.concurrent.ThreadPoolExecutor$DiscardPolicy"
+    , "java.util.concurrent.TimeUnit"
+    , "java.util.concurrent.TimeoutException"
+    , "java.util.concurrent.atomic.AtomicBoolean"
+    , "java.util.concurrent.atomic.AtomicInteger"
+    , "java.util.concurrent.atomic.AtomicIntegerArray"
+    , "java.util.concurrent.atomic.AtomicIntegerFieldUpdater"
+    , "java.util.concurrent.atomic.AtomicLong"
+    , "java.util.concurrent.atomic.AtomicLongArray"
+    , "java.util.concurrent.atomic.AtomicLongFieldUpdater"
+    , "java.util.concurrent.atomic.AtomicMarkableReference"
+    , "java.util.concurrent.atomic.AtomicReference"
+    , "java.util.concurrent.atomic.AtomicReferenceArray"
+    , "java.util.concurrent.atomic.AtomicReferenceFieldUpdater"
+    , "java.util.concurrent.atomic.AtomicStampedReference"
+    , "java.util.concurrent.locks.AbstractOwnableSynchronizer"
+    , "java.util.concurrent.locks.AbstractQueuedLongSynchronizer"
+    , "java.util.concurrent.locks.AbstractQueuedSynchronizer"
+    , "java.util.concurrent.locks.Condition"
+    , "java.util.concurrent.locks.Lock"
+    , "java.util.concurrent.locks.LockSupport"
+    , "java.util.concurrent.locks.ReadWriteLock"
+    , "java.util.concurrent.locks.ReentrantLock"
+    , "java.util.concurrent.locks.ReentrantReadWriteLock"
+    , "java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock"
+    , "java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock"
+    , "java.util.jar.Attributes"
+    , "java.util.jar.Attributes$Name"
+    , "java.util.jar.JarEntry"
+    , "java.util.jar.JarException"
+    , "java.util.jar.JarFile"
+    , "java.util.jar.JarInputStream"
+    , "java.util.jar.JarOutputStream"
+    , "java.util.jar.Manifest"
+    , "java.util.jar.Pack200"
+    , "java.util.jar.Pack200$Packer"
+    , "java.util.jar.Pack200$Unpacker"
+    , "java.util.logging.ConsoleHandler"
+    , "java.util.logging.ErrorManager"
+    , "java.util.logging.FileHandler"
+    , "java.util.logging.Filter"
+    , "java.util.logging.Formatter"
+    , "java.util.logging.Handler"
+    , "java.util.logging.Level"
+    , "java.util.logging.LogManager"
+    , "java.util.logging.LogRecord"
+    , "java.util.logging.Logger"
+    , "java.util.logging.LoggingMXBean"
+    , "java.util.logging.LoggingPermission"
+    , "java.util.logging.MemoryHandler"
+    , "java.util.logging.SimpleFormatter"
+    , "java.util.logging.SocketHandler"
+    , "java.util.logging.StreamHandler"
+    , "java.util.logging.XMLFormatter"
+    , "java.util.prefs.AbstractPreferences"
+    , "java.util.prefs.BackingStoreException"
+    , "java.util.prefs.InvalidPreferencesFormatException"
+    , "java.util.prefs.NodeChangeEvent"
+    , "java.util.prefs.NodeChangeListener"
+    , "java.util.prefs.PreferenceChangeEvent"
+    , "java.util.prefs.PreferenceChangeListener"
+    , "java.util.prefs.Preferences"
+    , "java.util.prefs.PreferencesFactory"
+    , "java.util.regex.MatchResult"
+    , "java.util.regex.Matcher"
+    , "java.util.regex.Pattern"
+    , "java.util.regex.PatternSyntaxException"
+    , "java.util.spi.CurrencyNameProvider"
+    , "java.util.spi.LocaleNameProvider"
+    , "java.util.spi.LocaleServiceProvider"
+    , "java.util.spi.TimeZoneNameProvider"
+    , "java.util.zip.Adler32"
+    , "java.util.zip.CRC32"
+    , "java.util.zip.CheckedInputStream"
+    , "java.util.zip.CheckedOutputStream"
+    , "java.util.zip.Checksum"
+    , "java.util.zip.DataFormatException"
+    , "java.util.zip.Deflater"
+    , "java.util.zip.DeflaterInputStream"
+    , "java.util.zip.DeflaterOutputStream"
+    , "java.util.zip.GZIPInputStream"
+    , "java.util.zip.GZIPOutputStream"
+    , "java.util.zip.Inflater"
+    , "java.util.zip.InflaterInputStream"
+    , "java.util.zip.InflaterOutputStream"
+    , "java.util.zip.ZipEntry"
+    , "java.util.zip.ZipError"
+    , "java.util.zip.ZipException"
+    , "java.util.zip.ZipFile"
+    , "java.util.zip.ZipInputStream"
+    , "java.util.zip.ZipOutputStream"
+    , "javax.accessibility.Accessible"
+    , "javax.accessibility.AccessibleAction"
+    , "javax.accessibility.AccessibleAttributeSequence"
+    , "javax.accessibility.AccessibleBundle"
+    , "javax.accessibility.AccessibleComponent"
+    , "javax.accessibility.AccessibleContext"
+    , "javax.accessibility.AccessibleEditableText"
+    , "javax.accessibility.AccessibleExtendedComponent"
+    , "javax.accessibility.AccessibleExtendedTable"
+    , "javax.accessibility.AccessibleExtendedText"
+    , "javax.accessibility.AccessibleHyperlink"
+    , "javax.accessibility.AccessibleHypertext"
+    , "javax.accessibility.AccessibleIcon"
+    , "javax.accessibility.AccessibleKeyBinding"
+    , "javax.accessibility.AccessibleRelation"
+    , "javax.accessibility.AccessibleRelationSet"
+    , "javax.accessibility.AccessibleResourceBundle"
+    , "javax.accessibility.AccessibleRole"
+    , "javax.accessibility.AccessibleSelection"
+    , "javax.accessibility.AccessibleState"
+    , "javax.accessibility.AccessibleStateSet"
+    , "javax.accessibility.AccessibleStreamable"
+    , "javax.accessibility.AccessibleTable"
+    , "javax.accessibility.AccessibleTableModelChange"
+    , "javax.accessibility.AccessibleText"
+    , "javax.accessibility.AccessibleTextSequence"
+    , "javax.accessibility.AccessibleValue"
+    , "javax.activation.ActivationDataFlavor"
+    , "javax.activation.CommandInfo"
+    , "javax.activation.CommandMap"
+    , "javax.activation.CommandObject"
+    , "javax.activation.DataContentHandler"
+    , "javax.activation.DataContentHandlerFactory"
+    , "javax.activation.DataHandler"
+    , "javax.activation.DataSource"
+    , "javax.activation.FileDataSource"
+    , "javax.activation.FileTypeMap"
+    , "javax.activation.MailcapCommandMap"
+    , "javax.activation.MimeType"
+    , "javax.activation.MimeTypeParameterList"
+    , "javax.activation.MimeTypeParseException"
+    , "javax.activation.MimetypesFileTypeMap"
+    , "javax.activation.URLDataSource"
+    , "javax.activation.UnsupportedDataTypeException"
+    , "javax.activity.ActivityCompletedException"
+    , "javax.activity.ActivityRequiredException"
+    , "javax.activity.InvalidActivityException"
+    , "javax.annotation.Generated"
+    , "javax.annotation.PostConstruct"
+    , "javax.annotation.PreDestroy"
+    , "javax.annotation.Resource"
+    , "javax.annotation.Resource$AuthenticationType"
+    , "javax.annotation.Resources"
+    , "javax.annotation.processing.AbstractProcessor"
+    , "javax.annotation.processing.Completion"
+    , "javax.annotation.processing.Completions"
+    , "javax.annotation.processing.Filer"
+    , "javax.annotation.processing.FilerException"
+    , "javax.annotation.processing.Messager"
+    , "javax.annotation.processing.ProcessingEnvironment"
+    , "javax.annotation.processing.Processor"
+    , "javax.annotation.processing.RoundEnvironment"
+    , "javax.annotation.processing.SupportedAnnotationTypes"
+    , "javax.annotation.processing.SupportedOptions"
+    , "javax.annotation.processing.SupportedSourceVersion"
+    , "javax.crypto.BadPaddingException"
+    , "javax.crypto.Cipher"
+    , "javax.crypto.CipherInputStream"
+    , "javax.crypto.CipherOutputStream"
+    , "javax.crypto.CipherSpi"
+    , "javax.crypto.EncryptedPrivateKeyInfo"
+    , "javax.crypto.ExemptionMechanism"
+    , "javax.crypto.ExemptionMechanismException"
+    , "javax.crypto.ExemptionMechanismSpi"
+    , "javax.crypto.IllegalBlockSizeException"
+    , "javax.crypto.KeyAgreement"
+    , "javax.crypto.KeyAgreementSpi"
+    , "javax.crypto.KeyGenerator"
+    , "javax.crypto.KeyGeneratorSpi"
+    , "javax.crypto.Mac"
+    , "javax.crypto.MacSpi"
+    , "javax.crypto.NoSuchPaddingException"
+    , "javax.crypto.NullCipher"
+    , "javax.crypto.SealedObject"
+    , "javax.crypto.SecretKey"
+    , "javax.crypto.SecretKeyFactory"
+    , "javax.crypto.SecretKeyFactorySpi"
+    , "javax.crypto.ShortBufferException"
+    , "javax.crypto.interfaces.DHKey"
+    , "javax.crypto.interfaces.DHPrivateKey"
+    , "javax.crypto.interfaces.DHPublicKey"
+    , "javax.crypto.interfaces.PBEKey"
+    , "javax.crypto.spec.DESKeySpec"
+    , "javax.crypto.spec.DESedeKeySpec"
+    , "javax.crypto.spec.DHGenParameterSpec"
+    , "javax.crypto.spec.DHParameterSpec"
+    , "javax.crypto.spec.DHPrivateKeySpec"
+    , "javax.crypto.spec.DHPublicKeySpec"
+    , "javax.crypto.spec.IvParameterSpec"
+    , "javax.crypto.spec.OAEPParameterSpec"
+    , "javax.crypto.spec.PBEKeySpec"
+    , "javax.crypto.spec.PBEParameterSpec"
+    , "javax.crypto.spec.PSource"
+    , "javax.crypto.spec.PSource$PSpecified"
+    , "javax.crypto.spec.RC2ParameterSpec"
+    , "javax.crypto.spec.RC5ParameterSpec"
+    , "javax.crypto.spec.SecretKeySpec"
+    , "javax.imageio.IIOException"
+    , "javax.imageio.IIOImage"
+    , "javax.imageio.IIOParam"
+    , "javax.imageio.IIOParamController"
+    , "javax.imageio.ImageIO"
+    , "javax.imageio.ImageReadParam"
+    , "javax.imageio.ImageReader"
+    , "javax.imageio.ImageTranscoder"
+    , "javax.imageio.ImageTypeSpecifier"
+    , "javax.imageio.ImageWriteParam"
+    , "javax.imageio.ImageWriter"
+    , "javax.imageio.event.IIOReadProgressListener"
+    , "javax.imageio.event.IIOReadUpdateListener"
+    , "javax.imageio.event.IIOReadWarningListener"
+    , "javax.imageio.event.IIOWriteProgressListener"
+    , "javax.imageio.event.IIOWriteWarningListener"
+    , "javax.imageio.metadata.IIOInvalidTreeException"
+    , "javax.imageio.metadata.IIOMetadata"
+    , "javax.imageio.metadata.IIOMetadataController"
+    , "javax.imageio.metadata.IIOMetadataFormat"
+    , "javax.imageio.metadata.IIOMetadataFormatImpl"
+    , "javax.imageio.metadata.IIOMetadataNode"
+    , "javax.imageio.plugins.bmp.BMPImageWriteParam"
+    , "javax.imageio.plugins.jpeg.JPEGHuffmanTable"
+    , "javax.imageio.plugins.jpeg.JPEGImageReadParam"
+    , "javax.imageio.plugins.jpeg.JPEGImageWriteParam"
+    , "javax.imageio.plugins.jpeg.JPEGQTable"
+    , "javax.imageio.spi.IIORegistry"
+    , "javax.imageio.spi.IIOServiceProvider"
+    , "javax.imageio.spi.ImageInputStreamSpi"
+    , "javax.imageio.spi.ImageOutputStreamSpi"
+    , "javax.imageio.spi.ImageReaderSpi"
+    , "javax.imageio.spi.ImageReaderWriterSpi"
+    , "javax.imageio.spi.ImageTranscoderSpi"
+    , "javax.imageio.spi.ImageWriterSpi"
+    , "javax.imageio.spi.RegisterableService"
+    , "javax.imageio.spi.ServiceRegistry"
+    , "javax.imageio.spi.ServiceRegistry$Filter"
+    , "javax.imageio.stream.FileCacheImageInputStream"
+    , "javax.imageio.stream.FileCacheImageOutputStream"
+    , "javax.imageio.stream.FileImageInputStream"
+    , "javax.imageio.stream.FileImageOutputStream"
+    , "javax.imageio.stream.IIOByteBuffer"
+    , "javax.imageio.stream.ImageInputStream"
+    , "javax.imageio.stream.ImageInputStreamImpl"
+    , "javax.imageio.stream.ImageOutputStream"
+    , "javax.imageio.stream.ImageOutputStreamImpl"
+    , "javax.imageio.stream.MemoryCacheImageInputStream"
+    , "javax.imageio.stream.MemoryCacheImageOutputStream"
+    , "javax.jws.HandlerChain"
+    , "javax.jws.Oneway"
+    , "javax.jws.WebMethod"
+    , "javax.jws.WebParam"
+    , "javax.jws.WebParam$Mode"
+    , "javax.jws.WebResult"
+    , "javax.jws.WebService"
+    , "javax.jws.soap.InitParam"
+    , "javax.jws.soap.SOAPBinding"
+    , "javax.jws.soap.SOAPBinding$ParameterStyle"
+    , "javax.jws.soap.SOAPBinding$Style"
+    , "javax.jws.soap.SOAPBinding$Use"
+    , "javax.jws.soap.SOAPMessageHandler"
+    , "javax.jws.soap.SOAPMessageHandlers"
+    , "javax.lang.model.SourceVersion"
+    , "javax.lang.model.element.AnnotationMirror"
+    , "javax.lang.model.element.AnnotationValue"
+    , "javax.lang.model.element.AnnotationValueVisitor"
+    , "javax.lang.model.element.Element"
+    , "javax.lang.model.element.ElementKind"
+    , "javax.lang.model.element.ElementVisitor"
+    , "javax.lang.model.element.ExecutableElement"
+    , "javax.lang.model.element.Modifier"
+    , "javax.lang.model.element.Name"
+    , "javax.lang.model.element.NestingKind"
+    , "javax.lang.model.element.PackageElement"
+    , "javax.lang.model.element.TypeElement"
+    , "javax.lang.model.element.TypeParameterElement"
+    , "javax.lang.model.element.UnknownAnnotationValueException"
+    , "javax.lang.model.element.UnknownElementException"
+    , "javax.lang.model.element.VariableElement"
+    , "javax.lang.model.type.ArrayType"
+    , "javax.lang.model.type.DeclaredType"
+    , "javax.lang.model.type.ErrorType"
+    , "javax.lang.model.type.ExecutableType"
+    , "javax.lang.model.type.MirroredTypeException"
+    , "javax.lang.model.type.MirroredTypesException"
+    , "javax.lang.model.type.NoType"
+    , "javax.lang.model.type.NullType"
+    , "javax.lang.model.type.PrimitiveType"
+    , "javax.lang.model.type.ReferenceType"
+    , "javax.lang.model.type.TypeKind"
+    , "javax.lang.model.type.TypeMirror"
+    , "javax.lang.model.type.TypeVariable"
+    , "javax.lang.model.type.TypeVisitor"
+    , "javax.lang.model.type.UnknownTypeException"
+    , "javax.lang.model.type.WildcardType"
+    , "javax.lang.model.util.AbstractAnnotationValueVisitor6"
+    , "javax.lang.model.util.AbstractElementVisitor6"
+    , "javax.lang.model.util.AbstractTypeVisitor6"
+    , "javax.lang.model.util.ElementFilter"
+    , "javax.lang.model.util.ElementKindVisitor6"
+    , "javax.lang.model.util.ElementScanner6"
+    , "javax.lang.model.util.Elements"
+    , "javax.lang.model.util.SimpleAnnotationValueVisitor6"
+    , "javax.lang.model.util.SimpleElementVisitor6"
+    , "javax.lang.model.util.SimpleTypeVisitor6"
+    , "javax.lang.model.util.TypeKindVisitor6"
+    , "javax.lang.model.util.Types"
+    , "javax.management.Attribute"
+    , "javax.management.AttributeChangeNotification"
+    , "javax.management.AttributeChangeNotificationFilter"
+    , "javax.management.AttributeList"
+    , "javax.management.AttributeNotFoundException"
+    , "javax.management.AttributeValueExp"
+    , "javax.management.BadAttributeValueExpException"
+    , "javax.management.BadBinaryOpValueExpException"
+    , "javax.management.BadStringOperationException"
+    , "javax.management.DefaultLoaderRepository"
+    , "javax.management.Descriptor"
+    , "javax.management.DescriptorAccess"
+    , "javax.management.DescriptorKey"
+    , "javax.management.DescriptorRead"
+    , "javax.management.DynamicMBean"
+    , "javax.management.ImmutableDescriptor"
+    , "javax.management.InstanceAlreadyExistsException"
+    , "javax.management.InstanceNotFoundException"
+    , "javax.management.IntrospectionException"
+    , "javax.management.InvalidApplicationException"
+    , "javax.management.InvalidAttributeValueException"
+    , "javax.management.JMException"
+    , "javax.management.JMRuntimeException"
+    , "javax.management.JMX"
+    , "javax.management.ListenerNotFoundException"
+    , "javax.management.MBeanAttributeInfo"
+    , "javax.management.MBeanConstructorInfo"
+    , "javax.management.MBeanException"
+    , "javax.management.MBeanFeatureInfo"
+    , "javax.management.MBeanInfo"
+    , "javax.management.MBeanNotificationInfo"
+    , "javax.management.MBeanOperationInfo"
+    , "javax.management.MBeanParameterInfo"
+    , "javax.management.MBeanPermission"
+    , "javax.management.MBeanRegistration"
+    , "javax.management.MBeanRegistrationException"
+    , "javax.management.MBeanServer"
+    , "javax.management.MBeanServerBuilder"
+    , "javax.management.MBeanServerConnection"
+    , "javax.management.MBeanServerDelegate"
+    , "javax.management.MBeanServerDelegateMBean"
+    , "javax.management.MBeanServerFactory"
+    , "javax.management.MBeanServerInvocationHandler"
+    , "javax.management.MBeanServerNotification"
+    , "javax.management.MBeanServerPermission"
+    , "javax.management.MBeanTrustPermission"
+    , "javax.management.MXBean"
+    , "javax.management.MalformedObjectNameException"
+    , "javax.management.NotCompliantMBeanException"
+    , "javax.management.Notification"
+    , "javax.management.NotificationBroadcaster"
+    , "javax.management.NotificationBroadcasterSupport"
+    , "javax.management.NotificationEmitter"
+    , "javax.management.NotificationFilter"
+    , "javax.management.NotificationFilterSupport"
+    , "javax.management.NotificationListener"
+    , "javax.management.ObjectInstance"
+    , "javax.management.ObjectName"
+    , "javax.management.OperationsException"
+    , "javax.management.PersistentMBean"
+    , "javax.management.Query"
+    , "javax.management.QueryEval"
+    , "javax.management.QueryExp"
+    , "javax.management.ReflectionException"
+    , "javax.management.RuntimeErrorException"
+    , "javax.management.RuntimeMBeanException"
+    , "javax.management.RuntimeOperationsException"
+    , "javax.management.ServiceNotFoundException"
+    , "javax.management.StandardEmitterMBean"
+    , "javax.management.StandardMBean"
+    , "javax.management.StringValueExp"
+    , "javax.management.ValueExp"
+    , "javax.management.loading.ClassLoaderRepository"
+    , "javax.management.loading.DefaultLoaderRepository"
+    , "javax.management.loading.MLet"
+    , "javax.management.loading.MLetContent"
+    , "javax.management.loading.MLetMBean"
+    , "javax.management.loading.PrivateClassLoader"
+    , "javax.management.loading.PrivateMLet"
+    , "javax.management.modelmbean.DescriptorSupport"
+    , "javax.management.modelmbean.InvalidTargetObjectTypeException"
+    , "javax.management.modelmbean.ModelMBean"
+    , "javax.management.modelmbean.ModelMBeanAttributeInfo"
+    , "javax.management.modelmbean.ModelMBeanConstructorInfo"
+    , "javax.management.modelmbean.ModelMBeanInfo"
+    , "javax.management.modelmbean.ModelMBeanInfoSupport"
+    , "javax.management.modelmbean.ModelMBeanNotificationBroadcaster"
+    , "javax.management.modelmbean.ModelMBeanNotificationInfo"
+    , "javax.management.modelmbean.ModelMBeanOperationInfo"
+    , "javax.management.modelmbean.RequiredModelMBean"
+    , "javax.management.modelmbean.XMLParseException"
+    , "javax.management.monitor.CounterMonitor"
+    , "javax.management.monitor.CounterMonitorMBean"
+    , "javax.management.monitor.GaugeMonitor"
+    , "javax.management.monitor.GaugeMonitorMBean"
+    , "javax.management.monitor.Monitor"
+    , "javax.management.monitor.MonitorMBean"
+    , "javax.management.monitor.MonitorNotification"
+    , "javax.management.monitor.MonitorSettingException"
+    , "javax.management.monitor.StringMonitor"
+    , "javax.management.monitor.StringMonitorMBean"
+    , "javax.management.openmbean.ArrayType"
+    , "javax.management.openmbean.CompositeData"
+    , "javax.management.openmbean.CompositeDataInvocationHandler"
+    , "javax.management.openmbean.CompositeDataSupport"
+    , "javax.management.openmbean.CompositeDataView"
+    , "javax.management.openmbean.CompositeType"
+    , "javax.management.openmbean.InvalidKeyException"
+    , "javax.management.openmbean.InvalidOpenTypeException"
+    , "javax.management.openmbean.KeyAlreadyExistsException"
+    , "javax.management.openmbean.OpenDataException"
+    , "javax.management.openmbean.OpenMBeanAttributeInfo"
+    , "javax.management.openmbean.OpenMBeanAttributeInfoSupport"
+    , "javax.management.openmbean.OpenMBeanConstructorInfo"
+    , "javax.management.openmbean.OpenMBeanConstructorInfoSupport"
+    , "javax.management.openmbean.OpenMBeanInfo"
+    , "javax.management.openmbean.OpenMBeanInfoSupport"
+    , "javax.management.openmbean.OpenMBeanOperationInfo"
+    , "javax.management.openmbean.OpenMBeanOperationInfoSupport"
+    , "javax.management.openmbean.OpenMBeanParameterInfo"
+    , "javax.management.openmbean.OpenMBeanParameterInfoSupport"
+    , "javax.management.openmbean.OpenType"
+    , "javax.management.openmbean.SimpleType"
+    , "javax.management.openmbean.TabularData"
+    , "javax.management.openmbean.TabularDataSupport"
+    , "javax.management.openmbean.TabularType"
+    , "javax.management.relation.InvalidRelationIdException"
+    , "javax.management.relation.InvalidRelationServiceException"
+    , "javax.management.relation.InvalidRelationTypeException"
+    , "javax.management.relation.InvalidRoleInfoException"
+    , "javax.management.relation.InvalidRoleValueException"
+    , "javax.management.relation.MBeanServerNotificationFilter"
+    , "javax.management.relation.Relation"
+    , "javax.management.relation.RelationException"
+    , "javax.management.relation.RelationNotFoundException"
+    , "javax.management.relation.RelationNotification"
+    , "javax.management.relation.RelationService"
+    , "javax.management.relation.RelationServiceMBean"
+    , "javax.management.relation.RelationServiceNotRegisteredException"
+    , "javax.management.relation.RelationSupport"
+    , "javax.management.relation.RelationSupportMBean"
+    , "javax.management.relation.RelationType"
+    , "javax.management.relation.RelationTypeNotFoundException"
+    , "javax.management.relation.RelationTypeSupport"
+    , "javax.management.relation.Role"
+    , "javax.management.relation.RoleInfo"
+    , "javax.management.relation.RoleInfoNotFoundException"
+    , "javax.management.relation.RoleList"
+    , "javax.management.relation.RoleNotFoundException"
+    , "javax.management.relation.RoleResult"
+    , "javax.management.relation.RoleStatus"
+    , "javax.management.relation.RoleUnresolved"
+    , "javax.management.relation.RoleUnresolvedList"
+    , "javax.management.remote.JMXAddressable"
+    , "javax.management.remote.JMXAuthenticator"
+    , "javax.management.remote.JMXConnectionNotification"
+    , "javax.management.remote.JMXConnector"
+    , "javax.management.remote.JMXConnectorFactory"
+    , "javax.management.remote.JMXConnectorProvider"
+    , "javax.management.remote.JMXConnectorServer"
+    , "javax.management.remote.JMXConnectorServerFactory"
+    , "javax.management.remote.JMXConnectorServerMBean"
+    , "javax.management.remote.JMXConnectorServerProvider"
+    , "javax.management.remote.JMXPrincipal"
+    , "javax.management.remote.JMXProviderException"
+    , "javax.management.remote.JMXServerErrorException"
+    , "javax.management.remote.JMXServiceURL"
+    , "javax.management.remote.MBeanServerForwarder"
+    , "javax.management.remote.NotificationResult"
+    , "javax.management.remote.SubjectDelegationPermission"
+    , "javax.management.remote.TargetedNotification"
+    , "javax.management.remote.rmi.RMIConnection"
+    , "javax.management.remote.rmi.RMIConnectionImpl"
+    , "javax.management.remote.rmi.RMIConnectionImpl_Stub"
+    , "javax.management.remote.rmi.RMIConnector"
+    , "javax.management.remote.rmi.RMIConnectorServer"
+    , "javax.management.remote.rmi.RMIIIOPServerImpl"
+    , "javax.management.remote.rmi.RMIJRMPServerImpl"
+    , "javax.management.remote.rmi.RMIServer"
+    , "javax.management.remote.rmi.RMIServerImpl"
+    , "javax.management.remote.rmi.RMIServerImpl_Stub"
+    , "javax.management.timer.Timer"
+    , "javax.management.timer.TimerMBean"
+    , "javax.management.timer.TimerNotification"
+    , "javax.naming.AuthenticationException"
+    , "javax.naming.AuthenticationNotSupportedException"
+    , "javax.naming.BinaryRefAddr"
+    , "javax.naming.Binding"
+    , "javax.naming.CannotProceedException"
+    , "javax.naming.CommunicationException"
+    , "javax.naming.CompositeName"
+    , "javax.naming.CompoundName"
+    , "javax.naming.ConfigurationException"
+    , "javax.naming.Context"
+    , "javax.naming.ContextNotEmptyException"
+    , "javax.naming.InitialContext"
+    , "javax.naming.InsufficientResourcesException"
+    , "javax.naming.InterruptedNamingException"
+    , "javax.naming.InvalidNameException"
+    , "javax.naming.LimitExceededException"
+    , "javax.naming.LinkException"
+    , "javax.naming.LinkLoopException"
+    , "javax.naming.LinkRef"
+    , "javax.naming.MalformedLinkException"
+    , "javax.naming.Name"
+    , "javax.naming.NameAlreadyBoundException"
+    , "javax.naming.NameClassPair"
+    , "javax.naming.NameNotFoundException"
+    , "javax.naming.NameParser"
+    , "javax.naming.NamingEnumeration"
+    , "javax.naming.NamingException"
+    , "javax.naming.NamingSecurityException"
+    , "javax.naming.NoInitialContextException"
+    , "javax.naming.NoPermissionException"
+    , "javax.naming.NotContextException"
+    , "javax.naming.OperationNotSupportedException"
+    , "javax.naming.PartialResultException"
+    , "javax.naming.RefAddr"
+    , "javax.naming.Reference"
+    , "javax.naming.Referenceable"
+    , "javax.naming.ReferralException"
+    , "javax.naming.ServiceUnavailableException"
+    , "javax.naming.SizeLimitExceededException"
+    , "javax.naming.StringRefAddr"
+    , "javax.naming.TimeLimitExceededException"
+    , "javax.naming.directory.Attribute"
+    , "javax.naming.directory.AttributeInUseException"
+    , "javax.naming.directory.AttributeModificationException"
+    , "javax.naming.directory.Attributes"
+    , "javax.naming.directory.BasicAttribute"
+    , "javax.naming.directory.BasicAttributes"
+    , "javax.naming.directory.DirContext"
+    , "javax.naming.directory.InitialDirContext"
+    , "javax.naming.directory.InvalidAttributeIdentifierException"
+    , "javax.naming.directory.InvalidAttributeValueException"
+    , "javax.naming.directory.InvalidAttributesException"
+    , "javax.naming.directory.InvalidSearchControlsException"
+    , "javax.naming.directory.InvalidSearchFilterException"
+    , "javax.naming.directory.ModificationItem"
+    , "javax.naming.directory.NoSuchAttributeException"
+    , "javax.naming.directory.SchemaViolationException"
+    , "javax.naming.directory.SearchControls"
+    , "javax.naming.directory.SearchResult"
+    , "javax.naming.event.EventContext"
+    , "javax.naming.event.EventDirContext"
+    , "javax.naming.event.NamespaceChangeListener"
+    , "javax.naming.event.NamingEvent"
+    , "javax.naming.event.NamingExceptionEvent"
+    , "javax.naming.event.NamingListener"
+    , "javax.naming.event.ObjectChangeListener"
+    , "javax.naming.ldap.BasicControl"
+    , "javax.naming.ldap.Control"
+    , "javax.naming.ldap.ControlFactory"
+    , "javax.naming.ldap.ExtendedRequest"
+    , "javax.naming.ldap.ExtendedResponse"
+    , "javax.naming.ldap.HasControls"
+    , "javax.naming.ldap.InitialLdapContext"
+    , "javax.naming.ldap.LdapContext"
+    , "javax.naming.ldap.LdapName"
+    , "javax.naming.ldap.LdapReferralException"
+    , "javax.naming.ldap.ManageReferralControl"
+    , "javax.naming.ldap.PagedResultsControl"
+    , "javax.naming.ldap.PagedResultsResponseControl"
+    , "javax.naming.ldap.Rdn"
+    , "javax.naming.ldap.SortControl"
+    , "javax.naming.ldap.SortKey"
+    , "javax.naming.ldap.SortResponseControl"
+    , "javax.naming.ldap.StartTlsRequest"
+    , "javax.naming.ldap.StartTlsResponse"
+    , "javax.naming.ldap.UnsolicitedNotification"
+    , "javax.naming.ldap.UnsolicitedNotificationEvent"
+    , "javax.naming.ldap.UnsolicitedNotificationListener"
+    , "javax.naming.spi.DirObjectFactory"
+    , "javax.naming.spi.DirStateFactory"
+    , "javax.naming.spi.DirStateFactory$Result"
+    , "javax.naming.spi.DirectoryManager"
+    , "javax.naming.spi.InitialContextFactory"
+    , "javax.naming.spi.InitialContextFactoryBuilder"
+    , "javax.naming.spi.NamingManager"
+    , "javax.naming.spi.ObjectFactory"
+    , "javax.naming.spi.ObjectFactoryBuilder"
+    , "javax.naming.spi.ResolveResult"
+    , "javax.naming.spi.Resolver"
+    , "javax.naming.spi.StateFactory"
+    , "javax.net.ServerSocketFactory"
+    , "javax.net.SocketFactory"
+    , "javax.net.ssl.CertPathTrustManagerParameters"
+    , "javax.net.ssl.HandshakeCompletedEvent"
+    , "javax.net.ssl.HandshakeCompletedListener"
+    , "javax.net.ssl.HostnameVerifier"
+    , "javax.net.ssl.HttpsURLConnection"
+    , "javax.net.ssl.KeyManager"
+    , "javax.net.ssl.KeyManagerFactory"
+    , "javax.net.ssl.KeyManagerFactorySpi"
+    , "javax.net.ssl.KeyStoreBuilderParameters"
+    , "javax.net.ssl.ManagerFactoryParameters"
+    , "javax.net.ssl.SSLContext"
+    , "javax.net.ssl.SSLContextSpi"
+    , "javax.net.ssl.SSLEngine"
+    , "javax.net.ssl.SSLEngineResult"
+    , "javax.net.ssl.SSLEngineResult$HandshakeStatus"
+    , "javax.net.ssl.SSLEngineResult$Status"
+    , "javax.net.ssl.SSLException"
+    , "javax.net.ssl.SSLHandshakeException"
+    , "javax.net.ssl.SSLKeyException"
+    , "javax.net.ssl.SSLParameters"
+    , "javax.net.ssl.SSLPeerUnverifiedException"
+    , "javax.net.ssl.SSLPermission"
+    , "javax.net.ssl.SSLProtocolException"
+    , "javax.net.ssl.SSLServerSocket"
+    , "javax.net.ssl.SSLServerSocketFactory"
+    , "javax.net.ssl.SSLSession"
+    , "javax.net.ssl.SSLSessionBindingEvent"
+    , "javax.net.ssl.SSLSessionBindingListener"
+    , "javax.net.ssl.SSLSessionContext"
+    , "javax.net.ssl.SSLSocket"
+    , "javax.net.ssl.SSLSocketFactory"
+    , "javax.net.ssl.TrustManager"
+    , "javax.net.ssl.TrustManagerFactory"
+    , "javax.net.ssl.TrustManagerFactorySpi"
+    , "javax.net.ssl.X509ExtendedKeyManager"
+    , "javax.net.ssl.X509KeyManager"
+    , "javax.net.ssl.X509TrustManager"
+    , "javax.print.AttributeException"
+    , "javax.print.CancelablePrintJob"
+    , "javax.print.Doc"
+    , "javax.print.DocFlavor"
+    , "javax.print.DocFlavor$BYTE_ARRAY"
+    , "javax.print.DocFlavor$CHAR_ARRAY"
+    , "javax.print.DocFlavor$INPUT_STREAM"
+    , "javax.print.DocFlavor$READER"
+    , "javax.print.DocFlavor$SERVICE_FORMATTED"
+    , "javax.print.DocFlavor$STRING"
+    , "javax.print.DocFlavor$URL"
+    , "javax.print.DocPrintJob"
+    , "javax.print.FlavorException"
+    , "javax.print.MultiDoc"
+    , "javax.print.MultiDocPrintJob"
+    , "javax.print.MultiDocPrintService"
+    , "javax.print.PrintException"
+    , "javax.print.PrintService"
+    , "javax.print.PrintServiceLookup"
+    , "javax.print.ServiceUI"
+    , "javax.print.ServiceUIFactory"
+    , "javax.print.SimpleDoc"
+    , "javax.print.StreamPrintService"
+    , "javax.print.StreamPrintServiceFactory"
+    , "javax.print.URIException"
+    , "javax.print.attribute.Attribute"
+    , "javax.print.attribute.AttributeSet"
+    , "javax.print.attribute.AttributeSetUtilities"
+    , "javax.print.attribute.DateTimeSyntax"
+    , "javax.print.attribute.DocAttribute"
+    , "javax.print.attribute.DocAttributeSet"
+    , "javax.print.attribute.EnumSyntax"
+    , "javax.print.attribute.HashAttributeSet"
+    , "javax.print.attribute.HashDocAttributeSet"
+    , "javax.print.attribute.HashPrintJobAttributeSet"
+    , "javax.print.attribute.HashPrintRequestAttributeSet"
+    , "javax.print.attribute.HashPrintServiceAttributeSet"
+    , "javax.print.attribute.IntegerSyntax"
+    , "javax.print.attribute.PrintJobAttribute"
+    , "javax.print.attribute.PrintJobAttributeSet"
+    , "javax.print.attribute.PrintRequestAttribute"
+    , "javax.print.attribute.PrintRequestAttributeSet"
+    , "javax.print.attribute.PrintServiceAttribute"
+    , "javax.print.attribute.PrintServiceAttributeSet"
+    , "javax.print.attribute.ResolutionSyntax"
+    , "javax.print.attribute.SetOfIntegerSyntax"
+    , "javax.print.attribute.Size2DSyntax"
+    , "javax.print.attribute.SupportedValuesAttribute"
+    , "javax.print.attribute.TextSyntax"
+    , "javax.print.attribute.URISyntax"
+    , "javax.print.attribute.UnmodifiableSetException"
+    , "javax.print.attribute.standard.Chromaticity"
+    , "javax.print.attribute.standard.ColorSupported"
+    , "javax.print.attribute.standard.Compression"
+    , "javax.print.attribute.standard.Copies"
+    , "javax.print.attribute.standard.CopiesSupported"
+    , "javax.print.attribute.standard.DateTimeAtCompleted"
+    , "javax.print.attribute.standard.DateTimeAtCreation"
+    , "javax.print.attribute.standard.DateTimeAtProcessing"
+    , "javax.print.attribute.standard.Destination"
+    , "javax.print.attribute.standard.DocumentName"
+    , "javax.print.attribute.standard.Fidelity"
+    , "javax.print.attribute.standard.Finishings"
+    , "javax.print.attribute.standard.JobHoldUntil"
+    , "javax.print.attribute.standard.JobImpressions"
+    , "javax.print.attribute.standard.JobImpressionsCompleted"
+    , "javax.print.attribute.standard.JobImpressionsSupported"
+    , "javax.print.attribute.standard.JobKOctets"
+    , "javax.print.attribute.standard.JobKOctetsProcessed"
+    , "javax.print.attribute.standard.JobKOctetsSupported"
+    , "javax.print.attribute.standard.JobMediaSheets"
+    , "javax.print.attribute.standard.JobMediaSheetsCompleted"
+    , "javax.print.attribute.standard.JobMediaSheetsSupported"
+    , "javax.print.attribute.standard.JobMessageFromOperator"
+    , "javax.print.attribute.standard.JobName"
+    , "javax.print.attribute.standard.JobOriginatingUserName"
+    , "javax.print.attribute.standard.JobPriority"
+    , "javax.print.attribute.standard.JobPrioritySupported"
+    , "javax.print.attribute.standard.JobSheets"
+    , "javax.print.attribute.standard.JobState"
+    , "javax.print.attribute.standard.JobStateReason"
+    , "javax.print.attribute.standard.JobStateReasons"
+    , "javax.print.attribute.standard.Media"
+    , "javax.print.attribute.standard.MediaName"
+    , "javax.print.attribute.standard.MediaPrintableArea"
+    , "javax.print.attribute.standard.MediaSize"
+    , "javax.print.attribute.standard.MediaSize$Engineering"
+    , "javax.print.attribute.standard.MediaSize$ISO"
+    , "javax.print.attribute.standard.MediaSize$JIS"
+    , "javax.print.attribute.standard.MediaSize$NA"
+    , "javax.print.attribute.standard.MediaSize$Other"
+    , "javax.print.attribute.standard.MediaSizeName"
+    , "javax.print.attribute.standard.MediaTray"
+    , "javax.print.attribute.standard.MultipleDocumentHandling"
+    , "javax.print.attribute.standard.NumberOfDocuments"
+    , "javax.print.attribute.standard.NumberOfInterveningJobs"
+    , "javax.print.attribute.standard.NumberUp"
+    , "javax.print.attribute.standard.NumberUpSupported"
+    , "javax.print.attribute.standard.OrientationRequested"
+    , "javax.print.attribute.standard.OutputDeviceAssigned"
+    , "javax.print.attribute.standard.PDLOverrideSupported"
+    , "javax.print.attribute.standard.PageRanges"
+    , "javax.print.attribute.standard.PagesPerMinute"
+    , "javax.print.attribute.standard.PagesPerMinuteColor"
+    , "javax.print.attribute.standard.PresentationDirection"
+    , "javax.print.attribute.standard.PrintQuality"
+    , "javax.print.attribute.standard.PrinterInfo"
+    , "javax.print.attribute.standard.PrinterIsAcceptingJobs"
+    , "javax.print.attribute.standard.PrinterLocation"
+    , "javax.print.attribute.standard.PrinterMakeAndModel"
+    , "javax.print.attribute.standard.PrinterMessageFromOperator"
+    , "javax.print.attribute.standard.PrinterMoreInfo"
+    , "javax.print.attribute.standard.PrinterMoreInfoManufacturer"
+    , "javax.print.attribute.standard.PrinterName"
+    , "javax.print.attribute.standard.PrinterResolution"
+    , "javax.print.attribute.standard.PrinterState"
+    , "javax.print.attribute.standard.PrinterStateReason"
+    , "javax.print.attribute.standard.PrinterStateReasons"
+    , "javax.print.attribute.standard.PrinterURI"
+    , "javax.print.attribute.standard.QueuedJobCount"
+    , "javax.print.attribute.standard.ReferenceUriSchemesSupported"
+    , "javax.print.attribute.standard.RequestingUserName"
+    , "javax.print.attribute.standard.Severity"
+    , "javax.print.attribute.standard.SheetCollate"
+    , "javax.print.attribute.standard.Sides"
+    , "javax.print.event.PrintEvent"
+    , "javax.print.event.PrintJobAdapter"
+    , "javax.print.event.PrintJobAttributeEvent"
+    , "javax.print.event.PrintJobAttributeListener"
+    , "javax.print.event.PrintJobEvent"
+    , "javax.print.event.PrintJobListener"
+    , "javax.print.event.PrintServiceAttributeEvent"
+    , "javax.print.event.PrintServiceAttributeListener"
+    , "javax.rmi.CORBA.ClassDesc"
+    , "javax.rmi.CORBA.PortableRemoteObjectDelegate"
+    , "javax.rmi.CORBA.Stub"
+    , "javax.rmi.CORBA.StubDelegate"
+    , "javax.rmi.CORBA.Tie"
+    , "javax.rmi.CORBA.Util"
+    , "javax.rmi.CORBA.UtilDelegate"
+    , "javax.rmi.CORBA.ValueHandler"
+    , "javax.rmi.CORBA.ValueHandlerMultiFormat"
+    , "javax.rmi.PortableRemoteObject"
+    , "javax.rmi.ssl.SslRMIClientSocketFactory"
+    , "javax.rmi.ssl.SslRMIServerSocketFactory"
+    , "javax.script.AbstractScriptEngine"
+    , "javax.script.Bindings"
+    , "javax.script.Compilable"
+    , "javax.script.CompiledScript"
+    , "javax.script.Invocable"
+    , "javax.script.ScriptContext"
+    , "javax.script.ScriptEngine"
+    , "javax.script.ScriptEngineFactory"
+    , "javax.script.ScriptEngineManager"
+    , "javax.script.ScriptException"
+    , "javax.script.SimpleBindings"
+    , "javax.script.SimpleScriptContext"
+    , "javax.security.auth.AuthPermission"
+    , "javax.security.auth.DestroyFailedException"
+    , "javax.security.auth.Destroyable"
+    , "javax.security.auth.Policy"
+    , "javax.security.auth.PrivateCredentialPermission"
+    , "javax.security.auth.RefreshFailedException"
+    , "javax.security.auth.Refreshable"
+    , "javax.security.auth.Subject"
+    , "javax.security.auth.SubjectDomainCombiner"
+    , "javax.security.auth.callback.Callback"
+    , "javax.security.auth.callback.CallbackHandler"
+    , "javax.security.auth.callback.ChoiceCallback"
+    , "javax.security.auth.callback.ConfirmationCallback"
+    , "javax.security.auth.callback.LanguageCallback"
+    , "javax.security.auth.callback.NameCallback"
+    , "javax.security.auth.callback.PasswordCallback"
+    , "javax.security.auth.callback.TextInputCallback"
+    , "javax.security.auth.callback.TextOutputCallback"
+    , "javax.security.auth.callback.UnsupportedCallbackException"
+    , "javax.security.auth.kerberos.DelegationPermission"
+    , "javax.security.auth.kerberos.KerberosKey"
+    , "javax.security.auth.kerberos.KerberosPrincipal"
+    , "javax.security.auth.kerberos.KerberosTicket"
+    , "javax.security.auth.kerberos.ServicePermission"
+    , "javax.security.auth.login.AccountException"
+    , "javax.security.auth.login.AccountExpiredException"
+    , "javax.security.auth.login.AccountLockedException"
+    , "javax.security.auth.login.AccountNotFoundException"
+    , "javax.security.auth.login.AppConfigurationEntry"
+    , "javax.security.auth.login.AppConfigurationEntry$LoginModuleControlFlag"
+    , "javax.security.auth.login.Configuration"
+    , "javax.security.auth.login.Configuration$Parameters"
+    , "javax.security.auth.login.ConfigurationSpi"
+    , "javax.security.auth.login.CredentialException"
+    , "javax.security.auth.login.CredentialExpiredException"
+    , "javax.security.auth.login.CredentialNotFoundException"
+    , "javax.security.auth.login.FailedLoginException"
+    , "javax.security.auth.login.LoginContext"
+    , "javax.security.auth.login.LoginException"
+    , "javax.security.auth.spi.LoginModule"
+    , "javax.security.auth.x500.X500Principal"
+    , "javax.security.auth.x500.X500PrivateCredential"
+    , "javax.security.cert.Certificate"
+    , "javax.security.cert.CertificateEncodingException"
+    , "javax.security.cert.CertificateException"
+    , "javax.security.cert.CertificateExpiredException"
+    , "javax.security.cert.CertificateNotYetValidException"
+    , "javax.security.cert.CertificateParsingException"
+    , "javax.security.cert.X509Certificate"
+    , "javax.security.sasl.AuthenticationException"
+    , "javax.security.sasl.AuthorizeCallback"
+    , "javax.security.sasl.RealmCallback"
+    , "javax.security.sasl.RealmChoiceCallback"
+    , "javax.security.sasl.Sasl"
+    , "javax.security.sasl.SaslClient"
+    , "javax.security.sasl.SaslClientFactory"
+    , "javax.security.sasl.SaslException"
+    , "javax.security.sasl.SaslServer"
+    , "javax.security.sasl.SaslServerFactory"
+    , "javax.sound.midi.ControllerEventListener"
+    , "javax.sound.midi.Instrument"
+    , "javax.sound.midi.InvalidMidiDataException"
+    , "javax.sound.midi.MetaEventListener"
+    , "javax.sound.midi.MetaMessage"
+    , "javax.sound.midi.MidiChannel"
+    , "javax.sound.midi.MidiDevice"
+    , "javax.sound.midi.MidiDevice$Info"
+    , "javax.sound.midi.MidiEvent"
+    , "javax.sound.midi.MidiFileFormat"
+    , "javax.sound.midi.MidiMessage"
+    , "javax.sound.midi.MidiSystem"
+    , "javax.sound.midi.MidiUnavailableException"
+    , "javax.sound.midi.Patch"
+    , "javax.sound.midi.Receiver"
+    , "javax.sound.midi.Sequence"
+    , "javax.sound.midi.Sequencer"
+    , "javax.sound.midi.Sequencer$SyncMode"
+    , "javax.sound.midi.ShortMessage"
+    , "javax.sound.midi.Soundbank"
+    , "javax.sound.midi.SoundbankResource"
+    , "javax.sound.midi.Synthesizer"
+    , "javax.sound.midi.SysexMessage"
+    , "javax.sound.midi.Track"
+    , "javax.sound.midi.Transmitter"
+    , "javax.sound.midi.VoiceStatus"
+    , "javax.sound.midi.spi.MidiDeviceProvider"
+    , "javax.sound.midi.spi.MidiFileReader"
+    , "javax.sound.midi.spi.MidiFileWriter"
+    , "javax.sound.midi.spi.SoundbankReader"
+    , "javax.sound.sampled.AudioFileFormat"
+    , "javax.sound.sampled.AudioFileFormat$Type"
+    , "javax.sound.sampled.AudioFormat"
+    , "javax.sound.sampled.AudioFormat$Encoding"
+    , "javax.sound.sampled.AudioInputStream"
+    , "javax.sound.sampled.AudioPermission"
+    , "javax.sound.sampled.AudioSystem"
+    , "javax.sound.sampled.BooleanControl"
+    , "javax.sound.sampled.BooleanControl$Type"
+    , "javax.sound.sampled.Clip"
+    , "javax.sound.sampled.CompoundControl"
+    , "javax.sound.sampled.CompoundControl$Type"
+    , "javax.sound.sampled.Control"
+    , "javax.sound.sampled.Control$Type"
+    , "javax.sound.sampled.DataLine"
+    , "javax.sound.sampled.DataLine$Info"
+    , "javax.sound.sampled.EnumControl"
+    , "javax.sound.sampled.EnumControl$Type"
+    , "javax.sound.sampled.FloatControl"
+    , "javax.sound.sampled.FloatControl$Type"
+    , "javax.sound.sampled.Line"
+    , "javax.sound.sampled.Line$Info"
+    , "javax.sound.sampled.LineEvent"
+    , "javax.sound.sampled.LineEvent$Type"
+    , "javax.sound.sampled.LineListener"
+    , "javax.sound.sampled.LineUnavailableException"
+    , "javax.sound.sampled.Mixer"
+    , "javax.sound.sampled.Mixer$Info"
+    , "javax.sound.sampled.Port"
+    , "javax.sound.sampled.Port$Info"
+    , "javax.sound.sampled.ReverbType"
+    , "javax.sound.sampled.SourceDataLine"
+    , "javax.sound.sampled.TargetDataLine"
+    , "javax.sound.sampled.UnsupportedAudioFileException"
+    , "javax.sound.sampled.spi.AudioFileReader"
+    , "javax.sound.sampled.spi.AudioFileWriter"
+    , "javax.sound.sampled.spi.FormatConversionProvider"
+    , "javax.sound.sampled.spi.MixerProvider"
+    , "javax.sql.CommonDataSource"
+    , "javax.sql.ConnectionEvent"
+    , "javax.sql.ConnectionEventListener"
+    , "javax.sql.ConnectionPoolDataSource"
+    , "javax.sql.DataSource"
+    , "javax.sql.PooledConnection"
+    , "javax.sql.RowSet"
+    , "javax.sql.RowSetEvent"
+    , "javax.sql.RowSetInternal"
+    , "javax.sql.RowSetListener"
+    , "javax.sql.RowSetMetaData"
+    , "javax.sql.RowSetReader"
+    , "javax.sql.RowSetWriter"
+    , "javax.sql.StatementEvent"
+    , "javax.sql.StatementEventListener"
+    , "javax.sql.XAConnection"
+    , "javax.sql.XADataSource"
+    , "javax.sql.rowset.BaseRowSet"
+    , "javax.sql.rowset.CachedRowSet"
+    , "javax.sql.rowset.FilteredRowSet"
+    , "javax.sql.rowset.JdbcRowSet"
+    , "javax.sql.rowset.JoinRowSet"
+    , "javax.sql.rowset.Joinable"
+    , "javax.sql.rowset.Predicate"
+    , "javax.sql.rowset.RowSetMetaDataImpl"
+    , "javax.sql.rowset.RowSetWarning"
+    , "javax.sql.rowset.WebRowSet"
+    , "javax.sql.rowset.serial.SQLInputImpl"
+    , "javax.sql.rowset.serial.SQLOutputImpl"
+    , "javax.sql.rowset.serial.SerialArray"
+    , "javax.sql.rowset.serial.SerialBlob"
+    , "javax.sql.rowset.serial.SerialClob"
+    , "javax.sql.rowset.serial.SerialDatalink"
+    , "javax.sql.rowset.serial.SerialException"
+    , "javax.sql.rowset.serial.SerialJavaObject"
+    , "javax.sql.rowset.serial.SerialRef"
+    , "javax.sql.rowset.serial.SerialStruct"
+    , "javax.sql.rowset.spi.SyncFactory"
+    , "javax.sql.rowset.spi.SyncFactoryException"
+    , "javax.sql.rowset.spi.SyncProvider"
+    , "javax.sql.rowset.spi.SyncProviderException"
+    , "javax.sql.rowset.spi.SyncResolver"
+    , "javax.sql.rowset.spi.TransactionalWriter"
+    , "javax.sql.rowset.spi.XmlReader"
+    , "javax.sql.rowset.spi.XmlWriter"
+    , "javax.swing.AbstractAction"
+    , "javax.swing.AbstractButton"
+    , "javax.swing.AbstractCellEditor"
+    , "javax.swing.AbstractListModel"
+    , "javax.swing.AbstractSpinnerModel"
+    , "javax.swing.Action"
+    , "javax.swing.ActionMap"
+    , "javax.swing.BorderFactory"
+    , "javax.swing.BoundedRangeModel"
+    , "javax.swing.Box"
+    , "javax.swing.Box$Filler"
+    , "javax.swing.BoxLayout"
+    , "javax.swing.ButtonGroup"
+    , "javax.swing.ButtonModel"
+    , "javax.swing.CellEditor"
+    , "javax.swing.CellRendererPane"
+    , "javax.swing.ComboBoxEditor"
+    , "javax.swing.ComboBoxModel"
+    , "javax.swing.ComponentInputMap"
+    , "javax.swing.DebugGraphics"
+    , "javax.swing.DefaultBoundedRangeModel"
+    , "javax.swing.DefaultButtonModel"
+    , "javax.swing.DefaultCellEditor"
+    , "javax.swing.DefaultComboBoxModel"
+    , "javax.swing.DefaultDesktopManager"
+    , "javax.swing.DefaultFocusManager"
+    , "javax.swing.DefaultListCellRenderer"
+    , "javax.swing.DefaultListCellRenderer$UIResource"
+    , "javax.swing.DefaultListModel"
+    , "javax.swing.DefaultListSelectionModel"
+    , "javax.swing.DefaultRowSorter"
+    , "javax.swing.DefaultRowSorter$ModelWrapper"
+    , "javax.swing.DefaultSingleSelectionModel"
+    , "javax.swing.DesktopManager"
+    , "javax.swing.DropMode"
+    , "javax.swing.FocusManager"
+    , "javax.swing.GrayFilter"
+    , "javax.swing.GroupLayout"
+    , "javax.swing.GroupLayout$Alignment"
+    , "javax.swing.Icon"
+    , "javax.swing.ImageIcon"
+    , "javax.swing.InputMap"
+    , "javax.swing.InputVerifier"
+    , "javax.swing.InternalFrameFocusTraversalPolicy"
+    , "javax.swing.JApplet"
+    , "javax.swing.JButton"
+    , "javax.swing.JCheckBox"
+    , "javax.swing.JCheckBoxMenuItem"
+    , "javax.swing.JColorChooser"
+    , "javax.swing.JComboBox"
+    , "javax.swing.JComboBox$KeySelectionManager"
+    , "javax.swing.JComponent"
+    , "javax.swing.JDesktopPane"
+    , "javax.swing.JDialog"
+    , "javax.swing.JEditorPane"
+    , "javax.swing.JFileChooser"
+    , "javax.swing.JFormattedTextField"
+    , "javax.swing.JFormattedTextField$AbstractFormatter"
+    , "javax.swing.JFormattedTextField$AbstractFormatterFactory"
+    , "javax.swing.JFrame"
+    , "javax.swing.JInternalFrame"
+    , "javax.swing.JInternalFrame$JDesktopIcon"
+    , "javax.swing.JLabel"
+    , "javax.swing.JLayeredPane"
+    , "javax.swing.JList"
+    , "javax.swing.JList$DropLocation"
+    , "javax.swing.JMenu"
+    , "javax.swing.JMenuBar"
+    , "javax.swing.JMenuItem"
+    , "javax.swing.JOptionPane"
+    , "javax.swing.JPanel"
+    , "javax.swing.JPasswordField"
+    , "javax.swing.JPopupMenu"
+    , "javax.swing.JPopupMenu$Separator"
+    , "javax.swing.JProgressBar"
+    , "javax.swing.JRadioButton"
+    , "javax.swing.JRadioButtonMenuItem"
+    , "javax.swing.JRootPane"
+    , "javax.swing.JScrollBar"
+    , "javax.swing.JScrollPane"
+    , "javax.swing.JSeparator"
+    , "javax.swing.JSlider"
+    , "javax.swing.JSpinner"
+    , "javax.swing.JSpinner$DateEditor"
+    , "javax.swing.JSpinner$DefaultEditor"
+    , "javax.swing.JSpinner$ListEditor"
+    , "javax.swing.JSpinner$NumberEditor"
+    , "javax.swing.JSplitPane"
+    , "javax.swing.JTabbedPane"
+    , "javax.swing.JTable"
+    , "javax.swing.JTable$DropLocation"
+    , "javax.swing.JTable$PrintMode"
+    , "javax.swing.JTextArea"
+    , "javax.swing.JTextField"
+    , "javax.swing.JTextPane"
+    , "javax.swing.JToggleButton"
+    , "javax.swing.JToggleButton$ToggleButtonModel"
+    , "javax.swing.JToolBar"
+    , "javax.swing.JToolBar$Separator"
+    , "javax.swing.JToolTip"
+    , "javax.swing.JTree"
+    , "javax.swing.JTree$DropLocation"
+    , "javax.swing.JTree$DynamicUtilTreeNode"
+    , "javax.swing.JTree$EmptySelectionModel"
+    , "javax.swing.JViewport"
+    , "javax.swing.JWindow"
+    , "javax.swing.KeyStroke"
+    , "javax.swing.LayoutFocusTraversalPolicy"
+    , "javax.swing.LayoutStyle"
+    , "javax.swing.LayoutStyle$ComponentPlacement"
+    , "javax.swing.ListCellRenderer"
+    , "javax.swing.ListModel"
+    , "javax.swing.ListSelectionModel"
+    , "javax.swing.LookAndFeel"
+    , "javax.swing.MenuElement"
+    , "javax.swing.MenuSelectionManager"
+    , "javax.swing.MutableComboBoxModel"
+    , "javax.swing.OverlayLayout"
+    , "javax.swing.Popup"
+    , "javax.swing.PopupFactory"
+    , "javax.swing.ProgressMonitor"
+    , "javax.swing.ProgressMonitorInputStream"
+    , "javax.swing.Renderer"
+    , "javax.swing.RepaintManager"
+    , "javax.swing.RootPaneContainer"
+    , "javax.swing.RowFilter"
+    , "javax.swing.RowFilter$ComparisonType"
+    , "javax.swing.RowFilter$Entry"
+    , "javax.swing.RowSorter"
+    , "javax.swing.RowSorter$SortKey"
+    , "javax.swing.ScrollPaneConstants"
+    , "javax.swing.ScrollPaneLayout"
+    , "javax.swing.ScrollPaneLayout$UIResource"
+    , "javax.swing.Scrollable"
+    , "javax.swing.SingleSelectionModel"
+    , "javax.swing.SizeRequirements"
+    , "javax.swing.SizeSequence"
+    , "javax.swing.SortOrder"
+    , "javax.swing.SortingFocusTraversalPolicy"
+    , "javax.swing.SpinnerDateModel"
+    , "javax.swing.SpinnerListModel"
+    , "javax.swing.SpinnerModel"
+    , "javax.swing.SpinnerNumberModel"
+    , "javax.swing.Spring"
+    , "javax.swing.SpringLayout"
+    , "javax.swing.SpringLayout$Constraints"
+    , "javax.swing.SwingConstants"
+    , "javax.swing.SwingUtilities"
+    , "javax.swing.SwingWorker"
+    , "javax.swing.SwingWorker$StateValue"
+    , "javax.swing.Timer"
+    , "javax.swing.ToolTipManager"
+    , "javax.swing.TransferHandler"
+    , "javax.swing.TransferHandler$DropLocation"
+    , "javax.swing.TransferHandler$TransferSupport"
+    , "javax.swing.UIDefaults"
+    , "javax.swing.UIDefaults$ActiveValue"
+    , "javax.swing.UIDefaults$LazyInputMap"
+    , "javax.swing.UIDefaults$LazyValue"
+    , "javax.swing.UIDefaults$ProxyLazyValue"
+    , "javax.swing.UIManager"
+    , "javax.swing.UIManager$LookAndFeelInfo"
+    , "javax.swing.UnsupportedLookAndFeelException"
+    , "javax.swing.ViewportLayout"
+    , "javax.swing.WindowConstants"
+    , "javax.swing.border.AbstractBorder"
+    , "javax.swing.border.BevelBorder"
+    , "javax.swing.border.Border"
+    , "javax.swing.border.CompoundBorder"
+    , "javax.swing.border.EmptyBorder"
+    , "javax.swing.border.EtchedBorder"
+    , "javax.swing.border.LineBorder"
+    , "javax.swing.border.MatteBorder"
+    , "javax.swing.border.SoftBevelBorder"
+    , "javax.swing.border.TitledBorder"
+    , "javax.swing.colorchooser.AbstractColorChooserPanel"
+    , "javax.swing.colorchooser.ColorChooserComponentFactory"
+    , "javax.swing.colorchooser.ColorSelectionModel"
+    , "javax.swing.colorchooser.DefaultColorSelectionModel"
+    , "javax.swing.event.AncestorEvent"
+    , "javax.swing.event.AncestorListener"
+    , "javax.swing.event.CaretEvent"
+    , "javax.swing.event.CaretListener"
+    , "javax.swing.event.CellEditorListener"
+    , "javax.swing.event.ChangeEvent"
+    , "javax.swing.event.ChangeListener"
+    , "javax.swing.event.DocumentEvent"
+    , "javax.swing.event.DocumentEvent$ElementChange"
+    , "javax.swing.event.DocumentEvent$EventType"
+    , "javax.swing.event.DocumentListener"
+    , "javax.swing.event.EventListenerList"
+    , "javax.swing.event.HyperlinkEvent"
+    , "javax.swing.event.HyperlinkEvent$EventType"
+    , "javax.swing.event.HyperlinkListener"
+    , "javax.swing.event.InternalFrameAdapter"
+    , "javax.swing.event.InternalFrameEvent"
+    , "javax.swing.event.InternalFrameListener"
+    , "javax.swing.event.ListDataEvent"
+    , "javax.swing.event.ListDataListener"
+    , "javax.swing.event.ListSelectionEvent"
+    , "javax.swing.event.ListSelectionListener"
+    , "javax.swing.event.MenuDragMouseEvent"
+    , "javax.swing.event.MenuDragMouseListener"
+    , "javax.swing.event.MenuEvent"
+    , "javax.swing.event.MenuKeyEvent"
+    , "javax.swing.event.MenuKeyListener"
+    , "javax.swing.event.MenuListener"
+    , "javax.swing.event.MouseInputAdapter"
+    , "javax.swing.event.MouseInputListener"
+    , "javax.swing.event.PopupMenuEvent"
+    , "javax.swing.event.PopupMenuListener"
+    , "javax.swing.event.RowSorterEvent"
+    , "javax.swing.event.RowSorterEvent$Type"
+    , "javax.swing.event.RowSorterListener"
+    , "javax.swing.event.SwingPropertyChangeSupport"
+    , "javax.swing.event.TableColumnModelEvent"
+    , "javax.swing.event.TableColumnModelListener"
+    , "javax.swing.event.TableModelEvent"
+    , "javax.swing.event.TableModelListener"
+    , "javax.swing.event.TreeExpansionEvent"
+    , "javax.swing.event.TreeExpansionListener"
+    , "javax.swing.event.TreeModelEvent"
+    , "javax.swing.event.TreeModelListener"
+    , "javax.swing.event.TreeSelectionEvent"
+    , "javax.swing.event.TreeSelectionListener"
+    , "javax.swing.event.TreeWillExpandListener"
+    , "javax.swing.event.UndoableEditEvent"
+    , "javax.swing.event.UndoableEditListener"
+    , "javax.swing.filechooser.FileFilter"
+    , "javax.swing.filechooser.FileNameExtensionFilter"
+    , "javax.swing.filechooser.FileSystemView"
+    , "javax.swing.filechooser.FileView"
+    , "javax.swing.plaf.ActionMapUIResource"
+    , "javax.swing.plaf.BorderUIResource"
+    , "javax.swing.plaf.BorderUIResource$BevelBorderUIResource"
+    , "javax.swing.plaf.BorderUIResource$CompoundBorderUIResource"
+    , "javax.swing.plaf.BorderUIResource$EmptyBorderUIResource"
+    , "javax.swing.plaf.BorderUIResource$EtchedBorderUIResource"
+    , "javax.swing.plaf.BorderUIResource$LineBorderUIResource"
+    , "javax.swing.plaf.BorderUIResource$MatteBorderUIResource"
+    , "javax.swing.plaf.BorderUIResource$TitledBorderUIResource"
+    , "javax.swing.plaf.ButtonUI"
+    , "javax.swing.plaf.ColorChooserUI"
+    , "javax.swing.plaf.ColorUIResource"
+    , "javax.swing.plaf.ComboBoxUI"
+    , "javax.swing.plaf.ComponentInputMapUIResource"
+    , "javax.swing.plaf.ComponentUI"
+    , "javax.swing.plaf.DesktopIconUI"
+    , "javax.swing.plaf.DesktopPaneUI"
+    , "javax.swing.plaf.DimensionUIResource"
+    , "javax.swing.plaf.FileChooserUI"
+    , "javax.swing.plaf.FontUIResource"
+    , "javax.swing.plaf.IconUIResource"
+    , "javax.swing.plaf.InputMapUIResource"
+    , "javax.swing.plaf.InsetsUIResource"
+    , "javax.swing.plaf.InternalFrameUI"
+    , "javax.swing.plaf.LabelUI"
+    , "javax.swing.plaf.ListUI"
+    , "javax.swing.plaf.MenuBarUI"
+    , "javax.swing.plaf.MenuItemUI"
+    , "javax.swing.plaf.OptionPaneUI"
+    , "javax.swing.plaf.PanelUI"
+    , "javax.swing.plaf.PopupMenuUI"
+    , "javax.swing.plaf.ProgressBarUI"
+    , "javax.swing.plaf.RootPaneUI"
+    , "javax.swing.plaf.ScrollBarUI"
+    , "javax.swing.plaf.ScrollPaneUI"
+    , "javax.swing.plaf.SeparatorUI"
+    , "javax.swing.plaf.SliderUI"
+    , "javax.swing.plaf.SpinnerUI"
+    , "javax.swing.plaf.SplitPaneUI"
+    , "javax.swing.plaf.TabbedPaneUI"
+    , "javax.swing.plaf.TableHeaderUI"
+    , "javax.swing.plaf.TableUI"
+    , "javax.swing.plaf.TextUI"
+    , "javax.swing.plaf.ToolBarUI"
+    , "javax.swing.plaf.ToolTipUI"
+    , "javax.swing.plaf.TreeUI"
+    , "javax.swing.plaf.UIResource"
+    , "javax.swing.plaf.ViewportUI"
+    , "javax.swing.plaf.basic.BasicArrowButton"
+    , "javax.swing.plaf.basic.BasicBorders"
+    , "javax.swing.plaf.basic.BasicBorders$ButtonBorder"
+    , "javax.swing.plaf.basic.BasicBorders$FieldBorder"
+    , "javax.swing.plaf.basic.BasicBorders$MarginBorder"
+    , "javax.swing.plaf.basic.BasicBorders$MenuBarBorder"
+    , "javax.swing.plaf.basic.BasicBorders$RadioButtonBorder"
+    , "javax.swing.plaf.basic.BasicBorders$RolloverButtonBorder"
+    , "javax.swing.plaf.basic.BasicBorders$SplitPaneBorder"
+    , "javax.swing.plaf.basic.BasicBorders$ToggleButtonBorder"
+    , "javax.swing.plaf.basic.BasicButtonListener"
+    , "javax.swing.plaf.basic.BasicButtonUI"
+    , "javax.swing.plaf.basic.BasicCheckBoxMenuItemUI"
+    , "javax.swing.plaf.basic.BasicCheckBoxUI"
+    , "javax.swing.plaf.basic.BasicColorChooserUI"
+    , "javax.swing.plaf.basic.BasicComboBoxEditor"
+    , "javax.swing.plaf.basic.BasicComboBoxEditor$UIResource"
+    , "javax.swing.plaf.basic.BasicComboBoxRenderer"
+    , "javax.swing.plaf.basic.BasicComboBoxRenderer$UIResource"
+    , "javax.swing.plaf.basic.BasicComboBoxUI"
+    , "javax.swing.plaf.basic.BasicComboPopup"
+    , "javax.swing.plaf.basic.BasicDesktopIconUI"
+    , "javax.swing.plaf.basic.BasicDesktopPaneUI"
+    , "javax.swing.plaf.basic.BasicDirectoryModel"
+    , "javax.swing.plaf.basic.BasicEditorPaneUI"
+    , "javax.swing.plaf.basic.BasicFileChooserUI"
+    , "javax.swing.plaf.basic.BasicFormattedTextFieldUI"
+    , "javax.swing.plaf.basic.BasicGraphicsUtils"
+    , "javax.swing.plaf.basic.BasicHTML"
+    , "javax.swing.plaf.basic.BasicIconFactory"
+    , "javax.swing.plaf.basic.BasicInternalFrameTitlePane"
+    , "javax.swing.plaf.basic.BasicInternalFrameUI"
+    , "javax.swing.plaf.basic.BasicLabelUI"
+    , "javax.swing.plaf.basic.BasicListUI"
+    , "javax.swing.plaf.basic.BasicLookAndFeel"
+    , "javax.swing.plaf.basic.BasicMenuBarUI"
+    , "javax.swing.plaf.basic.BasicMenuItemUI"
+    , "javax.swing.plaf.basic.BasicMenuUI"
+    , "javax.swing.plaf.basic.BasicOptionPaneUI"
+    , "javax.swing.plaf.basic.BasicOptionPaneUI$ButtonAreaLayout"
+    , "javax.swing.plaf.basic.BasicPanelUI"
+    , "javax.swing.plaf.basic.BasicPasswordFieldUI"
+    , "javax.swing.plaf.basic.BasicPopupMenuSeparatorUI"
+    , "javax.swing.plaf.basic.BasicPopupMenuUI"
+    , "javax.swing.plaf.basic.BasicProgressBarUI"
+    , "javax.swing.plaf.basic.BasicRadioButtonMenuItemUI"
+    , "javax.swing.plaf.basic.BasicRadioButtonUI"
+    , "javax.swing.plaf.basic.BasicRootPaneUI"
+    , "javax.swing.plaf.basic.BasicScrollBarUI"
+    , "javax.swing.plaf.basic.BasicScrollPaneUI"
+    , "javax.swing.plaf.basic.BasicSeparatorUI"
+    , "javax.swing.plaf.basic.BasicSliderUI"
+    , "javax.swing.plaf.basic.BasicSpinnerUI"
+    , "javax.swing.plaf.basic.BasicSplitPaneDivider"
+    , "javax.swing.plaf.basic.BasicSplitPaneUI"
+    , "javax.swing.plaf.basic.BasicTabbedPaneUI"
+    , "javax.swing.plaf.basic.BasicTableHeaderUI"
+    , "javax.swing.plaf.basic.BasicTableUI"
+    , "javax.swing.plaf.basic.BasicTextAreaUI"
+    , "javax.swing.plaf.basic.BasicTextFieldUI"
+    , "javax.swing.plaf.basic.BasicTextPaneUI"
+    , "javax.swing.plaf.basic.BasicTextUI"
+    , "javax.swing.plaf.basic.BasicTextUI$BasicCaret"
+    , "javax.swing.plaf.basic.BasicTextUI$BasicHighlighter"
+    , "javax.swing.plaf.basic.BasicToggleButtonUI"
+    , "javax.swing.plaf.basic.BasicToolBarSeparatorUI"
+    , "javax.swing.plaf.basic.BasicToolBarUI"
+    , "javax.swing.plaf.basic.BasicToolTipUI"
+    , "javax.swing.plaf.basic.BasicTreeUI"
+    , "javax.swing.plaf.basic.BasicViewportUI"
+    , "javax.swing.plaf.basic.ComboPopup"
+    , "javax.swing.plaf.basic.DefaultMenuLayout"
+    , "javax.swing.plaf.metal.DefaultMetalTheme"
+    , "javax.swing.plaf.metal.MetalBorders"
+    , "javax.swing.plaf.metal.MetalBorders$ButtonBorder"
+    , "javax.swing.plaf.metal.MetalBorders$Flush3DBorder"
+    , "javax.swing.plaf.metal.MetalBorders$InternalFrameBorder"
+    , "javax.swing.plaf.metal.MetalBorders$MenuBarBorder"
+    , "javax.swing.plaf.metal.MetalBorders$MenuItemBorder"
+    , "javax.swing.plaf.metal.MetalBorders$OptionDialogBorder"
+    , "javax.swing.plaf.metal.MetalBorders$PaletteBorder"
+    , "javax.swing.plaf.metal.MetalBorders$PopupMenuBorder"
+    , "javax.swing.plaf.metal.MetalBorders$RolloverButtonBorder"
+    , "javax.swing.plaf.metal.MetalBorders$ScrollPaneBorder"
+    , "javax.swing.plaf.metal.MetalBorders$TableHeaderBorder"
+    , "javax.swing.plaf.metal.MetalBorders$TextFieldBorder"
+    , "javax.swing.plaf.metal.MetalBorders$ToggleButtonBorder"
+    , "javax.swing.plaf.metal.MetalBorders$ToolBarBorder"
+    , "javax.swing.plaf.metal.MetalButtonUI"
+    , "javax.swing.plaf.metal.MetalCheckBoxIcon"
+    , "javax.swing.plaf.metal.MetalCheckBoxUI"
+    , "javax.swing.plaf.metal.MetalComboBoxButton"
+    , "javax.swing.plaf.metal.MetalComboBoxEditor"
+    , "javax.swing.plaf.metal.MetalComboBoxEditor$UIResource"
+    , "javax.swing.plaf.metal.MetalComboBoxIcon"
+    , "javax.swing.plaf.metal.MetalComboBoxUI"
+    , "javax.swing.plaf.metal.MetalDesktopIconUI"
+    , "javax.swing.plaf.metal.MetalFileChooserUI"
+    , "javax.swing.plaf.metal.MetalIconFactory"
+    , "javax.swing.plaf.metal.MetalIconFactory$FileIcon16"
+    , "javax.swing.plaf.metal.MetalIconFactory$FolderIcon16"
+    , "javax.swing.plaf.metal.MetalIconFactory$PaletteCloseIcon"
+    , "javax.swing.plaf.metal.MetalIconFactory$TreeControlIcon"
+    , "javax.swing.plaf.metal.MetalIconFactory$TreeFolderIcon"
+    , "javax.swing.plaf.metal.MetalIconFactory$TreeLeafIcon"
+    , "javax.swing.plaf.metal.MetalInternalFrameTitlePane"
+    , "javax.swing.plaf.metal.MetalInternalFrameUI"
+    , "javax.swing.plaf.metal.MetalLabelUI"
+    , "javax.swing.plaf.metal.MetalLookAndFeel"
+    , "javax.swing.plaf.metal.MetalMenuBarUI"
+    , "javax.swing.plaf.metal.MetalPopupMenuSeparatorUI"
+    , "javax.swing.plaf.metal.MetalProgressBarUI"
+    , "javax.swing.plaf.metal.MetalRadioButtonUI"
+    , "javax.swing.plaf.metal.MetalRootPaneUI"
+    , "javax.swing.plaf.metal.MetalScrollBarUI"
+    , "javax.swing.plaf.metal.MetalScrollButton"
+    , "javax.swing.plaf.metal.MetalScrollPaneUI"
+    , "javax.swing.plaf.metal.MetalSeparatorUI"
+    , "javax.swing.plaf.metal.MetalSliderUI"
+    , "javax.swing.plaf.metal.MetalSplitPaneUI"
+    , "javax.swing.plaf.metal.MetalTabbedPaneUI"
+    , "javax.swing.plaf.metal.MetalTextFieldUI"
+    , "javax.swing.plaf.metal.MetalTheme"
+    , "javax.swing.plaf.metal.MetalToggleButtonUI"
+    , "javax.swing.plaf.metal.MetalToolBarUI"
+    , "javax.swing.plaf.metal.MetalToolTipUI"
+    , "javax.swing.plaf.metal.MetalTreeUI"
+    , "javax.swing.plaf.metal.OceanTheme"
+    , "javax.swing.plaf.multi.MultiButtonUI"
+    , "javax.swing.plaf.multi.MultiColorChooserUI"
+    , "javax.swing.plaf.multi.MultiComboBoxUI"
+    , "javax.swing.plaf.multi.MultiDesktopIconUI"
+    , "javax.swing.plaf.multi.MultiDesktopPaneUI"
+    , "javax.swing.plaf.multi.MultiFileChooserUI"
+    , "javax.swing.plaf.multi.MultiInternalFrameUI"
+    , "javax.swing.plaf.multi.MultiLabelUI"
+    , "javax.swing.plaf.multi.MultiListUI"
+    , "javax.swing.plaf.multi.MultiLookAndFeel"
+    , "javax.swing.plaf.multi.MultiMenuBarUI"
+    , "javax.swing.plaf.multi.MultiMenuItemUI"
+    , "javax.swing.plaf.multi.MultiOptionPaneUI"
+    , "javax.swing.plaf.multi.MultiPanelUI"
+    , "javax.swing.plaf.multi.MultiPopupMenuUI"
+    , "javax.swing.plaf.multi.MultiProgressBarUI"
+    , "javax.swing.plaf.multi.MultiRootPaneUI"
+    , "javax.swing.plaf.multi.MultiScrollBarUI"
+    , "javax.swing.plaf.multi.MultiScrollPaneUI"
+    , "javax.swing.plaf.multi.MultiSeparatorUI"
+    , "javax.swing.plaf.multi.MultiSliderUI"
+    , "javax.swing.plaf.multi.MultiSpinnerUI"
+    , "javax.swing.plaf.multi.MultiSplitPaneUI"
+    , "javax.swing.plaf.multi.MultiTabbedPaneUI"
+    , "javax.swing.plaf.multi.MultiTableHeaderUI"
+    , "javax.swing.plaf.multi.MultiTableUI"
+    , "javax.swing.plaf.multi.MultiTextUI"
+    , "javax.swing.plaf.multi.MultiToolBarUI"
+    , "javax.swing.plaf.multi.MultiToolTipUI"
+    , "javax.swing.plaf.multi.MultiTreeUI"
+    , "javax.swing.plaf.multi.MultiViewportUI"
+    , "javax.swing.plaf.synth.ColorType"
+    , "javax.swing.plaf.synth.Region"
+    , "javax.swing.plaf.synth.SynthConstants"
+    , "javax.swing.plaf.synth.SynthContext"
+    , "javax.swing.plaf.synth.SynthGraphicsUtils"
+    , "javax.swing.plaf.synth.SynthLookAndFeel"
+    , "javax.swing.plaf.synth.SynthPainter"
+    , "javax.swing.plaf.synth.SynthStyle"
+    , "javax.swing.plaf.synth.SynthStyleFactory"
+    , "javax.swing.table.AbstractTableModel"
+    , "javax.swing.table.DefaultTableCellRenderer"
+    , "javax.swing.table.DefaultTableCellRenderer$UIResource"
+    , "javax.swing.table.DefaultTableColumnModel"
+    , "javax.swing.table.DefaultTableModel"
+    , "javax.swing.table.JTableHeader"
+    , "javax.swing.table.TableCellEditor"
+    , "javax.swing.table.TableCellRenderer"
+    , "javax.swing.table.TableColumn"
+    , "javax.swing.table.TableColumnModel"
+    , "javax.swing.table.TableModel"
+    , "javax.swing.table.TableRowSorter"
+    , "javax.swing.table.TableStringConverter"
+    , "javax.swing.text.AbstractDocument"
+    , "javax.swing.text.AbstractDocument$AttributeContext"
+    , "javax.swing.text.AbstractDocument$Content"
+    , "javax.swing.text.AbstractDocument$ElementEdit"
+    , "javax.swing.text.AbstractWriter"
+    , "javax.swing.text.AsyncBoxView"
+    , "javax.swing.text.AttributeSet"
+    , "javax.swing.text.AttributeSet$CharacterAttribute"
+    , "javax.swing.text.AttributeSet$ColorAttribute"
+    , "javax.swing.text.AttributeSet$FontAttribute"
+    , "javax.swing.text.AttributeSet$ParagraphAttribute"
+    , "javax.swing.text.BadLocationException"
+    , "javax.swing.text.BoxView"
+    , "javax.swing.text.Caret"
+    , "javax.swing.text.ChangedCharSetException"
+    , "javax.swing.text.ComponentView"
+    , "javax.swing.text.CompositeView"
+    , "javax.swing.text.DateFormatter"
+    , "javax.swing.text.DefaultCaret"
+    , "javax.swing.text.DefaultEditorKit"
+    , "javax.swing.text.DefaultEditorKit$BeepAction"
+    , "javax.swing.text.DefaultEditorKit$CopyAction"
+    , "javax.swing.text.DefaultEditorKit$CutAction"
+    , "javax.swing.text.DefaultEditorKit$DefaultKeyTypedAction"
+    , "javax.swing.text.DefaultEditorKit$InsertBreakAction"
+    , "javax.swing.text.DefaultEditorKit$InsertContentAction"
+    , "javax.swing.text.DefaultEditorKit$InsertTabAction"
+    , "javax.swing.text.DefaultEditorKit$PasteAction"
+    , "javax.swing.text.DefaultFormatter"
+    , "javax.swing.text.DefaultFormatterFactory"
+    , "javax.swing.text.DefaultHighlighter"
+    , "javax.swing.text.DefaultHighlighter$DefaultHighlightPainter"
+    , "javax.swing.text.DefaultStyledDocument"
+    , "javax.swing.text.DefaultStyledDocument$AttributeUndoableEdit"
+    , "javax.swing.text.DefaultStyledDocument$ElementSpec"
+    , "javax.swing.text.DefaultTextUI"
+    , "javax.swing.text.Document"
+    , "javax.swing.text.DocumentFilter"
+    , "javax.swing.text.DocumentFilter$FilterBypass"
+    , "javax.swing.text.EditorKit"
+    , "javax.swing.text.Element"
+    , "javax.swing.text.ElementIterator"
+    , "javax.swing.text.FieldView"
+    , "javax.swing.text.FlowView"
+    , "javax.swing.text.FlowView$FlowStrategy"
+    , "javax.swing.text.GapContent"
+    , "javax.swing.text.GlyphView"
+    , "javax.swing.text.GlyphView$GlyphPainter"
+    , "javax.swing.text.Highlighter"
+    , "javax.swing.text.Highlighter$Highlight"
+    , "javax.swing.text.Highlighter$HighlightPainter"
+    , "javax.swing.text.IconView"
+    , "javax.swing.text.InternationalFormatter"
+    , "javax.swing.text.JTextComponent"
+    , "javax.swing.text.JTextComponent$DropLocation"
+    , "javax.swing.text.JTextComponent$KeyBinding"
+    , "javax.swing.text.Keymap"
+    , "javax.swing.text.LabelView"
+    , "javax.swing.text.LayeredHighlighter"
+    , "javax.swing.text.LayeredHighlighter$LayerPainter"
+    , "javax.swing.text.LayoutQueue"
+    , "javax.swing.text.MaskFormatter"
+    , "javax.swing.text.MutableAttributeSet"
+    , "javax.swing.text.NavigationFilter"
+    , "javax.swing.text.NavigationFilter$FilterBypass"
+    , "javax.swing.text.NumberFormatter"
+    , "javax.swing.text.ParagraphView"
+    , "javax.swing.text.PasswordView"
+    , "javax.swing.text.PlainDocument"
+    , "javax.swing.text.PlainView"
+    , "javax.swing.text.Position"
+    , "javax.swing.text.Position$Bias"
+    , "javax.swing.text.Segment"
+    , "javax.swing.text.SimpleAttributeSet"
+    , "javax.swing.text.StringContent"
+    , "javax.swing.text.Style"
+    , "javax.swing.text.StyleConstants"
+    , "javax.swing.text.StyleConstants$CharacterConstants"
+    , "javax.swing.text.StyleConstants$ColorConstants"
+    , "javax.swing.text.StyleConstants$FontConstants"
+    , "javax.swing.text.StyleConstants$ParagraphConstants"
+    , "javax.swing.text.StyleContext"
+    , "javax.swing.text.StyledDocument"
+    , "javax.swing.text.StyledEditorKit"
+    , "javax.swing.text.StyledEditorKit$AlignmentAction"
+    , "javax.swing.text.StyledEditorKit$BoldAction"
+    , "javax.swing.text.StyledEditorKit$FontFamilyAction"
+    , "javax.swing.text.StyledEditorKit$FontSizeAction"
+    , "javax.swing.text.StyledEditorKit$ForegroundAction"
+    , "javax.swing.text.StyledEditorKit$ItalicAction"
+    , "javax.swing.text.StyledEditorKit$StyledTextAction"
+    , "javax.swing.text.StyledEditorKit$UnderlineAction"
+    , "javax.swing.text.TabExpander"
+    , "javax.swing.text.TabSet"
+    , "javax.swing.text.TabStop"
+    , "javax.swing.text.TabableView"
+    , "javax.swing.text.TableView"
+    , "javax.swing.text.TextAction"
+    , "javax.swing.text.Utilities"
+    , "javax.swing.text.View"
+    , "javax.swing.text.ViewFactory"
+    , "javax.swing.text.WrappedPlainView"
+    , "javax.swing.text.ZoneView"
+    , "javax.swing.text.html.BlockView"
+    , "javax.swing.text.html.CSS"
+    , "javax.swing.text.html.CSS$Attribute"
+    , "javax.swing.text.html.FormSubmitEvent"
+    , "javax.swing.text.html.FormSubmitEvent$MethodType"
+    , "javax.swing.text.html.FormView"
+    , "javax.swing.text.html.HTML"
+    , "javax.swing.text.html.HTML$Attribute"
+    , "javax.swing.text.html.HTML$Tag"
+    , "javax.swing.text.html.HTML$UnknownTag"
+    , "javax.swing.text.html.HTMLDocument"
+    , "javax.swing.text.html.HTMLDocument$Iterator"
+    , "javax.swing.text.html.HTMLEditorKit"
+    , "javax.swing.text.html.HTMLEditorKit$HTMLFactory"
+    , "javax.swing.text.html.HTMLEditorKit$HTMLTextAction"
+    , "javax.swing.text.html.HTMLEditorKit$InsertHTMLTextAction"
+    , "javax.swing.text.html.HTMLEditorKit$LinkController"
+    , "javax.swing.text.html.HTMLEditorKit$Parser"
+    , "javax.swing.text.html.HTMLEditorKit$ParserCallback"
+    , "javax.swing.text.html.HTMLFrameHyperlinkEvent"
+    , "javax.swing.text.html.HTMLWriter"
+    , "javax.swing.text.html.ImageView"
+    , "javax.swing.text.html.InlineView"
+    , "javax.swing.text.html.ListView"
+    , "javax.swing.text.html.MinimalHTMLWriter"
+    , "javax.swing.text.html.ObjectView"
+    , "javax.swing.text.html.Option"
+    , "javax.swing.text.html.ParagraphView"
+    , "javax.swing.text.html.StyleSheet"
+    , "javax.swing.text.html.StyleSheet$BoxPainter"
+    , "javax.swing.text.html.StyleSheet$ListPainter"
+    , "javax.swing.text.html.parser.AttributeList"
+    , "javax.swing.text.html.parser.ContentModel"
+    , "javax.swing.text.html.parser.DTD"
+    , "javax.swing.text.html.parser.DTDConstants"
+    , "javax.swing.text.html.parser.DocumentParser"
+    , "javax.swing.text.html.parser.Element"
+    , "javax.swing.text.html.parser.Entity"
+    , "javax.swing.text.html.parser.Parser"
+    , "javax.swing.text.html.parser.ParserDelegator"
+    , "javax.swing.text.html.parser.TagElement"
+    , "javax.swing.text.rtf.RTFEditorKit"
+    , "javax.swing.tree.AbstractLayoutCache"
+    , "javax.swing.tree.AbstractLayoutCache$NodeDimensions"
+    , "javax.swing.tree.DefaultMutableTreeNode"
+    , "javax.swing.tree.DefaultTreeCellEditor"
+    , "javax.swing.tree.DefaultTreeCellRenderer"
+    , "javax.swing.tree.DefaultTreeModel"
+    , "javax.swing.tree.DefaultTreeSelectionModel"
+    , "javax.swing.tree.ExpandVetoException"
+    , "javax.swing.tree.FixedHeightLayoutCache"
+    , "javax.swing.tree.MutableTreeNode"
+    , "javax.swing.tree.RowMapper"
+    , "javax.swing.tree.TreeCellEditor"
+    , "javax.swing.tree.TreeCellRenderer"
+    , "javax.swing.tree.TreeModel"
+    , "javax.swing.tree.TreeNode"
+    , "javax.swing.tree.TreePath"
+    , "javax.swing.tree.TreeSelectionModel"
+    , "javax.swing.tree.VariableHeightLayoutCache"
+    , "javax.swing.undo.AbstractUndoableEdit"
+    , "javax.swing.undo.CannotRedoException"
+    , "javax.swing.undo.CannotUndoException"
+    , "javax.swing.undo.CompoundEdit"
+    , "javax.swing.undo.StateEdit"
+    , "javax.swing.undo.StateEditable"
+    , "javax.swing.undo.UndoManager"
+    , "javax.swing.undo.UndoableEdit"
+    , "javax.swing.undo.UndoableEditSupport"
+    , "javax.tools.Diagnostic"
+    , "javax.tools.Diagnostic$Kind"
+    , "javax.tools.DiagnosticCollector"
+    , "javax.tools.DiagnosticListener"
+    , "javax.tools.FileObject"
+    , "javax.tools.ForwardingFileObject"
+    , "javax.tools.ForwardingJavaFileManager"
+    , "javax.tools.ForwardingJavaFileObject"
+    , "javax.tools.JavaCompiler"
+    , "javax.tools.JavaCompiler$CompilationTask"
+    , "javax.tools.JavaFileManager"
+    , "javax.tools.JavaFileManager$Location"
+    , "javax.tools.JavaFileObject"
+    , "javax.tools.JavaFileObject$Kind"
+    , "javax.tools.OptionChecker"
+    , "javax.tools.SimpleJavaFileObject"
+    , "javax.tools.StandardJavaFileManager"
+    , "javax.tools.StandardLocation"
+    , "javax.tools.Tool"
+    , "javax.tools.ToolProvider"
+    , "javax.transaction.InvalidTransactionException"
+    , "javax.transaction.TransactionRequiredException"
+    , "javax.transaction.TransactionRolledbackException"
+    , "javax.transaction.xa.XAException"
+    , "javax.transaction.xa.XAResource"
+    , "javax.transaction.xa.Xid"
+    , "javax.xml.XMLConstants"
+    , "javax.xml.bind.Binder"
+    , "javax.xml.bind.DataBindingException"
+    , "javax.xml.bind.DatatypeConverter"
+    , "javax.xml.bind.DatatypeConverterInterface"
+    , "javax.xml.bind.Element"
+    , "javax.xml.bind.JAXB"
+    , "javax.xml.bind.JAXBContext"
+    , "javax.xml.bind.JAXBElement"
+    , "javax.xml.bind.JAXBElement$GlobalScope"
+    , "javax.xml.bind.JAXBException"
+    , "javax.xml.bind.JAXBIntrospector"
+    , "javax.xml.bind.MarshalException"
+    , "javax.xml.bind.Marshaller"
+    , "javax.xml.bind.Marshaller$Listener"
+    , "javax.xml.bind.NotIdentifiableEvent"
+    , "javax.xml.bind.ParseConversionEvent"
+    , "javax.xml.bind.PrintConversionEvent"
+    , "javax.xml.bind.PropertyException"
+    , "javax.xml.bind.SchemaOutputResolver"
+    , "javax.xml.bind.TypeConstraintException"
+    , "javax.xml.bind.UnmarshalException"
+    , "javax.xml.bind.Unmarshaller"
+    , "javax.xml.bind.Unmarshaller$Listener"
+    , "javax.xml.bind.UnmarshallerHandler"
+    , "javax.xml.bind.ValidationEvent"
+    , "javax.xml.bind.ValidationEventHandler"
+    , "javax.xml.bind.ValidationEventLocator"
+    , "javax.xml.bind.ValidationException"
+    , "javax.xml.bind.Validator"
+    , "javax.xml.bind.annotation.DomHandler"
+    , "javax.xml.bind.annotation.W3CDomHandler"
+    , "javax.xml.bind.annotation.XmlAccessOrder"
+    , "javax.xml.bind.annotation.XmlAccessType"
+    , "javax.xml.bind.annotation.XmlAccessorOrder"
+    , "javax.xml.bind.annotation.XmlAccessorType"
+    , "javax.xml.bind.annotation.XmlAnyAttribute"
+    , "javax.xml.bind.annotation.XmlAnyElement"
+    , "javax.xml.bind.annotation.XmlAttachmentRef"
+    , "javax.xml.bind.annotation.XmlAttribute"
+    , "javax.xml.bind.annotation.XmlElement"
+    , "javax.xml.bind.annotation.XmlElement$DEFAULT"
+    , "javax.xml.bind.annotation.XmlElementDecl"
+    , "javax.xml.bind.annotation.XmlElementDecl$GLOBAL"
+    , "javax.xml.bind.annotation.XmlElementRef"
+    , "javax.xml.bind.annotation.XmlElementRef$DEFAULT"
+    , "javax.xml.bind.annotation.XmlElementRefs"
+    , "javax.xml.bind.annotation.XmlElementWrapper"
+    , "javax.xml.bind.annotation.XmlElements"
+    , "javax.xml.bind.annotation.XmlEnum"
+    , "javax.xml.bind.annotation.XmlEnumValue"
+    , "javax.xml.bind.annotation.XmlID"
+    , "javax.xml.bind.annotation.XmlIDREF"
+    , "javax.xml.bind.annotation.XmlInlineBinaryData"
+    , "javax.xml.bind.annotation.XmlList"
+    , "javax.xml.bind.annotation.XmlMimeType"
+    , "javax.xml.bind.annotation.XmlMixed"
+    , "javax.xml.bind.annotation.XmlNs"
+    , "javax.xml.bind.annotation.XmlNsForm"
+    , "javax.xml.bind.annotation.XmlRegistry"
+    , "javax.xml.bind.annotation.XmlRootElement"
+    , "javax.xml.bind.annotation.XmlSchema"
+    , "javax.xml.bind.annotation.XmlSchemaType"
+    , "javax.xml.bind.annotation.XmlSchemaType$DEFAULT"
+    , "javax.xml.bind.annotation.XmlSchemaTypes"
+    , "javax.xml.bind.annotation.XmlSeeAlso"
+    , "javax.xml.bind.annotation.XmlTransient"
+    , "javax.xml.bind.annotation.XmlType"
+    , "javax.xml.bind.annotation.XmlType$DEFAULT"
+    , "javax.xml.bind.annotation.XmlValue"
+    , "javax.xml.bind.annotation.adapters.CollapsedStringAdapter"
+    , "javax.xml.bind.annotation.adapters.HexBinaryAdapter"
+    , "javax.xml.bind.annotation.adapters.NormalizedStringAdapter"
+    , "javax.xml.bind.annotation.adapters.XmlAdapter"
+    , "javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter"
+    , "javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter$DEFAULT"
+    , "javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters"
+    , "javax.xml.bind.attachment.AttachmentMarshaller"
+    , "javax.xml.bind.attachment.AttachmentUnmarshaller"
+    , "javax.xml.bind.helpers.AbstractMarshallerImpl"
+    , "javax.xml.bind.helpers.AbstractUnmarshallerImpl"
+    , "javax.xml.bind.helpers.DefaultValidationEventHandler"
+    , "javax.xml.bind.helpers.NotIdentifiableEventImpl"
+    , "javax.xml.bind.helpers.ParseConversionEventImpl"
+    , "javax.xml.bind.helpers.PrintConversionEventImpl"
+    , "javax.xml.bind.helpers.ValidationEventImpl"
+    , "javax.xml.bind.helpers.ValidationEventLocatorImpl"
+    , "javax.xml.bind.util.JAXBResult"
+    , "javax.xml.bind.util.JAXBSource"
+    , "javax.xml.bind.util.ValidationEventCollector"
+    , "javax.xml.crypto.AlgorithmMethod"
+    , "javax.xml.crypto.Data"
+    , "javax.xml.crypto.KeySelector"
+    , "javax.xml.crypto.KeySelector$Purpose"
+    , "javax.xml.crypto.KeySelectorException"
+    , "javax.xml.crypto.KeySelectorResult"
+    , "javax.xml.crypto.MarshalException"
+    , "javax.xml.crypto.NoSuchMechanismException"
+    , "javax.xml.crypto.NodeSetData"
+    , "javax.xml.crypto.OctetStreamData"
+    , "javax.xml.crypto.URIDereferencer"
+    , "javax.xml.crypto.URIReference"
+    , "javax.xml.crypto.URIReferenceException"
+    , "javax.xml.crypto.XMLCryptoContext"
+    , "javax.xml.crypto.XMLStructure"
+    , "javax.xml.crypto.dom.DOMCryptoContext"
+    , "javax.xml.crypto.dom.DOMStructure"
+    , "javax.xml.crypto.dom.DOMURIReference"
+    , "javax.xml.crypto.dsig.CanonicalizationMethod"
+    , "javax.xml.crypto.dsig.DigestMethod"
+    , "javax.xml.crypto.dsig.Manifest"
+    , "javax.xml.crypto.dsig.Reference"
+    , "javax.xml.crypto.dsig.SignatureMethod"
+    , "javax.xml.crypto.dsig.SignatureProperties"
+    , "javax.xml.crypto.dsig.SignatureProperty"
+    , "javax.xml.crypto.dsig.SignedInfo"
+    , "javax.xml.crypto.dsig.Transform"
+    , "javax.xml.crypto.dsig.TransformException"
+    , "javax.xml.crypto.dsig.TransformService"
+    , "javax.xml.crypto.dsig.XMLObject"
+    , "javax.xml.crypto.dsig.XMLSignContext"
+    , "javax.xml.crypto.dsig.XMLSignature"
+    , "javax.xml.crypto.dsig.XMLSignature$SignatureValue"
+    , "javax.xml.crypto.dsig.XMLSignatureException"
+    , "javax.xml.crypto.dsig.XMLSignatureFactory"
+    , "javax.xml.crypto.dsig.XMLValidateContext"
+    , "javax.xml.crypto.dsig.dom.DOMSignContext"
+    , "javax.xml.crypto.dsig.dom.DOMValidateContext"
+    , "javax.xml.crypto.dsig.keyinfo.KeyInfo"
+    , "javax.xml.crypto.dsig.keyinfo.KeyInfoFactory"
+    , "javax.xml.crypto.dsig.keyinfo.KeyName"
+    , "javax.xml.crypto.dsig.keyinfo.KeyValue"
+    , "javax.xml.crypto.dsig.keyinfo.PGPData"
+    , "javax.xml.crypto.dsig.keyinfo.RetrievalMethod"
+    , "javax.xml.crypto.dsig.keyinfo.X509Data"
+    , "javax.xml.crypto.dsig.keyinfo.X509IssuerSerial"
+    , "javax.xml.crypto.dsig.spec.C14NMethodParameterSpec"
+    , "javax.xml.crypto.dsig.spec.DigestMethodParameterSpec"
+    , "javax.xml.crypto.dsig.spec.ExcC14NParameterSpec"
+    , "javax.xml.crypto.dsig.spec.HMACParameterSpec"
+    , "javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec"
+    , "javax.xml.crypto.dsig.spec.TransformParameterSpec"
+    , "javax.xml.crypto.dsig.spec.XPathFilter2ParameterSpec"
+    , "javax.xml.crypto.dsig.spec.XPathFilterParameterSpec"
+    , "javax.xml.crypto.dsig.spec.XPathType"
+    , "javax.xml.crypto.dsig.spec.XPathType$Filter"
+    , "javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec"
+    , "javax.xml.datatype.DatatypeConfigurationException"
+    , "javax.xml.datatype.DatatypeConstants"
+    , "javax.xml.datatype.DatatypeConstants$Field"
+    , "javax.xml.datatype.DatatypeFactory"
+    , "javax.xml.datatype.Duration"
+    , "javax.xml.datatype.XMLGregorianCalendar"
+    , "javax.xml.namespace.NamespaceContext"
+    , "javax.xml.namespace.QName"
+    , "javax.xml.parsers.DocumentBuilder"
+    , "javax.xml.parsers.DocumentBuilderFactory"
+    , "javax.xml.parsers.FactoryConfigurationError"
+    , "javax.xml.parsers.ParserConfigurationException"
+    , "javax.xml.parsers.SAXParser"
+    , "javax.xml.parsers.SAXParserFactory"
+    , "javax.xml.soap.AttachmentPart"
+    , "javax.xml.soap.Detail"
+    , "javax.xml.soap.DetailEntry"
+    , "javax.xml.soap.MessageFactory"
+    , "javax.xml.soap.MimeHeader"
+    , "javax.xml.soap.MimeHeaders"
+    , "javax.xml.soap.Name"
+    , "javax.xml.soap.Node"
+    , "javax.xml.soap.SAAJMetaFactory"
+    , "javax.xml.soap.SAAJResult"
+    , "javax.xml.soap.SOAPBody"
+    , "javax.xml.soap.SOAPBodyElement"
+    , "javax.xml.soap.SOAPConnection"
+    , "javax.xml.soap.SOAPConnectionFactory"
+    , "javax.xml.soap.SOAPConstants"
+    , "javax.xml.soap.SOAPElement"
+    , "javax.xml.soap.SOAPElementFactory"
+    , "javax.xml.soap.SOAPEnvelope"
+    , "javax.xml.soap.SOAPException"
+    , "javax.xml.soap.SOAPFactory"
+    , "javax.xml.soap.SOAPFault"
+    , "javax.xml.soap.SOAPFaultElement"
+    , "javax.xml.soap.SOAPHeader"
+    , "javax.xml.soap.SOAPHeaderElement"
+    , "javax.xml.soap.SOAPMessage"
+    , "javax.xml.soap.SOAPPart"
+    , "javax.xml.soap.Text"
+    , "javax.xml.stream.EventFilter"
+    , "javax.xml.stream.FactoryConfigurationError"
+    , "javax.xml.stream.Location"
+    , "javax.xml.stream.StreamFilter"
+    , "javax.xml.stream.XMLEventFactory"
+    , "javax.xml.stream.XMLEventReader"
+    , "javax.xml.stream.XMLEventWriter"
+    , "javax.xml.stream.XMLInputFactory"
+    , "javax.xml.stream.XMLOutputFactory"
+    , "javax.xml.stream.XMLReporter"
+    , "javax.xml.stream.XMLResolver"
+    , "javax.xml.stream.XMLStreamConstants"
+    , "javax.xml.stream.XMLStreamException"
+    , "javax.xml.stream.XMLStreamReader"
+    , "javax.xml.stream.XMLStreamWriter"
+    , "javax.xml.stream.events.Attribute"
+    , "javax.xml.stream.events.Characters"
+    , "javax.xml.stream.events.Comment"
+    , "javax.xml.stream.events.DTD"
+    , "javax.xml.stream.events.EndDocument"
+    , "javax.xml.stream.events.EndElement"
+    , "javax.xml.stream.events.EntityDeclaration"
+    , "javax.xml.stream.events.EntityReference"
+    , "javax.xml.stream.events.Namespace"
+    , "javax.xml.stream.events.NotationDeclaration"
+    , "javax.xml.stream.events.ProcessingInstruction"
+    , "javax.xml.stream.events.StartDocument"
+    , "javax.xml.stream.events.StartElement"
+    , "javax.xml.stream.events.XMLEvent"
+    , "javax.xml.stream.util.EventReaderDelegate"
+    , "javax.xml.stream.util.StreamReaderDelegate"
+    , "javax.xml.stream.util.XMLEventAllocator"
+    , "javax.xml.stream.util.XMLEventConsumer"
+    , "javax.xml.transform.ErrorListener"
+    , "javax.xml.transform.OutputKeys"
+    , "javax.xml.transform.Result"
+    , "javax.xml.transform.Source"
+    , "javax.xml.transform.SourceLocator"
+    , "javax.xml.transform.Templates"
+    , "javax.xml.transform.Transformer"
+    , "javax.xml.transform.TransformerConfigurationException"
+    , "javax.xml.transform.TransformerException"
+    , "javax.xml.transform.TransformerFactory"
+    , "javax.xml.transform.TransformerFactoryConfigurationError"
+    , "javax.xml.transform.URIResolver"
+    , "javax.xml.transform.dom.DOMLocator"
+    , "javax.xml.transform.dom.DOMResult"
+    , "javax.xml.transform.dom.DOMSource"
+    , "javax.xml.transform.sax.SAXResult"
+    , "javax.xml.transform.sax.SAXSource"
+    , "javax.xml.transform.sax.SAXTransformerFactory"
+    , "javax.xml.transform.sax.TemplatesHandler"
+    , "javax.xml.transform.sax.TransformerHandler"
+    , "javax.xml.transform.stax.StAXResult"
+    , "javax.xml.transform.stax.StAXSource"
+    , "javax.xml.transform.stream.StreamResult"
+    , "javax.xml.transform.stream.StreamSource"
+    , "javax.xml.validation.Schema"
+    , "javax.xml.validation.SchemaFactory"
+    , "javax.xml.validation.SchemaFactoryLoader"
+    , "javax.xml.validation.TypeInfoProvider"
+    , "javax.xml.validation.Validator"
+    , "javax.xml.validation.ValidatorHandler"
+    , "javax.xml.ws.Action"
+    , "javax.xml.ws.AsyncHandler"
+    , "javax.xml.ws.Binding"
+    , "javax.xml.ws.BindingProvider"
+    , "javax.xml.ws.BindingType"
+    , "javax.xml.ws.Dispatch"
+    , "javax.xml.ws.Endpoint"
+    , "javax.xml.ws.EndpointReference"
+    , "javax.xml.ws.FaultAction"
+    , "javax.xml.ws.Holder"
+    , "javax.xml.ws.LogicalMessage"
+    , "javax.xml.ws.ProtocolException"
+    , "javax.xml.ws.Provider"
+    , "javax.xml.ws.RequestWrapper"
+    , "javax.xml.ws.RespectBinding"
+    , "javax.xml.ws.RespectBindingFeature"
+    , "javax.xml.ws.Response"
+    , "javax.xml.ws.ResponseWrapper"
+    , "javax.xml.ws.Service"
+    , "javax.xml.ws.Service$Mode"
+    , "javax.xml.ws.ServiceMode"
+    , "javax.xml.ws.WebEndpoint"
+    , "javax.xml.ws.WebFault"
+    , "javax.xml.ws.WebServiceClient"
+    , "javax.xml.ws.WebServiceContext"
+    , "javax.xml.ws.WebServiceException"
+    , "javax.xml.ws.WebServiceFeature"
+    , "javax.xml.ws.WebServicePermission"
+    , "javax.xml.ws.WebServiceProvider"
+    , "javax.xml.ws.WebServiceRef"
+    , "javax.xml.ws.WebServiceRefs"
+    , "javax.xml.ws.handler.Handler"
+    , "javax.xml.ws.handler.HandlerResolver"
+    , "javax.xml.ws.handler.LogicalHandler"
+    , "javax.xml.ws.handler.LogicalMessageContext"
+    , "javax.xml.ws.handler.MessageContext"
+    , "javax.xml.ws.handler.MessageContext$Scope"
+    , "javax.xml.ws.handler.PortInfo"
+    , "javax.xml.ws.handler.soap.SOAPHandler"
+    , "javax.xml.ws.handler.soap.SOAPMessageContext"
+    , "javax.xml.ws.http.HTTPBinding"
+    , "javax.xml.ws.http.HTTPException"
+    , "javax.xml.ws.soap.Addressing"
+    , "javax.xml.ws.soap.AddressingFeature"
+    , "javax.xml.ws.soap.MTOM"
+    , "javax.xml.ws.soap.MTOMFeature"
+    , "javax.xml.ws.soap.SOAPBinding"
+    , "javax.xml.ws.soap.SOAPFaultException"
+    , "javax.xml.ws.spi.Provider"
+    , "javax.xml.ws.spi.ServiceDelegate"
+    , "javax.xml.ws.spi.WebServiceFeatureAnnotation"
+    , "javax.xml.ws.wsaddressing.W3CEndpointReference"
+    , "javax.xml.ws.wsaddressing.W3CEndpointReferenceBuilder"
+    , "javax.xml.xpath.XPath"
+    , "javax.xml.xpath.XPathConstants"
+    , "javax.xml.xpath.XPathException"
+    , "javax.xml.xpath.XPathExpression"
+    , "javax.xml.xpath.XPathExpressionException"
+    , "javax.xml.xpath.XPathFactory"
+    , "javax.xml.xpath.XPathFactoryConfigurationException"
+    , "javax.xml.xpath.XPathFunction"
+    , "javax.xml.xpath.XPathFunctionException"
+    , "javax.xml.xpath.XPathFunctionResolver"
+    , "javax.xml.xpath.XPathVariableResolver"
+    , "org.ietf.jgss.ChannelBinding"
+    , "org.ietf.jgss.GSSContext"
+    , "org.ietf.jgss.GSSCredential"
+    , "org.ietf.jgss.GSSException"
+    , "org.ietf.jgss.GSSManager"
+    , "org.ietf.jgss.GSSName"
+    , "org.ietf.jgss.MessageProp"
+    , "org.ietf.jgss.Oid"
+    , "org.omg.CORBA.ACTIVITY_COMPLETED"
+    , "org.omg.CORBA.ACTIVITY_REQUIRED"
+    , "org.omg.CORBA.ARG_IN"
+    , "org.omg.CORBA.ARG_INOUT"
+    , "org.omg.CORBA.ARG_OUT"
+    , "org.omg.CORBA.Any"
+    , "org.omg.CORBA.AnyHolder"
+    , "org.omg.CORBA.AnySeqHelper"
+    , "org.omg.CORBA.AnySeqHolder"
+    , "org.omg.CORBA.BAD_CONTEXT"
+    , "org.omg.CORBA.BAD_INV_ORDER"
+    , "org.omg.CORBA.BAD_OPERATION"
+    , "org.omg.CORBA.BAD_PARAM"
+    , "org.omg.CORBA.BAD_POLICY"
+    , "org.omg.CORBA.BAD_POLICY_TYPE"
+    , "org.omg.CORBA.BAD_POLICY_VALUE"
+    , "org.omg.CORBA.BAD_QOS"
+    , "org.omg.CORBA.BAD_TYPECODE"
+    , "org.omg.CORBA.BooleanHolder"
+    , "org.omg.CORBA.BooleanSeqHelper"
+    , "org.omg.CORBA.BooleanSeqHolder"
+    , "org.omg.CORBA.Bounds"
+    , "org.omg.CORBA.ByteHolder"
+    , "org.omg.CORBA.CODESET_INCOMPATIBLE"
+    , "org.omg.CORBA.COMM_FAILURE"
+    , "org.omg.CORBA.CTX_RESTRICT_SCOPE"
+    , "org.omg.CORBA.CharHolder"
+    , "org.omg.CORBA.CharSeqHelper"
+    , "org.omg.CORBA.CharSeqHolder"
+    , "org.omg.CORBA.CompletionStatus"
+    , "org.omg.CORBA.CompletionStatusHelper"
+    , "org.omg.CORBA.Context"
+    , "org.omg.CORBA.ContextList"
+    , "org.omg.CORBA.Current"
+    , "org.omg.CORBA.CurrentHelper"
+    , "org.omg.CORBA.CurrentHolder"
+    , "org.omg.CORBA.CurrentOperations"
+    , "org.omg.CORBA.CustomMarshal"
+    , "org.omg.CORBA.DATA_CONVERSION"
+    , "org.omg.CORBA.DataInputStream"
+    , "org.omg.CORBA.DataOutputStream"
+    , "org.omg.CORBA.DefinitionKind"
+    , "org.omg.CORBA.DefinitionKindHelper"
+    , "org.omg.CORBA.DomainManager"
+    , "org.omg.CORBA.DomainManagerOperations"
+    , "org.omg.CORBA.DoubleHolder"
+    , "org.omg.CORBA.DoubleSeqHelper"
+    , "org.omg.CORBA.DoubleSeqHolder"
+    , "org.omg.CORBA.DynAny"
+    , "org.omg.CORBA.DynAnyPackage.Invalid"
+    , "org.omg.CORBA.DynAnyPackage.InvalidSeq"
+    , "org.omg.CORBA.DynAnyPackage.InvalidValue"
+    , "org.omg.CORBA.DynAnyPackage.TypeMismatch"
+    , "org.omg.CORBA.DynArray"
+    , "org.omg.CORBA.DynEnum"
+    , "org.omg.CORBA.DynFixed"
+    , "org.omg.CORBA.DynSequence"
+    , "org.omg.CORBA.DynStruct"
+    , "org.omg.CORBA.DynUnion"
+    , "org.omg.CORBA.DynValue"
+    , "org.omg.CORBA.DynamicImplementation"
+    , "org.omg.CORBA.Environment"
+    , "org.omg.CORBA.ExceptionList"
+    , "org.omg.CORBA.FREE_MEM"
+    , "org.omg.CORBA.FieldNameHelper"
+    , "org.omg.CORBA.FixedHolder"
+    , "org.omg.CORBA.FloatHolder"
+    , "org.omg.CORBA.FloatSeqHelper"
+    , "org.omg.CORBA.FloatSeqHolder"
+    , "org.omg.CORBA.IDLType"
+    , "org.omg.CORBA.IDLTypeHelper"
+    , "org.omg.CORBA.IDLTypeOperations"
+    , "org.omg.CORBA.IMP_LIMIT"
+    , "org.omg.CORBA.INITIALIZE"
+    , "org.omg.CORBA.INTERNAL"
+    , "org.omg.CORBA.INTF_REPOS"
+    , "org.omg.CORBA.INVALID_ACTIVITY"
+    , "org.omg.CORBA.INVALID_TRANSACTION"
+    , "org.omg.CORBA.INV_FLAG"
+    , "org.omg.CORBA.INV_IDENT"
+    , "org.omg.CORBA.INV_OBJREF"
+    , "org.omg.CORBA.INV_POLICY"
+    , "org.omg.CORBA.IRObject"
+    , "org.omg.CORBA.IRObjectOperations"
+    , "org.omg.CORBA.IdentifierHelper"
+    , "org.omg.CORBA.IntHolder"
+    , "org.omg.CORBA.LocalObject"
+    , "org.omg.CORBA.LongHolder"
+    , "org.omg.CORBA.LongLongSeqHelper"
+    , "org.omg.CORBA.LongLongSeqHolder"
+    , "org.omg.CORBA.LongSeqHelper"
+    , "org.omg.CORBA.LongSeqHolder"
+    , "org.omg.CORBA.MARSHAL"
+    , "org.omg.CORBA.NO_IMPLEMENT"
+    , "org.omg.CORBA.NO_MEMORY"
+    , "org.omg.CORBA.NO_PERMISSION"
+    , "org.omg.CORBA.NO_RESOURCES"
+    , "org.omg.CORBA.NO_RESPONSE"
+    , "org.omg.CORBA.NVList"
+    , "org.omg.CORBA.NameValuePair"
+    , "org.omg.CORBA.NameValuePairHelper"
+    , "org.omg.CORBA.NamedValue"
+    , "org.omg.CORBA.OBJECT_NOT_EXIST"
+    , "org.omg.CORBA.OBJ_ADAPTER"
+    , "org.omg.CORBA.OMGVMCID"
+    , "org.omg.CORBA.ORB"
+    , "org.omg.CORBA.ORBPackage.InconsistentTypeCode"
+    , "org.omg.CORBA.ORBPackage.InvalidName"
+    , "org.omg.CORBA.Object"
+    , "org.omg.CORBA.ObjectHelper"
+    , "org.omg.CORBA.ObjectHolder"
+    , "org.omg.CORBA.OctetSeqHelper"
+    , "org.omg.CORBA.OctetSeqHolder"
+    , "org.omg.CORBA.PERSIST_STORE"
+    , "org.omg.CORBA.PRIVATE_MEMBER"
+    , "org.omg.CORBA.PUBLIC_MEMBER"
+    , "org.omg.CORBA.ParameterMode"
+    , "org.omg.CORBA.ParameterModeHelper"
+    , "org.omg.CORBA.ParameterModeHolder"
+    , "org.omg.CORBA.Policy"
+    , "org.omg.CORBA.PolicyError"
+    , "org.omg.CORBA.PolicyErrorCodeHelper"
+    , "org.omg.CORBA.PolicyErrorHelper"
+    , "org.omg.CORBA.PolicyErrorHolder"
+    , "org.omg.CORBA.PolicyHelper"
+    , "org.omg.CORBA.PolicyHolder"
+    , "org.omg.CORBA.PolicyListHelper"
+    , "org.omg.CORBA.PolicyListHolder"
+    , "org.omg.CORBA.PolicyOperations"
+    , "org.omg.CORBA.PolicyTypeHelper"
+    , "org.omg.CORBA.Principal"
+    , "org.omg.CORBA.PrincipalHolder"
+    , "org.omg.CORBA.REBIND"
+    , "org.omg.CORBA.RepositoryIdHelper"
+    , "org.omg.CORBA.Request"
+    , "org.omg.CORBA.ServerRequest"
+    , "org.omg.CORBA.ServiceDetail"
+    , "org.omg.CORBA.ServiceDetailHelper"
+    , "org.omg.CORBA.ServiceInformation"
+    , "org.omg.CORBA.ServiceInformationHelper"
+    , "org.omg.CORBA.ServiceInformationHolder"
+    , "org.omg.CORBA.SetOverrideType"
+    , "org.omg.CORBA.SetOverrideTypeHelper"
+    , "org.omg.CORBA.ShortHolder"
+    , "org.omg.CORBA.ShortSeqHelper"
+    , "org.omg.CORBA.ShortSeqHolder"
+    , "org.omg.CORBA.StringHolder"
+    , "org.omg.CORBA.StringSeqHelper"
+    , "org.omg.CORBA.StringSeqHolder"
+    , "org.omg.CORBA.StringValueHelper"
+    , "org.omg.CORBA.StructMember"
+    , "org.omg.CORBA.StructMemberHelper"
+    , "org.omg.CORBA.SystemException"
+    , "org.omg.CORBA.TCKind"
+    , "org.omg.CORBA.TIMEOUT"
+    , "org.omg.CORBA.TRANSACTION_MODE"
+    , "org.omg.CORBA.TRANSACTION_REQUIRED"
+    , "org.omg.CORBA.TRANSACTION_ROLLEDBACK"
+    , "org.omg.CORBA.TRANSACTION_UNAVAILABLE"
+    , "org.omg.CORBA.TRANSIENT"
+    , "org.omg.CORBA.TypeCode"
+    , "org.omg.CORBA.TypeCodeHolder"
+    , "org.omg.CORBA.TypeCodePackage.BadKind"
+    , "org.omg.CORBA.TypeCodePackage.Bounds"
+    , "org.omg.CORBA.ULongLongSeqHelper"
+    , "org.omg.CORBA.ULongLongSeqHolder"
+    , "org.omg.CORBA.ULongSeqHelper"
+    , "org.omg.CORBA.ULongSeqHolder"
+    , "org.omg.CORBA.UNKNOWN"
+    , "org.omg.CORBA.UNSUPPORTED_POLICY"
+    , "org.omg.CORBA.UNSUPPORTED_POLICY_VALUE"
+    , "org.omg.CORBA.UShortSeqHelper"
+    , "org.omg.CORBA.UShortSeqHolder"
+    , "org.omg.CORBA.UnionMember"
+    , "org.omg.CORBA.UnionMemberHelper"
+    , "org.omg.CORBA.UnknownUserException"
+    , "org.omg.CORBA.UnknownUserExceptionHelper"
+    , "org.omg.CORBA.UnknownUserExceptionHolder"
+    , "org.omg.CORBA.UserException"
+    , "org.omg.CORBA.VM_ABSTRACT"
+    , "org.omg.CORBA.VM_CUSTOM"
+    , "org.omg.CORBA.VM_NONE"
+    , "org.omg.CORBA.VM_TRUNCATABLE"
+    , "org.omg.CORBA.ValueBaseHelper"
+    , "org.omg.CORBA.ValueBaseHolder"
+    , "org.omg.CORBA.ValueMember"
+    , "org.omg.CORBA.ValueMemberHelper"
+    , "org.omg.CORBA.VersionSpecHelper"
+    , "org.omg.CORBA.VisibilityHelper"
+    , "org.omg.CORBA.WCharSeqHelper"
+    , "org.omg.CORBA.WCharSeqHolder"
+    , "org.omg.CORBA.WStringSeqHelper"
+    , "org.omg.CORBA.WStringSeqHolder"
+    , "org.omg.CORBA.WStringValueHelper"
+    , "org.omg.CORBA.WrongTransaction"
+    , "org.omg.CORBA.WrongTransactionHelper"
+    , "org.omg.CORBA.WrongTransactionHolder"
+    , "org.omg.CORBA._IDLTypeStub"
+    , "org.omg.CORBA._PolicyStub"
+    , "org.omg.CORBA.portable.ApplicationException"
+    , "org.omg.CORBA.portable.BoxedValueHelper"
+    , "org.omg.CORBA.portable.CustomValue"
+    , "org.omg.CORBA.portable.Delegate"
+    , "org.omg.CORBA.portable.IDLEntity"
+    , "org.omg.CORBA.portable.IndirectionException"
+    , "org.omg.CORBA.portable.InputStream"
+    , "org.omg.CORBA.portable.InvokeHandler"
+    , "org.omg.CORBA.portable.ObjectImpl"
+    , "org.omg.CORBA.portable.OutputStream"
+    , "org.omg.CORBA.portable.RemarshalException"
+    , "org.omg.CORBA.portable.ResponseHandler"
+    , "org.omg.CORBA.portable.ServantObject"
+    , "org.omg.CORBA.portable.Streamable"
+    , "org.omg.CORBA.portable.StreamableValue"
+    , "org.omg.CORBA.portable.UnknownException"
+    , "org.omg.CORBA.portable.ValueBase"
+    , "org.omg.CORBA.portable.ValueFactory"
+    , "org.omg.CORBA.portable.ValueInputStream"
+    , "org.omg.CORBA.portable.ValueOutputStream"
+    , "org.omg.CORBA_2_3.ORB"
+    , "org.omg.CORBA_2_3.portable.Delegate"
+    , "org.omg.CORBA_2_3.portable.InputStream"
+    , "org.omg.CORBA_2_3.portable.ObjectImpl"
+    , "org.omg.CORBA_2_3.portable.OutputStream"
+    , "org.omg.CosNaming.Binding"
+    , "org.omg.CosNaming.BindingHelper"
+    , "org.omg.CosNaming.BindingHolder"
+    , "org.omg.CosNaming.BindingIterator"
+    , "org.omg.CosNaming.BindingIteratorHelper"
+    , "org.omg.CosNaming.BindingIteratorHolder"
+    , "org.omg.CosNaming.BindingIteratorOperations"
+    , "org.omg.CosNaming.BindingIteratorPOA"
+    , "org.omg.CosNaming.BindingListHelper"
+    , "org.omg.CosNaming.BindingListHolder"
+    , "org.omg.CosNaming.BindingType"
+    , "org.omg.CosNaming.BindingTypeHelper"
+    , "org.omg.CosNaming.BindingTypeHolder"
+    , "org.omg.CosNaming.IstringHelper"
+    , "org.omg.CosNaming.NameComponent"
+    , "org.omg.CosNaming.NameComponentHelper"
+    , "org.omg.CosNaming.NameComponentHolder"
+    , "org.omg.CosNaming.NameHelper"
+    , "org.omg.CosNaming.NameHolder"
+    , "org.omg.CosNaming.NamingContext"
+    , "org.omg.CosNaming.NamingContextExt"
+    , "org.omg.CosNaming.NamingContextExtHelper"
+    , "org.omg.CosNaming.NamingContextExtHolder"
+    , "org.omg.CosNaming.NamingContextExtOperations"
+    , "org.omg.CosNaming.NamingContextExtPOA"
+    , "org.omg.CosNaming.NamingContextExtPackage.AddressHelper"
+    , "org.omg.CosNaming.NamingContextExtPackage.InvalidAddress"
+    , "org.omg.CosNaming.NamingContextExtPackage.InvalidAddressHelper"
+    , "org.omg.CosNaming.NamingContextExtPackage.InvalidAddressHolder"
+    , "org.omg.CosNaming.NamingContextExtPackage.StringNameHelper"
+    , "org.omg.CosNaming.NamingContextExtPackage.URLStringHelper"
+    , "org.omg.CosNaming.NamingContextHelper"
+    , "org.omg.CosNaming.NamingContextHolder"
+    , "org.omg.CosNaming.NamingContextOperations"
+    , "org.omg.CosNaming.NamingContextPOA"
+    , "org.omg.CosNaming.NamingContextPackage.AlreadyBound"
+    , "org.omg.CosNaming.NamingContextPackage.AlreadyBoundHelper"
+    , "org.omg.CosNaming.NamingContextPackage.AlreadyBoundHolder"
+    , "org.omg.CosNaming.NamingContextPackage.CannotProceed"
+    , "org.omg.CosNaming.NamingContextPackage.CannotProceedHelper"
+    , "org.omg.CosNaming.NamingContextPackage.CannotProceedHolder"
+    , "org.omg.CosNaming.NamingContextPackage.InvalidName"
+    , "org.omg.CosNaming.NamingContextPackage.InvalidNameHelper"
+    , "org.omg.CosNaming.NamingContextPackage.InvalidNameHolder"
+    , "org.omg.CosNaming.NamingContextPackage.NotEmpty"
+    , "org.omg.CosNaming.NamingContextPackage.NotEmptyHelper"
+    , "org.omg.CosNaming.NamingContextPackage.NotEmptyHolder"
+    , "org.omg.CosNaming.NamingContextPackage.NotFound"
+    , "org.omg.CosNaming.NamingContextPackage.NotFoundHelper"
+    , "org.omg.CosNaming.NamingContextPackage.NotFoundHolder"
+    , "org.omg.CosNaming.NamingContextPackage.NotFoundReason"
+    , "org.omg.CosNaming.NamingContextPackage.NotFoundReasonHelper"
+    , "org.omg.CosNaming.NamingContextPackage.NotFoundReasonHolder"
+    , "org.omg.CosNaming._BindingIteratorImplBase"
+    , "org.omg.CosNaming._BindingIteratorStub"
+    , "org.omg.CosNaming._NamingContextExtStub"
+    , "org.omg.CosNaming._NamingContextImplBase"
+    , "org.omg.CosNaming._NamingContextStub"
+    , "org.omg.Dynamic.Parameter"
+    , "org.omg.DynamicAny.AnySeqHelper"
+    , "org.omg.DynamicAny.DynAny"
+    , "org.omg.DynamicAny.DynAnyFactory"
+    , "org.omg.DynamicAny.DynAnyFactoryHelper"
+    , "org.omg.DynamicAny.DynAnyFactoryOperations"
+    , "org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode"
+    , "org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCodeHelper"
+    , "org.omg.DynamicAny.DynAnyHelper"
+    , "org.omg.DynamicAny.DynAnyOperations"
+    , "org.omg.DynamicAny.DynAnyPackage.InvalidValue"
+    , "org.omg.DynamicAny.DynAnyPackage.InvalidValueHelper"
+    , "org.omg.DynamicAny.DynAnyPackage.TypeMismatch"
+    , "org.omg.DynamicAny.DynAnyPackage.TypeMismatchHelper"
+    , "org.omg.DynamicAny.DynAnySeqHelper"
+    , "org.omg.DynamicAny.DynArray"
+    , "org.omg.DynamicAny.DynArrayHelper"
+    , "org.omg.DynamicAny.DynArrayOperations"
+    , "org.omg.DynamicAny.DynEnum"
+    , "org.omg.DynamicAny.DynEnumHelper"
+    , "org.omg.DynamicAny.DynEnumOperations"
+    , "org.omg.DynamicAny.DynFixed"
+    , "org.omg.DynamicAny.DynFixedHelper"
+    , "org.omg.DynamicAny.DynFixedOperations"
+    , "org.omg.DynamicAny.DynSequence"
+    , "org.omg.DynamicAny.DynSequenceHelper"
+    , "org.omg.DynamicAny.DynSequenceOperations"
+    , "org.omg.DynamicAny.DynStruct"
+    , "org.omg.DynamicAny.DynStructHelper"
+    , "org.omg.DynamicAny.DynStructOperations"
+    , "org.omg.DynamicAny.DynUnion"
+    , "org.omg.DynamicAny.DynUnionHelper"
+    , "org.omg.DynamicAny.DynUnionOperations"
+    , "org.omg.DynamicAny.DynValue"
+    , "org.omg.DynamicAny.DynValueBox"
+    , "org.omg.DynamicAny.DynValueBoxOperations"
+    , "org.omg.DynamicAny.DynValueCommon"
+    , "org.omg.DynamicAny.DynValueCommonOperations"
+    , "org.omg.DynamicAny.DynValueHelper"
+    , "org.omg.DynamicAny.DynValueOperations"
+    , "org.omg.DynamicAny.FieldNameHelper"
+    , "org.omg.DynamicAny.NameDynAnyPair"
+    , "org.omg.DynamicAny.NameDynAnyPairHelper"
+    , "org.omg.DynamicAny.NameDynAnyPairSeqHelper"
+    , "org.omg.DynamicAny.NameValuePair"
+    , "org.omg.DynamicAny.NameValuePairHelper"
+    , "org.omg.DynamicAny.NameValuePairSeqHelper"
+    , "org.omg.DynamicAny._DynAnyFactoryStub"
+    , "org.omg.DynamicAny._DynAnyStub"
+    , "org.omg.DynamicAny._DynArrayStub"
+    , "org.omg.DynamicAny._DynEnumStub"
+    , "org.omg.DynamicAny._DynFixedStub"
+    , "org.omg.DynamicAny._DynSequenceStub"
+    , "org.omg.DynamicAny._DynStructStub"
+    , "org.omg.DynamicAny._DynUnionStub"
+    , "org.omg.DynamicAny._DynValueStub"
+    , "org.omg.IOP.CodeSets"
+    , "org.omg.IOP.Codec"
+    , "org.omg.IOP.CodecFactory"
+    , "org.omg.IOP.CodecFactoryHelper"
+    , "org.omg.IOP.CodecFactoryOperations"
+    , "org.omg.IOP.CodecFactoryPackage.UnknownEncoding"
+    , "org.omg.IOP.CodecFactoryPackage.UnknownEncodingHelper"
+    , "org.omg.IOP.CodecOperations"
+    , "org.omg.IOP.CodecPackage.FormatMismatch"
+    , "org.omg.IOP.CodecPackage.FormatMismatchHelper"
+    , "org.omg.IOP.CodecPackage.InvalidTypeForEncoding"
+    , "org.omg.IOP.CodecPackage.InvalidTypeForEncodingHelper"
+    , "org.omg.IOP.CodecPackage.TypeMismatch"
+    , "org.omg.IOP.CodecPackage.TypeMismatchHelper"
+    , "org.omg.IOP.ComponentIdHelper"
+    , "org.omg.IOP.ENCODING_CDR_ENCAPS"
+    , "org.omg.IOP.Encoding"
+    , "org.omg.IOP.ExceptionDetailMessage"
+    , "org.omg.IOP.IOR"
+    , "org.omg.IOP.IORHelper"
+    , "org.omg.IOP.IORHolder"
+    , "org.omg.IOP.MultipleComponentProfileHelper"
+    , "org.omg.IOP.MultipleComponentProfileHolder"
+    , "org.omg.IOP.ProfileIdHelper"
+    , "org.omg.IOP.RMICustomMaxStreamFormat"
+    , "org.omg.IOP.ServiceContext"
+    , "org.omg.IOP.ServiceContextHelper"
+    , "org.omg.IOP.ServiceContextHolder"
+    , "org.omg.IOP.ServiceContextListHelper"
+    , "org.omg.IOP.ServiceContextListHolder"
+    , "org.omg.IOP.ServiceIdHelper"
+    , "org.omg.IOP.TAG_ALTERNATE_IIOP_ADDRESS"
+    , "org.omg.IOP.TAG_CODE_SETS"
+    , "org.omg.IOP.TAG_INTERNET_IOP"
+    , "org.omg.IOP.TAG_JAVA_CODEBASE"
+    , "org.omg.IOP.TAG_MULTIPLE_COMPONENTS"
+    , "org.omg.IOP.TAG_ORB_TYPE"
+    , "org.omg.IOP.TAG_POLICIES"
+    , "org.omg.IOP.TAG_RMI_CUSTOM_MAX_STREAM_FORMAT"
+    , "org.omg.IOP.TaggedComponent"
+    , "org.omg.IOP.TaggedComponentHelper"
+    , "org.omg.IOP.TaggedComponentHolder"
+    , "org.omg.IOP.TaggedProfile"
+    , "org.omg.IOP.TaggedProfileHelper"
+    , "org.omg.IOP.TaggedProfileHolder"
+    , "org.omg.IOP.TransactionService"
+    , "org.omg.Messaging.SYNC_WITH_TRANSPORT"
+    , "org.omg.Messaging.SyncScopeHelper"
+    , "org.omg.PortableInterceptor.ACTIVE"
+    , "org.omg.PortableInterceptor.AdapterManagerIdHelper"
+    , "org.omg.PortableInterceptor.AdapterNameHelper"
+    , "org.omg.PortableInterceptor.AdapterStateHelper"
+    , "org.omg.PortableInterceptor.ClientRequestInfo"
+    , "org.omg.PortableInterceptor.ClientRequestInfoOperations"
+    , "org.omg.PortableInterceptor.ClientRequestInterceptor"
+    , "org.omg.PortableInterceptor.ClientRequestInterceptorOperations"
+    , "org.omg.PortableInterceptor.Current"
+    , "org.omg.PortableInterceptor.CurrentHelper"
+    , "org.omg.PortableInterceptor.CurrentOperations"
+    , "org.omg.PortableInterceptor.DISCARDING"
+    , "org.omg.PortableInterceptor.ForwardRequest"
+    , "org.omg.PortableInterceptor.ForwardRequestHelper"
+    , "org.omg.PortableInterceptor.HOLDING"
+    , "org.omg.PortableInterceptor.INACTIVE"
+    , "org.omg.PortableInterceptor.IORInfo"
+    , "org.omg.PortableInterceptor.IORInfoOperations"
+    , "org.omg.PortableInterceptor.IORInterceptor"
+    , "org.omg.PortableInterceptor.IORInterceptorOperations"
+    , "org.omg.PortableInterceptor.IORInterceptor_3_0"
+    , "org.omg.PortableInterceptor.IORInterceptor_3_0Helper"
+    , "org.omg.PortableInterceptor.IORInterceptor_3_0Holder"
+    , "org.omg.PortableInterceptor.IORInterceptor_3_0Operations"
+    , "org.omg.PortableInterceptor.Interceptor"
+    , "org.omg.PortableInterceptor.InterceptorOperations"
+    , "org.omg.PortableInterceptor.InvalidSlot"
+    , "org.omg.PortableInterceptor.InvalidSlotHelper"
+    , "org.omg.PortableInterceptor.LOCATION_FORWARD"
+    , "org.omg.PortableInterceptor.NON_EXISTENT"
+    , "org.omg.PortableInterceptor.ORBIdHelper"
+    , "org.omg.PortableInterceptor.ORBInitInfo"
+    , "org.omg.PortableInterceptor.ORBInitInfoOperations"
+    , "org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName"
+    , "org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateNameHelper"
+    , "org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName"
+    , "org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidNameHelper"
+    , "org.omg.PortableInterceptor.ORBInitInfoPackage.ObjectIdHelper"
+    , "org.omg.PortableInterceptor.ORBInitializer"
+    , "org.omg.PortableInterceptor.ORBInitializerOperations"
+    , "org.omg.PortableInterceptor.ObjectIdHelper"
+    , "org.omg.PortableInterceptor.ObjectReferenceFactory"
+    , "org.omg.PortableInterceptor.ObjectReferenceFactoryHelper"
+    , "org.omg.PortableInterceptor.ObjectReferenceFactoryHolder"
+    , "org.omg.PortableInterceptor.ObjectReferenceTemplate"
+    , "org.omg.PortableInterceptor.ObjectReferenceTemplateHelper"
+    , "org.omg.PortableInterceptor.ObjectReferenceTemplateHolder"
+    , "org.omg.PortableInterceptor.ObjectReferenceTemplateSeqHelper"
+    , "org.omg.PortableInterceptor.ObjectReferenceTemplateSeqHolder"
+    , "org.omg.PortableInterceptor.PolicyFactory"
+    , "org.omg.PortableInterceptor.PolicyFactoryOperations"
+    , "org.omg.PortableInterceptor.RequestInfo"
+    , "org.omg.PortableInterceptor.RequestInfoOperations"
+    , "org.omg.PortableInterceptor.SUCCESSFUL"
+    , "org.omg.PortableInterceptor.SYSTEM_EXCEPTION"
+    , "org.omg.PortableInterceptor.ServerIdHelper"
+    , "org.omg.PortableInterceptor.ServerRequestInfo"
+    , "org.omg.PortableInterceptor.ServerRequestInfoOperations"
+    , "org.omg.PortableInterceptor.ServerRequestInterceptor"
+    , "org.omg.PortableInterceptor.ServerRequestInterceptorOperations"
+    , "org.omg.PortableInterceptor.TRANSPORT_RETRY"
+    , "org.omg.PortableInterceptor.UNKNOWN"
+    , "org.omg.PortableInterceptor.USER_EXCEPTION"
+    , "org.omg.PortableServer.AdapterActivator"
+    , "org.omg.PortableServer.AdapterActivatorOperations"
+    , "org.omg.PortableServer.Current"
+    , "org.omg.PortableServer.CurrentHelper"
+    , "org.omg.PortableServer.CurrentOperations"
+    , "org.omg.PortableServer.CurrentPackage.NoContext"
+    , "org.omg.PortableServer.CurrentPackage.NoContextHelper"
+    , "org.omg.PortableServer.DynamicImplementation"
+    , "org.omg.PortableServer.ForwardRequest"
+    , "org.omg.PortableServer.ForwardRequestHelper"
+    , "org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID"
+    , "org.omg.PortableServer.ID_UNIQUENESS_POLICY_ID"
+    , "org.omg.PortableServer.IMPLICIT_ACTIVATION_POLICY_ID"
+    , "org.omg.PortableServer.IdAssignmentPolicy"
+    , "org.omg.PortableServer.IdAssignmentPolicyOperations"
+    , "org.omg.PortableServer.IdAssignmentPolicyValue"
+    , "org.omg.PortableServer.IdUniquenessPolicy"
+    , "org.omg.PortableServer.IdUniquenessPolicyOperations"
+    , "org.omg.PortableServer.IdUniquenessPolicyValue"
+    , "org.omg.PortableServer.ImplicitActivationPolicy"
+    , "org.omg.PortableServer.ImplicitActivationPolicyOperations"
+    , "org.omg.PortableServer.ImplicitActivationPolicyValue"
+    , "org.omg.PortableServer.LIFESPAN_POLICY_ID"
+    , "org.omg.PortableServer.LifespanPolicy"
+    , "org.omg.PortableServer.LifespanPolicyOperations"
+    , "org.omg.PortableServer.LifespanPolicyValue"
+    , "org.omg.PortableServer.POA"
+    , "org.omg.PortableServer.POAHelper"
+    , "org.omg.PortableServer.POAManager"
+    , "org.omg.PortableServer.POAManagerOperations"
+    , "org.omg.PortableServer.POAManagerPackage.AdapterInactive"
+    , "org.omg.PortableServer.POAManagerPackage.AdapterInactiveHelper"
+    , "org.omg.PortableServer.POAManagerPackage.State"
+    , "org.omg.PortableServer.POAOperations"
+    , "org.omg.PortableServer.POAPackage.AdapterAlreadyExists"
+    , "org.omg.PortableServer.POAPackage.AdapterAlreadyExistsHelper"
+    , "org.omg.PortableServer.POAPackage.AdapterNonExistent"
+    , "org.omg.PortableServer.POAPackage.AdapterNonExistentHelper"
+    , "org.omg.PortableServer.POAPackage.InvalidPolicy"
+    , "org.omg.PortableServer.POAPackage.InvalidPolicyHelper"
+    , "org.omg.PortableServer.POAPackage.NoServant"
+    , "org.omg.PortableServer.POAPackage.NoServantHelper"
+    , "org.omg.PortableServer.POAPackage.ObjectAlreadyActive"
+    , "org.omg.PortableServer.POAPackage.ObjectAlreadyActiveHelper"
+    , "org.omg.PortableServer.POAPackage.ObjectNotActive"
+    , "org.omg.PortableServer.POAPackage.ObjectNotActiveHelper"
+    , "org.omg.PortableServer.POAPackage.ServantAlreadyActive"
+    , "org.omg.PortableServer.POAPackage.ServantAlreadyActiveHelper"
+    , "org.omg.PortableServer.POAPackage.ServantNotActive"
+    , "org.omg.PortableServer.POAPackage.ServantNotActiveHelper"
+    , "org.omg.PortableServer.POAPackage.WrongAdapter"
+    , "org.omg.PortableServer.POAPackage.WrongAdapterHelper"
+    , "org.omg.PortableServer.POAPackage.WrongPolicy"
+    , "org.omg.PortableServer.POAPackage.WrongPolicyHelper"
+    , "org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID"
+    , "org.omg.PortableServer.RequestProcessingPolicy"
+    , "org.omg.PortableServer.RequestProcessingPolicyOperations"
+    , "org.omg.PortableServer.RequestProcessingPolicyValue"
+    , "org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID"
+    , "org.omg.PortableServer.Servant"
+    , "org.omg.PortableServer.ServantActivator"
+    , "org.omg.PortableServer.ServantActivatorHelper"
+    , "org.omg.PortableServer.ServantActivatorOperations"
+    , "org.omg.PortableServer.ServantActivatorPOA"
+    , "org.omg.PortableServer.ServantLocator"
+    , "org.omg.PortableServer.ServantLocatorHelper"
+    , "org.omg.PortableServer.ServantLocatorOperations"
+    , "org.omg.PortableServer.ServantLocatorPOA"
+    , "org.omg.PortableServer.ServantLocatorPackage.CookieHolder"
+    , "org.omg.PortableServer.ServantManager"
+    , "org.omg.PortableServer.ServantManagerOperations"
+    , "org.omg.PortableServer.ServantRetentionPolicy"
+    , "org.omg.PortableServer.ServantRetentionPolicyOperations"
+    , "org.omg.PortableServer.ServantRetentionPolicyValue"
+    , "org.omg.PortableServer.THREAD_POLICY_ID"
+    , "org.omg.PortableServer.ThreadPolicy"
+    , "org.omg.PortableServer.ThreadPolicyOperations"
+    , "org.omg.PortableServer.ThreadPolicyValue"
+    , "org.omg.PortableServer._ServantActivatorStub"
+    , "org.omg.PortableServer._ServantLocatorStub"
+    , "org.omg.PortableServer.portable.Delegate"
+    , "org.omg.SendingContext.RunTime"
+    , "org.omg.SendingContext.RunTimeOperations"
+    , "org.omg.stub.java.rmi._Remote_Stub"
+    , "org.w3c.dom.Attr"
+    , "org.w3c.dom.CDATASection"
+    , "org.w3c.dom.CharacterData"
+    , "org.w3c.dom.Comment"
+    , "org.w3c.dom.DOMConfiguration"
+    , "org.w3c.dom.DOMError"
+    , "org.w3c.dom.DOMErrorHandler"
+    , "org.w3c.dom.DOMException"
+    , "org.w3c.dom.DOMImplementation"
+    , "org.w3c.dom.DOMImplementationList"
+    , "org.w3c.dom.DOMImplementationSource"
+    , "org.w3c.dom.DOMLocator"
+    , "org.w3c.dom.DOMStringList"
+    , "org.w3c.dom.Document"
+    , "org.w3c.dom.DocumentFragment"
+    , "org.w3c.dom.DocumentType"
+    , "org.w3c.dom.Element"
+    , "org.w3c.dom.Entity"
+    , "org.w3c.dom.EntityReference"
+    , "org.w3c.dom.NameList"
+    , "org.w3c.dom.NamedNodeMap"
+    , "org.w3c.dom.Node"
+    , "org.w3c.dom.NodeList"
+    , "org.w3c.dom.Notation"
+    , "org.w3c.dom.ProcessingInstruction"
+    , "org.w3c.dom.Text"
+    , "org.w3c.dom.TypeInfo"
+    , "org.w3c.dom.UserDataHandler"
+    , "org.w3c.dom.bootstrap.DOMImplementationRegistry"
+    , "org.w3c.dom.events.DocumentEvent"
+    , "org.w3c.dom.events.Event"
+    , "org.w3c.dom.events.EventException"
+    , "org.w3c.dom.events.EventListener"
+    , "org.w3c.dom.events.EventTarget"
+    , "org.w3c.dom.events.MouseEvent"
+    , "org.w3c.dom.events.MutationEvent"
+    , "org.w3c.dom.events.UIEvent"
+    , "org.w3c.dom.ls.DOMImplementationLS"
+    , "org.w3c.dom.ls.LSException"
+    , "org.w3c.dom.ls.LSInput"
+    , "org.w3c.dom.ls.LSLoadEvent"
+    , "org.w3c.dom.ls.LSOutput"
+    , "org.w3c.dom.ls.LSParser"
+    , "org.w3c.dom.ls.LSParserFilter"
+    , "org.w3c.dom.ls.LSProgressEvent"
+    , "org.w3c.dom.ls.LSResourceResolver"
+    , "org.w3c.dom.ls.LSSerializer"
+    , "org.w3c.dom.ls.LSSerializerFilter"
+    , "org.xml.sax.AttributeList"
+    , "org.xml.sax.Attributes"
+    , "org.xml.sax.ContentHandler"
+    , "org.xml.sax.DTDHandler"
+    , "org.xml.sax.DocumentHandler"
+    , "org.xml.sax.EntityResolver"
+    , "org.xml.sax.ErrorHandler"
+    , "org.xml.sax.HandlerBase"
+    , "org.xml.sax.InputSource"
+    , "org.xml.sax.Locator"
+    , "org.xml.sax.Parser"
+    , "org.xml.sax.SAXException"
+    , "org.xml.sax.SAXNotRecognizedException"
+    , "org.xml.sax.SAXNotSupportedException"
+    , "org.xml.sax.SAXParseException"
+    , "org.xml.sax.XMLFilter"
+    , "org.xml.sax.XMLReader"
+    , "org.xml.sax.ext.Attributes2"
+    , "org.xml.sax.ext.Attributes2Impl"
+    , "org.xml.sax.ext.DeclHandler"
+    , "org.xml.sax.ext.DefaultHandler2"
+    , "org.xml.sax.ext.EntityResolver2"
+    , "org.xml.sax.ext.LexicalHandler"
+    , "org.xml.sax.ext.Locator2"
+    , "org.xml.sax.ext.Locator2Impl"
+    , "org.xml.sax.helpers.AttributeListImpl"
+    , "org.xml.sax.helpers.AttributesImpl"
+    , "org.xml.sax.helpers.DefaultHandler"
+    , "org.xml.sax.helpers.LocatorImpl"
+    , "org.xml.sax.helpers.NamespaceSupport"
+    , "org.xml.sax.helpers.ParserAdapter"
+    , "org.xml.sax.helpers.ParserFactory"
+    , "org.xml.sax.helpers.XMLFilterImpl"
+    , "org.xml.sax.helpers.XMLReaderAdapter"
+    , "org.xml.sax.helpers.XMLReaderFactory" ]
+
+
diff --git a/src/Foreign/Java/Bindings/JavaTypes.hs b/src/Foreign/Java/Bindings/JavaTypes.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/JavaTypes.hs
@@ -0,0 +1,211 @@
+{-# LANGUAGE Haskell2010
+    , DeriveDataTypeable
+ #-}
+{-# OPTIONS -Wall #-}
+
+-- |
+-- Module       : Foreign.Java.Bindings.JavaTypes
+-- Copyright    : (c) Julian Fleischer 2013
+-- License      : MIT (See LICENSE file in cabal package)
+--
+-- Maintainer   : julian.fleischer@fu-berlin.de
+-- Stability    : provisional
+-- Portability  : non-portable (DeriveDataTypeable)
+--
+-- Data structures that describe the interface of
+-- Java structures such as classes, generic types,
+-- their methods, etc.
+--
+-- All types are instances of 'Data' and 'Typeable' and
+-- can therefor be used with /Scrap Your Boilerplate/
+-- combinators (see "Data.Generics").
+module Foreign.Java.Bindings.JavaTypes where
+
+import Foreign.Java.Utils
+import Data.Int
+import Data.Data
+
+-- type JavaClassCache = Map (String, [JavaType]) JavaClass
+
+-- | A JavaType is either a Primitive Type, an Array, or an Object.
+data JavaType
+    = JBoolean
+    | JChar
+    | JByte
+    | JShort
+    | JInt
+    | JLong
+    | JFloat
+    | JDouble
+    | JObj {
+        typeName :: String
+      }
+    | JArr {
+        componentType :: JavaType
+      }
+  deriving (Eq, Ord, Show, Read, Data, Typeable)
+
+
+printJavaType :: JavaType -> String
+printJavaType t = case t of
+    JBoolean -> "boolean"
+    JChar -> "char"
+    JByte -> "byte"
+    JShort -> "short"
+    JInt -> "int"
+    JLong -> "long"
+    JFloat -> "float"
+    JDouble -> "double"
+    JObj n -> n
+    JArr c -> printJavaType c ++ "[]"
+
+-- | The interface of a Java class.
+data JavaClass = JavaClass {
+    className :: String,
+    classPackage :: Maybe String,
+    classModName :: String,
+    classParents :: [String],
+    classIfaces :: [String],
+    classConstructors :: [JavaConstructor],
+    classMethods :: [JavaMethod],
+    classTypeParams :: [JavaTypeParam],
+    classEnum :: Bool,
+    classEnumConstants :: [(Int32, String)],
+    classIface :: Bool,
+    classAnnotation :: Bool,
+    classAbstract :: Bool,
+    classFinal :: Bool
+  } deriving (Eq, Show, Read, Data, Typeable)
+
+data JavaClassType = Annotation | Interface | Enum | Class | Exception | Error
+    deriving (Eq, Ord, Show, Read, Data, Typeable)
+
+
+classType :: JavaClass -> JavaClassType
+-- ^ Determines the 'JavaClassType' of a 'JavaClass'.
+classType clazz
+    | "java.lang.Error"     `elem` classParents clazz = Error
+    | "java.lang.Exception" `elem` classParents clazz = Exception
+    | classAnnotation clazz = Annotation
+    | classIface clazz      = Interface
+    | classEnum clazz       = Enum
+    | otherwise             = Class
+
+
+classDependencies :: JavaClass -> [String]
+-- ^ Calculate all classes that are referenced in any way by this class.
+classDependencies clazz = concat [
+    classParents clazz,
+    classIfaces clazz,
+    concatMap methodDependencies (classMethods clazz),
+    concatMap constructorDependencies (classConstructors clazz) ]
+
+classFullName :: JavaClass -> String
+-- ^ Derive the full name from a class definition. See also 'makeName'.
+classFullName clazz = makeName (classPackage clazz) (className clazz)
+    
+
+-- | A Type variable declaration.
+data JavaTypeParam = JavaTypeParam {
+    paramName :: TyVar,
+    paramBounds :: [JavaGenericType]
+  } deriving (Eq, Ord, Show, Read, Data, Typeable)
+
+-- | A Type variable. This is merely a name.
+newtype TyVar = TyVar { tyVarName :: String }
+    deriving (Eq, Ord, Show, Read, Data, Typeable)
+
+data JavaGenericType
+    = -- | @<? super X>@, @<? extends X>@
+      Wildcard {
+        jgtBounds :: [JavaGenericType],
+        jgtLowerBounds :: [JavaGenericType]
+    }
+    | -- | @java.util.List<X>@
+      Parameterized {
+        -- | The full name of the base type, e.g. @java.lang.Class@.
+        jgtBasetype :: String,
+        -- | The parameters.
+        jgtParameters :: [JavaGenericType]
+    }
+    | -- | @X[]@
+      GenericArray {
+        -- | The base type of the generic array, e.g. @java.lang.Number@.
+        jgtComponentType :: JavaGenericType
+    }
+    | -- | @<X>@
+      TypeVarReference {
+        -- | The name of the type variable, e.g. @E@ or @X@.
+        jgtName :: TyVar
+    }
+    | -- java.lang.Object
+      NotSoGeneric {
+        -- | A plain type, full name. Used for example in a 'Parameterized'
+        -- type, which may be parameterized by a plain type (like
+        -- @Class<Number>@.
+        jgtBasetype :: String
+    } deriving (Eq, Ord, Show, Read, Data, Typeable)
+
+-- | The type of a generic type.
+data JavaGenericTypeType = WildcardT
+                         | ParameterizedT
+                         | GenericArrayT
+                         | TypeVarReferenceT
+                         | NotSoGenericT
+
+jgtType :: JavaGenericType -> JavaGenericTypeType
+-- ^ Get the type of a generic type.
+jgtType t = case t of
+    (Wildcard _ _)       -> WildcardT
+    (Parameterized _ _)  -> ParameterizedT
+    (GenericArray _)     -> GenericArrayT
+    (TypeVarReference _) -> TypeVarReferenceT
+    (NotSoGeneric _)     -> NotSoGenericT
+
+
+-- | The interface to a method in the Java language.
+data JavaMethod = JavaMethod {
+    methodName :: String,
+    methodName' :: String,
+    methodParams :: [JavaType],
+    methodGenericParams :: [JavaGenericType],
+    methodReturnType :: Maybe JavaType,
+    methodGenericReturnType :: JavaGenericType,
+    methodTypeParams :: [JavaTypeParam],
+    methodStatic :: Bool,
+    methodAbstract :: Bool,
+    methodPublic :: Bool,
+    methodFinal :: Bool,
+    methodNative :: Bool,
+    methodSynchronized :: Bool
+  } deriving (Eq, Show, Read, Data, Typeable)
+
+methodDependencies :: JavaMethod -> [String]
+-- ^ Return the full names of all classes that this method
+-- references in its definition.
+methodDependencies method = foldl classReference [] referenced
+  where
+    referenced = maybe paramTypes (: paramTypes) (methodReturnType method)
+    paramTypes = methodParams method
+    classReference r c = case c of
+        JObj n -> n : r
+        _ -> r
+
+-- | A Constructor in the Java language.
+data JavaConstructor = JavaConstructor {
+    constructorParams :: [JavaType],
+    constructorGenericParams :: [JavaGenericType],
+    constructorTypeParams :: [JavaTypeParam]
+  } deriving (Eq, Show, Read, Data, Typeable)
+
+constructorDependencies :: JavaConstructor -> [String]
+-- ^ Retrieve all classes that this constructor definition
+-- references in its parameters or generic declaration.
+constructorDependencies constr = foldl classReference []
+                              $ constructorParams constr
+  where
+    classReference r c = case c of
+        JObj n -> n : r
+        _ -> r
+
+
diff --git a/src/Foreign/Java/Bindings/ReflectHaskell.hs b/src/Foreign/Java/Bindings/ReflectHaskell.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/ReflectHaskell.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE Haskell2010 #-}
+
+module Foreign.Java.Bindings.ReflectHaskell where
+
+
+
diff --git a/src/Foreign/Java/Bindings/ReflectJava.hs b/src/Foreign/Java/Bindings/ReflectJava.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/ReflectJava.hs
@@ -0,0 +1,523 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-missing-signatures
+    -fno-warn-name-shadowing
+ #-}
+
+-- |
+-- Module       : Foreign.Java.Bindings.ReflectJava
+-- Copyright    : (c) Julian Fleischer 2013
+-- License      : MIT (See LICENSE file in cabal package)
+--
+-- Maintainer   : julian.fleischer@fu-berlin.de
+-- Stability    : provisional
+--
+-- Methods for reflecting Java classes using a JVM as source of information.
+module Foreign.Java.Bindings.ReflectJava where
+
+
+import qualified Data.Map as Map
+import Data.Map (Map)
+
+import qualified Data.Set as Set
+import Data.Set (Set)
+
+import Data.Int
+import Data.Word
+import Data.Maybe (fromJust)
+
+import Foreign.Java
+import Foreign.Java.Bindings.JavaTypes
+import Foreign.Java.Utils
+
+
+-- (
+--  [Methods = [types] ],
+--  (Maybe Parentclass, [Interfaces])
+-- )
+type Class = ([String], (Maybe String, [String]))
+
+
+findClasses :: Word32 -> [String] -> Java [String] --Java (Map String Class)
+findClasses maxDepth classNamesToFind = do
+
+    (Just clazz)   <- getClass "java.lang.Class"
+    (Just cMethod) <- getClass "java.lang.reflect.Method"
+    (Just cConstr) <- getClass "java.lang.reflect.Constructor"
+
+    getMethods     <- clazz   `bindMethod` "getMethods"
+                        ::= array (object "java.lang.reflect.Method")
+    getConstructors <- clazz `bindMethod` "getConstructors"
+                        ::= array (object "java.lang.reflect.Constructor")
+    getReturnType  <- cMethod `bindMethod` "getReturnType"
+                        ::= object "java.lang.Class"
+    getClassName   <- clazz   `bindMethod` "getName"
+                        ::= string
+    getParametersM <- cMethod `bindMethod` "getParameterTypes"
+                        ::= array (object "java.lang.Class")
+    getParametersC <- cConstr `bindMethod` "getParameterTypes"
+                        ::= array (object "java.lang.Class")
+    getSuperclass  <- clazz   `bindMethod` "getSuperclass"
+                        ::= object "java.lang.Class"
+    getInterfaces  <- clazz   `bindMethod` "getInterfaces"
+                        ::= array (object "java.lang.Class")
+
+    (Just classLoader) <- getClass "java.lang.ClassLoader"
+    getSystemClassLoader <- classLoader `bindStaticMethod` "getSystemClassLoader"
+        ::= object "java.lang.ClassLoader"
+    (Just systemClassLoader) <- getSystemClassLoader
+
+    (Just loadClass) <- classLoader `getMethod` "loadClass"
+        ::= string --> boolean --> object "java.lang.Class"
+
+    let getClass' :: String -> Java (Maybe JObject)
+        getClass' clazz = callMethodE loadClass systemClassLoader clazz False
+            >>= return . either (const Nothing) id
+
+        readClass :: JObject -> Java Class
+        readClass clazz = do
+            constructors <- getConstructors clazz
+                >>= toList . fromJust
+                >>= mapM (readConstructor . fromJust)
+                >>= return . concat
+            methods <- getMethods clazz
+                >>= toList . fromJust
+                >>= mapM (readMethod . fromJust)
+                >>= return . concat
+            superclass <- getSuperclass clazz
+                >>= maybe (return Nothing) getClassName
+            interfaces <- getInterfaces clazz
+                >>= toList . fromJust
+                >>= mapM (getClassName . fromJust)
+                >>= return . map fromJust
+            return (constructors ++ methods, (superclass, interfaces))
+
+        readMethod :: JObject -> Java [String]
+        readMethod method = do
+            args <- readMethodParameters method
+--          excs <- readMethodExceptions method
+            (Just returnType) <- getReturnType method >>= getClassName . fromJust
+            
+            return (returnType : args)
+
+        readConstructor :: JObject -> Java [String]
+        readConstructor constr = do
+            args <- readConstructorParameters constr
+--          excs <- readConstructorExceptions constr
+            
+            return args
+
+        readMethodParameters :: JObject -> Java [String]
+        readMethodParameters method = getParametersM method
+            >>= toList . fromJust
+            >>= mapM (getClassName . fromJust)
+            >>= return . map fromJust
+
+        readConstructorParameters :: JObject -> Java [String]
+        readConstructorParameters method = getParametersC method
+            >>= toList . fromJust
+            >>= mapM (getClassName . fromJust)
+            >>= return . map fromJust
+
+        readReferences :: Class -> [String]
+        readReferences (refs1, (super, ifaces)) =
+            let refs2 = maybe ifaces (: ifaces) super
+            in refs2 ++ refs1
+
+        isPrimitive x = head x == '[' || x `elem` ["byte", "short", "int", "long",
+                                                   "float", "double", "boolean", "char",
+                                                   "void"]
+
+        resolve :: Map String Class -> Set String -> [String]
+                -> Java (Map String Class, Set String)
+        resolve map set css = case css of
+            (x:xs) -> if x `Map.member` map
+                then do resolve map set xs
+                else getClass' x >>= maybe (resolve map set xs) (\clazz -> do
+                        clazz' <- readClass clazz
+                        let newClasses = Set.filter (`Map.notMember` map)
+                                            $ Set.fromList (readReferences clazz')
+                        resolve (Map.insert x clazz' map)
+                                (newClasses `Set.union` set)
+                                xs)
+            [] -> do return (map, Set.filter (not . isPrimitive) set)
+
+        findAll :: Word32 -> Map String Class -> [String] -> Java (Map String Class)
+        findAll 0 classes _xs = return classes
+        findAll limit classes xs = do
+            (classes', new) <- resolve classes Set.empty xs
+            if Set.null new
+                then return classes'
+                else findAll (pred limit) classes' (Set.toList new)
+    
+    Map.keys `fmap` findAll maxDepth Map.empty classNamesToFind
+
+reflectClasses :: [String] -> Java [JavaClass]
+reflectClasses classes = do
+
+    (Just clazz)     <- getClass "java.lang.Class"
+    (Just cMethod)   <- getClass "java.lang.reflect.Method"
+    (Just cConstr)   <- getClass "java.lang.reflect.Constructor"
+    (Just cTypeV)    <- getClass "java.lang.reflect.TypeVariable"
+    (Just cParamT)   <- getClass "java.lang.reflect.ParameterizedType"
+    (Just cWildT)    <- getClass "java.lang.reflect.WildcardType"
+    (Just cGenArrT)  <- getClass "java.lang.reflect.GenericArrayType"
+    (Just cEnum)     <- getClass "java.lang.Enum"
+    (Just modifiers) <- getClass "java.lang.reflect.Modifier"
+
+    getMethods <- clazz `bindMethod` "getMethods"
+        ::= array (object "java.lang.reflect.Method")
+    getReturnType <- cMethod `bindMethod` "getReturnType"
+        ::= object "java.lang.Class"
+    getName <- clazz `bindMethod` "getName"
+        ::= string
+    getMethodName <- cMethod `bindMethod` "getName"
+        ::= string
+    getParameters <- cMethod `bindMethod` "getParameterTypes"
+        ::= array (object "java.lang.Class")
+    getParameters' <- cConstr `bindMethod` "getParameterTypes"
+        ::= array (object "java.lang.Class")
+    getGenericParametersM <- cMethod `bindMethod` "getGenericParameterTypes"
+        ::= array (object "java.lang.reflect.Type")
+    getGenericParametersC <- cConstr `bindMethod` "getGenericParameterTypes"
+        ::= array (object "java.lang.reflect.Type")
+    getGenericReturnType <- cMethod `bindMethod` "getGenericReturnType"
+        ::= object "java.lang.reflect.Type"
+    getSuperclass <- clazz `bindMethod` "getSuperclass"
+        ::= object "java.lang.Class"
+    getInterfaces <- clazz `bindMethod` "getInterfaces"
+        ::= array (object "java.lang.Class")
+    getModifiersC <- clazz `bindMethod` "getModifiers"
+        ::= int
+    getModifiersM <- cMethod `bindMethod` "getModifiers"
+        ::= int
+    getConstructors <- clazz `bindMethod` "getConstructors"
+        ::= array (object "java.lang.reflect.Constructor")
+    getComponentType <- clazz `bindMethod` "getComponentType"
+        ::= object "java.lang.Class"
+    getEnumConstants <- clazz `bindMethod` "getEnumConstants"
+        ::= array (object "java.lang.Object")
+    getTypeParameters <- clazz `bindMethod` "getTypeParameters"
+        ::= array (object "java.lang.reflect.TypeVariable")
+    getTypeParametersC <- cConstr `bindMethod` "getTypeParameters"
+        ::= array (object "java.lang.reflect.TypeVariable")
+    getTypeParametersM <- cMethod `bindMethod` "getTypeParameters"
+        ::= array (object "java.lang.reflect.TypeVariable")
+
+    -- reflect TypeVariables
+    getTypeVariableName <- cTypeV `bindMethod` "getName"
+        ::= string
+    getTypeVariableBounds <- cTypeV `bindMethod` "getBounds"
+        ::= array (object "java.lang.reflect.Type")
+
+    -- reflect ParameterizedTypes
+    getActualTypeArguments <- cParamT `bindMethod` "getActualTypeArguments"
+        ::= array (object "java.lang.reflect.Type")
+    getRawType <- cParamT `bindMethod` "getRawType"
+        ::= object "java.lang.reflect.Type"
+    
+    -- reflect WildcardTypes
+    getLowerBounds <- cWildT `bindMethod` "getLowerBounds"
+        ::= array (object "java.lang.reflect.Type")
+    getUpperBounds <- cWildT `bindMethod` "getUpperBounds"
+        ::= array (object "java.lang.reflect.Type")
+
+    -- reflect GenericArrayTypes
+    getGenericComponentType <- cGenArrT `bindMethod` "getGenericComponentType"
+        ::= object "java.lang.reflect.Type"
+
+    -- reflect Enum types
+    getEnumName <- cEnum `bindMethod` "name"
+        ::= string
+    getEnumOrdinal <- cEnum `bindMethod` "ordinal"
+        ::= int
+
+    isAnnotation <- clazz `bindMethod` "isAnnotation"
+        ::= boolean
+    isArray <- clazz `bindMethod` "isArray"
+        ::= boolean
+    isEnum <- clazz `bindMethod` "isEnum"
+        ::= boolean
+    isInterface <- clazz `bindMethod` "isInterface"
+        ::= boolean
+    isPrimitive <- clazz `bindMethod` "isPrimitive"
+        ::= boolean
+
+    isStatic <- modifiers `bindStaticMethod` "isStatic"
+        ::= int --> boolean
+    isAbstract <- modifiers `bindStaticMethod` "isAbstract"
+        ::= int --> boolean
+    isPublic <- modifiers `bindStaticMethod` "isPublic"
+        ::= int --> boolean
+    isFinal <- modifiers `bindStaticMethod` "isFinal"
+        ::= int --> boolean
+    isNative <- modifiers `bindStaticMethod` "isNative"
+        ::= int --> boolean
+    isSynchronized <- modifiers `bindStaticMethod` "isSynchronized"
+        ::= int --> boolean
+
+    (Just classLoader) <- getClass "java.lang.ClassLoader"
+    getSystemClassLoader <- classLoader `bindStaticMethod` "getSystemClassLoader"
+        ::= object "java.lang.ClassLoader"
+    (Just systemClassLoader) <- getSystemClassLoader
+    (Just loadClass) <- classLoader `getMethod` "loadClass"
+        ::= string --> boolean --> object "java.lang.Class"
+
+    let findParentClasses :: JObject -- of type java.lang.Class
+                          -> Java [JObject]
+        findParentClasses clazz = do
+            parent <- getSuperclass clazz
+            case parent of
+                (Just parent) -> do
+                    parents <- findParentClasses parent
+                    return $ parent : parents
+                _ -> return []
+        
+        reflectType :: JObject -- of type java.lang.Class
+                    -> Java (Maybe JavaType)
+        reflectType javatype = do
+
+            isActuallyPrimitive <- isPrimitive javatype
+            isActuallyAnArray   <- isArray javatype
+            
+            case undefined of
+                _ | isActuallyPrimitive -> do
+                    stringRepresentation <- toString javatype
+                    return $ case stringRepresentation of
+                        "boolean" -> Just JBoolean 
+                        "char"    -> Just JChar
+                        "byte"    -> Just JByte
+                        "short"   -> Just JShort
+                        "int"     -> Just JInt
+                        "long"    -> Just JLong
+                        "float"   -> Just JFloat
+                        "double"  -> Just JDouble
+                        "void"    -> Nothing
+                        x -> error ("can't be: " ++ show x)  -- these are all primitive types
+
+                _ | isActuallyAnArray -> do
+                    (Just componentType) <- getComponentType javatype
+                    reflectType componentType >>= return . Just . JArr . fromJust
+
+                _otherwiseItsAnObjectType -> do
+                    (Just name) <- getName javatype
+
+                    return $ Just $ JObj {
+                        typeName = name
+                    }
+
+        reflectTypeParameter :: JObject -- of type java.lang.reflect.TypeVariable<?>
+                             -> Java JavaTypeParam
+        reflectTypeParameter typeParameter = do
+            
+            (Just name) <- getTypeVariableName typeParameter
+            (Just bounds) <- getTypeVariableBounds typeParameter
+
+            bounds' <- toList bounds
+                >>= mapM (reflectGenericType . fromJust)
+
+            return $ JavaTypeParam {
+                paramName = (TyVar name),
+                paramBounds = bounds'
+            }
+
+        reflectGenericType :: JObject -- of type java.lang.reflect.Type
+                           -> Java JavaGenericType
+        reflectGenericType genericType = do
+
+            isGenericArrayType  <- genericType `isInstanceOf` cGenArrT
+            isParameterizedType <- genericType `isInstanceOf` cParamT
+            isTypeVariable      <- genericType `isInstanceOf` cTypeV
+            isWildcardType      <- genericType `isInstanceOf` cWildT
+
+            case undefined of
+                _ | isGenericArrayType -> do
+                    (Just basetype) <- getGenericComponentType genericType
+                    reflectedType <- reflectGenericType basetype
+
+                    return $ GenericArray {
+                        jgtComponentType = reflectedType
+                    }
+
+                _ | isParameterizedType -> do
+                    (Just typeargs) <- getActualTypeArguments genericType
+                    (Just basetype) <- getRawType genericType
+                    isClass <- basetype `isInstanceOf` clazz
+                    basetypeName <- if isClass
+                        then getName basetype >>= return . fromJust
+                        else fail "Type parameterized on a type variable. That was not possible <= Java 8."
+
+                    parameters <- toList typeargs >>= mapM (reflectGenericType . fromJust)
+
+                    return $ Parameterized {
+                        jgtBasetype = basetypeName,
+                        jgtParameters = parameters
+                    }
+
+                _ | isTypeVariable -> do
+                    (Just name) <- getTypeVariableName genericType
+                    
+                    return $ TypeVarReference {
+                        jgtName = (TyVar name)
+                    }
+
+                _ | isWildcardType -> do
+                    (Just lowerBounds) <- getLowerBounds genericType
+                    (Just bounds) <- getUpperBounds genericType
+
+                    lowerBounds' <- toList lowerBounds
+                        >>= mapM (reflectGenericType . fromJust)
+                    bounds' <- toList bounds
+                        >>= mapM (reflectGenericType . fromJust)
+                    
+                    return $ Wildcard {
+                        jgtBounds = bounds',
+                        jgtLowerBounds = lowerBounds'
+                    }
+
+                _ -> getName genericType >>= return . NotSoGeneric . fromJust
+                    
+
+        reflectEnumConstant :: JObject -- of type java.lang.Enum
+                            -> Java (Int32, String)
+        reflectEnumConstant enumConstant = do
+            (Just name) <- getEnumName enumConstant
+            ordinal     <- getEnumOrdinal enumConstant
+            return (ordinal, name)
+
+        reflectConstructor :: JObject -- of type java.lang.reflect.Constructor
+                           -> Java JavaConstructor
+        reflectConstructor constructor = do
+
+            parameters <- getParameters' constructor
+                >>= maybe (return []) toList
+                >>= mapM (fmap fromJust . reflectType . fromJust)
+
+            genericParams <- getGenericParametersC constructor
+                >>= maybe (return []) toList
+                >>= mapM (reflectGenericType . fromJust)
+
+            typeParams <- getTypeParametersC constructor
+                >>= maybe (return []) toList
+                >>= mapM (reflectTypeParameter . fromJust)
+
+            return $ JavaConstructor {
+                constructorParams = parameters,
+                constructorGenericParams = genericParams,
+                constructorTypeParams = typeParams
+            }
+
+        reflectMethod :: JObject -- of type java.lang.reflect.Method
+                      -> Java JavaMethod
+        reflectMethod method = do
+
+            (Just name) <- getMethodName method
+            modifiers <- getModifiersM method
+
+            returnType <- getReturnType method
+                >>= maybe (return Nothing) reflectType
+
+            parameters <- getParameters method
+                >>= maybe (return []) toList
+                >>= mapM (fmap fromJust . reflectType . fromJust)
+
+            genericParams <- getGenericParametersM method
+                >>= maybe (return []) toList
+                >>= mapM (reflectGenericType . fromJust)
+
+            genericReturnType <- getGenericReturnType method
+                >>= reflectGenericType . fromJust
+                            
+            typeParams <- getTypeParametersM method
+                >>= maybe (return []) toList
+                >>= mapM (reflectTypeParameter . fromJust)
+
+            isActuallyStatic   <- isStatic modifiers
+            isActuallyAbstract <- isAbstract modifiers
+            isActuallyPublic   <- isPublic modifiers
+            isActuallyFinal    <- isFinal modifiers
+            isActuallyNative   <- isNative modifiers
+            isActuallySynchronized <- isSynchronized modifiers
+
+            return $ JavaMethod {
+                methodName = name,
+                methodName' = "", -- filled in later on
+                methodParams = parameters,
+                methodReturnType = returnType,
+                methodGenericParams = genericParams,
+                methodGenericReturnType = genericReturnType,
+                methodTypeParams = typeParams,
+                methodStatic = isActuallyStatic,
+                methodAbstract = isActuallyAbstract,
+                methodPublic = isActuallyPublic,
+                methodFinal = isActuallyFinal,
+                methodNative = isActuallyNative,
+                methodSynchronized = isActuallySynchronized
+            }
+
+        reflectClass :: String -> Java JavaClass
+        reflectClass className = do
+            
+            (Just clazz) <- callMethod loadClass systemClassLoader className False
+            modifiers <- getModifiersC clazz
+
+            isActuallyAbstract <- isAbstract modifiers
+            isActuallyFinal <- isFinal modifiers
+
+            let name        = takeClassName   className
+                packageName = takePackageName className
+            
+            parents <- asObject clazz
+                >>= findParentClasses
+                >>= mapM (fmap fromJust . getName)
+
+            interfaces <- asObject clazz
+                >>= getInterfaces
+                >>= maybe (return []) toList
+                >>= mapM (getName . maybe undefined id)
+                >>= mapM (maybe undefined return)
+
+            methods <- asObject clazz
+                >>= getMethods
+                >>= maybe (return []) toList
+                >>= mapM (maybe undefined reflectMethod)
+
+            constructors <- asObject clazz
+                >>= getConstructors
+                >>= maybe (return []) toList
+                >>= mapM (maybe undefined reflectConstructor)
+
+            parameters <- asObject clazz
+                >>= getTypeParameters
+                >>= maybe (return []) toList
+                >>= mapM (maybe undefined reflectTypeParameter)
+
+            enumConstants <- asObject clazz
+                >>= getEnumConstants
+                >>= maybe (return []) toList
+                >>= mapM (maybe undefined reflectEnumConstant)
+
+            isActuallyEnum  <- asObject clazz >>= isEnum
+            isActuallyIface <- asObject clazz >>= isInterface
+            isActuallyAnn   <- asObject clazz >>= isAnnotation
+
+            return $ JavaClass {
+                className = name,
+                classPackage = packageName,
+                classModName = "", -- is filled in later
+                classMethods = methods,
+                classParents = parents,
+                classIfaces = interfaces,
+                classConstructors = constructors,
+                classTypeParams = parameters,
+                classEnum = isActuallyEnum,
+                classEnumConstants = enumConstants,
+                classIface = isActuallyIface,
+                classAnnotation = isActuallyAnn,
+                classAbstract = isActuallyAbstract,
+                classFinal = isActuallyFinal
+            }
+
+    mapM reflectClass classes
+
diff --git a/src/Foreign/Java/Bindings/Support.cpphs b/src/Foreign/Java/Bindings/Support.cpphs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/Support.cpphs
@@ -0,0 +1,356 @@
+{-# LANGUAGE Haskell2010
+    , TypeFamilies
+    , FlexibleContexts
+    , FlexibleInstances
+    , TypeSynonymInstances
+ #-}
+{-# OPTIONS
+    -Wall
+ #-}
+
+-- |
+-- Module       : Foreign.Java.Bindings.Support
+-- Copyright    : (c) Julian Fleischer 2013
+-- License      : MIT (See LICENSE file in cabal package)
+--
+-- Maintainer   : julian.fleischer@fu-berlin.de
+-- Stability    : experimental
+-- Portability  : non-portable (TypeFamilies)
+--
+-- This module provides type classes and instances for
+-- supporting the high level bindings. This module should
+-- not be imported directly.
+module Foreign.Java.Bindings.Support where
+
+import Control.Monad.State hiding (void)
+
+import Data.Int
+import Data.Word
+import Data.Maybe
+
+import Foreign.Ptr
+import Foreign.ForeignPtr
+import Foreign.C.Types
+
+import Foreign.Java
+import Foreign.Java.JavaMonad
+import Foreign.Java.Types as T
+import qualified Foreign.Java.JNI.Safe as JNI
+import qualified Foreign.Java.JNI.Types as Core
+
+
+---------------
+-- Utilities --
+---------------
+
+
+object' :: String -> Q
+object' = T.object'
+
+
+------------------------------
+-- Primitive argument types --
+------------------------------
+
+class JBoolean a  where toBoolean :: a -> Java Bool
+class JChar a     where toChar    :: a -> Java Word16
+class JByte a     where toByte    :: a -> Java Int8
+class JShort a    where toShort   :: a -> Java Int16
+class JInt a      where toInt     :: a -> Java Int32
+class JLong a     where toLong    :: a -> Java Int64
+class JFloat a    where toFloat   :: a -> Java Float
+class JDouble a   where toDouble  :: a -> Java Double
+
+
+instance JBoolean Bool   where toBoolean = return
+
+instance JChar Char      where toChar = return . fromIntegral . fromEnum
+instance JChar Int8      where toChar = return . fromIntegral
+instance JChar Word16    where toChar = return
+
+instance JByte Int8      where toByte = return
+
+instance JShort Int8     where toShort = return . fromIntegral
+instance JShort Word8    where toShort = return . fromIntegral
+instance JShort Int16    where toShort = return
+
+instance JInt Int        where toInt = return . fromIntegral
+instance JInt Int8       where toInt = return . fromIntegral
+instance JInt Word8      where toInt = return . fromIntegral
+instance JInt Int16      where toInt = return . fromIntegral
+instance JInt Word16     where toInt = return . fromIntegral
+instance JInt Int32      where toInt = return
+
+instance JLong Int       where toLong = return . fromIntegral
+instance JLong Int8      where toLong = return . fromIntegral
+instance JLong Word8     where toLong = return . fromIntegral
+instance JLong Int16     where toLong = return . fromIntegral
+instance JLong Word16    where toLong = return . fromIntegral
+instance JLong Int32     where toLong = return . fromIntegral
+instance JLong Word32    where toLong = return . fromIntegral
+instance JLong Int64     where toLong = return
+
+instance JFloat CFloat   where toFloat = return . realToFrac
+instance JFloat Float    where toFloat = return
+
+instance JDouble CDouble where toDouble = return . realToFrac
+instance JDouble Double  where toDouble = return
+
+
+--------------------------
+-- Array argument types --
+--------------------------
+
+class Array a where
+    asMaybeArrayObject :: a -> Java (Maybe JObject)
+
+
+----------------------------
+-- Primitive result types --
+----------------------------
+
+#define PRIMITIVE_RESULT(NAME, TYPE) \
+    class NAME ## Result m where {\
+        to ## NAME ## Result :: Either JThrowable TYPE -> Java m }\
+    ;\
+    instance NAME ## Result TYPE where {\
+        to ## NAME ## Result = either (\exc -> toString exc >>= fail) return }\
+    ;\
+    instance NAME ## Result (Either JThrowable TYPE) where {\
+        to ## NAME ## Result = return }
+
+-- | The result of a function call that is of type @boolean@.
+PRIMITIVE_RESULT(Boolean, Bool)
+-- | The result of a function call that is of type @char@.
+PRIMITIVE_RESULT(Char, Word16)
+-- | The result of a function call that is of type @byte@.
+PRIMITIVE_RESULT(Byte, Int8)
+-- | The result of a function call that is of type @short@.
+PRIMITIVE_RESULT(Short, Int16)
+-- | The result of a function call that is of type @int@.
+PRIMITIVE_RESULT(Int, Int32)
+-- | The result of a function call that is of type @long@.
+PRIMITIVE_RESULT(Long, Int64)
+-- | The result of a function call that is of type @float@.
+PRIMITIVE_RESULT(Float, Float)
+-- | The result of a function call that is of type @double@.
+PRIMITIVE_RESULT(Double, Double)
+
+-- | The result of a function call that is of type @void@.
+class VoidResult m where
+    toVoidResult :: Either JThrowable () -> Java m
+    
+instance VoidResult () where
+    toVoidResult = either (\exc -> toString exc >>= fail) return
+
+instance VoidResult (Either JThrowable ()) where
+    toVoidResult = return
+    
+instance VoidResult (Maybe JThrowable) where
+    toVoidResult = return . either Just (const Nothing)
+
+
+------------------------
+-- Array result types --
+------------------------
+
+-- | An array result of a function call.
+class JavaArray (ArrayResultType m) (ArrayResultComponent m) => ArrayResult m where
+    -- | The JVM machine type of the components of the array.
+    type ArrayResultType m
+
+    -- | The type of the component of the array as returned by
+    -- the low level JNI call.
+    type ArrayResultComponent m
+
+    -- | Convert the array to a sophisticated type.
+    toArrayResult :: Either JThrowable (Maybe (JArray (ArrayResultType m))) -> Java m
+
+instance ArrayResult a => ArrayResult (Either JThrowable a) where
+    type ArrayResultType (Either JThrowable a) = ArrayResultType a
+    type ArrayResultComponent (Either JThrowable a) = ArrayResultComponent a
+
+    toArrayResult = either (return . Left) (toArrayResult . Right)
+
+#define ARRAY_RESULT(TYPE, PRIM) \
+    instance ArrayResult [TYPE] where {\
+        type ArrayResultType [TYPE] = T.PRIM ;\
+        type ArrayResultComponent [TYPE] = TYPE ;\
+        \
+        toArrayResult = either (\exc -> toString exc >>= fail) \
+                               (maybe (return []) toList) }
+
+ARRAY_RESULT(Bool,   Z)
+ARRAY_RESULT(Word16, C)
+ARRAY_RESULT(Int8,   B)
+ARRAY_RESULT(Int16,  S)
+ARRAY_RESULT(Int32,  I)
+ARRAY_RESULT(Int64,  J)
+ARRAY_RESULT(Float,  F)
+ARRAY_RESULT(Double, D)
+
+
+instance ArrayResult [Char] where
+    type ArrayResultType [Char] = T.C
+    type ArrayResultComponent [Char] = Word16
+
+    toArrayResult = either (\exc -> toString exc >>= fail)
+                           (maybe (return [])
+                                  (fmap (map (toEnum . fromIntegral)) . toList))
+
+instance ArrayResult [String] where
+    type ArrayResultType [String] = T.L
+    type ArrayResultComponent [String] = Maybe JObject
+
+    toArrayResult =
+        either (\exc -> toString exc >>= fail)
+               (maybe (return [])
+                      (\arr -> toList arr >>= mapM (maybe (return "") toString)))
+
+
+
+-----------------------
+-- All other objects --
+-----------------------
+
+
+-- | The result of a function call that is of type @object@.
+class ObjectResult m where
+    -- | 
+    toObjectResult :: Either JThrowable (Maybe JObject) -> Java m
+
+instance UnsafeCast a => ObjectResult (Value JThrowable a) where
+    toObjectResult = either (return . Fail)
+                            (maybe (return NoValue)
+                                   (fmap Value . unsafeFromJObject))
+
+instance UnsafeCast a => ObjectResult (Either (Maybe JThrowable) a) where
+    toObjectResult = either (return . Left . Just)
+                            (maybe (return (Left Nothing))
+                                   (fmap Right . unsafeFromJObject))
+
+instance UnsafeCast a => ObjectResult (Either JThrowable (Maybe a)) where
+    toObjectResult = either (return . Left)
+                            (fmap Right . maybe (return Nothing)
+                                                (fmap Just . unsafeFromJObject))
+
+instance UnsafeCast a => ObjectResult (Maybe a) where
+    toObjectResult = either (\exc -> toString exc >>= fail)
+                            (maybe (return Nothing)
+                                   (fmap Just . unsafeFromJObject))
+
+instance ObjectResult [Char] where
+    toObjectResult = either (\exc -> toString exc >>= fail)
+                            (maybe (return "null") toString)
+
+
+---------------------------------------------------
+-- Advanced features (Callbacks, Subtyping, ...) --
+---------------------------------------------------
+
+
+-- | A convenient alternative to 'isInstanceOf'.
+--
+-- Minimal complete definition: 'coerce' or 'whenInstanceOf'.
+class InstanceOf a where
+    type CoercedType a
+
+    -- | Check if the object of type @a@ is an instance
+    -- of the type represented by @b@. 
+    instanceOf :: JavaObject o => o -> a -> Java Bool
+
+    -- | Check if the object of type @a@ is an instance
+    -- of the type @c@, represented by @b@. If so, it will coerce
+    -- the object of type @a@ and pass it to the given action.
+    --
+    -- If @a@ was an instance of @c@ (where @c@ is represented
+    -- by @b@) this function will return @'Just' d@, where @d@ is
+    -- the result of the optional computation. If not, 'Nothing'
+    -- is returned.
+    whenInstanceOf :: JavaObject o => o -> a -> (CoercedType a -> Java d) -> Java (Maybe d)
+
+    -- | Coerces the given object of type @a@ to an object of
+    -- @c@, where @c@ is represented by a value of type @b@.
+    -- Returns @'Nothing'@ if this is not possible.
+    coerce :: JavaObject o => o -> a -> Java (Maybe (CoercedType a))
+
+    instanceOf o t =
+        whenInstanceOf o t (return . const ())
+            >>= return . maybe False (const True)
+
+    whenInstanceOf o t a =
+        coerce o t >>= maybe (return Nothing) (fmap Just . a)
+
+    coerce o t = whenInstanceOf o t return
+
+-- | For INTERNAL use only. Is however not in a hidden module,
+-- so that other libraries can link against it.
+class UnsafeCast a where
+    -- | For INTERNAL use only. Do not use yourself.
+    unsafeFromJObject :: JObject -> Java a
+
+
+
+---------------
+-- Callbacks --
+---------------
+
+
+registerCallbacks :: Core.JClass -> Java Bool
+-- ^ Yepp. Register callbacks. Do it.
+registerCallbacks (Core.JClass ptr) = do
+    vm <- getVM
+    io $ withForeignPtr ptr $ \clazz -> JNI.registerCallbacks vm clazz
+
+
+type WrappedFun = Ptr Core.JVM
+               -> Ptr Core.JObjectRef
+               -> Ptr Core.JObjectRef
+               -> Ptr Core.JObjectRef
+               -> IO (Ptr Core.JObjectRef)
+
+
+runJava_ :: Ptr Core.JVM -> Java a -> IO a
+runJava_ vm f = runStateT (_runJava f) (newJVMState vm) >>= return . fst
+
+foreign import ccall safe "wrapper"
+    wrap_ :: WrappedFun -> IO (FunPtr WrappedFun)
+
+foreign export ccall freeFunPtr :: FunPtr WrappedFun -> IO ()
+
+freeFunPtr :: FunPtr WrappedFun -> IO ()
+freeFunPtr ptr = freeHaskellFunPtr ptr
+
+
+wrap :: Java () -> IO (FunPtr WrappedFun)
+wrap f = do
+
+    let func vm _self _method _args = do
+            runJava_ vm f
+            return nullPtr
+            
+    func' <- wrap_ func
+
+    return func'
+
+intify :: Java () -> IO Int64
+intify = fmap (fromIntegral . ptrToIntPtr . castFunPtrToPtr) . wrap
+
+
+sushimaki :: String -> Java () -> Java JObject
+sushimaki ifaceName func = do
+    iface <- getClass ifaceName >>= asObject . fromJust
+    (Just clazz) <- getClass "HFunction"
+    _success <- registerCallbacks clazz
+    makeFunction <- clazz `bindStaticMethod` "makeFunction"
+        ::= object "java.lang.Class" --> long --> object "java.lang.Object"
+    (Just impl) <- io (intify func) >>= makeFunction (Just iface)
+    return impl
+
+
+delete :: Core.JObject -> Java ()
+delete (Core.JObject ptr) = io $ do
+    finalizeForeignPtr ptr
+
+
+
diff --git a/src/Foreign/Java/Bindings/Typomatic.hs b/src/Foreign/Java/Bindings/Typomatic.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Bindings/Typomatic.hs
@@ -0,0 +1,400 @@
+{-# LANGUAGE Haskell2010
+    , GeneralizedNewtypeDeriving
+    , DeriveDataTypeable
+ #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-name-shadowing
+ #-}
+
+-- | INTERNAL module is used to infer Haskell types from Java types.
+module Foreign.Java.Bindings.Typomatic (
+    runTypomatic,
+    typomatic,
+    ArgInfo (..),
+
+    dataTName,
+    dataCName,
+    newtTName,
+    newtCName,
+    tyclTName
+) where
+
+import Foreign.Java.Util
+-- import Foreign.Java.Utils
+import Foreign.Java.Bindings.JavaTypes
+
+import Control.Monad.State hiding (void)
+import qualified Control.Monad.State as State
+import Data.Functor.Identity
+import Data.Functor ((<$>))
+
+import Data.Generics
+
+import qualified Data.Set as Set
+import Data.Set (Set)
+import qualified Data.Map as Map
+import Data.Map (Map)
+import qualified Data.List as List
+
+dataTName, dataCName, newtTName, newtCName, tyclTName :: String -> String
+
+dataTName = (++ "''")
+dataCName = id -- (++ "")
+newtTName = (++ "'")
+newtCName = (++ "'")
+tyclTName = id -- (++ "")
+
+-- | This is the information which is ultimately
+-- gathered by the use of this module.
+data ArgInfo = ArgInfo {
+    fSignature :: String,
+    fArguments :: [TVar],
+    fReturnType :: TVar,
+    fArgNames :: [String],
+    fJavaSignature :: String,
+    fJavaReturnType :: String,
+    fJniSignature :: String
+  }
+
+
+--------------------
+-- Type variables --
+--------------------
+
+data TVar = TVar String | TVars [TVar]
+    deriving (Eq, Ord, Show, Data, Typeable)
+
+printTVar :: TVar -> String
+printTVar var = case var of
+    (TVar v) -> v
+    (TVars vs) -> concat ["(", tail (concatMap ((' ':) . printTVar) vs), ")"]
+
+
+---------------
+-- Utilities --
+---------------
+
+printJniType :: JavaType -> String
+printJniType t = case t of
+    JBoolean -> "JNI.boolean"
+    JChar    -> "JNI.char"
+    JByte    -> "JNI.byte"
+    JShort   -> "JNI.short"
+    JInt     -> "JNI.int"
+    JLong    -> "JNI.long"
+    JFloat   -> "JNI.float"
+    JDouble  -> "JNI.double"
+    JObj n   -> "JNI.object \"" ++ n ++ "\""
+    -- arrays are treated as objects:
+    JArr c   -> "JNIS.object' \"[" ++ printJniRawType c ++ "\""
+
+
+printJniRawType :: JavaType -> String
+printJniRawType t = case t of
+    JBoolean -> "Z"
+    JChar    -> "C"
+    JByte    -> "B"
+    JShort   -> "S"
+    JInt     -> "I"
+    JLong    -> "J"
+    JFloat   -> "F"
+    JDouble  -> "D"
+    JObj n   -> 'L' : tr '.' '/' n ++ ";"
+    JArr c   -> '[' : printJniRawType c
+
+
+printJniSignature :: JavaMethod -> String
+printJniSignature method = show name ++ " JNI.::= " ++ args ++ ret
+  where
+    name = methodName method
+    args = concatMap ((++ " --> ") . printJniType) (methodParams method)
+    ret  = maybe "JNI.void" printJniType (methodReturnType method)
+
+
+
+typomatic :: JavaClass -> JavaMethod -> Typomatic ArgInfo
+typomatic clazz method_ = do
+
+    let className = classFullName clazz
+        classParams = classTypeParams clazz
+
+        -- sanitize tyVars tied to the method by distinguishing
+        -- from tyVars tied to the class by adding an apostrophe
+        -- to the name of the tyVar if it is tied to the method.
+        methodTypeVars = map paramName (methodTypeParams method_)
+        safe var@(TyVar str)
+            | var `elem` methodTypeVars = TyVar (str ++ "'")
+            | otherwise = var
+        method = everywhere (mkT safe) method_
+
+        -- the following three functions create the list of
+        -- argument parameters, including @this@ (if the method
+        -- is not static) and the return type. The return type
+        -- is separated later on again.
+        thisParam = if null classParams
+            then NotSoGeneric className
+            else Parameterized {
+                    jgtBasetype = className,
+                    jgtParameters = (map (TypeVarReference . paramName) classParams)
+                  }
+        params = (if methodStatic method then [] else [thisParam])
+            ++ methodGenericParams method
+            ++ [maybe (TypeVarReference (TyVar "()"))
+                      (const $ methodGenericReturnType method)
+                      (methodReturnType method)]
+        jtypes = (if methodStatic method then [] else [JObj className])
+            ++ methodParams method
+
+        -- turns a JavaGenericType definition into type variables.
+        -- The names are taken from the monad via 'newVar'.
+        tvar param = case jgtType param of
+            WildcardT -> do
+                name <- newVar
+                return $ TVar name
+            ParameterizedT -> do
+                name <- newVar
+                params <- mapM tvar (jgtParameters param)
+                return $ TVars $ TVar name : params
+            GenericArrayT -> do
+                name <- newVar
+                return $ TVar name
+            TypeVarReferenceT -> do
+                let name = (tyVarName (jgtName param))
+                return $ TVar name
+            NotSoGenericT -> do
+                name <- newVar
+                return $ TVar name
+
+        -- creates a haskell signature (-> String)
+        signature typeVars returnVar = do
+            -- retrieve the context and turn each variable into a String.
+            contexts <- getContext >>= mapM (\(tvar, context) -> do
+                return $ context ++ " " ++ printTVar tvar)
+
+            let argTypes = concatMap ((++ " -> ") . printTVar) typeVars
+                -- the final type is wrapped in the Java monad
+                returnType = "JNI.Java " ++ printTVar returnVar
+                -- finally assemble the conetext.
+                context = if null contexts then "" else
+                    "(" ++ concat (List.intersperse ", " contexts) ++ ") => "
+            
+            -- return the full signature, consisting of the context,
+            -- the type of the arguments, and the return type.
+            return $ concat [context, argTypes, returnType]
+
+        -- create a java signature (-> String)
+        javaSignature = do
+            let name = methodName method
+                args = map printJavaType $ methodParams method
+            return $ name ++ "(" ++ concat (List.intersperse ", " args) ++ ")"
+            
+
+    -- if this is not a static method the first argument
+    -- is /this/. This merely pushed the name into the list
+    -- of type variable names in the monad.
+    when (not $ methodStatic method) (pushVar "this")
+
+    -- get type variables for all arguments, including the
+    -- return type (as the return type may be the same as
+    -- one of the argument types).
+    --
+    -- Split the result into arguments and return var again,
+    -- since the return variable will get special treatment
+    -- henceforth.
+    (typeVars, returnVar_) <- breakLast <$> mapM tvar params
+
+    -- augment the return type variable, i.e. if it is not
+    -- a type variable at all, replace the variable name by
+    -- a constant reference to a specific type.
+    --
+    -- This is only the case with parameterized type variables
+    -- and not-so-generic ones.
+    returnVar <- case methodReturnType method of
+        Just (JObj typeName) -> case jgtType (methodGenericReturnType method) of
+            ParameterizedT -> do
+                clazz <- getClass typeName
+                let (TVars (TVar _ : ts)) = returnVar_
+                return $ TVars (TVar (newtTName (classModName clazz)) : ts)
+            NotSoGenericT -> do
+                clazz <- getClass typeName
+                return $ TVar (newtTName (classModName clazz))
+            _ -> return returnVar_
+        _ -> return returnVar_
+
+    -- Add contexts for all arguments and augment array types
+    let makeContext typeVar jtype = case jtype of
+            JObj name -> do
+                clazz <- getClass name
+                addContext typeVar $ tyclTName $ classModName clazz
+                return typeVar
+            JArr componentType -> do
+                addContext typeVar "JNIS.Array"
+                return typeVar
+            JBoolean -> do
+                addContext typeVar "JNIS.JBoolean"
+                return typeVar
+            JChar -> do
+                addContext typeVar "JNIS.JChar"
+                return typeVar
+            JByte -> do
+                addContext typeVar "JNIS.JByte"
+                return typeVar
+            JShort -> do
+                addContext typeVar "JNIS.JShort"
+                return typeVar
+            JInt -> do
+                addContext typeVar "JNIS.JInt"
+                return typeVar
+            JLong -> do
+                addContext typeVar "JNIS.JLong"
+                return typeVar
+            JFloat -> do
+                addContext typeVar "JNIS.JFloat"
+                return typeVar
+            JDouble -> do
+                addContext typeVar "JNIS.JDouble"
+                return typeVar
+
+    -- Here makeContexts is applied (see above). In the same pass a new
+    -- set of typeVars (typeVars') is generated, since makeContexts
+    -- migth further investigate array and create type variables for
+    -- their component types.
+    typeVars' <- mapM (uncurry makeContext) (zip typeVars jtypes)
+
+    -- Create contexts for the ultimate return type.
+    returnVar' <- case methodReturnType method of
+            Nothing -> do
+                let tvar = TVar "void"
+                addContext tvar "JNIS.VoidResult"
+                return tvar
+            Just t -> case t of
+                JObj _   -> do
+                    let tvar = TVars [TVar "object", returnVar]
+                    addContext tvar "JNIS.ObjectResult"
+                    return tvar
+                JArr _   -> do
+                    let tvar = TVar "array"
+                    addContext tvar "JNIS.ArrayResult"
+                    return tvar
+                JBoolean -> do
+                    let tvar = TVar "boolean"
+                    addContext tvar "JNIS.BooleanResult"
+                    return tvar
+                JChar    -> do
+                    let tvar = TVar "char"
+                    addContext tvar "JNIS.CharResult"
+                    return tvar
+                JByte    -> do
+                    let tvar = TVar "byte"
+                    addContext tvar "JNIS.ByteResult"
+                    return tvar
+                JShort   -> do
+                    let tvar = TVar "short"
+                    addContext tvar "JNIS.ShortResult"
+                    return tvar
+                JInt     -> do
+                    let tvar = TVar "int"
+                    addContext tvar "JNIS.IntResult"
+                    return tvar
+                JLong    -> do
+                    let tvar = TVar "long"
+                    addContext tvar "JNIS.LongResult"
+                    return tvar
+                JFloat   -> do
+                    let tvar = TVar "float"
+                    addContext tvar "JNIS.FloatResult"
+                    return tvar
+                JDouble  -> do
+                    let tvar = TVar "double"
+                    addContext tvar "JNIS.DoubleResult"
+                    return tvar
+
+    -- generate the Haskell signature (a String)
+    sig <- signature typeVars' returnVar'
+
+    -- generate the Java signature (a String).
+    -- This is used for documentation purposed later on
+    -- (i.e. inserted as haddock docstring).
+    jsig <- javaSignature
+
+    -- generate the names of the arguments
+    let argNames = (if methodStatic method then id else ("this":) . init)
+            $ zipWith (\_ i -> 'a' : show i) typeVars [(1 :: Integer)..]
+
+    -- assemble and return all the calculated information
+    return $ ArgInfo {
+        fArguments  = typeVars,
+        fReturnType = returnVar',
+        fArgNames   = argNames,
+        fSignature  = sig,
+        fJavaSignature = jsig,
+        fJavaReturnType = maybe "void" printJavaType (methodReturnType method),
+        fJniSignature = printJniSignature method
+      }
+
+--------------------------------------------
+-- The following are utilities for the monad
+--------------------------------------------
+
+-- | The state of the monad.
+data TypomaticState = TypomaticState {
+    tVars :: [String],
+    tContext :: Set (TVar, String),
+    tParams :: [String],
+    tClasses :: Map String JavaClass
+  }
+
+-- | Retrieve the definition of a class.
+--
+-- The monad has an internal store of class names
+-- and their definitions. See 'tClasses'.
+getClass :: String -> Typomatic JavaClass
+getClass name = do
+    state <- State.get
+    return ((tClasses state) Map.! name)
+
+-- | Get the current context as a list.
+getContext :: Typomatic [(TVar, String)]
+getContext = State.get >>= return . Set.toList . tContext
+
+-- | Add a context for a specific type variable.
+addContext :: TVar -> String -> Typomatic ()
+addContext tvar string = do
+    state <- State.get
+    State.put (state {tContext = ((tvar, string) `Set.insert` tContext state)})
+
+-- | Introduce a new name.
+--
+-- This simply takes the next element in the infinite
+-- 'tVars' list and stores the tail back in the monad.
+newVar :: Typomatic String
+newVar = do
+    state <- State.get
+    let (v:vs) = tVars state
+    State.put (state { tVars = vs})
+    return v
+
+-- | Push a new name in the front of the available names.
+pushVar :: String -> Typomatic ()
+pushVar name = do
+    state <- State.get
+    State.put (state {tVars = (name : tVars state)})
+
+-- | The monad.
+newtype Typomatic a = Typomatic { _runTypomatic :: StateT TypomaticState Identity a }
+    deriving (Monad, MonadState TypomaticState, Functor)
+
+-- | Run a computation in the monad.
+runTypomatic :: Map String JavaClass -> Typomatic a -> a
+runTypomatic classes =
+    let state = TypomaticState { -- initial state
+        tVars = map (('v':) . show) [(1 :: Integer)..],
+        tContext = Set.empty,
+        tParams = [],
+        tClasses = classes
+    } in fst . runIdentity . flip runStateT state . _runTypomatic
+
+
+
+
diff --git a/src/Foreign/Java/Control.hs b/src/Foreign/Java/Control.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Control.hs
@@ -0,0 +1,51 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# OPTIONS -Wall #-}
+
+-- | Utilities for controlling actions inside the Java monad.
+module Foreign.Java.Control where
+
+import Prelude hiding (pred, until)
+
+when :: Monad m => m Bool -> m () -> m ()
+-- ^ Execute an action if the given predicate
+-- evaluates to 'True'.
+when pred action = pred >>= (\p -> if p then action else return ())
+
+unless :: Monad m => m Bool -> m () -> m ()
+-- ^ Execute an action if the given predicate
+-- evaluates to 'False'.
+unless pred action = pred >>= (\p -> if not p then action else return ())
+
+whether :: Monad m => m Bool -> m a -> m a -> m a
+-- ^ Execute either the first or the second action,
+-- depending on whether the given predicate evaluates
+-- to 'True' or 'False'.
+whether pred actionIf actionElse = do
+    cond <- pred
+    if cond then actionIf else actionElse
+
+while :: Monad m => m Bool -> m () -> m ()
+-- ^ Run a computation as long as the given predicate
+-- evaluates to 'True'.
+while pred action = do
+    cond <- pred
+    if cond then action >> while pred action
+            else return ()
+
+for :: Monad m => a -> (a -> m Bool) -> (a -> m a) -> m a
+-- ^ Reiterate a computation on a given value as long
+-- as a condition is 'True'.
+for i pred action = do
+    continue <- pred i
+    if continue then action i >>= (\i' -> for i' pred action)
+                else return i
+
+until :: Monad m => a -> (a -> m (Bool, a)) -> m a
+-- ^ Reiterate a computation on a given value until
+-- a condition is 'True'.
+until i action = do
+    (done, result) <- action i
+    if done then return result
+             else until result action
+
+
diff --git a/src/Foreign/Java/IO.hs b/src/Foreign/Java/IO.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/IO.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE Haskell2010
+    , TypeSynonymInstances
+    , FlexibleInstances
+    , UndecidableInstances
+    , OverlappingInstances
+ #-}
+{-# OPTIONS -Wall #-}
+
+-- | 
+-- Module       : Foreign.Java.IO
+-- Copyright    : (c) Julian Fleischer 2013
+-- License      : MIT (See LICENSE file in cabal package)
+--
+-- Maintainer   : julian.fleischer@fu-berlin.de
+-- Stability    : provisional
+-- Portability  : non-portable (UndecidableInstances, OverlappingInstances)
+--
+-- Utilities to ease IO operations in the Java monad.
+module Foreign.Java.IO where
+
+import Prelude hiding (print)
+import Control.Monad.IO.Class
+import System.IO hiding (print)
+
+
+class PrintLn a where
+    -- | Like @'putStrLn' . 'show'@, but with a specialized
+    -- version for Strings plus it can be used within any
+    -- 'MonadIO' monad (such as IO and Java).
+    println :: MonadIO m => a -> m ()
+
+    -- | Like @'putStr' . 'show'@, but with a specialized
+    -- version for Strings plus it can be used within any
+    -- 'MonadIO' monad (such as IO and Java).
+    print :: MonadIO m => a -> m ()
+
+instance  PrintLn String where
+    println = liftIO . putStrLn
+    print x = liftIO (putStr x >> hFlush stdout)
+
+instance Show a => PrintLn a where
+    println = println . show
+    print = print . show
+
diff --git a/src/Foreign/Java/JNI/Types.hs b/src/Foreign/Java/JNI/Types.hs
--- a/src/Foreign/Java/JNI/Types.hs
+++ b/src/Foreign/Java/JNI/Types.hs
@@ -10,21 +10,6 @@
 
 import Foreign (ForeignPtr)
 
-data Z = Z deriving Show
-data C = C deriving Show
-data B = B deriving Show
-data S = S deriving Show
-data I = I deriving Show
-data J = J deriving Show
-data F = F deriving Show
-data D = D deriving Show
-data L = L String deriving Show
-data V = V deriving Show
-data A x = A x deriving Show
-data X = X deriving Show
-
-data Q = Q String deriving Show
-
 data JVM
 data JObjectRef
 data JClassRef
diff --git a/src/Foreign/Java/JNI/core.hs b/src/Foreign/Java/JNI/core.hs
--- a/src/Foreign/Java/JNI/core.hs
+++ b/src/Foreign/Java/JNI/core.hs
@@ -47,18 +47,6 @@
 getConstructorID,
 newObject,
 
--- ** Array creation
-
-newBooleanArray,
-newCharArray,
-newLongArray,
-newIntArray,
-newShortArray,
-newByteArray,
-newFloatArray,
-newDoubleArray,
-newObjectArray,
-
 -- * Method access
 
 JStaticMethodID,
@@ -224,11 +212,6 @@
 setLibjvmPath,
 registerCallbacks,
 
--- * Primitive types
-
-Z (Z), C (C), B (B), S (S), I (I), J (J),
-D (D), F (F), L (L), V (V), A (A), X (X),
-
 -- * Workarounds for certain platforms
 
 runCocoaMain
@@ -534,33 +517,6 @@
 foreign import ccall %SAFETY% "ffijni.h setJValueString"
     setJValueString :: Ptr JVM -> Ptr JValues -> CInt -> CString -> IO ()
 
-foreign import ccall %SAFETY% "ffijni.h newBooleanArray"
-    newBooleanArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newCharArray"
-    newCharArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newLongArray"
-    newLongArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newIntArray"
-    newIntArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newShortArray"
-    newShortArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newByteArray"
-    newByteArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newFloatArray"
-    newFloatArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newDoubleArray"
-    newDoubleArray :: Ptr JVM -> Int32 -> Ptr JObjectRef
-
-foreign import ccall %SAFETY% "ffijni.h newObjectArray"
-    newObjectArray :: Ptr JVM -> Int32 -> Ptr JClass -> Ptr JObjectRef
-
 foreign import ccall %SAFETY% "ffijni.h newJString"
     newJString :: Ptr JVM -> CString -> IO (Ptr JObjectRef)
 
@@ -675,7 +631,7 @@
 foreign import ccall %SAFETY% "ffijni.h getDebugStatus"
     getDebugStatus :: IO Bool
 
-foreign import ccall %SAFETY% "ffijni.h setDebugStatus"
+foreign import ccall %SAFETY% "ffijni.g setDebugStatus"
     setDebugStatus :: Bool -> IO ()
 
 foreign import ccall %SAFETY% "ffijni.h runCocoaMain"
diff --git a/src/Foreign/Java/JavaMonad.hs b/src/Foreign/Java/JavaMonad.hs
--- a/src/Foreign/Java/JavaMonad.hs
+++ b/src/Foreign/Java/JavaMonad.hs
@@ -144,7 +144,7 @@
 -- Use one of 'runJava' or 'runJava'' to perform operations in the
 -- Java monad.
 newtype Java a = Java { _runJava :: StateT JVMState IO a }
-  deriving (Monad, MonadState JVMState, Functor, MonadIO)
+    deriving (Monad, MonadState JVMState, Functor, MonadIO)
 
 -- | INTERNAL Retrieve the 'jvmPtr' from this Java Monads
 -- State.
diff --git a/src/Foreign/Java/Maybe.hs b/src/Foreign/Java/Maybe.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Maybe.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# OPTIONS
+    -Wall
+    -fno-warn-orphans
+ #-}
+
+-- |
+-- Module       : Foreign.Java.Maybe
+-- Copyright    : (c) Julian Fleischer 2013
+-- License      : MIT (See LICENSE file in cabal package)
+--
+-- Maintainer   : julian.fleischer@fu-berlin.de
+-- Stability    : provisional
+-- Portability  : portable (Haskell2010)
+--
+-- Every java methods returns in priniciple either Nothing or
+-- Just a value. This is quite cumbersome to work with. This module
+-- contains utility functions for working with Maybe values in the
+-- java monad.
+--
+-- This module offers the orphan instance (!)
+--
+-- > instance JavaObject a => JavaObject (Maybe a)
+--
+-- This instance allows you to apply 'toString' and the like
+-- without unwrapping a 'Maybe' value.
+--
+-- Note that the 'asObject' function provided by this instance
+-- is undefined (since @null@ is not an object). This is also the
+-- reason why this instance is not included in "Foreign.Java" by
+-- default. Invoking it will call @error "NullPointerException"@.
+-- In other words: This fine module will bring back all the joy of
+-- Java you might miss in Haskell :-)
+--
+-- 'toString' will return @null@ for @Nothing@.
+--
+-- 'hashCode' will return @0@ for @Nothing@.
+--
+-- 'classOf' will return the class for @java.lang.Void@ on @Nothing@,
+-- as this is a class for which there gare no object instances. This is
+-- only a stopgap and slightly incorrect, as null is not an object,
+-- and does therefor not have a class.
+module Foreign.Java.Maybe where
+
+
+import Foreign.Java
+
+
+instance JavaObject a => JavaObject (Maybe a) where
+
+    toString m = case m of
+        Just obj -> toString obj
+        Nothing -> return "null"
+
+    hashCode m = case m of
+        Just obj -> hashCode obj
+        Nothing -> return 0
+
+    asObject m = case m of
+        Just obj -> asObject obj
+        Nothing -> error "NullPointerException"
+
+    classOf m = case m of
+        Just obj -> classOf obj
+        Nothing -> getClass "java.lang.Void" >>= classOf
+
+
diff --git a/src/Foreign/Java/Tutorial.hs b/src/Foreign/Java/Tutorial.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Java/Tutorial.hs
@@ -0,0 +1,52 @@
+module Foreign.Java.Tutorial (
+
+-- * High level bindings
+-- $highLevelBindings
+
+-- ** Generating the bindings
+-- $generatingTheBindings
+
+-- ** Using the bindings
+-- $usingTheBindings
+
+-- ** Calling back into Haskell
+-- $callingBackIntoHaskell
+
+-- * Medium level bindings
+-- $mediumLevelBindings
+
+-- * Low level bindings
+-- $lowLevelBindings
+) where
+
+{- $java2haskell
+
+-}
+
+{- $highLevelBindings
+
+-}
+
+{- $generatingTheBindings
+
+-}
+
+{- $usingTheBindings
+
+-}
+
+{- $mediumLevelBindings
+
+    "Foreign.Java"
+
+-}
+
+{- $lowLevelBindings
+
+    "Foreign.Java.JNI.Safe", "Foreign.Java.JNI.Unsafe"
+
+-}
+
+{- $callingBackIntoHaskell
+
+-}
diff --git a/src/Foreign/Java/Types.hs b/src/Foreign/Java/Types.hs
--- a/src/Foreign/Java/Types.hs
+++ b/src/Foreign/Java/Types.hs
@@ -61,6 +61,20 @@
 import qualified Foreign.Java.JNI.Types as Core
 import Foreign.Java.Util
 
+data Z = Z deriving Show
+data C = C deriving Show
+data B = B deriving Show
+data S = S deriving Show
+data I = I deriving Show
+data J = J deriving Show
+data F = F deriving Show
+data D = D deriving Show
+data L = L String deriving Show
+data V = V deriving Show
+data A x = A x deriving Show
+data X = X deriving Show
+
+data Q = Q String deriving Show
 
 boolean = Z
 char    = C
diff --git a/src/Foreign/Java/Value.hs b/src/Foreign/Java/Value.hs
--- a/src/Foreign/Java/Value.hs
+++ b/src/Foreign/Java/Value.hs
@@ -17,20 +17,18 @@
 -- nothing, or a special value describing an error condition.
 module Foreign.Java.Value where
 
-import Foreign.Java.JNI.Types (JThrowable)
-
 -- | A ternary value type to hold one of two possible value types
 -- or none at all.
-data Value a
+data Value e a
   = Value a -- ^ An actual value
   | NoValue -- ^ No value
-  | Fail JThrowable -- ^ A value describing the error
+  | Fail e  -- ^ A value describing the error
 
 -- | fold on a 'Value', like 'either' for 'Either' or 'maybe' for 'Maybe'.
 value :: b -- ^ default value if neither a value nor a fail value is given
-      -> (JThrowable -> b) -- ^ function to handle a fail value
+      -> (e -> b) -- ^ function to handle a fail value
       -> (a -> b) -- ^ function to handle an actual value
-      -> Value a -- ^ the value
+      -> Value e a -- ^ the value
       -> b -- ^ the final return value
 value noValue fail success value = case value of
     (Value a) -> success a
diff --git a/src/ffijni.c b/src/ffijni.c
--- a/src/ffijni.c
+++ b/src/ffijni.c
@@ -1,6 +1,5 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
 #include <string.h>
 
 #include "ffijni.h"
@@ -79,14 +78,9 @@
 #define STR(s) #s
 
 #define GLOBAL_REF(VMI, LOCAL, GLOBAL) \
-    jobject GLOBAL; \
-    if (LOCAL == NULL) { \
-        GLOBAL = NULL; \
-    } else { \
-        GLOBAL = (*VMI->env)->NewGlobalRef(VMI->env, LOCAL); \
-        (*VMI->env)->DeleteLocalRef(VMI->env, LOCAL); \
-    } \
-    DEBUG2("-> new global ref from local: %p -> %p", LOCAL, GLOBAL)
+    jobject GLOBAL = (*VMI->env)->NewGlobalRef(VMI->env, LOCAL); \
+    (*VMI->env)->DeleteLocalRef(VMI->env, LOCAL); \
+    DEBUG2("-> new global ref from local: %p -> %p", LOCAL, GLOBAL);
 
 #ifdef FFIJNI_OSX_FRAMEWORK /* def FFIJNI_OSX_FRAMEWORK */
 
@@ -201,7 +195,7 @@
 jobject JNICALL
 _callCallback(JNIEnv* env, jobject self, jlong func, jobject method, jobjectArray args)
 {
-    WrappedFun funPtr = (WrappedFun) (intptr_t) func;
+    WrappedFun funPtr = (WrappedFun) func;
     DEBUG3("Callback called (func: %d -> %p, method: %p)\m", func, funPtr, method)
     vm_t vmi;
     vmi.env = env;
@@ -213,7 +207,7 @@
 void JNICALL
 _releaseCallback(JNIEnv* env, jobject self, jlong func)
 {
-    WrappedFun funPtr = (WrappedFun) (intptr_t) func;
+    WrappedFun funPtr = (WrappedFun) func;
     DEBUG2("Callback released (func: %d -> %p)", func, funPtr)
     freeFunPtr(funPtr);
 }
@@ -551,8 +545,12 @@
     DEBUG2("callStaticObjectMethod(%p, %p)", clazz, method)
 
     jobject objLocal = (*vmi->env)->CallStaticObjectMethodA(vmi->env, clazz, method, args);
-    GLOBAL_REF(vmi, objLocal, obj)
-    return obj;
+    if (objLocal) {
+        GLOBAL_REF(vmi, objLocal, obj)
+        return obj;
+    } else {
+        return NULL;
+    }
 }
 
 const char*
@@ -562,9 +560,7 @@
 
     jobject string = (*vmi->env)->CallStaticObjectMethodA(vmi->env, clazz, method, args);
     if (string) {
-        const char* cstring = jStringToCString(vmi, string);
-        (*vmi->env)->DeleteLocalRef(vmi->env, string);
-        return cstring;
+        return jStringToCString(vmi, string);
     } else {
         return NULL;
     }
@@ -648,8 +644,12 @@
     DEBUG2("callObjectMethod(%p, %p)", object, method)
 
     jobject objLocal = (*vmi->env)->CallObjectMethodA(vmi->env, object, method, args);
-    GLOBAL_REF(vmi, objLocal, obj)
-    return obj;
+    if (objLocal) {
+        GLOBAL_REF(vmi, objLocal, obj)
+        return obj;
+    } else {
+        return NULL;
+    }
 }
 
 const char*
@@ -659,9 +659,7 @@
 
     jobject string = (*vmi->env)->CallObjectMethodA(vmi->env, object, method, args);
     if (string) {
-        const char* cstring = jStringToCString(vmi, string);
-        (*vmi->env)->DeleteLocalRef(vmi->env, string);
-        return cstring;
+        return jStringToCString(vmi, string);
     } else {
         return NULL;
     }
@@ -782,7 +780,6 @@
 getObjectField (vm_t* vmi, jobject object, jfieldID field)
 {
     jobject objLocal = (*vmi->env)->GetObjectField(vmi->env, object, field);
-    
     GLOBAL_REF(vmi, objLocal, obj)
     return obj;
 }
@@ -791,9 +788,7 @@
 getStringField (vm_t* vmi, jobject object, jfieldID field)
 {
     jobject string = (*vmi->env)->GetObjectField(vmi->env, object, field);
-    const char* cstring = jStringToCString(vmi, string);
-    (*vmi->env)->DeleteLocalRef(vmi->env, string);
-    return cstring;
+    return jStringToCString(vmi, string);
 }
 
 void
@@ -984,78 +979,6 @@
 setJValueObject (jvalue* array, int ix, jobject object)
 {
     (array + ix)->l = object;
-}
-
-jarray
-newBooleanArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newBooleanArray(%d)", size)
-
-    return (*vmi->env)->NewBooleanArray(vmi->env, size);
-}
-
-jarray
-newLongArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newLongArray(%d)", size)
-
-    return (*vmi->env)->NewLongArray(vmi->env, size);
-}
-
-jarray
-newIntArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newIntArray(%d)", size)
-
-    return (*vmi->env)->NewIntArray(vmi->env, size);
-}
-
-jarray
-newShortArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newShortArray(%d)", size)
-
-    return (*vmi->env)->NewShortArray(vmi->env, size);
-}
-
-jarray
-newByteArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newByteArray(%d)", size)
-
-    return (*vmi->env)->NewByteArray(vmi->env, size);
-}
-
-jarray
-newFloatArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newFloatArray(%d)", size)
-
-    return (*vmi->env)->NewFloatArray(vmi->env, size);
-}
-
-jarray
-newDoubleArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newDoubleArray(%d)", size)
-
-    return (*vmi->env)->NewDoubleArray(vmi->env, size);
-}
-
-jarray
-newCharArray (vm_t* vmi, jsize size)
-{
-    DEBUG1("newCharArray(%d)", size)
-
-    return (*vmi->env)->NewCharArray(vmi->env, size);
-}
-
-jarray
-newObjectArray (vm_t* vmi, jsize size, jclass elementType)
-{
-    DEBUG2("newObjectArray(%d, %p)", size, elementType)
-
-    return (*vmi->env)->NewObjectArray(vmi->env, size, elementType, NULL);
 }
 
 jobject
diff --git a/src/ffijni.h b/src/ffijni.h
--- a/src/ffijni.h
+++ b/src/ffijni.h
@@ -288,33 +288,6 @@
 void
 setJValueObject (jvalue*, int, jobject);
 
-jarray
-newBooleanArray (vm_t*, jsize);
-
-jarray
-newLongArray (vm_t*, jsize);
-
-jarray
-newIntArray (vm_t*, jsize);
-
-jarray
-newShortArray (vm_t*, jsize);
-
-jarray
-newByteArray (vm_t*, jsize);
-
-jarray
-newFloatArray (vm_t*, jsize);
-
-jarray
-newDoubleArray (vm_t*, jsize);
-
-jarray
-newCharArray (vm_t*, jsize);
-
-jarray
-newObjectArray (vm_t*, jsize, jclass);
-
 jobject
 newJString (vm_t*, const char*);
 
diff --git a/src/hfunction.h b/src/hfunction.h
deleted file mode 100644
--- a/src/hfunction.h
+++ /dev/null
@@ -1,72 +0,0 @@
-
-#define FFIJNI_HFUNCTION_LENGTH 1057
-
-static jbyte hFunctionClass[FFIJNI_HFUNCTION_LENGTH] = {
-  -54, -2, -70, -66, 0, 0, 0, 50, 0, 48, 10, 0, 10, 0, 31, 9, 
-  0, 5, 0, 32, 10, 0, 5, 0, 33, 10, 0, 5, 0, 34, 7, 0, 
-  35, 10, 0, 5, 0, 36, 10, 0, 8, 0, 37, 7, 0, 38, 10, 0, 
-  39, 0, 40, 7, 0, 41, 7, 0, 42, 1, 0, 9, 104, 70, 117, 110, 
-  99, 116, 105, 111, 110, 1, 0, 1, 74, 1, 0, 7, 114, 101, 108, 101, 
-  97, 115, 101, 1, 0, 4, 40, 74, 41, 86, 1, 0, 4, 99, 97, 108, 
-  108, 1, 0, 66, 40, 74, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 
-  47, 114, 101, 102, 108, 101, 99, 116, 47, 77, 101, 116, 104, 111, 100, 59, 
-  91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 
-  99, 116, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 
-  98, 106, 101, 99, 116, 59, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 
-  0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 
-  98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 6, 105, 110, 118, 111, 107, 
-  101, 1, 0, 83, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 
-  79, 98, 106, 101, 99, 116, 59, 76, 106, 97, 118, 97, 47, 108, 97, 110, 
-  103, 47, 114, 101, 102, 108, 101, 99, 116, 47, 77, 101, 116, 104, 111, 100, 
-  59, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 
-  101, 99, 116, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 
-  79, 98, 106, 101, 99, 116, 59, 1, 0, 8, 102, 105, 110, 97, 108, 105, 
-  122, 101, 1, 0, 3, 40, 41, 86, 1, 0, 12, 109, 97, 107, 101, 70, 
-  117, 110, 99, 116, 105, 111, 110, 1, 0, 38, 40, 76, 106, 97, 118, 97, 
-  47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 74, 41, 76, 106, 
-  97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 
-  1, 0, 9, 83, 105, 103, 110, 97, 116, 117, 114, 101, 1, 0, 50, 60, 
-  84, 58, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 
-  101, 99, 116, 59, 62, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 
-  47, 67, 108, 97, 115, 115, 60, 84, 84, 59, 62, 59, 74, 41, 84, 84, 
-  59, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 
-  14, 72, 70, 117, 110, 99, 116, 105, 111, 110, 46, 106, 97, 118, 97, 12, 
-  0, 18, 0, 24, 12, 0, 12, 0, 13, 12, 0, 16, 0, 17, 12, 0, 
-  14, 0, 15, 1, 0, 9, 72, 70, 117, 110, 99, 116, 105, 111, 110, 12, 
-  0, 18, 0, 15, 12, 0, 43, 0, 44, 1, 0, 15, 106, 97, 118, 97, 
-  47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 7, 0, 45, 12, 0, 
-  46, 0, 47, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 
-  79, 98, 106, 101, 99, 116, 1, 0, 35, 106, 97, 118, 97, 47, 108, 97, 
-  110, 103, 47, 114, 101, 102, 108, 101, 99, 116, 47, 73, 110, 118, 111, 99, 
-  97, 116, 105, 111, 110, 72, 97, 110, 100, 108, 101, 114, 1, 0, 14, 103, 
-  101, 116, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 1, 0, 25, 
-  40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 
-  115, 115, 76, 111, 97, 100, 101, 114, 59, 1, 0, 23, 106, 97, 118, 97, 
-  47, 108, 97, 110, 103, 47, 114, 101, 102, 108, 101, 99, 116, 47, 80, 114, 
-  111, 120, 121, 1, 0, 16, 110, 101, 119, 80, 114, 111, 120, 121, 73, 110, 
-  115, 116, 97, 110, 99, 101, 1, 0, 98, 40, 76, 106, 97, 118, 97, 47, 
-  108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 
-  59, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 
-  115, 115, 59, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 114, 101, 
-  102, 108, 101, 99, 116, 47, 73, 110, 118, 111, 99, 97, 116, 105, 111, 110, 
-  72, 97, 110, 100, 108, 101, 114, 59, 41, 76, 106, 97, 118, 97, 47, 108, 
-  97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 0, 33, 0, 5, 0, 
-  10, 0, 1, 0, 11, 0, 1, 0, 18, 0, 12, 0, 13, 0, 0, 0, 
-  6, 1, 8, 0, 14, 0, 15, 0, 0, 1, 8, 0, 16, 0, 17, 0, 
-  0, 0, 1, 0, 18, 0, 15, 0, 1, 0, 19, 0, 0, 0, 42, 0, 
-  3, 0, 3, 0, 0, 0, 10, 42, -73, 0, 1, 42, 31, -75, 0, 2, 
-  -79, 0, 0, 0, 1, 0, 20, 0, 0, 0, 14, 0, 3, 0, 0, 0, 
-  21, 0, 4, 0, 22, 0, 9, 0, 23, 0, 1, 0, 21, 0, 22, 0, 
-  1, 0, 19, 0, 0, 0, 34, 0, 4, 0, 4, 0, 0, 0, 10, 42, 
-  -76, 0, 2, 44, 45, -72, 0, 3, -80, 0, 0, 0, 1, 0, 20, 0, 
-  0, 0, 6, 0, 1, 0, 0, 0, 26, 0, 4, 0, 23, 0, 24, 0, 
-  1, 0, 19, 0, 0, 0, 36, 0, 2, 0, 1, 0, 0, 0, 8, 42, 
-  -76, 0, 2, -72, 0, 4, -79, 0, 0, 0, 1, 0, 20, 0, 0, 0, 
-  10, 0, 2, 0, 0, 0, 30, 0, 7, 0, 31, 0, 9, 0, 25, 0, 
-  26, 0, 2, 0, 19, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 
-  26, -69, 0, 5, 89, 31, -73, 0, 6, 78, 42, -74, 0, 7, 4, -67, 
-  0, 8, 89, 3, 42, 83, 45, -72, 0, 9, -80, 0, 0, 0, 1, 0, 
-  20, 0, 0, 0, 10, 0, 2, 0, 0, 0, 41, 0, 9, 0, 42, 0, 
-  27, 0, 0, 0, 2, 0, 28, 0, 1, 0, 29, 0, 0, 0, 2, 0, 
-  30
-};
