<!--
 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.
-->

changes for Apache BSF 2.4.0 (from RELEASE-NOTE.txt)

    *) can be used as an extension package to Java by placing it into
       "jre/lib/ext" [using the thread's context classloader, ie. the result
       of 'Thread.currentThread().getContextClassLoader()']

    *) removed experimental 'DebugLog' class, superceded by commons-logging
       and log4j

    *) removed 'org.apache.bsf.engines.activescript.*', as it is not
       supported anymore (stems from the original IBM codebase, but would
       need native Windows code to bridge OLE/ActiveX)

    *) removed 'org.apache.bsf.engines.jpython', as it is superceded by
       the newer 'org.apache.bsf.engines.jython'

    *) 'org.apache.bsf.BSFMain.java': new method
       "public String getVersion()", returns string in the form of a
       dewey decimal number 'abc' (three levels, each between 0 and 9)
       'abc.yyyymmdd', 'yyyy' four digit year, 'mm' two digit month,
       'dd' two digit day;
       e.g. '240.20060925' stands for: BSF version 2.4.0 as of 2006-09-25

    *) new class 'org.apache.bsf.utils.BSFEventProcessorReturningEventInfos'

    *) 'org.apache.bsf.utils.EngineUtils.java': added the method
       'addEventListenerReturningEventInfos(...)'


changes for Apache BSF 2.3.0
    *) Revert BSF debug support (due to several usability issues)
       and refactor source.

    *) add javadocs and realclean targets to build.xml
       scrub remaining email addresses from source for spam prevention
       add AUTHORS, BUILDING, INSTALL, README, and TODO files

    *) Cleaned out META* junk

    *) Removed bsf/src/org/apache/bsf/engines/activescript/samples/*
       because of copyright issues

    *) Changes for org.apache.* namespace, license changes

changes to BSF 2.2
    *) Fix taglibs, and allow debugging through taglibs

    *) Entry/Exit debugging added

    *) Overall logging solution, involving a loglevel property

    *) BSF taglib added to drop package

    *) Debug Protocol versioning and handshake

    *) Miscellaneous bugfixes, additions, and cleanups.

    *) updated XSLT support for Xalan 2

    *) added Jython engine

    *) JSDI and debug engine for ECMAScript

    *) added master build.xml

    *) added scripts module to the bsf23 module

    *) added bsf23 module for rollup of bsf, bsf_debug, and jsdb
       created bsf-build-23 module for other files (support, build.xml)
