/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


 /*
     2015-01-15, rgf: take into account that a context thread class loader may be null (not set)

     2007-09-21: Rony G. Flatscher, new class loading sequence:

            - Thread's context class loader
            - BSFManager's defining class loader

     2007-01-29: Rony G. Flatscher: added BSF_Log[Factory] to allow BSF to run without org.apache.commons.logging present
 */

package org.apache.bsf.util.event.generator;

import org.apache.bsf.BSF_Log;
import org.apache.bsf.BSF_LogFactory;

import org.apache.bsf.BSFManager;

import java.io.FileOutputStream;
import java.io.IOException;


/** EventAdapterGenerator
  *
  * Generate an "Event Adapter" dynamically during program execution
  *
  **/
public class EventAdapterGenerator
{
  public static AdapterClassLoader ldr = new AdapterClassLoader();
  static Class  EVENTLISTENER          = null;
  static String CLASSPACKAGE           = "org/apache/bsf/util/event/adapters/";
  static String WRITEDIRECTORY         = null;

  // starting 8 bytes of all Java Class files
  static byte   CLASSHEADER[];
  // constant pool items found in all event adapters
  static short  BASECPCOUNT; // number of cp items + 1 ( cp item # 0 reserved for JVM )
  static byte   BASECP[];    //
  // some bytes in the middle of the class file (see below)
  static byte   FIXEDCLASSBYTES[];
  // the initialization method, noargs constructor
  static byte   INITMETHOD[];

  private static BSF_Log logger=null;

  /* The static initializer */
  static
  {
    // logger = LogFactory.getLog((org.apache.bsf.util.event.generator.EventAdapterGenerator.class).getName());
        logger = BSF_LogFactory.getLog((org.apache.bsf.util.event.generator.EventAdapterGenerator.class).getName());

    String USERCLASSPACKAGE = System.getProperty("DynamicEventClassPackage",
                                                 "");

    if (!USERCLASSPACKAGE.equals(""))
    {
      CLASSPACKAGE = USERCLASSPACKAGE;
    }

    if(CLASSPACKAGE.length() > 0 )
    {
      CLASSPACKAGE = CLASSPACKAGE.replace('\\','/');
      if(!CLASSPACKAGE.endsWith("/"))
      { CLASSPACKAGE = CLASSPACKAGE+"/"; }
    }
    WRITEDIRECTORY = System.getProperty("DynamicEventClassWriteDirectory",CLASSPACKAGE);
    if(WRITEDIRECTORY.length() > 0 )
    {
      WRITEDIRECTORY = WRITEDIRECTORY.replace('\\','/');
      if(!WRITEDIRECTORY.endsWith("/"))
      { WRITEDIRECTORY = WRITEDIRECTORY+"/"; }
    }
    try
    // { EVENTLISTENER = Class.forName("java.util.EventListener"); }
    {
            // EVENTLISTENER = Thread.currentThread().getContextClassLoader().loadClass ("java.util.EventListener"); // rgf, 2006-01-05

            // rgf, 20070917: first try context class loader, then BSFManager's defining class loader
            EVENTLISTENER=null;
            ClassLoader tccl=Thread.currentThread().getContextClassLoader();

            if (tccl!=null)
            {
                try {
                     EVENTLISTENER = tccl.loadClass ("java.util.EventListener");
                }
                catch(ClassNotFoundException ex01)
                {}
            }

            if (EVENTLISTENER==null)    // did not work, try to load it via the definedClassLoader
            {
                EVENTLISTENER = BSFManager.getDefinedClassLoader().loadClass ("java.util.EventListener");
            }

        }
    catch(ClassNotFoundException ex)
    {
            System.err.println(ex.getMessage());
            ex.printStackTrace();
        }


    // start of the Java Class File
    CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xCA);  // magic
    CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xFE);  // magic
    CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xBA);  // magic
    CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(byte)0xBE);  // magic
    CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(short)3);    // minor version
    CLASSHEADER = ByteUtility.addBytes(CLASSHEADER,(short)45);   // major version

    // Start the constant pool for base items in all event adapter classes
    BASECPCOUNT = 17; // number of cp items + 1 ( cp item # 0 reserved for JVM )

    // cp item 01
    BASECP = Bytecode.addUtf8(BASECP,"()V");

    // cp item 02
    BASECP = Bytecode.addUtf8(BASECP,"<init>");

    // cp item 03
    BASECP = Bytecode.addUtf8(BASECP,"Code");

    // cp item 04
    BASECP = Bytecode.addUtf8(BASECP,"eventProcessor");

    // cp item 05
    BASECP = Bytecode.addUtf8(BASECP,"java/lang/Object");

    // cp item 06
    BASECP = Bytecode.addUtf8(BASECP,"org/apache/bsf/util/event/EventAdapterImpl");

    // cp item 07
    BASECP = Bytecode.addUtf8(BASECP,"org/apache/bsf/util/event/EventProcessor");

    // cp item 08
    BASECP = Bytecode.addUtf8(BASECP,"(Ljava/lang/String;[Ljava/lang/Object;)V");

    // cp item 09
    BASECP = Bytecode.addUtf8(BASECP,"Lorg/apache/bsf/util/event/EventProcessor;");

    // cp item 10
    BASECP = Bytecode.addClass(BASECP,(short)5); // Class "java/lang/Object"

    // cp item 11
    BASECP = Bytecode.addClass(BASECP,(short)6); // Class "org/apache/bsf/util/event/EventAdapterImpl"

    // cp item 12
    BASECP = Bytecode.addClass(BASECP,(short)7); // Class "org/apache/bsf/util/event/EventProcessor"

    // cp item 13
    BASECP = Bytecode.addNameAndType(BASECP,(short)2,(short)1); // "<init>" "()V"

    // cp item 14
    BASECP = Bytecode.addNameAndType(BASECP,(short)4,(short)9); // "eventProcessor" "Lorg/apache/bsf/util/event/EventProcessor;"

    // cp item 15
    BASECP = Bytecode.addFieldRef(BASECP,(short)11,(short)14);

    // cp item 16
    BASECP = Bytecode.addMethodRef(BASECP,(short)11,(short)13);

    // fixed bytes in middle of class file
    FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)0x21); // access_flags        (fixed)
    FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)20);   // this_class          (fixed)
    FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)11);   // super_class         (fixed)
    FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)1);    // interface_count     (fixed)
    FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)19);   // interfaces          (fixed)
    FIXEDCLASSBYTES = ByteUtility.addBytes(FIXEDCLASSBYTES,(short)0);    // field_count         (fixed)

    // initialization method, constructor
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1);              // access_flags
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)2);              // name_index "<init>"
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1);              // descriptor_index "()V"
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1);              // attribute_count
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)3);              // attribute_name_index "Code"
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(long)17);              // attribute_length
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1);              // max_stack
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)1);              // max_locals
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(long)5);               // code_length
    //code
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0x2A);            // aload_0
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0xB7);            // invokespecial
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)16);             // method_ref index
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(byte)0xB1);            // return
    // exception table
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)0);              // exception_table_length
    INITMETHOD = ByteUtility.addBytes(INITMETHOD,(short)0);              // attributes_count

  }

  /* methods that take an EventListener Class Type to create an EventAdapterClass */
  public static Class makeEventAdapterClass(Class listenerType,boolean writeClassFile)
  {
      logger.debug("EventAdapterGenerator");

        if( EVENTLISTENER.isAssignableFrom(listenerType) )
    {
      boolean exceptionable    = false;
      boolean nonExceptionable = false;
      byte    constantPool[]   = null;
      short   cpBaseIndex;
      short   cpCount          = 0;
      short   cpExceptionBaseIndex;
      short   exceptionableCount;
      short   nonExceptionableCount;

      /* Derive Names */
      String listenerTypeName      = listenerType.getName();
          logger.debug("ListenerTypeName: "+listenerTypeName);
      String adapterClassName      =
        CLASSPACKAGE+
        (listenerTypeName.endsWith("Listener")
         ? listenerTypeName.substring(0, listenerTypeName.length() - 8)
         : listenerTypeName).replace('.', '_') +
        "Adapter";
      String finalAdapterClassName = adapterClassName;
      Class  cached                = null;
      int    suffixIndex           = 0;

      do
      {
        if (null != (cached = ldr.getLoadedClass(finalAdapterClassName)))
        {
                    logger.debug("cached:  "+cached);
          try
          {
            if (!listenerType.isAssignableFrom(cached))
              finalAdapterClassName = adapterClassName + "_" + suffixIndex++;
            else
              return cached;
          }
          catch(VerifyError ex)
          {
                      System.err.println(ex.getMessage());
                      ex.printStackTrace();
                      return cached;
          }
        }
      }
      while (cached != null);

      String eventListenerName = listenerTypeName.replace('.', '/');

      /* method stuff */
      java.lang.reflect.Method lms[] = listenerType.getMethods();

      /* ****************************************************************************************** */
      // Listener interface
      // Class name
      cpCount += 4;

      // cp item 17
      constantPool = Bytecode.addUtf8(constantPool,eventListenerName);

      // cp item 18
      constantPool = Bytecode.addUtf8(constantPool,finalAdapterClassName);

      // cp item 19
      constantPool = Bytecode.addClass(constantPool,(short)17);

      // cp item 20
      constantPool = Bytecode.addClass(constantPool,(short)18);

      // do we have nonExceptionalble event, exceptionable or both
      for (int i = 0 ; i < lms.length ; ++i)
      {
        Class exceptionTypes[] = lms[i].getExceptionTypes();
        if( 0 < exceptionTypes.length)
        { exceptionable = true; }
        else
        { nonExceptionable = true; }
      }/* End for*/

      /* ****************************************************************************************** */
      // optional inclusion of nonexceptional events affects exceptional events indices

      nonExceptionableCount = 0;
      if(nonExceptionable)
      {
        nonExceptionableCount = 3;
        cpCount += nonExceptionableCount;

        // cp item 21
        constantPool = Bytecode.addUtf8(constantPool,"processEvent");

        // cp item 22
        constantPool = Bytecode.addNameAndType(constantPool,(short)21,(short)8);


        // cp item 23
        constantPool = Bytecode.addInterfaceMethodRef(constantPool,(short)12,(short)22);
      }

      /* ****************************************************************************************** */
      // optional inclusion of exceptional events affects CP Items which follow for specific methods

      exceptionableCount = 0;
      if(exceptionable)
      {
        int classIndex = BASECPCOUNT + cpCount + 1;
        int nameIndex  = BASECPCOUNT + cpCount + 0;
        int natIndex   = BASECPCOUNT + cpCount + 3;

        exceptionableCount = 5;
        cpCount += exceptionableCount;

        // cp item 24 or 21
        constantPool = Bytecode.addUtf8(constantPool,"processExceptionableEvent");

        // cp item 25 or 22
        constantPool = Bytecode.addUtf8(constantPool,"java/lang/Exception");

        // cp item 26 or 23
        constantPool = Bytecode.addClass(constantPool,(short)classIndex);

        // cp item 27 or 24
        constantPool = Bytecode.addNameAndType(constantPool,(short)nameIndex,(short)8);

        // cp item 28 or 25
        constantPool = Bytecode.addInterfaceMethodRef(constantPool,(short)12,(short)natIndex);

      }

      // base index for method cp references
      cpBaseIndex = (short)(BASECPCOUNT + cpCount);
          logger.debug("cpBaseIndex: " + cpBaseIndex);

      for (int i = 0 ; i < lms.length ; ++i)
      {
        String eventMethodName = lms[i].getName();
        String eventName = lms[i].getParameterTypes()[0].getName().replace('.','/');
        cpCount += 3;
        // cp items for event methods
        constantPool = Bytecode.addUtf8(constantPool,eventMethodName);
        constantPool = Bytecode.addUtf8(constantPool,("(L" + eventName + ";)V"));
        constantPool = Bytecode.addString(constantPool,(short)(BASECPCOUNT+cpCount-3));
      }/* End for*/

      boolean propertyChangeFlag[] = new boolean[lms.length];
      int cpIndexPCE = 0;
      for (int i = 0 ; i < lms.length ; ++i)
      {
        String eventName = lms[i].getParameterTypes()[0].getName().replace('.','/');
        // cp items for PropertyChangeEvent special handling
        if(eventName.equalsIgnoreCase("java/beans/PropertyChangeEvent"))
        {
          propertyChangeFlag[i] = true;
          if( 0 == cpIndexPCE )
          {
            constantPool = Bytecode.addUtf8(constantPool,eventName);
            constantPool = Bytecode.addUtf8(constantPool,"getPropertyName");
            constantPool = Bytecode.addUtf8(constantPool,"()Ljava/lang/String;");
            constantPool = Bytecode.addClass(constantPool,(short)(BASECPCOUNT + cpCount));
            constantPool = Bytecode.addNameAndType(constantPool,
                                                   (short)(BASECPCOUNT + cpCount + 1),
                                                   (short)(BASECPCOUNT + cpCount + 2));
            constantPool = Bytecode.addMethodRef(constantPool,
                                                 (short)(BASECPCOUNT + cpCount + 3),
                                                 (short)(BASECPCOUNT + cpCount + 4));
            cpCount += 6;
            cpIndexPCE = BASECPCOUNT + cpCount - 1;

          }
        }
        else
        { propertyChangeFlag[i] = false; }
      }/* End for*/

      cpExceptionBaseIndex = (short)(BASECPCOUNT + cpCount);
          logger.debug("cpExceptionBaseIndex: " + cpExceptionBaseIndex);

      int excpIndex[][] = new int[lms.length][];
      for (int i = 0 ; i < lms.length ; ++i)
      {
        Class exceptionTypes[] = lms[i].getExceptionTypes();
        excpIndex[i] = new int[exceptionTypes.length];
        for ( int j = 0 ; j < exceptionTypes.length ; j++)
        {
          constantPool = Bytecode.addUtf8(constantPool,exceptionTypes[j].getName().replace('.', '/'));
          constantPool = Bytecode.addClass(constantPool,(short)(BASECPCOUNT+cpCount));
          excpIndex[i][j] = BASECPCOUNT + cpCount + 1;
          cpCount += 2;
        }
      }/* End for*/
      /* end constant pool */

      /* ************************************************************************************************ */
      // put the Class byte array together

      /* start */
      byte newClass[] = CLASSHEADER;                                   // magic, version      (fixed)
      short count = (short)(BASECPCOUNT + cpCount);
      newClass = ByteUtility.addBytes(newClass,count);                 // constant_pool_count (variable)
      newClass = ByteUtility.addBytes(newClass,BASECP);                // constant_pool       (fixed)
      newClass = ByteUtility.addBytes(newClass,constantPool);          // constant_pool       (variable)
      newClass = ByteUtility.addBytes(newClass,FIXEDCLASSBYTES);       // see FIXEDCLASSBYTES (fixed)
      newClass = ByteUtility.addBytes(newClass,(short)(lms.length+1)); // method_count        (variable)
      newClass = ByteUtility.addBytes(newClass,INITMETHOD);            // constructor <init>  (fixed)
      // methods

      /* ****************************************************************************************** */
      /* loop over listener methods from listenerType */
      for (int i = 0 ; i < lms.length ; ++i)
      {
        newClass = ByteUtility.addBytes(newClass,(short)1);                   // access_flags             (fixed)
        newClass = ByteUtility.addBytes(newClass,(short)(cpBaseIndex+3*i+0)); // name_index               (variable)
        newClass = ByteUtility.addBytes(newClass,(short)(cpBaseIndex+3*i+1)); // descriptor_index         (variable)
        newClass = ByteUtility.addBytes(newClass,(short)1);                   // attribute_count          (fixed)
        newClass = ByteUtility.addBytes(newClass,(short)3);                   // attribute_name_index code(fixed)

        // Code Attribute Length
        int length = 32;
        if( 0 < excpIndex[i].length )
        { length += 5 + 8 * ( 1 + excpIndex[i].length ); }
        if(propertyChangeFlag[i])
        { length += 2; }
        newClass = ByteUtility.addBytes(newClass,(long)length);               // attribute_length         (variable)

        // start code attribute
        newClass = ByteUtility.addBytes(newClass,(short)6);                   // max_stack                (fixed)
        newClass = ByteUtility.addBytes(newClass,(short)3);                   // max_locals               (fixed)

        // Code Length
        length = 20;
        if(exceptionable && 0 < excpIndex[i].length)
        { length += 5; }
        if(propertyChangeFlag[i])
        { length += 2; }
        newClass = ByteUtility.addBytes(newClass,(long)length);               // code_length              (variable)

        // start code
        newClass = ByteUtility.addBytes(newClass,(byte)0x2A);                 // aload_0                  (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0xB4);                 // getfield                 (fixed)
        newClass = ByteUtility.addBytes(newClass,(short)15);                  // index                    (fixed)


        if(propertyChangeFlag[i])
        { // the propertyName is passed as the first parameter
          newClass = ByteUtility.addBytes(newClass,(byte)0x2B);               // aload_1                  (fixed)
          newClass = ByteUtility.addBytes(newClass,(byte)0xB6);               // invokevirtual            (fixed)
          newClass = ByteUtility.addBytes(newClass,(short)cpIndexPCE);        // methodref                (variable)
        }
        else
        { // the eventMethodName is passed as the first parameter
          // Target for method invocation.
          newClass = ByteUtility.addBytes(newClass,(byte)0x12);                 // ldc                    (fixed)
          newClass = ByteUtility.addBytes(newClass,(byte)(cpBaseIndex+3*i+2));  // index (byte)           (variable)
        }

        newClass = ByteUtility.addBytes(newClass,(byte)0x04);                 // iconst_1                 (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0xBD);                 // anewarray                (fixed)
        newClass = ByteUtility.addBytes(newClass,(short)10);                  // Class java/lang/Object   (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0x59);                 // dup                      (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0x03);                 // iconst_0                 (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0x2B);                 // aload_1                  (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0x53);                 // aastore                  (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0xB9);                 // invokeinterface          (fixed)

        // index to processEvent or processExceptionableEvent method
        length = 23; // actually an index into cp
        if(exceptionable && nonExceptionable)
        { // interface method index
          if( 0 < lms[i].getExceptionTypes().length )
          { length += 5; }
        }
        else if(exceptionable)
        { length += 2; }
        newClass = ByteUtility.addBytes(newClass,(short)length);              // index (process??????...) (variable)

        newClass = ByteUtility.addBytes(newClass,(byte)0x03);                 // iconst_0                 (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0x00);                 // noop                     (fixed)
        newClass = ByteUtility.addBytes(newClass,(byte)0xB1);                 // return                   (fixed)

        if(exceptionable && 0 < excpIndex[i].length)
        { // exception code
          newClass = ByteUtility.addBytes(newClass,(byte)0x4D);               // astore_2                 (fixed)
          newClass = ByteUtility.addBytes(newClass,(byte)0x2C);               // aload_2                  (fixed)
          newClass = ByteUtility.addBytes(newClass,(byte)0xBF);               // athrow                   (fixed)
          newClass = ByteUtility.addBytes(newClass,(byte)0x57);               // pop                      (fixed)
          newClass = ByteUtility.addBytes(newClass,(byte)0xB1);               // return                   (fixed)
        // end code

          // exception table
          length = excpIndex[i].length;
          newClass = ByteUtility.addBytes(newClass,(short)(1+length));        // exception_table_length   (variable)
          for( int j = 0 ; j < length ; j++ )
          { // catch exception types and rethrow
            newClass = ByteUtility.addBytes(newClass,(short)0);               // start_pc                 (fixed)
            if(propertyChangeFlag[i])
            {
              newClass = ByteUtility.addBytes(newClass,(short)21);            // end_pc                   (fixed)
              newClass = ByteUtility.addBytes(newClass,(short)22);            // handler_pc               (fixed)
            }
            else
            {
              newClass = ByteUtility.addBytes(newClass,(short)19);            // end_pc                   (fixed)
              newClass = ByteUtility.addBytes(newClass,(short)20);            // handler_pc               (fixed)
            }
            newClass = ByteUtility.addBytes(newClass,(short)excpIndex[i][j]); // catch_type               (variable)
          }
          // catch "exception" and trap it
          newClass = ByteUtility.addBytes(newClass,(short)0);                 // start_pc                 (fixed)
          if(propertyChangeFlag[i])
          {
            newClass = ByteUtility.addBytes(newClass,(short)21);              // end_pc                   (fixed)
            newClass = ByteUtility.addBytes(newClass,(short)25);              // handler_pc               (fixed)
          }
          else
          {
            newClass = ByteUtility.addBytes(newClass,(short)19);              // end_pc                   (fixed)
            newClass = ByteUtility.addBytes(newClass,(short)23);              // handler_pc               (fixed)
          }
          if(nonExceptionable)
          { newClass = ByteUtility.addBytes(newClass,(short)26); }            // catch_type               (fixed)
          else                                                                                            // or
          { newClass = ByteUtility.addBytes(newClass,(short)23); }            // catch_type               (fixed)
        }
        else
        { newClass = ByteUtility.addBytes(newClass,(short)0); }               // exception_table_length   (fixed)
        // attributes on the code attribute (none)
        newClass = ByteUtility.addBytes(newClass,(short)0);                   // attribute_count          (fixed)
        // end code attribute


      }/* End for*/
      // Class Attributes (none for this)
      newClass = ByteUtility.addBytes(newClass,(short)0);                     // attribute_count          (fixed)
      /* done */

          logger.debug("adapterName: " + finalAdapterClassName);
          logger.debug("cpCount: " + count + " = " + BASECPCOUNT + " + " +  cpCount);
          logger.debug("methodCount: " + (lms.length+1));
      // output to disk class file
      /* ****************************************************************************************** */

      // now create the class and load it
      // return the Class.

      if (writeClassFile)
      {
        try
        {
                    // removed "WRITEDIRECTORY+", as this path is already part of 'finalAdapterClassName'
          FileOutputStream fos =  new FileOutputStream(finalAdapterClassName+".class");
          fos.write(newClass);
          fos.close();
        }
        catch(IOException ex)
        {
                    System.err.println(ex.getMessage());
                    ex.printStackTrace();
                }

        try
        {
          Class ret = ldr.loadClass(finalAdapterClassName);
          logger.debug("EventAdapterGenerator: " +
                             ret.getName() +
                             " dynamically generated");
          return ret;
        }
        catch (ClassNotFoundException ex)
        {
                    System.err.println(ex.getMessage());
                    ex.printStackTrace();
                }
      }

      try
      {
        Class ret = ldr.defineClass(finalAdapterClassName,newClass);
        logger.debug("EventAdapterGenerator: " +
                                       ret.getName() +
                                       " dynamically generated");
        return ret;
      }

      catch(Throwable ex)           // rgf, 2012-01-15
      {
        System.err.println(ex.getMessage());
        ex.printStackTrace();
      }
    }
    return null;
  }
}
