// Path: src/main/java/com/technofovea/hllib/methods/FullLibrary.java
// public interface FullLibrary extends BasicLibrary {
// 
//     /**
//      * Called to initialize the DLL library.
//      */
//     public void initialize();
// 
//     /**
//      * Called to shut down the DLL library.
//      */
//     public void shutdown();
// 
//     public boolean itemGetSize(DirectoryItem item, IntByReference size);
// 
//     public boolean itemGetSizeEx(DirectoryItem item, LongByReference size);
// 
//     public boolean itemGetSizeOnDisk(DirectoryItem item, IntByReference size);
// 
//     public boolean itemGetSizeOnDiskEx(DirectoryItem item, LongByReference size);
// 
//     public void itemGetPath(DirectoryItem item, byte[] buffer, int bufsize);
// 
//     public boolean createPackage(PackageType ePackageType, IntByReference packageId);
// 
//     public void packageClose();
// 
//     public void deletePackage(HlPackage pkg);
// 
//     public boolean packageGetExtractable(DirectoryItem file, ByteByReference extractable);
// 
//     public boolean packageGetFileSize(DirectoryItem file, IntByReference size);
// 
//     public boolean packageGetFileSizeOnDisk(DirectoryItem file, IntByReference size);
// 
//     public boolean packageCreateStream(DirectoryItem file, PointerByReference stream);
// 
//     public boolean fileCreateStream(DirectoryItem item, PointerByReference stream);
// }
// 
// Path: src/main/java/com/technofovea/hllib/methods/ManagedCalls.java
// public interface ManagedCalls {
// 
//     public int itemGetSize(DirectoryItem item);
// 
//     public int itemGetSizeOnDisk(DirectoryItem item);
// 
//     public long itemGetSizeEx(DirectoryItem item);
// 
//     public long itemGetSizeOnDiskEx(DirectoryItem item);
// 
//     public String itemGetPath(DirectoryItem item);
// 
//     public HlPackage getCurrentlyBoundPackage();
// 
//     public HlPackage createPackage(PackageType ePackageType);
// 
//     public PackageType getPackageType(File f);
// 
//     /**
//      * Replaces packageClose() and packageDelete() with a single call, primarily
//      * to make it easier to handle the safe marking of HlPackage and DirectoryItem
//      * objects as invalid.
//      * @param pkg The package to remove and close.
//      */
//     public void packageRemove(HlPackage pkg);
// 
//     public void packageRemoveAll();
// 
//     public boolean packageGetExtractable(DirectoryItem file);
// 
//     public int packageGetFileSize(DirectoryItem file);
// 
//     public int packageGetFileSizeOnDisk(DirectoryItem file);
// 
//     public HlStream packageCreateStream(DirectoryItem file);
// 
//     public HlStream fileCreateStream(DirectoryItem item);
// }


import com.technofovea.hllib.methods.FullLibrary;
import com.technofovea.hllib.methods.ManagedCalls;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package com.technofovea.hllib;


class InvocationManager implements InvocationHandler {

    private static final Logger logger = LoggerFactory.getLogger(InvocationManager.class);

    FullLibrary delegate;
    ManagedCallImpl lackey;

    InvocationManager(FullLibrary target) {
        super();
        this.delegate = target;
        lackey = new ManagedCallImpl(this.delegate);
    }

    @Override
    protected void finalize() throws Throwable {
        delegate.shutdown();
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (args == null) {
            args = new Object[0];
        }
        logger.trace("New invocation: "+method.getName());
        // Depending on what comes in, normally target the libarary instance or
        // else retarget to our managed call implementation.

        Object target = delegate;
        Object result = null;

        // Anything declared in ManagedLibrary or sub-interfaces is something we
        // must intercept and re-target.
// Path: src/main/java/com/technofovea/hllib/methods/FullLibrary.java
// public interface FullLibrary extends BasicLibrary {
// 
//     /**
//      * Called to initialize the DLL library.
//      */
//     public void initialize();
// 
//     /**
//      * Called to shut down the DLL library.
//      */
//     public void shutdown();
// 
//     public boolean itemGetSize(DirectoryItem item, IntByReference size);
// 
//     public boolean itemGetSizeEx(DirectoryItem item, LongByReference size);
// 
//     public boolean itemGetSizeOnDisk(DirectoryItem item, IntByReference size);
// 
//     public boolean itemGetSizeOnDiskEx(DirectoryItem item, LongByReference size);
// 
//     public void itemGetPath(DirectoryItem item, byte[] buffer, int bufsize);
// 
//     public boolean createPackage(PackageType ePackageType, IntByReference packageId);
// 
//     public void packageClose();
// 
//     public void deletePackage(HlPackage pkg);
// 
//     public boolean packageGetExtractable(DirectoryItem file, ByteByReference extractable);
// 
//     public boolean packageGetFileSize(DirectoryItem file, IntByReference size);
// 
//     public boolean packageGetFileSizeOnDisk(DirectoryItem file, IntByReference size);
// 
//     public boolean packageCreateStream(DirectoryItem file, PointerByReference stream);
// 
//     public boolean fileCreateStream(DirectoryItem item, PointerByReference stream);
// }
// 
// Path: src/main/java/com/technofovea/hllib/methods/ManagedCalls.java
// public interface ManagedCalls {
// 
//     public int itemGetSize(DirectoryItem item);
// 
//     public int itemGetSizeOnDisk(DirectoryItem item);
// 
//     public long itemGetSizeEx(DirectoryItem item);
// 
//     public long itemGetSizeOnDiskEx(DirectoryItem item);
// 
//     public String itemGetPath(DirectoryItem item);
// 
//     public HlPackage getCurrentlyBoundPackage();
// 
//     public HlPackage createPackage(PackageType ePackageType);
// 
//     public PackageType getPackageType(File f);
// 
//     /**
//      * Replaces packageClose() and packageDelete() with a single call, primarily
//      * to make it easier to handle the safe marking of HlPackage and DirectoryItem
//      * objects as invalid.
//      * @param pkg The package to remove and close.
//      */
//     public void packageRemove(HlPackage pkg);
// 
//     public void packageRemoveAll();
// 
//     public boolean packageGetExtractable(DirectoryItem file);
// 
//     public int packageGetFileSize(DirectoryItem file);
// 
//     public int packageGetFileSizeOnDisk(DirectoryItem file);
// 
//     public HlStream packageCreateStream(DirectoryItem file);
// 
//     public HlStream fileCreateStream(DirectoryItem item);
// }


// Path: src/main/java/com/technofovea/hllib/InvocationManager.java
import com.technofovea.hllib.methods.FullLibrary;
import com.technofovea.hllib.methods.ManagedCalls;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

package com.technofovea.hllib;


class InvocationManager implements InvocationHandler {

    private static final Logger logger = LoggerFactory.getLogger(InvocationManager.class);

    FullLibrary delegate;
    ManagedCallImpl lackey;

    InvocationManager(FullLibrary target) {
        super();
        this.delegate = target;
        lackey = new ManagedCallImpl(this.delegate);
    }

    @Override
    protected void finalize() throws Throwable {
        delegate.shutdown();
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (args == null) {
            args = new Object[0];
        }
        logger.trace("New invocation: "+method.getName());
        // Depending on what comes in, normally target the libarary instance or
        // else retarget to our managed call implementation.

        Object target = delegate;
        Object result = null;

        // Anything declared in ManagedLibrary or sub-interfaces is something we
        // must intercept and re-target.
        if (ManagedCalls.class.isAssignableFrom(method.getDeclaringClass())) {