[commons-jci] 02/08: New upstream version 1.0

tony mancill tmancill at debian.org
Mon Dec 4 01:08:12 UTC 2017


This is an automated email from the git hooks/post-receive script.

tmancill pushed a commit to branch master
in repository commons-jci.

commit 6bf17a9c10e5e472773c8b63413ea38f400fb20c
Author: tony mancill <tmancill at debian.org>
Date:   Sun Dec 3 16:46:22 2017 -0800

    New upstream version 1.0
---
 KEYS.txt                                           | 722 +++++++++++++++++++++
 LICENSE.txt                                        | 201 ++++++
 NOTICE.txt                                         |   5 +
 README.txt                                         |  14 +
 TODO.txt                                           |  15 +
 build-dists.sh                                     |  84 +++
 compilers/eclipse/pom.xml                          |  58 ++
 .../jci/compilers/EclipseCompilationProblem.java   |  79 +++
 .../commons/jci/compilers/EclipseJavaCompiler.java | 378 +++++++++++
 .../jci/compilers/EclipseJavaCompilerSettings.java |  59 ++
 compilers/eclipse/src/main/resources/LICENSE.txt   | 201 ++++++
 compilers/eclipse/src/main/resources/NOTICE.txt    |   5 +
 .../jci/compilers/EclipseJavaCompilerTestCase.java |  30 +
 .../src/test/resources/simplelog.properties        |   2 +
 compilers/groovy/pom.xml                           |  58 ++
 .../jci/compilers/GroovyCompilationProblem.java    | 106 +++
 .../commons/jci/compilers/GroovyJavaCompiler.java  | 132 ++++
 .../jci/compilers/GroovyJavaCompilerSettings.java  |  39 ++
 compilers/groovy/src/main/resources/LICENSE.txt    | 201 ++++++
 compilers/groovy/src/main/resources/NOTICE.txt     |   5 +
 .../jci/compilers/GroovyJavaCompilerTestCase.java  |  38 ++
 .../groovy/src/test/resources/simplelog.properties |   2 +
 compilers/janino/pom.xml                           |  58 ++
 .../jci/compilers/JaninoCompilationProblem.java    | 100 +++
 .../commons/jci/compilers/JaninoJavaCompiler.java  | 172 +++++
 .../jci/compilers/JaninoJavaCompilerSettings.java  |  22 +
 compilers/janino/src/main/resources/LICENSE.txt    | 201 ++++++
 compilers/janino/src/main/resources/NOTICE.txt     |   5 +
 .../jci/compilers/JaninoJavaCompilerTestCase.java  |  34 +
 .../janino/src/test/resources/simplelog.properties |   2 +
 compilers/javac/pom.xml                            |  58 ++
 .../jci/compilers/FileInputStreamProxy.java        | 106 +++
 .../jci/compilers/FileOutputStreamProxy.java       |  94 +++
 .../commons/jci/compilers/JavacClassLoader.java    | 154 +++++
 .../jci/compilers/JavacCompilationProblem.java     |  90 +++
 .../commons/jci/compilers/JavacJavaCompiler.java   | 265 ++++++++
 .../jci/compilers/JavacJavaCompilerSettings.java   |  62 ++
 compilers/javac/src/main/resources/LICENSE.txt     | 201 ++++++
 compilers/javac/src/main/resources/NOTICE.txt      |   5 +
 .../jci/compilers/JavacJavaCompilerTestCase.java   |  30 +
 .../javac/src/test/resources/simplelog.properties  |   2 +
 compilers/jsr199/pom.xml                           |  59 ++
 .../jci/compilers/Jsr199CompilationProblem.java    |  68 ++
 .../commons/jci/compilers/Jsr199JavaCompiler.java  | 212 ++++++
 compilers/jsr199/src/main/resources/LICENSE.txt    | 201 ++++++
 compilers/jsr199/src/main/resources/NOTICE.txt     |   5 +
 .../jci/compilers/Jsr199JavaCompilerTestCase.java  |  31 +
 compilers/rhino/pom.xml                            |  58 ++
 .../jci/compilers/RhinoCompilationProblem.java     |  70 ++
 .../commons/jci/compilers/RhinoJavaCompiler.java   | 279 ++++++++
 .../jci/compilers/RhinoJavaCompilerSettings.java   |  27 +
 compilers/rhino/src/main/resources/LICENSE.txt     | 201 ++++++
 compilers/rhino/src/main/resources/NOTICE.txt      |   5 +
 .../jci/compilers/RhinoJavaCompilerTestCase.java   | 122 ++++
 core/pom.xml                                       |  83 +++
 .../apache/commons/jci/ReloadingClassLoader.java   | 123 ++++
 .../jci/compilers/AbstractJavaCompiler.java        |  54 ++
 .../commons/jci/compilers/CompilationResult.java   |  64 ++
 .../apache/commons/jci/compilers/JavaCompiler.java |  87 +++
 .../commons/jci/compilers/JavaCompilerFactory.java |  93 +++
 .../jci/compilers/JavaCompilerSettings.java        |  93 +++
 .../org/apache/commons/jci/compilers/package.html  |  20 +
 .../commons/jci/listeners/CompilingListener.java   | 185 ++++++
 .../commons/jci/listeners/FileChangeListener.java  |  71 ++
 .../jci/listeners/ReloadNotificationListener.java  |  29 +
 .../commons/jci/listeners/ReloadingListener.java   | 164 +++++
 .../org/apache/commons/jci/listeners/package.html  |  20 +
 .../main/java/org/apache/commons/jci/package.html  |  18 +
 .../commons/jci/problems/CompilationProblem.java   |  65 ++
 .../jci/problems/CompilationProblemHandler.java    |  39 ++
 .../org/apache/commons/jci/problems/package.html   |  20 +
 .../commons/jci/readers/FileResourceReader.java    |  73 +++
 .../commons/jci/readers/MemoryResourceReader.java  |  68 ++
 .../apache/commons/jci/readers/ResourceReader.java |  30 +
 .../org/apache/commons/jci/readers/package.html    |  20 +
 .../commons/jci/stores/FileResourceStore.java      | 113 ++++
 .../commons/jci/stores/MemoryResourceStore.java    |  75 +++
 .../apache/commons/jci/stores/ResourceStore.java   |  29 +
 .../jci/stores/ResourceStoreClassLoader.java       |  96 +++
 .../apache/commons/jci/stores/Transactional.java   |  30 +
 .../jci/stores/TransactionalResourceStore.java     |  54 ++
 .../org/apache/commons/jci/stores/package.html     |  20 +
 .../apache/commons/jci/utils/ConversionUtils.java  |  96 +++
 .../java/org/apache/commons/jci/utils/package.html |  20 +
 core/src/main/resources/LICENSE.txt                | 201 ++++++
 core/src/main/resources/NOTICE.txt                 |   5 +
 core/src/site/site.xml                             |  38 ++
 .../org/apache/commons/jci/AbstractTestCase.java   | 122 ++++
 .../commons/jci/CompilingClassLoaderTestCase.java  | 240 +++++++
 .../jci/ReloadingClassLoaderRemoveTestCase.java    | 262 ++++++++
 .../commons/jci/ReloadingClassLoaderTestCase.java  | 166 +++++
 .../apache/commons/jci/classes/ExtendedDump.java   |  77 +++
 .../org/apache/commons/jci/classes/SimpleDump.java |  69 ++
 .../jci/compilers/AbstractCompilerTestCase.java    | 241 +++++++
 .../jci/readers/ResourceReaderTestCase.java        |  48 ++
 .../commons/jci/stores/ResourceStoreTestCase.java  |  70 ++
 core/src/test/resources/simplelog.properties       |   2 +
 examples/pom.xml                                   |  74 +++
 .../examples/commandline/CommandlineCompiler.java  | 189 ++++++
 .../commons/jci/examples/commandline/package.html  |  20 +
 .../jci/examples/configuration/Configurable.java   |  26 +
 .../configuration/ConfigurationException.java      |  24 +
 .../configuration/ConfigurationReloading.java      |  91 +++
 .../jci/examples/configuration/Something.java      |  28 +
 .../jci/examples/configuration/package.html        |  20 +
 .../org/apache/commons/jci/examples/package.html   |  20 +
 .../jci/examples/serverpages/JspGenerator.java     | 166 +++++
 .../jci/examples/serverpages/JspReader.java        |  59 ++
 .../examples/serverpages/ServerPageServlet.java    | 246 +++++++
 .../commons/jci/examples/serverpages/package.html  |  20 +
 examples/src/main/resources/LICENSE.txt            | 201 ++++++
 examples/src/main/resources/NOTICE.txt             |   5 +
 examples/src/main/webapp/WEB-INF/jsp/Test.jsp      |  23 +
 .../src/main/webapp/WEB-INF/jsp/org/vafer/Test.jsp |  18 +
 examples/src/main/webapp/WEB-INF/web.xml           |  33 +
 fam/pom.xml                                        |  58 ++
 .../AbstractFilesystemAlterationListener.java      | 200 ++++++
 .../jci/monitor/FilesystemAlterationListener.java  |  39 ++
 .../jci/monitor/FilesystemAlterationMonitor.java   | 134 ++++
 .../jci/monitor/FilesystemAlterationObserver.java  |  41 ++
 .../monitor/FilesystemAlterationObserverImpl.java  | 374 +++++++++++
 .../org/apache/commons/jci/monitor/package.html    |  20 +
 fam/src/main/resources/LICENSE.txt                 | 201 ++++++
 fam/src/main/resources/NOTICE.txt                  |   5 +
 .../FilesystemAlterationMonitorTestCase.java       | 322 +++++++++
 fam/src/test/resources/simplelog.properties        |   2 +
 pom.xml                                            | 282 ++++++++
 src/site/resources/jci-logo-white.png              | Bin 0 -> 10303 bytes
 src/site/site.xml                                  |  34 +
 src/site/xdoc/downloads.xml                        |  77 +++
 src/site/xdoc/faq.xml                              |  51 ++
 src/site/xdoc/index.xml                            |  52 ++
 src/site/xdoc/usage.xml                            |  76 +++
 133 files changed, 12157 insertions(+)

diff --git a/KEYS.txt b/KEYS.txt
new file mode 100644
index 0000000..24f9d5b
--- /dev/null
+++ b/KEYS.txt
@@ -0,0 +1,722 @@
+This file contains the PGP keys of various developers.
+Please don't use them for email unless you have to. Their main
+purpose is code signing.
+
+Users: pgp < KEYS
+Developers:
+        pgp -kxa <your name> and append it to this file.
+        (pgpk -ll <your name> && pgpk -xa <your name>) >> this file.
+        (gpg --list-sigs <your name>
+             && gpg --armor --export <your name>) >> this file.
+
+pub   1024D/7C200941 2004-04-24
+uid                  Torsten Curdt <tcurdt at apache.org>
+sig 3        7C200941 2004-09-25  Torsten Curdt <tcurdt at apache.org>
+sig 3        23CB7A2A 2004-04-27  David Crossley <crossley at apache.org>
+sig          C4C57B42 2004-06-23  Marcus Crafter <crafterm at debian.org>
+sig 3        7C200941 2004-04-24  Torsten Curdt <tcurdt at apache.org>
+sig 3        015AFC8A 2004-10-16  Bertrand Delacretaz <bdelacretaz at apache.org>
+sig 3        E2D774DF 2004-10-28  Sylvain Wallez <sylvain at apache.org>
+sig 3        E41EDC7E 2004-10-30  Carsten Ziegeler <cziegeler at apache.org>
+sig 3        298BC7D0 2004-11-16  Justin Mason <jm at jmason.org>
+sig 3        EC140B81 2004-11-16  Dirk-Willem van Gulik <dirkx at asemantics.com>
+sig 3        E04F9A89 2004-11-17  Roy T. Fielding <fielding at gbiv.com>
+sig          873CF1AD 2004-11-19  Cory Friend <cory.friend at atmosenergy.com>
+sig 3        A99F75DD 2004-11-23  Rodent of Unusual Size <coar at OpenSource.Org>
+sig 3        12BFE79A 2004-11-22  Kevin L. Collins (General Purpose Key) <kcollins at klcollins.org>
+sig 3        2C312D2F 2004-11-23  Rodent of Unusual Size <coar at OpenSource.Org>
+sig 3        302DA568 2004-11-23  Rodent of Unusual Size (DSA) <coar at Apache.Org>
+sig 3        D1AA8962 2004-11-24  Brian Behlendorf <brian at collab.net>
+sig          6C7C4F5D 2004-11-17  Robyn Wagner, Esq. <robyn at rwlaw.us>
+sig 3        E0D4776D 2004-11-22  Ilkka Tammela (illord) <ilkka.tammela at iki.fi>
+sig 2        E580B363 2004-12-06  Theo Van Dinter <felicity at kluge.net>
+sig 3        1C43D850 2004-11-29  Heather Stephens <heathers at apache.org>
+sig 2        E4136392 2004-12-11  Noel J. Bergman <noel at apache.org>
+sig 3        16A8D3AB 2004-12-14  Julie MacNaught <jmacna at apache.org>
+sig          152924AF 2004-12-03  Sander Temme <sander at temme.net>
+sig          3BAFDEC8 2005-02-02  Tim Engelhardt <mail at timengelhardt.de>
+sig          084C9113 2005-02-08  Brett Porter <brett at apache.org>
+sig          A54746D8 2005-04-26  Joan Ametller Esquerra <Joan.Ametller at uab.cat>
+sig          8103A37E 2005-07-20  Andre Malo <nd at apache.org>
+sig          5793498F 2005-07-21  Tim Ellison <tim at ellison.name>
+sig 2        FC243F3C 2005-07-20  Henk P. Penning <penning at cs.uu.nl>
+sig 3        EE65E321 2005-07-20  Martin Kraemer <martin at apache.org>
+sig 3        21D0A71B 2005-07-20  Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx at anywi.com>
+sig 3        3642CB4B 2005-07-20  Martin Kraemer <martin at apache.org>
+sig 3        2261D073 2005-07-20  Astrid Kessler (Kess) <kess at kess-net.de>
+sig          1CD4861F 2005-07-22  Eran Chinthaka (Web mail) <eran.chinthaka at gmail.com>
+sig          EA1BA38D 2005-07-25  Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith at apache.org>
+sig 3        9C85222B 2004-12-18  Henning Schmiedehausen <hps at intermeta.de>
+sig 3        CC78C893 2005-07-22  Rich Bowen <rbowen at rcbowen.com>
+sig 3        87315C31 2005-07-23  Raphaël Luta <raphael.luta at aptiwan.com>
+sig 3        F39B3750 2005-07-24  Colm MacCarthaigh <colm at allcosts.net>
+sig 3        40581837 2005-07-24  Nick Kew <nick at webthing.com>
+sig 3        9978AF86 2005-07-25  Christoph Probst <chris at netzpunkt.org>
+sig 3        2A623F72 2005-07-25  Christoph Probst <chris at netzpunkt.org>
+sig 3        C152431A 2005-07-27  Steve Loughran <stevel at apache.org>
+sig 3        5F6B8B72 2005-07-22  Stefan Bodewig <bodewig at apache.org>
+sig          E2226795 2005-12-14  Justin R. Erenkrantz <justin at erenkrantz.com>
+sig          AB821FBC 2005-12-15  Andrew McIntyre <fuzzylogic at apache.org>
+sig          A43C4492 2005-12-18  Carlos Sanchez <carlos.sanchez at mergere.com>
+sig 2        E4B880E2 2005-12-17  Michael Parker <parkerm at pobox.com>
+sig 3        35C100F0 2005-12-14  Bernt M. Johnsen <bernt at apache.org>
+sig 3        08C975E5 2005-12-15  Jim Jagielski <jim at apache.org>
+sig 3        A879FCF5 2005-12-16  Gregory Trubetskoy (Grisha) <grisha at ispol.com>
+sig 3        BB96EB06 2005-12-21  Saminda Wishwajith Abeyruwan (this is my first key) <samindaa at gmail.com>
+sig          6103BF59 2006-01-17  Davanum Srinivas <dims at wso2.com>
+sig          28284F99 2006-01-17  Davanum Srinivas <dims at wso2.com>
+sig 3        75A67692 2006-02-22  Erik Abele <erik at codefaktor.de>
+sig 3        0C8EBFBE 2006-03-07  David Van Couvering (My Apache Key) <davidvc at apache.org>
+sig          17AA5B25 2006-06-06  [User ID not found]
+sig          CE419C8F 2006-12-29  Upayavira <upayavira at odoko.co.uk>
+sig          4D2313D5 2007-02-26  Adriaan Peeters <apeeters at lashout.net>
+sig          F2D8462F 2007-02-26  Richard Braun (Syn) <syn at hurdfr.org>
+sig          872CBA04 2007-02-26  David C. Weichert <dcweichert at freenet.de>
+sig          12EEF62A 2007-02-25  David Härdeman <david at hardeman.nu>
+sig          800969EF 2007-02-25  Samuel Mimram <samuel.mimram at ens-lyon.org>
+sig          C5D34D05 2007-02-25  Philip Paeps <philip at paeps.cx>
+sig          E1C21845 2007-02-26  [User ID not found]
+sig          C272A126 2007-02-26  Andreas Jaeger <aj at suse.de>
+sig          D7273981 2007-02-26  Rutger Claes <rgc at rgc.be>
+sig          9161E911 2007-02-25  Alexander Prinsier <aphexer at mailhaven.com>
+sig          9E4A9C9D 2007-02-26  Pierre Letouzey <Pierre.Letouzey at pps.jussieu.fr>
+sig          747935DD 2007-02-25  Cyril Brulebois <cyril.brulebois at enst-bretagne.fr>
+sig          D0AB4075 2007-02-26  Pascal Terjan (Professional) <pterjan at mandriva.com>
+sig          AC1E715E 2007-02-26  Jeroen Dekkers <jeroen at dekkers.cx>
+sig 3        0DC0B7D6 2007-02-26  Wouter van Heyst <larstiq at larstiq.dyndns.org>
+sig          01FA8B4A 2007-02-26  Sune Vuorela <sune at vuorela.dk>
+sig          211B6EEF 2007-02-26  Wytze van der Raay <wytze at NLnet.nl>
+sig          9DFFAAD4 2007-02-26  Ludovic Brenta <lbrenta at debian.org>
+sig          968BD587 2007-02-26  Michael Bienia <michael at vorlon.ping.de>
+sig          AE4D1CD4 2007-02-26  Frederic Lepied <fred at lepied.com>
+sig          023B3F4F 2007-02-26  Lucas Nussbaum <lucas at lucas-nussbaum.net>
+sig          9B7C328D 2007-02-25  Luk Claes <luk at debian.org>
+sig          0DCB0431 2007-02-26  Daniel Hess <daniel at rio-grande.ping.de>
+sig          E63CD6D6 2007-02-26  Daniel Hess <daniel at rio-grande.ping.de>
+sig 3        406CDBF5 2007-02-25  Ludovic Hirlimann <ludovic at joost.com>
+sig          08AC04F9 2007-03-01  Eric Kow <eric.kow at gmail.com>
+sig     PN   AF79D29E 2007-03-02  Wouter Verhelst <wouter at grep.be>
+sig          1B9CC2EA 2007-02-27  Asbjørn Sloth Tønnesen (Personal) <asbjorn at asbjorn.it>
+sig          962E3890 2007-02-28  Arjan Oosting <arjanoosting at home.nl>
+sig          91A707E4 2007-02-28  Thomas Schwinge <tschwinge at gnu.org>
+sig          3AF59D16 2007-02-26  Matthew Walster <matthew at walster.org>
+sig          AAE6022E 2007-03-04  Karlheinz Geyer (TUD) <geyerk.fv.tu at nds.tu-darmstadt.de>
+sig          61FFDAAB 2007-02-28  Marcin Juszkiewicz (HaeRWu) <haerwu at hrw.one.pl>
+sig 3   P    CF3401A9 2007-03-06  Elmar Hoffmann <elho at elho.net>
+sig          969457F0 2007-03-07  Joost van Baal <joostvb at mdcc.cx>
+sig          0B86B067 2007-03-08  Joost E. van Baal (Nederland, 1970)
+sig          6AABC2A1 2007-03-12  Hans Ulrich Niedermann <hun at n-dimensional.de>
+sig          B79A871C 2007-03-14  Maurice van der Pot (Griffon26) <griffon26 at gentoo.org>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.5 (Darwin)
+
+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
+BK5NHNRi2gCfWQn5pP1JbnV3wNIx3yywSv09KcIAoL/DFZFJCR2TgtIOQIECVPBA
+Z6zsiEYEEBECAAYFAkXi0GUACgkQ2hliNwI7P09B0QCgqvptBGodRwt8J6nL0oAq
+MsSwJVUAoKzebdxfiA7AMgFt4YW3N9U7SJFqiEYEEBECAAYFAkXiFVwACgkQ5UTe
+B5t8Mo2ZKQCdGTQk4j0IyTMvtP9smSBmeFqfTX4AoJ0iPQLfeLgBX7+ed89gBDIX
+x2TJiQEcBBABAgAGBQJF4ytkAAoJEOjgYvYNywQxzwIH+wSUjYkgRkHzJgurWvGx
+gy1mu+nXgssC95mdXCGDPb6jNhVvNsxVVJ4WMlMpvhXwNmUqqBNEnTYmfI+7VqZ6
+ZFmqNFhHqd/WEyRjAeVSoQs3S2HeqZfjB+hAzXUckQ6sMPrJPXDQORjHQ2wBn1kX
+dr5pjaxBv3JXW3RDVagGZsQ8HRRoir4Xp+DyFAupCTqgc5AGzB1gf4OLY6IGY+1Q
+kYn2qy6ANeMZrzTEFfPb5JNWyY9aCUZH3pip00JEtusf5fkMH7sxi4EBzRZRHtB9
+0LHaIfQof/IvzEfKEygoFK3sBQ/IQ+aGKOsPIgNO0tUrcJTLHmHjbs+8G4JtBzgA
+AGmIRgQQEQIABgUCReMsPwAKCRAonP/A5jzW1iDvAJsEF/A/e7ebPZUOcD7EbETz
+wPhpMACfXYrV+NzTak7xlK43ZE22W1eIX/CIRgQTEQIABgUCReHiJwAKCRC1IYnk
+QGzb9VBlAJ4tmyRPfi9y5T0/OoMYUbSS4TxR5QCfcrFUCLlv0qjgYcWt5U3AXZ/0
+zoKIRgQQEQIABgUCRec8wAAKCRAFSs7CCKwE+S2vAJwLMrk8a/DhJ93/MOnnIu7p
+IMHHxgCgm8S7V7SKmHF+untnDtne3F52Y7yI9QQQEQIAtQUCRef6AocUgAAAAAAQ
+AG5zaWdub3Rlc0BncmVwLmJlImh0dHA6Ly93d3cuZ3JlcC5iZS9ncGcvNDI2NzEw
+MTNGOTRBMEFCRUI0Q0U5QjZEM0RGQzJDNjJBRjc5RDI5RS8zOTA5QzI4NzkyMzI3
+RkFEMzgxMDBFQUYwNDYzM0E1NzdDMjAwOTQxLmFzYyImGmh0dHA6Ly93d3cuZ3Jl
+cC5iZS9ncGcvY2VydC1wb2xpY3ktdjIACgkQPfwsYq950p7dNwCePxBdSt6rpxO/
+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
+QpLIEy9J3X2KrVpX2CLKTBtuy42BYFWXA+mL/Twh+hc/weICXEZ06fbd9I57U/7A
+hsFJxXJ1WrZZL7SgGYQJJIUK07mTDM/YuvrtOKF676jIrqecs3hc/fif0sf3topA
+tGHxwBq9SIerHXrJVkIHWB56BYp4l5gguT0eiEYEEBECAAYFAkXjLD8ACgkQKJz/
+wOY81tbV2QCeLmFNw8FlWlLqZAeK4xxy664mDdEAoL2svJk3qqXaiQst8vaLTRcw
+Oi70iEYEExECAAYFAkXh4icACgkQtSGJ5EBs2/WtuwCgjl3ni5tZD7lQUumJlCNk
+HD+NJysAnRztskSht7CgB9OR7dB08mFlFfk+iEYEEBECAAYFAkXnPMIACgkQBUrO
+wgisBPm6SACg5q2oRLWPox43iWtQBz6vZisiCsYAoKYOyVzY167OUoQhHVD94Nag
+ZM6HiEYEEBECAAYFAkXjlVkACgkQOHNNd4eQFFIVJgCg9spqXrLw5Y6cB6V6yb0B
+XDxQxnQAoO6O3kcoDMgTkSxNDOXbVzbZNATliPUEEBECALUFAkXn+gWHFIAAAAAA
+EABuc2lnbm90ZXNAZ3JlcC5iZSJodHRwOi8vd3d3LmdyZXAuYmUvZ3BnLzQyNjcx
+MDEzRjk0QTBBQkVCNENFOUI2RDNERkMyQzYyQUY3OUQyOUUvMzkwOUMyODc5MjMy
+N0ZBRDM4MTAwRUFGMDQ2MzNBNTc3QzIwMDk0MS5hc2MiJhpodHRwOi8vd3d3Lmdy
+ZXAuYmUvZ3BnL2NlcnQtcG9saWN5LXYyAAoJED38LGKvedKerzUAnjVXt6J1glkw
++A4QwRGkwpjWjXetAJ9cEvK0swKHE5a8TFzFQPXWtMr4ZIhGBBARAgAGBQJF5MBD
+AAoJEElYlpcbnMLq3lcAnjgCwT9oizaNBSp6Ex59djBqbpzDAJ9ErV4g2fb6R1ES
+kCIRHSTlAAhWRohGBBARAgAGBQJF5VrtAAoJEFAC77GWLjiQ+4EAn30Mj+CXdK9t
+9HK5mh/Wl5KFpT9FAJ42QxV21HpoOeO0L4zH+1W3znJdJYhGBBARAgAGBQJF5bML
+AAoJEM6A78SRpwfkW9cAn3SBm24dTSRsiHtXXYQkpS/I7QF8AJ9//qbEYEcGqB+Z
+T0aN/A1oJwcSbIhGBBARAgAGBQJF4xzCAAoJEHCyAyE69Z0WJcgAoIidGye6K3yI
+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
+=zTu4
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/NOTICE.txt b/NOTICE.txt
new file mode 100644
index 0000000..adaa0b5
--- /dev/null
+++ b/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..5190293
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,14 @@
+In order to build commons-jci please use subversion to check it out via
+
+ svn co http://svn.apache.org/repos/asf/jakarta/commons/proper/jci/trunk/
+
+You need to have maven 2.0.x installed. All you need to do is to call
+
+ mvn clean install
+
+Releases are done with
+
+ mvn -Prelease release:prepare
+ mvn -Prelease release:perform
+
+It is suggested to be using a ssh and gpg agent for the release process.
diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..9f8c672
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,15 @@
+o compiler implementations
+  o jsr199
+  o jikes
+  o pizza
+  o jruby (maybe?)
+  o jpython (maybe?)
+  o c# (maybe?)
+o documentation
+o dependency analysis for proper re-try after errors
+o removing of anonymous classes if parent class is being removed
+o ability to add (contents of) jars to the store ...and be able to remove them again
+o maven plugin to compile with any of the compilers -> codehaus.org/mojo
+o compiler discovery via META-INF
+o finish common configuration for some compilers
+o build javac classpath from provided classloader
diff --git a/build-dists.sh b/build-dists.sh
new file mode 100755
index 0000000..52baf3b
--- /dev/null
+++ b/build-dists.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+set -e
+
+BASE=`pwd`
+
+RC=`xml sel -N m=http://maven.apache.org/POM/4.0.0 -t -v '/m:project/m:properties/m:release.tag' $BASE/pom.xml`
+STAGING=`xml sel -N m=http://maven.apache.org/POM/4.0.0 -t -v "/m:project/m:profiles/m:profile[m:id/text() = 'release']/m:distributionManagement/m:repository/m:url" $BASE/pom.xml | sed "s/\\${commons.deployment.protocol}:\/\//$USER@/" | sed "s/\\${release.tag}/$RC/" | sed 's#/#:/#'`
+RELEASE=`echo $RC|sed s/-.*//`
+
+echo "creating $RELEASE from $RC at $STAGING"
+
+MAVEN_RELEASE="$BASE/target/maven-dist"
+DIST="$BASE/target/dist"
+
+
+rm -Rf $DIST 2>/dev/null || true
+find $BASE/target -name "commons-jci*" -delete
+
+
+rm -R $MAVEN_RELEASE 2>/dev/null || true
+scp -r $STAGING $MAVEN_RELEASE
+
+
+# build binary dist
+
+LIB="$DIST/bin/commons-jci-$RELEASE-bin/lib"
+mkdir -p $LIB 2>/dev/null
+
+JARS=`find $MAVEN_RELEASE -type f -name "*-$RELEASE.jar"`
+
+for A in $JARS ; do
+    cp $A $LIB
+done
+
+cp $BASE/LICENSE.txt $BASE/NOTICE.txt $DIST/bin/commons-jci-$RELEASE-bin/
+
+cd $DIST/bin
+
+tar czvf $BASE/target/commons-jci-$RELEASE-bin.tar.gz .
+zip -r $BASE/target/commons-jci-$RELEASE-bin.zip .
+
+cd -
+
+
+
+
+# build source dist
+
+SOURCE=`xml sel -N m=http://maven.apache.org/POM/4.0.0 -t -v "/m:project/m:scm/m:developerConnection" $BASE/pom.xml | sed 's/scn:svn://' | sed "s/trunk/tags\/$RC/"`
+
+mkdir -p $DIST/src 2>/dev/null
+cd $DIST/src
+
+svn co $SOURCE commons-jci-$RELEASE-src
+
+tar czvf $BASE/target/commons-jci-$RELEASE-src.tar.gz --exclude .svn --exclude target --exclude dist.sh .
+zip -r $BASE/target/commons-jci-$RELEASE-src.zip . -x "*.svn/*" -x "target/*"
+
+
+# sign
+
+ARTIFACTS="`find $BASE/target -name *.zip -maxdepth 1` `find $BASE/target -name *.tar.gz -maxdepth 1`"
+
+RUNNING=`ps -ax | grep gpg-agent | grep -v grep`
+if [ -z "$RUNNING" ]; then
+  echo "starting gpg-agent..."
+  gpg-agent --daemon --use-standard-socket > $HOME/.gnupg/.gpg-agent
+fi
+
+export GPG_AGENT_INFO="$HOME/.gnupg/S.gpg-agent:4559:1"
+
+for A in $ARTIFACTS ; do
+  echo $A
+  rm $A.asc* 2>/dev/null || true
+  gpg --armor --output $A.asc --detach-sig $A
+  openssl md5 < $A > $A.md5
+  openssl sha1 < $A > $A.sha1
+done
+
+for A in $ARTIFACTS ; do
+  echo $A
+  gpg --verify $A.asc $A
+done
diff --git a/compilers/eclipse/pom.xml b/compilers/eclipse/pom.xml
new file mode 100644
index 0000000..9dba78a
--- /dev/null
+++ b/compilers/eclipse/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-eclipse</artifactId>
+    <version>1.0</version>
+    <name>compiler-eclipse</name>
+    <description>
+        Commons JCI compiler implementation for the eclipse compiler.
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jdt</groupId>
+            <artifactId>core</artifactId>
+            <version>3.2.0.658</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseCompilationProblem.java b/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseCompilationProblem.java
new file mode 100755
index 0000000..cdfeecf
--- /dev/null
+++ b/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseCompilationProblem.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * Wrapping an Eclipse compiler problem
+ * 
+ * @author tcurdt
+ */
+public final class EclipseCompilationProblem implements CompilationProblem {
+
+    private final IProblem problem;
+
+    public EclipseCompilationProblem(final IProblem pProblem) {
+        problem = pProblem;
+    }
+
+    public boolean isError() {
+        return problem.isError();
+    }
+
+    public String getFileName() {
+        return new String(problem.getOriginatingFileName());
+    }
+
+    public int getStartLine() {
+        return problem.getSourceLineNumber();
+    }
+
+    public int getStartColumn() {
+        return problem.getSourceStart();
+    }
+
+    public int getEndLine() {
+        return getStartLine();
+    }
+
+    public int getEndColumn() {
+        return problem.getSourceEnd();
+    }
+
+    public String getMessage() {
+        return problem.getMessage();
+    }
+
+    public String toString() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append(getFileName()).append(" (");
+        sb.append(getStartLine());
+        sb.append(":");
+        sb.append(getStartColumn());
+        sb.append(") : ");
+        sb.append(getMessage());
+        return sb.toString();
+    }
+
+    public int getId() {
+        return problem.getID();
+    }
+
+}
diff --git a/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseJavaCompiler.java b/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseJavaCompiler.java
new file mode 100644
index 0000000..f7dddb0
--- /dev/null
+++ b/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseJavaCompiler.java
@@ -0,0 +1,378 @@
+/*
+ * 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.
+ */
+package org.apache.commons.jci.compilers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+
+/**
+ * Eclipse compiler implemenation
+ * 
+ * @author tcurdt
+ */
+public final class EclipseJavaCompiler extends AbstractJavaCompiler {
+
+    private final Log log = LogFactory.getLog(EclipseJavaCompiler.class);
+    private final EclipseJavaCompilerSettings defaultSettings;
+
+    public EclipseJavaCompiler() {
+        this(new EclipseJavaCompilerSettings());
+    }
+
+    public EclipseJavaCompiler(final Map pSettings) {
+        defaultSettings = new EclipseJavaCompilerSettings(pSettings);
+    }
+
+    public EclipseJavaCompiler(final EclipseJavaCompilerSettings pSettings) {
+        defaultSettings = pSettings;
+    }
+
+    final class CompilationUnit implements ICompilationUnit {
+
+        final private String clazzName;
+        final private String fileName;
+        final private char[] typeName;
+        final private char[][] packageName;
+        final private ResourceReader reader;
+
+        CompilationUnit( final ResourceReader pReader, final String pSourceFile ) {
+            reader = pReader;
+            clazzName = ConversionUtils.convertResourceToClassName(pSourceFile);
+            fileName = pSourceFile;
+            int dot = clazzName.lastIndexOf('.');
+            if (dot > 0) {
+                typeName = clazzName.substring(dot + 1).toCharArray();
+            } else {
+                typeName = clazzName.toCharArray();
+            }
+            
+            log.debug("className=" + clazzName);
+            log.debug("fileName=" + fileName);
+            log.debug("typeName=" + new String(typeName)); 
+            
+            final StringTokenizer izer = new StringTokenizer(clazzName, ".");
+            packageName = new char[izer.countTokens() - 1][];
+            for (int i = 0; i < packageName.length; i++) {
+                packageName[i] = izer.nextToken().toCharArray();
+                log.debug("package[" + i + "]=" + new String(packageName[i]));
+            }
+        }
+
+        public char[] getFileName() {
+            return fileName.toCharArray();
+        }
+
+        public char[] getContents() {
+            final byte[] content = reader.getBytes(fileName);
+
+            if (content == null) {
+                return null;
+                //throw new RuntimeException("resource " + fileName + " could not be found");
+            }
+
+            return new String(content).toCharArray();
+        }
+
+        public char[] getMainTypeName() {
+            return typeName;
+        }
+
+        public char[][] getPackageName() {
+            return packageName;
+        }
+    }
+
+    
+    public org.apache.commons.jci.compilers.CompilationResult compile(
+            final String[] pSourceFiles,
+            final ResourceReader pReader,
+            final ResourceStore pStore,
+            final ClassLoader pClassLoader,
+            final JavaCompilerSettings pSettings
+            ) {
+
+        final Map settingsMap = ((EclipseJavaCompilerSettings) defaultSettings).getMap();
+        
+        final Collection problems = new ArrayList();
+        
+        final ICompilationUnit[] compilationUnits = new ICompilationUnit[pSourceFiles.length];
+        for (int i = 0; i < compilationUnits.length; i++) {
+            final String sourceFile = pSourceFiles[i];
+            
+            if (pReader.isAvailable(sourceFile)) {            
+                compilationUnits[i] = new CompilationUnit(pReader, sourceFile);
+                log.debug("compiling " + sourceFile);
+            } else {
+                // log.error("source not found " + sourceFile);
+
+                final CompilationProblem problem = new CompilationProblem() {
+
+                    public int getEndColumn() {
+                        return 0;
+                    }
+
+                    public int getEndLine() {
+                        return 0;
+                    }
+
+                    public String getFileName() {
+                        return sourceFile;
+                    }
+
+                    public String getMessage() {
+                        return "Source " + sourceFile + " could not be found";
+                    }
+
+                    public int getStartColumn() {
+                        return 0;
+                    }
+
+                    public int getStartLine() {
+                        return 0;
+                    }
+
+                    public boolean isError() {
+                        return true;
+                    }
+                    
+                    public String toString() {
+                        return getMessage();
+                    }
+                };
+
+                if (problemHandler != null) {
+                    problemHandler.handle(problem);
+                }
+                
+                problems.add(problem);
+            }
+        }
+
+        if (problems.size() > 0) {
+            final CompilationProblem[] result = new CompilationProblem[problems.size()];
+            problems.toArray(result);
+            return new org.apache.commons.jci.compilers.CompilationResult(result);
+        }
+        
+        final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems();
+        final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());
+        final INameEnvironment nameEnvironment = new INameEnvironment() {
+
+            public NameEnvironmentAnswer findType( final char[][] pCompoundTypeName ) {
+                final StringBuffer result = new StringBuffer();
+                for (int i = 0; i < pCompoundTypeName.length; i++) {
+                    if (i != 0) {
+                        result.append('.');
+                    }
+                    result.append(pCompoundTypeName[i]);
+                }
+
+                //log.debug("finding compoundTypeName=" + result.toString());
+
+                return findType(result.toString());
+            }
+
+            public NameEnvironmentAnswer findType( final char[] pTypeName, final char[][] pPackageName ) {
+                final StringBuffer result = new StringBuffer();
+                for (int i = 0; i < pPackageName.length; i++) {
+                    result.append(pPackageName[i]);
+                    result.append('.');
+                }
+                
+//                log.debug("finding typeName=" + new String(typeName) + " packageName=" + result.toString());
+
+                result.append(pTypeName);
+                return findType(result.toString());
+            }
+
+            private NameEnvironmentAnswer findType( final String pClazzName ) {
+                
+                if (isPackage(pClazzName)) {
+                    return null;
+                }
+                
+                log.debug("finding " + pClazzName);
+                
+                final String resourceName = ConversionUtils.convertClassToResourcePath(pClazzName);
+                
+                final byte[] clazzBytes = pStore.read(pClazzName);
+                if (clazzBytes != null) {
+                    log.debug("loading from store " + pClazzName);
+
+                    final char[] fileName = pClazzName.toCharArray();
+                    try {
+                        final ClassFileReader classFileReader = new ClassFileReader(clazzBytes, fileName, true);
+                        return new NameEnvironmentAnswer(classFileReader, null);
+                    } catch (final ClassFormatException e) {
+                        log.error("wrong class format", e);
+                        return null;
+                    }
+                }
+                
+                log.debug("not in store " + pClazzName);
+                
+                final InputStream is = pClassLoader.getResourceAsStream(resourceName);
+                if (is == null) {
+                    log.debug("class " + pClazzName + " not found");
+                    return null;
+                }
+
+                final byte[] buffer = new byte[8192];
+                final ByteArrayOutputStream baos = new ByteArrayOutputStream(buffer.length);
+                int count;
+                try {
+                    while ((count = is.read(buffer, 0, buffer.length)) > 0) {
+                        baos.write(buffer, 0, count);
+                    }
+                    baos.flush();
+                    final char[] fileName = pClazzName.toCharArray();
+                    final ClassFileReader classFileReader = new ClassFileReader(baos.toByteArray(), fileName, true);
+                    return new NameEnvironmentAnswer(classFileReader, null);
+                } catch (final IOException e) {
+                    log.error("could not read class", e);
+                    return null;
+                } catch (final ClassFormatException e) {
+                    log.error("wrong class format", e);
+                    return null;
+                } finally {
+                    try {
+                        baos.close();
+                    } catch (final IOException oe) {
+                        log.error("could not close output stream", oe);
+                    }
+                    try {
+                        is.close();
+                    } catch (final IOException ie) {
+                        log.error("could not close input stream", ie);
+                    }
+                }
+            }
+
+            private boolean isPackage( final String pClazzName ) {
+                
+                final InputStream is = pClassLoader.getResourceAsStream(ConversionUtils.convertClassToResourcePath(pClazzName));
+                if (is != null) {
+                    log.debug("found the class for " + pClazzName + "- no package");
+                    return false;
+                }
+                
+                // FIXME: this should not be tied to the extension
+                final String source = pClazzName.replace('.', '/') + ".java";
+                if (pReader.isAvailable(source)) {
+                    log.debug("found the source " + source + " for " + pClazzName + " - no package ");
+                    return false;
+                }
+                
+                return true;
+            }
+
+            public boolean isPackage( char[][] parentPackageName, char[] pPackageName ) {
+                final StringBuffer result = new StringBuffer();
+                if (parentPackageName != null) {
+                    for (int i = 0; i < parentPackageName.length; i++) {
+                        if (i != 0) {
+                            result.append('.');
+                        }
+                        result.append(parentPackageName[i]);
+                    }
+                }
+                
+//                log.debug("isPackage parentPackageName=" + result.toString() + " packageName=" + new String(packageName));
+                
+                if (parentPackageName != null && parentPackageName.length > 0) {
+                    result.append('.');
+                }
+                result.append(pPackageName);
+                return isPackage(result.toString());
+            }
+
+            public void cleanup() {
+                log.debug("cleanup");
+            }
+        };
+
+        final ICompilerRequestor compilerRequestor = new ICompilerRequestor() {
+            public void acceptResult( final CompilationResult pResult ) {
+                if (pResult.hasProblems()) {
+                    final IProblem[] iproblems = pResult.getProblems();
+                    for (int i = 0; i < iproblems.length; i++) {
+                        final IProblem iproblem = iproblems[i];
+                        final CompilationProblem problem = new EclipseCompilationProblem(iproblem); 
+                        if (problemHandler != null) {
+                            problemHandler.handle(problem);
+                        }
+                        problems.add(problem);
+                    }
+                }
+                if (!pResult.hasErrors()) {
+                    final ClassFile[] clazzFiles = pResult.getClassFiles();
+                    for (int i = 0; i < clazzFiles.length; i++) {
+                        final ClassFile clazzFile = clazzFiles[i];
+                        final char[][] compoundName = clazzFile.getCompoundName();
+                        final StringBuffer clazzName = new StringBuffer();
+                        for (int j = 0; j < compoundName.length; j++) {
+                            if (j != 0) {
+                                clazzName.append('.');
+                            }
+                            clazzName.append(compoundName[j]);
+                        }
+                        pStore.write(clazzName.toString().replace('.', '/') + ".class", clazzFile.getBytes());
+                    }
+                }
+            }
+        };
+
+        final Compiler compiler = new Compiler(nameEnvironment, policy, settingsMap, compilerRequestor, problemFactory, false);
+
+        compiler.compile(compilationUnits);
+
+        final CompilationProblem[] result = new CompilationProblem[problems.size()];
+        problems.toArray(result);
+        return new org.apache.commons.jci.compilers.CompilationResult(result);
+    }
+
+    public JavaCompilerSettings createDefaultSettings() {
+        return defaultSettings;
+    }
+}
diff --git a/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseJavaCompilerSettings.java b/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseJavaCompilerSettings.java
new file mode 100644
index 0000000..e589562
--- /dev/null
+++ b/compilers/eclipse/src/main/java/org/apache/commons/jci/compilers/EclipseJavaCompilerSettings.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+/**
+ * Native Eclipse compiler settings
+ * 
+ * @author tcurdt
+ */
+public final class EclipseJavaCompilerSettings extends JavaCompilerSettings {
+
+    final private Map defaultEclipseSettings = new HashMap();
+
+    public EclipseJavaCompilerSettings() {
+        defaultEclipseSettings.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
+        defaultEclipseSettings.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE);
+        defaultEclipseSettings.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE);
+        defaultEclipseSettings.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
+    }
+    
+    public EclipseJavaCompilerSettings( final Map pMap ) {
+        defaultEclipseSettings.putAll(pMap);
+    }
+    
+    Map getMap() {
+        final Map map = new HashMap(defaultEclipseSettings);
+
+        map.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.GENERATE);
+        map.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+        map.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
+        map.put(CompilerOptions.OPTION_Encoding, "UTF-8");
+
+        return map;
+    }
+    
+    public String toString() {
+        return defaultEclipseSettings.toString();
+    }
+}
diff --git a/compilers/eclipse/src/main/resources/LICENSE.txt b/compilers/eclipse/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/compilers/eclipse/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/compilers/eclipse/src/main/resources/NOTICE.txt b/compilers/eclipse/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..eab85a0
--- /dev/null
+++ b/compilers/eclipse/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - Eclipse Compiler Implementation
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java b/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java
new file mode 100644
index 0000000..6b3c5db
--- /dev/null
+++ b/compilers/eclipse/src/test/java/org/apache/commons/jci/compilers/EclipseJavaCompilerTestCase.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+public final class EclipseJavaCompilerTestCase extends AbstractCompilerTestCase {
+
+    public String getCompilerName() {
+        return "eclipse";
+    }
+
+    public JavaCompiler createJavaCompiler() {
+        return new EclipseJavaCompiler();
+    }
+
+}
diff --git a/compilers/eclipse/src/test/resources/simplelog.properties b/compilers/eclipse/src/test/resources/simplelog.properties
new file mode 100644
index 0000000..6bd0ec9
--- /dev/null
+++ b/compilers/eclipse/src/test/resources/simplelog.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.simplelog.defaultlog=debug
+org.apache.commons.logging.simplelog.showdatetime=true
\ No newline at end of file
diff --git a/compilers/groovy/pom.xml b/compilers/groovy/pom.xml
new file mode 100644
index 0000000..cae0177
--- /dev/null
+++ b/compilers/groovy/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-groovy</artifactId>
+    <version>1.0</version>
+    <name>compiler-groovy</name>
+    <description>
+        Commons JCI compiler implementation for the groovy compiler.
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>groovy</groupId>
+            <artifactId>groovy-all</artifactId>
+            <version>1.0-jsr-03</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyCompilationProblem.java b/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyCompilationProblem.java
new file mode 100755
index 0000000..617f82c
--- /dev/null
+++ b/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyCompilationProblem.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.codehaus.groovy.control.messages.ExceptionMessage;
+import org.codehaus.groovy.control.messages.Message;
+import org.codehaus.groovy.control.messages.SimpleMessage;
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
+import org.codehaus.groovy.syntax.SyntaxException;
+
+/**
+ * Groovy version of a CompilationProblem
+ * 
+ * @author tcurdt
+ */
+public final class GroovyCompilationProblem implements CompilationProblem {
+
+    private final String fileName;
+    private final String message;
+    private final boolean error;
+    private final int startLine;
+    private final int startColumn;
+    private final int endLine;
+    private final int endColumn;
+
+    public GroovyCompilationProblem(final Message pMessage) {
+        if (pMessage instanceof SimpleMessage) {
+            error = false;
+        } else {
+            error = true;
+        }
+        if (pMessage instanceof SyntaxErrorMessage) {
+            SyntaxErrorMessage syntaxErrorMessage = (SyntaxErrorMessage)pMessage;
+            SyntaxException syntaxException = syntaxErrorMessage.getCause();
+            message = syntaxException.getMessage();
+            fileName = syntaxException.getSourceLocator();
+            // FIXME: getStartLine() vs. getLine()
+            startLine = syntaxException.getStartLine();
+            startColumn = syntaxException.getStartColumn();
+            endLine = syntaxException.getLine();
+            endColumn = syntaxException.getEndColumn();
+        } else {
+            fileName = "";
+            startLine = 0;
+            startColumn = 0;
+            endLine = 0;
+            endColumn = 0;
+            if (pMessage instanceof ExceptionMessage) {
+                message = ((ExceptionMessage)pMessage).getCause().getMessage();
+            } else if (pMessage instanceof SimpleMessage) {
+                message = ((SimpleMessage)pMessage).getMessage();
+            } else {
+                message = pMessage.toString();
+            }
+        }
+    }
+
+    public boolean isError() {
+        return error;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public int getStartLine() {
+        return startLine;
+    }
+
+    public int getStartColumn() {
+        return startColumn;
+    }
+
+    public int getEndLine() {
+        return endLine;
+    }
+
+    public int getEndColumn() {
+        return endColumn;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public String toString() {
+        return getMessage();
+    }
+
+}
diff --git a/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyJavaCompiler.java b/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyJavaCompiler.java
new file mode 100644
index 0000000..ab63eed
--- /dev/null
+++ b/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyJavaCompiler.java
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import groovy.lang.GroovyClassLoader;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.ErrorCollector;
+import org.codehaus.groovy.control.MultipleCompilationErrorsException;
+import org.codehaus.groovy.control.Phases;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.control.messages.Message;
+import org.codehaus.groovy.control.messages.WarningMessage;
+import org.codehaus.groovy.tools.GroovyClass;
+
+/**
+ * Groovy implementation of the JavaCompiler interface
+ * 
+ * @author tcurdt
+ */
+public final class GroovyJavaCompiler extends AbstractJavaCompiler {
+
+    private final Log log = LogFactory.getLog(GroovyJavaCompiler.class);
+    private final GroovyJavaCompilerSettings defaultSettings;
+    
+    public GroovyJavaCompiler() {
+        defaultSettings = new GroovyJavaCompilerSettings(new CompilerConfiguration());
+    }
+        
+    public CompilationResult compile(
+            final String[] pResourceNames,
+            final ResourceReader pReader,
+            final ResourceStore pStore,
+            final ClassLoader pClassLoader,
+            final JavaCompilerSettings pSettings
+            ) {
+
+        final CompilerConfiguration configuration = ((GroovyJavaCompilerSettings) pSettings).getCompilerConfiguration();
+        final ErrorCollector collector = new ErrorCollector(configuration);
+        final GroovyClassLoader groovyClassLoader = new GroovyClassLoader(pClassLoader);
+        final CompilationUnit unit = new CompilationUnit(configuration, null, groovyClassLoader);
+        final SourceUnit[] source = new SourceUnit[pResourceNames.length];
+        for (int i = 0; i < source.length; i++) {
+            final String resourceName = pResourceNames[i];
+            source[i] = new SourceUnit(
+                    ConversionUtils.convertResourceToClassName(resourceName),
+                    new String(pReader.getBytes(resourceName)), // FIXME delay the read
+                    configuration,
+                    groovyClassLoader,
+                    collector
+                    );
+            unit.addSource(source[i]);
+        }
+        
+        final Collection problems = new ArrayList();
+
+        try {
+            log.debug("compiling");
+            unit.compile(Phases.CLASS_GENERATION);
+            
+            final List classes = unit.getClasses();
+            for (final Iterator it = classes.iterator(); it.hasNext();) {
+                final GroovyClass clazz = (GroovyClass) it.next();
+                final byte[] bytes = clazz.getBytes();
+                pStore.write(ConversionUtils.convertClassToResourcePath(clazz.getName()), bytes);
+            }
+        } catch (final MultipleCompilationErrorsException e) {
+            final ErrorCollector col = e.getErrorCollector();
+            final Collection warnings = col.getWarnings();
+            if (warnings != null) {
+                for (final Iterator it = warnings.iterator(); it.hasNext();) {
+                    final WarningMessage warning = (WarningMessage) it.next();
+                    final CompilationProblem problem = new GroovyCompilationProblem(warning); 
+                    if (problemHandler != null) {
+                        problemHandler.handle(problem);
+                    }
+                    problems.add(problem);
+                }
+            }
+
+            final Collection errors = col.getErrors();
+            if (errors != null) {
+                for (final Iterator it = errors.iterator(); it.hasNext();) {
+                    final Message message = (Message) it.next();
+                    final CompilationProblem problem = new GroovyCompilationProblem(message); 
+                    if (problemHandler != null) {
+                        problemHandler.handle(problem);
+                    }
+                    problems.add(problem);
+                }
+            }
+        } catch (CompilationFailedException e) {
+            throw new RuntimeException("no expected");
+        }
+
+        final CompilationProblem[] result = new CompilationProblem[problems.size()];
+        problems.toArray(result);
+        return new CompilationResult(result);
+    }
+
+    public JavaCompilerSettings createDefaultSettings() {
+        return defaultSettings;
+    }
+}
diff --git a/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyJavaCompilerSettings.java b/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyJavaCompilerSettings.java
new file mode 100644
index 0000000..34d9f4b
--- /dev/null
+++ b/compilers/groovy/src/main/java/org/apache/commons/jci/compilers/GroovyJavaCompilerSettings.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.codehaus.groovy.control.CompilerConfiguration;
+
+/**
+ * Native configuration for the Groovy compiler
+ * 
+ * @author tcurdt
+ */
+public final class GroovyJavaCompilerSettings extends JavaCompilerSettings {
+
+    private final CompilerConfiguration settings;
+
+    public GroovyJavaCompilerSettings( final CompilerConfiguration pSettings ) {
+        settings = pSettings;
+    }
+
+    public CompilerConfiguration getCompilerConfiguration() {
+        return settings;
+    }
+
+}
diff --git a/compilers/groovy/src/main/resources/LICENSE.txt b/compilers/groovy/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/compilers/groovy/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/compilers/groovy/src/main/resources/NOTICE.txt b/compilers/groovy/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..320f4b0
--- /dev/null
+++ b/compilers/groovy/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - Groovy Compiler Implementation
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/compilers/groovy/src/test/java/org/apache/commons/jci/compilers/GroovyJavaCompilerTestCase.java b/compilers/groovy/src/test/java/org/apache/commons/jci/compilers/GroovyJavaCompilerTestCase.java
new file mode 100644
index 0000000..21067e4
--- /dev/null
+++ b/compilers/groovy/src/test/java/org/apache/commons/jci/compilers/GroovyJavaCompilerTestCase.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class GroovyJavaCompilerTestCase extends AbstractCompilerTestCase {
+
+    public String getCompilerName() {
+        return "groovy";
+    }
+
+    public JavaCompiler createJavaCompiler() {
+        return new GroovyJavaCompiler();
+    }
+
+    public void testInternalClassCompile() throws Exception {
+        // FIXME: inner classes not supported in groovy?
+    }
+
+}
diff --git a/compilers/groovy/src/test/resources/simplelog.properties b/compilers/groovy/src/test/resources/simplelog.properties
new file mode 100644
index 0000000..6bd0ec9
--- /dev/null
+++ b/compilers/groovy/src/test/resources/simplelog.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.simplelog.defaultlog=debug
+org.apache.commons.logging.simplelog.showdatetime=true
\ No newline at end of file
diff --git a/compilers/janino/pom.xml b/compilers/janino/pom.xml
new file mode 100644
index 0000000..21253be
--- /dev/null
+++ b/compilers/janino/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-janino</artifactId>
+    <version>1.0</version>
+    <name>compiler-janino</name>
+    <description>
+        Commons JCI compiler implementation for the janino compiler.
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>janino</groupId>
+            <artifactId>janino</artifactId>
+            <version>2.4.3</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoCompilationProblem.java b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoCompilationProblem.java
new file mode 100755
index 0000000..c2356e7
--- /dev/null
+++ b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoCompilationProblem.java
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.codehaus.janino.Location;
+import org.codehaus.janino.Scanner.LocatedException;
+
+/**
+ * Janino version of a CompilationProblem
+ * 
+ * @author tcurdt
+ */
+public final class JaninoCompilationProblem implements CompilationProblem {
+
+    private final Location location;
+    private final String fileName;
+    private final String message;
+    private final boolean error;
+
+    public JaninoCompilationProblem(final LocatedException pLocatedException) {
+        this(pLocatedException.getLocation(), pLocatedException.getMessage(), true);
+    }
+
+    public JaninoCompilationProblem(final Location pLocation, final String pMessage, final boolean pError) {
+      this(pLocation.getFileName(), pLocation, pMessage, pError);
+    }
+
+    public JaninoCompilationProblem(final String pFilename, final String pMessage, final boolean pError) {
+        this(pFilename, null, pMessage, pError);
+    }
+
+    public JaninoCompilationProblem(final String pFilename, final Location pLocation, final String pMessage, final boolean pError) {
+        location = pLocation;
+        fileName = pFilename;
+        message = pMessage;
+        error = pError;
+    }
+
+    public boolean isError() {
+        return error;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public int getStartLine() {
+        if (location == null) {
+            return 0;
+        }
+        return location.getLineNumber();
+    }
+
+    public int getStartColumn() {
+        if (location == null) {
+            return 0;
+        }
+        return location.getColumnNumber();
+    }
+
+    public int getEndLine() {
+        return getStartLine();
+    }
+
+    public int getEndColumn() {
+        return getStartColumn();
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public String toString() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append(getFileName()).append(" (");
+        sb.append(getStartLine());
+        sb.append(":");
+        sb.append(getStartColumn());
+        sb.append(") : ");
+        sb.append(getMessage());
+        return sb.toString();
+    }
+
+}
diff --git a/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompiler.java b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompiler.java
new file mode 100644
index 0000000..3b72949
--- /dev/null
+++ b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompiler.java
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.janino.ClassLoaderIClassLoader;
+import org.codehaus.janino.CompileException;
+import org.codehaus.janino.DebuggingInformation;
+import org.codehaus.janino.Descriptor;
+import org.codehaus.janino.IClass;
+import org.codehaus.janino.IClassLoader;
+import org.codehaus.janino.Java;
+import org.codehaus.janino.Location;
+import org.codehaus.janino.Parser;
+import org.codehaus.janino.Scanner;
+import org.codehaus.janino.UnitCompiler;
+import org.codehaus.janino.WarningHandler;
+import org.codehaus.janino.Scanner.LocatedException;
+import org.codehaus.janino.UnitCompiler.ErrorHandler;
+import org.codehaus.janino.util.ClassFile;
+
+/**
+ * @author art at gramlich-net.com
+ */
+public final class JaninoJavaCompiler extends AbstractJavaCompiler {
+
+    private final Log log = LogFactory.getLog(JaninoJavaCompiler.class);
+
+    private class CompilingIClassLoader extends IClassLoader {
+
+        private final Map types = new HashMap();
+        private final ResourceReader resourceReader;
+        private final Map classes;
+        private final Collection problems = new ArrayList();
+
+        private CompilingIClassLoader(final ResourceReader pResourceReader, final Map pClasses, final ClassLoader classLoader) {
+            super( new ClassLoaderIClassLoader( classLoader ) );
+            resourceReader = pResourceReader;
+            classes = pClasses;
+            super.postConstruct();
+        }
+
+        protected Collection getProblems() {
+            return problems;
+        }
+        
+        protected IClass findIClass(final String pType) {
+            final String className = Descriptor.toClassName(pType);
+            if (types.containsKey(pType)) {
+                return (IClass) types.get(pType);
+            }
+            
+            // FIXME: should not be tied to the extension            
+            final String resourceNameFromClass = className.replace('.', '/') + ".java";
+
+            final byte[] content = resourceReader.getBytes(resourceNameFromClass);
+            if (content == null) {
+                return null;
+            }
+            final Reader reader = new BufferedReader(new StringReader(new String(content)));
+            Scanner scanner = null;
+            try {
+                scanner = new Scanner(resourceNameFromClass, reader);
+                final Java.CompilationUnit unit = new Parser(scanner).parseCompilationUnit();
+                final UnitCompiler uc = new UnitCompiler(unit, this);
+                uc.setCompileErrorHandler(new ErrorHandler() {
+                    public void handleError(final String pMessage, final Location pOptionalLocation) throws CompileException {
+                        final CompilationProblem problem = new JaninoCompilationProblem(pOptionalLocation, pMessage, true);
+                        if (problemHandler != null) {
+                            problemHandler.handle(problem);
+                        }
+                        problems.add(problem);
+                    }
+                });
+                uc.setWarningHandler(new WarningHandler() {
+                    public void handleWarning(final String pHandle, final String pMessage, final Location pOptionalLocation) {
+                        final CompilationProblem problem = new JaninoCompilationProblem(pOptionalLocation, pMessage, false);
+                        if (problemHandler != null) {
+                            problemHandler.handle(problem);
+                        }
+                        problems.add(problem);
+                    }
+                });
+                log.debug("compile " + className);
+                final ClassFile[] classFiles = uc.compileUnit(DebuggingInformation.ALL);
+                for (int i = 0; i < classFiles.length; i++) {
+                    log.debug("compiled " + classFiles[i].getThisClassName());
+                    classes.put(classFiles[i].getThisClassName(), classFiles[i].toByteArray());
+                }
+                final IClass ic = uc.findClass(className);
+                if (null != ic) {
+                    types.put(pType, ic);
+                }
+                return ic;
+            } catch (final LocatedException e) {
+                problems.add(new JaninoCompilationProblem(e));
+            } catch (final IOException e) {
+                problems.add(new JaninoCompilationProblem(resourceNameFromClass, "IOException:" + e.getMessage(), true));
+            } catch (final Exception e) {
+                problems.add(new JaninoCompilationProblem(resourceNameFromClass, "Exception:" + e.getMessage(), true));
+            } finally {
+                if (scanner != null) {
+                    try {
+                        scanner.close();
+                    } catch (IOException e) {
+                        log.error("IOException occured while compiling " + className, e);
+                    }
+                }
+            }
+            return null;
+        }
+    }
+
+    public CompilationResult compile( final String[] pSourceNames, final ResourceReader pResourceReader, final ResourceStore pStore, final ClassLoader pClassLoader, final JavaCompilerSettings pSettings ) {
+
+        final Map classFilesByName = new HashMap();       
+        
+        final CompilingIClassLoader icl = new CompilingIClassLoader(pResourceReader, classFilesByName, pClassLoader);
+        for (int i = 0; i < pSourceNames.length; i++) {
+            log.debug("compiling " + pSourceNames[i]);
+            icl.loadIClass(Descriptor.fromClassName(ConversionUtils.convertResourceToClassName(pSourceNames[i])));
+        }
+        
+        // Store all fully compiled classes
+        for (Iterator i = classFilesByName.entrySet().iterator(); i.hasNext();) {
+            final Map.Entry entry = (Map.Entry)i.next();
+            final String clazzName = (String)entry.getKey(); 
+            pStore.write(ConversionUtils.convertClassToResourcePath(clazzName), (byte[])entry.getValue());
+        }
+        
+        final Collection problems = icl.getProblems();
+        final CompilationProblem[] result = new CompilationProblem[problems.size()];
+        problems.toArray(result);
+        return new CompilationResult(result);
+    }
+
+    public JavaCompilerSettings createDefaultSettings() {
+        // FIXME
+        return null;
+    }
+    
+}
diff --git a/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompilerSettings.java b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompilerSettings.java
new file mode 100644
index 0000000..1205943
--- /dev/null
+++ b/compilers/janino/src/main/java/org/apache/commons/jci/compilers/JaninoJavaCompilerSettings.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+public final class JaninoJavaCompilerSettings extends JavaCompilerSettings {
+    // TODO: implement the native janino compiler settings
+}
diff --git a/compilers/janino/src/main/resources/LICENSE.txt b/compilers/janino/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/compilers/janino/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/compilers/janino/src/main/resources/NOTICE.txt b/compilers/janino/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..d8774e4
--- /dev/null
+++ b/compilers/janino/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - Janino Compiler Implementation
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/compilers/janino/src/test/java/org/apache/commons/jci/compilers/JaninoJavaCompilerTestCase.java b/compilers/janino/src/test/java/org/apache/commons/jci/compilers/JaninoJavaCompilerTestCase.java
new file mode 100644
index 0000000..290d371
--- /dev/null
+++ b/compilers/janino/src/test/java/org/apache/commons/jci/compilers/JaninoJavaCompilerTestCase.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class JaninoJavaCompilerTestCase extends AbstractCompilerTestCase {
+
+    public String getCompilerName() {
+        return "janino";
+    }
+
+    public JavaCompiler createJavaCompiler() {
+        return new JaninoJavaCompiler();
+    }
+
+}
diff --git a/compilers/janino/src/test/resources/simplelog.properties b/compilers/janino/src/test/resources/simplelog.properties
new file mode 100644
index 0000000..6bd0ec9
--- /dev/null
+++ b/compilers/janino/src/test/resources/simplelog.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.simplelog.defaultlog=debug
+org.apache.commons.logging.simplelog.showdatetime=true
\ No newline at end of file
diff --git a/compilers/javac/pom.xml b/compilers/javac/pom.xml
new file mode 100644
index 0000000..67d0e63
--- /dev/null
+++ b/compilers/javac/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-javac</artifactId>
+    <version>1.0</version>
+    <name>compiler-javac</name>
+    <description>
+        Commons JCI compiler implementation for the javac compiler (up to JDK 1.5).
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.vafer</groupId>
+            <artifactId>dependency</artifactId>
+            <version>0.2</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/compilers/javac/src/main/java/org/apache/commons/jci/compilers/FileInputStreamProxy.java b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/FileInputStreamProxy.java
new file mode 100644
index 0000000..b304cc7
--- /dev/null
+++ b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/FileInputStreamProxy.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.utils.ConversionUtils;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class FileInputStreamProxy extends InputStream {
+
+    private final static ThreadLocal readerThreadLocal = new ThreadLocal();
+
+    private final InputStream in;
+    private final String name;
+
+    public static void setResourceReader( final ResourceReader pReader ) {
+        readerThreadLocal.set(pReader);
+    }
+
+    public FileInputStreamProxy(File pFile) throws FileNotFoundException {
+        this("" + pFile);
+    }
+
+    public FileInputStreamProxy(FileDescriptor fdObj) {
+        throw new RuntimeException();
+    }
+
+    public FileInputStreamProxy(String pName) throws FileNotFoundException {
+        name = ConversionUtils.getResourceNameFromFileName(pName);
+
+        final ResourceReader reader = (ResourceReader) readerThreadLocal.get();
+
+        if (reader == null) {
+            throw new RuntimeException("forgot to set the ResourceReader for this thread?");
+        }
+
+        final byte[] bytes = reader.getBytes(name);
+
+        if (bytes == null) {
+            throw new FileNotFoundException(name);
+        }
+
+        in = new ByteArrayInputStream(bytes);
+    }
+
+    public int read() throws IOException {
+        return in.read();
+    }
+
+    public int available() throws IOException {
+        return in.available();
+    }
+
+    public void close() throws IOException {
+        in.close();
+    }
+
+    public synchronized void mark(int readlimit) {
+        in.mark(readlimit);
+    }
+
+    public boolean markSupported() {
+        return in.markSupported();
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+        return in.read(b, off, len);
+    }
+
+    public int read(byte[] b) throws IOException {
+        return in.read(b);
+    }
+
+    public synchronized void reset() throws IOException {
+        in.reset();
+    }
+
+    public long skip(long n) throws IOException {
+        return in.skip(n);
+    }
+}
diff --git a/compilers/javac/src/main/java/org/apache/commons/jci/compilers/FileOutputStreamProxy.java b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/FileOutputStreamProxy.java
new file mode 100644
index 0000000..b20c914
--- /dev/null
+++ b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/FileOutputStreamProxy.java
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class FileOutputStreamProxy extends OutputStream {
+
+    private final static ThreadLocal storeThreadLocal = new ThreadLocal();
+
+    private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+    private final String name;
+
+
+    public static void setResourceStore( final ResourceStore pStore ) {
+        storeThreadLocal.set(pStore);
+    }
+
+
+    public FileOutputStreamProxy(File pFile, boolean append) throws FileNotFoundException {
+        this("" + pFile);
+    }
+
+    public FileOutputStreamProxy(File pFile) throws FileNotFoundException {
+        this("" + pFile);
+    }
+
+    public FileOutputStreamProxy(FileDescriptor fdObj) {
+        throw new RuntimeException();
+    }
+
+    public FileOutputStreamProxy(String pName, boolean append) throws FileNotFoundException {
+        this(pName);
+    }
+
+    public FileOutputStreamProxy(String pName) throws FileNotFoundException {
+        name = ConversionUtils.getResourceNameFromFileName(pName);
+    }
+
+    public void write(int value) throws IOException {
+        out.write(value);
+    }
+
+    public void close() throws IOException {
+        out.close();
+
+        final ResourceStore store = (ResourceStore) storeThreadLocal.get();
+
+        if (store == null) {
+            throw new RuntimeException("forgot to set the ResourceStore for this thread?");
+        }
+
+        store.write(name, out.toByteArray());
+    }
+
+    public void flush() throws IOException {
+        out.flush();
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException {
+        out.write(b, off, len);
+    }
+
+    public void write(byte[] b) throws IOException {
+        out.write(b);
+    }
+}
diff --git a/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacClassLoader.java b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacClassLoader.java
new file mode 100644
index 0000000..5b97ab5
--- /dev/null
+++ b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacClassLoader.java
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.util.CheckClassAdapter;
+import org.vafer.dependency.asm.RenamingVisitor;
+import org.vafer.dependency.utils.ResourceRenamer;
+
+
+/**
+ * This classloader injects the FileIn/OutputStream wrappers
+ * into javac. Access to the store/reader is done via ThreadLocals.
+ * It also tries to find the javac class on the system and expands
+ * the classpath accordingly.
+ * 
+ * @author tcurdt
+ */
+public final class JavacClassLoader extends URLClassLoader {
+
+    private final Map loaded = new HashMap();
+
+    public JavacClassLoader( final ClassLoader pParent ) {
+        super(getToolsJar(), pParent);
+    }
+
+    private static URL[] getToolsJar() {
+        try {
+            Class.forName("com.sun.tools.javac.Main");
+
+            // found - no addtional classpath entry required
+            return new URL[0];
+
+        } catch (Exception e) {
+        }
+
+        // no compiler in current classpath, let's try to find the tools.jar
+
+        String javaHome = System.getProperty("java.home");
+        if (javaHome.toLowerCase(Locale.US).endsWith(File.separator + "jre")) {
+            javaHome = javaHome.substring(0, javaHome.length()-4);
+        }
+
+        final File toolsJar = new File(javaHome + "/lib/tools.jar");
+
+        if (toolsJar.exists()) {
+            try {
+                return new URL[] { toolsJar.toURL() };
+            } catch (MalformedURLException e) {
+            }
+        }
+
+        final StringBuffer sb = new StringBuffer();
+        sb.append("Could not find javac compiler class (should be in the tools.jar/classes.jar in your JRE/JDK). ");
+        sb.append("os.name").append('=').append(System.getProperty("os.name")).append(", ");
+        sb.append("os.version").append('=').append(System.getProperty("os.version")).append(", ");
+        sb.append("java.class.path").append('=').append(System.getProperty("java.class.path"));
+
+        throw new RuntimeException(sb.toString());
+    }
+
+    protected Class findClass( final String name ) throws ClassNotFoundException {
+
+        if (name.startsWith("java.")) {
+            return super.findClass(name);
+        }
+
+        try {
+
+            final Class clazz = (Class) loaded.get(name);
+            if (clazz != null) {
+                return clazz;
+            }
+
+            final byte[] classBytes;
+
+            if (name.startsWith("com.sun.tools.javac.")) {
+                final InputStream classStream = getResourceAsStream(name.replace('.', '/') + ".class");
+
+                final ClassWriter renamedCw = new ClassWriter(true, false);
+                new ClassReader(classStream).accept(new RenamingVisitor(new CheckClassAdapter(renamedCw), new ResourceRenamer() {
+                    public String getNewNameFor(final String pOldName) {
+                        if (pOldName.startsWith(FileOutputStream.class.getName())) {
+                            return FileOutputStreamProxy.class.getName();
+                        }
+                        if (pOldName.startsWith(FileInputStream.class.getName())) {
+                            return FileInputStreamProxy.class.getName();
+                        }
+                        return pOldName;
+                    }
+                }), false);
+
+                classBytes = renamedCw.toByteArray();
+
+            } else {
+                return super.findClass(name);
+            }
+
+            final Class newClazz = defineClass(name, classBytes, 0, classBytes.length);
+            loaded.put(name, newClazz);
+            return newClazz;
+        } catch (IOException e) {
+            throw new ClassNotFoundException("", e);
+        }
+    }
+
+    protected synchronized Class loadClass( final String classname, final boolean resolve ) throws ClassNotFoundException {
+
+        Class theClass = findLoadedClass(classname);
+        if (theClass != null) {
+            return theClass;
+        }
+
+        try {
+            theClass = findClass(classname);
+        } catch (ClassNotFoundException cnfe) {
+            theClass = getParent().loadClass(classname);
+        }
+
+        if (resolve) {
+            resolveClass(theClass);
+        }
+
+        return theClass;
+    }
+}
\ No newline at end of file
diff --git a/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacCompilationProblem.java b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacCompilationProblem.java
new file mode 100644
index 0000000..bbe429f
--- /dev/null
+++ b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacCompilationProblem.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public class JavacCompilationProblem implements CompilationProblem {
+
+    private int endCoumn;
+    private int endLine;
+    private String fileName;
+    private String message;
+    private int startCoumn;
+    private int startLine;
+    private boolean isError;
+
+    public JavacCompilationProblem(String message, boolean isError) {
+        this.message = message;
+        this.isError = isError;
+        this.fileName = "";
+    }
+
+    public JavacCompilationProblem(String fileName, boolean isError, int startLine, int startCoumn, int endLine, int endCoumn, String message) {
+        this.message = message;
+        this.isError = isError;
+        this.fileName = fileName;
+        this.startCoumn = startCoumn;
+        this.endCoumn = endCoumn;
+        this.startLine = startLine;
+        this.endLine = endLine;
+    }
+
+    public int getEndColumn() {
+        return endCoumn;
+    }
+
+    public int getEndLine() {
+        return endLine;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public int getStartColumn() {
+        return startCoumn;
+    }
+
+    public int getStartLine() {
+        return startLine;
+    }
+
+    public boolean isError() {
+        return isError;
+    }
+
+    public String toString() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append(getFileName()).append(" (");
+        sb.append(getStartLine());
+        sb.append(":");
+        sb.append(getStartColumn());
+        sb.append(") : ");
+        sb.append(getMessage());
+        return sb.toString();
+    }
+}
diff --git a/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacJavaCompiler.java b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacJavaCompiler.java
new file mode 100644
index 0000000..9ae2e74
--- /dev/null
+++ b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacJavaCompiler.java
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+
+/**
+ * Compiler leveraging the javac from tools.jar. Using byte code rewriting
+ * it is tricked not to read/write from/to disk but use the ResourceReader and
+ * ResourceStore provided instead.
+ * 
+ * NOTE: (As of now) this compiler only works up until java5. Java6 comes with
+ * a new API based on jsr199. So please use that jsr199 compiler instead.
+ *   
+ * @author tcurdt
+ * @todo classpath and settings support
+ */
+public final class JavacJavaCompiler extends AbstractJavaCompiler {
+
+    private static final String EOL = System.getProperty("line.separator");
+    private static final String WARNING_PREFIX = "warning: ";
+    private static final String NOTE_PREFIX = "Note: ";
+    private static final String ERROR_PREFIX = "error: ";
+
+    private final JavacJavaCompilerSettings settings;
+
+    public JavacJavaCompiler() {
+        settings = new JavacJavaCompilerSettings();
+    }
+
+    public JavacJavaCompiler( final JavacJavaCompilerSettings pSettings ) {
+        settings = pSettings;
+    }
+
+    public CompilationResult compile( final String[] pSourcePaths, final ResourceReader pReader, ResourceStore pStore, final ClassLoader pClasspathClassLoader, final JavaCompilerSettings pSettings ) {
+
+        try {
+            final ClassLoader cl = new JavacClassLoader(pClasspathClassLoader);
+            final Class renamedClass = cl.loadClass("com.sun.tools.javac.Main");
+
+            FileInputStreamProxy.setResourceReader(pReader);
+            FileOutputStreamProxy.setResourceStore(pStore);
+
+            final Method compile = renamedClass.getMethod("compile", new Class[] { String[].class, PrintWriter.class });
+            final StringWriter out = new StringWriter();
+            final Integer ok = (Integer) compile.invoke(null, new Object[] { buildCompilerArguments(pSourcePaths, pClasspathClassLoader), new PrintWriter(out) });
+
+            final CompilationResult result = parseModernStream(new BufferedReader(new StringReader(out.toString())));
+
+            if (result.getErrors().length == 0 && ok.intValue() != 0) {
+                return new CompilationResult(new CompilationProblem[] {
+                        new JavacCompilationProblem("Failure executing javac, but could not parse the error: " + out.toString(), true) });
+            }
+
+            return result;
+
+        } catch(Exception e) {
+            return new CompilationResult(new CompilationProblem[] {
+                    new JavacCompilationProblem("Error while executing the compiler: " + e.toString(), true) });
+        } finally {
+            // help GC
+            FileInputStreamProxy.setResourceReader(null);
+            FileOutputStreamProxy.setResourceStore(null);
+        }
+    }
+
+    private CompilationResult parseModernStream( final BufferedReader pReader ) throws IOException {
+        final List problems = new ArrayList();
+        String line;
+
+        while (true) {
+            // cleanup the buffer
+            final StringBuffer buffer = new StringBuffer();
+
+            // most errors terminate with the '^' char
+            do {
+                line = pReader.readLine();
+                if (line == null) {
+                    return new CompilationResult((CompilationProblem[]) problems.toArray(new CompilationProblem[problems.size()]));
+                }
+
+                // TODO: there should be a better way to parse these
+                if (buffer.length() == 0 && line.startsWith(ERROR_PREFIX)) {
+                    problems.add(new JavacCompilationProblem(line, true));
+                }
+                else if (buffer.length() == 0 && line.startsWith(NOTE_PREFIX)) {
+                    // skip this one - it is JDK 1.5 telling us that the
+                    // interface is deprecated.
+                } else {
+                    buffer.append(line);
+                    buffer.append(EOL);
+                }
+            } while (!line.endsWith("^"));
+
+            // add the error
+            problems.add(parseModernError(buffer.toString()));
+        }
+    }
+
+    private CompilationProblem parseModernError( final String pError ) {
+        final StringTokenizer tokens = new StringTokenizer(pError, ":");
+        boolean isError = true;
+        try {
+            String file = tokens.nextToken();
+            // When will this happen?
+            if (file.length() == 1) {
+                file = new StringBuffer(file).append(":").append(
+                        tokens.nextToken()).toString();
+            }
+            final int line = Integer.parseInt(tokens.nextToken());
+            final StringBuffer msgBuffer = new StringBuffer();
+
+            String msg = tokens.nextToken(EOL).substring(2);
+            isError = !msg.startsWith(WARNING_PREFIX);
+
+            // Remove the 'warning: ' prefix
+            if (!isError) {
+                msg = msg.substring(WARNING_PREFIX.length());
+            }
+            msgBuffer.append(msg);
+
+            String context = tokens.nextToken(EOL);
+            String pointer = tokens.nextToken(EOL);
+
+            if (tokens.hasMoreTokens()) {
+                msgBuffer.append(EOL);
+                msgBuffer.append(context); // 'symbol' line
+                msgBuffer.append(EOL);
+                msgBuffer.append(pointer); // 'location' line
+                msgBuffer.append(EOL);
+
+                context = tokens.nextToken(EOL);
+
+                try {
+                    pointer = tokens.nextToken(EOL);
+                } catch (NoSuchElementException e) {
+                    pointer = context;
+                    context = null;
+                }
+            }
+            final String message = msgBuffer.toString();
+            int startcolumn = pointer.indexOf("^");
+            int endcolumn = context == null ? startcolumn : context.indexOf(" ", startcolumn);
+            if (endcolumn == -1) {
+                endcolumn = context.length();
+            }
+            return new JavacCompilationProblem(file, isError, line, startcolumn, line, endcolumn, message);
+        }
+        catch (NoSuchElementException e) {
+            return new JavacCompilationProblem("no more tokens - could not parse error message: " + pError, isError);
+        }
+        catch (NumberFormatException e) {
+            return new JavacCompilationProblem("could not parse error message: " + pError, isError);
+        }
+        catch (Exception e) {
+            return new JavacCompilationProblem("could not parse error message: " + pError, isError);
+        }
+    }
+
+    public JavaCompilerSettings createDefaultSettings() {
+        return settings;
+    }
+
+    private String[] buildCompilerArguments( final String[] resourcePaths, final ClassLoader classloader ) {
+
+        // FIXME: build classpath from classloader information
+        return resourcePaths;
+
+//    {
+//        final List args = new ArrayList();
+//        for (int i = 0; i < resourcePaths.length; i++) {
+//            args.add(resourcePaths[i]);
+//        }
+//
+//        if (settings != null) {
+//            if (settings.isOptimize()) {
+//                args.add("-O");
+//            }
+//
+//            if (settings.isDebug()) {
+//                args.add("-g");
+//            }
+//
+//            if (settings.isVerbose()) {
+//                args.add("-verbose");
+//            }
+//
+//            if (settings.isShowDeprecation()) {
+//                args.add("-deprecation");
+//                // This is required to actually display the deprecation messages
+//                settings.setShowWarnings(true);
+//            }
+//
+//            if (settings.getMaxmem() != null) {
+//                args.add("-J-Xmx" + settings.getMaxmem());
+//            }
+//
+//            if (settings.getMeminitial() != null) {
+//                args.add("-J-Xms" + settings.getMeminitial());
+//            }
+//
+//            if (!settings.isShowWarnings()) {
+//                args.add("-nowarn");
+//            }
+//
+//            // TODO: this could be much improved
+//            if (settings.getTargetVersion() != null) {
+//                // Required, or it defaults to the target of your JDK (eg 1.5)
+//                args.add("-target");
+//                args.add("1.1");
+//            } else {
+//                args.add("-target");
+//                args.add(settings.getTargetVersion());
+//            }
+//
+//            // TODO suppressSource
+//            if (settings.getSourceVersion() != null) {
+//                // If omitted, later JDKs complain about a 1.1 target
+//                args.add("-source");
+//                args.add("1.3");
+//            } else {
+//                args.add("-source");
+//                args.add(settings.getSourceVersion());
+//            }
+//
+//            // TODO suppressEncoding
+//            if (settings.getSourceEncoding() != null) {
+//                args.add("-encoding");
+//                args.add(settings.getSourceEncoding());
+//            }
+//
+//            // TODO CustomCompilerArguments
+//        }
+//
+//        return (String[]) args.toArray(new String[args.size()]);
+    }
+}
diff --git a/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacJavaCompilerSettings.java b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacJavaCompilerSettings.java
new file mode 100644
index 0000000..c74980b
--- /dev/null
+++ b/compilers/javac/src/main/java/org/apache/commons/jci/compilers/JavacJavaCompilerSettings.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.util.List;
+
+public final class JavacJavaCompilerSettings extends JavaCompilerSettings {
+
+    private boolean optimize;
+    private String maxmem;
+    private String meminitial;
+
+    private List customCompilerArguments;
+
+    public List getCustomCompilerArguments() {
+        return customCompilerArguments;
+    }
+
+    public void setCustomCompilerArguments(List customCompilerArguments) {
+        this.customCompilerArguments = customCompilerArguments;
+    }
+
+    public String getMaxmem() {
+        return maxmem;
+    }
+
+    public void setMaxmem(String maxmem) {
+        this.maxmem = maxmem;
+    }
+
+    public String getMeminitial() {
+        return meminitial;
+    }
+
+    public void setMeminitial(String meminitial) {
+        this.meminitial = meminitial;
+    }
+
+    public boolean isOptimize() {
+        return optimize;
+    }
+
+    public void setOptimize(boolean optimize) {
+        this.optimize = optimize;
+    }
+
+}
diff --git a/compilers/javac/src/main/resources/LICENSE.txt b/compilers/javac/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/compilers/javac/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/compilers/javac/src/main/resources/NOTICE.txt b/compilers/javac/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..89168e1
--- /dev/null
+++ b/compilers/javac/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - Javac Compiler Implementation
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/compilers/javac/src/test/java/org/apache/commons/jci/compilers/JavacJavaCompilerTestCase.java b/compilers/javac/src/test/java/org/apache/commons/jci/compilers/JavacJavaCompilerTestCase.java
new file mode 100644
index 0000000..286a792
--- /dev/null
+++ b/compilers/javac/src/test/java/org/apache/commons/jci/compilers/JavacJavaCompilerTestCase.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+public class JavacJavaCompilerTestCase extends AbstractCompilerTestCase {
+
+    public JavaCompiler createJavaCompiler() {
+        return new JavacJavaCompiler();
+    }
+
+    public String getCompilerName() {
+        return "javac";
+    }
+
+}
diff --git a/compilers/javac/src/test/resources/simplelog.properties b/compilers/javac/src/test/resources/simplelog.properties
new file mode 100644
index 0000000..6bd0ec9
--- /dev/null
+++ b/compilers/javac/src/test/resources/simplelog.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.simplelog.defaultlog=debug
+org.apache.commons.logging.simplelog.showdatetime=true
\ No newline at end of file
diff --git a/compilers/jsr199/pom.xml b/compilers/jsr199/pom.xml
new file mode 100644
index 0000000..d62f4a6
--- /dev/null
+++ b/compilers/jsr199/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-jsr166</artifactId>
+    <version>1.0</version>
+    <name>compiler-jsr166</name>
+    <description>
+        Commons JCI compiler implementation for JDK 1.6 and up.
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <properties>
+        <maven.compile.source>1.6</maven.compile.source>
+        <maven.compile.target>1.6</maven.compile.target>
+    </properties>
+
+</project>
diff --git a/compilers/jsr199/src/main/java/org/apache/commons/jci/compilers/Jsr199CompilationProblem.java b/compilers/jsr199/src/main/java/org/apache/commons/jci/compilers/Jsr199CompilationProblem.java
new file mode 100755
index 0000000..881dc94
--- /dev/null
+++ b/compilers/jsr199/src/main/java/org/apache/commons/jci/compilers/Jsr199CompilationProblem.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+package org.apache.commons.jci.compilers;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+
+public class Jsr199CompilationProblem implements CompilationProblem {
+
+    final Diagnostic<? extends JavaFileObject> problem;
+
+    public Jsr199CompilationProblem( final Diagnostic<? extends JavaFileObject> pProblem ) {
+        problem = pProblem;
+    }
+
+    public int getEndColumn() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public int getEndLine() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public String getFileName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getMessage() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public int getStartColumn() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public int getStartLine() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public boolean isError() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+}
diff --git a/compilers/jsr199/src/main/java/org/apache/commons/jci/compilers/Jsr199JavaCompiler.java b/compilers/jsr199/src/main/java/org/apache/commons/jci/compilers/Jsr199JavaCompiler.java
new file mode 100644
index 0000000..680efce
--- /dev/null
+++ b/compilers/jsr199/src/main/java/org/apache/commons/jci/compilers/Jsr199JavaCompiler.java
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+package org.apache.commons.jci.compilers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.FileObject;
+import javax.tools.JavaCompilerTool;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+import javax.tools.JavaFileObject.Kind;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public final class Jsr199JavaCompiler extends AbstractJavaCompiler {
+
+    private final Log log = LogFactory.getLog(Jsr199JavaCompiler.class);
+
+    private class CompilationUnit extends SimpleJavaFileObject {
+        final private ResourceReader reader;
+        final private String name;
+
+        public CompilationUnit( final String pName, final ResourceReader pReader ) {
+            super(URI.create("reader:///" + pName), Kind.SOURCE);
+            reader = pReader;
+            name = pName;
+        }
+
+        public boolean delete() {
+            log.debug("delete");
+            return super.delete();
+        }
+
+        public CharSequence getCharContent(boolean arg0) throws IOException {
+            log.debug("getCharContent of " + name);
+            byte[] content = reader.getBytes(name);
+            return new String(content);
+        }
+
+        public Kind getKind() {
+            log.debug("getKind" + super.getKind());
+            return super.getKind();
+        }
+
+        public long getLastModified() {
+            log.debug("getLastModified");
+            return super.getLastModified();
+        }
+
+        public String getName() {
+            log.debug("getName " + super.getName());
+            return super.getName();
+        }
+
+        public boolean isNameCompatible(String arg0, Kind arg1) {
+            log.debug("isNameCompatible " + arg0);
+            return super.isNameCompatible(arg0, arg1);
+        }
+
+        public InputStream openInputStream() throws IOException {
+            log.debug("openInputStream");
+            return super.openInputStream();
+        }
+
+        public OutputStream openOutputStream() throws IOException {
+            log.debug("openOutputStream");
+            return super.openOutputStream();
+        }
+
+        public Reader openReader(boolean arg0) throws IOException {
+            log.debug("openReader");
+            return super.openReader(arg0);
+        }
+
+        public Writer openWriter() throws IOException {
+            log.debug("openWriter");
+            return super.openWriter();
+        }
+
+        public URI toUri() {
+            log.debug("toUri " + super.toUri());
+            return super.toUri();
+        }
+
+
+    }
+    
+    private class JciJavaFileManager implements JavaFileManager {
+        private final ResourceStore store;
+        final Collection<JavaFileObject> units;
+
+    	public JciJavaFileManager( final Collection<JavaFileObject> pUnits, final ResourceStore pStore ) {
+    		store = pStore;
+    		units = pUnits;
+    	}
+
+        public void close() {
+            log.debug("close");
+        }
+        public void flush() {
+            log.debug("flush");
+        }
+        public ClassLoader getClassLoader(JavaFileManager.Location location) {
+            log.debug("getClassLoader");
+            return null;
+        }
+        public FileObject getFileForInput(JavaFileManager.Location location, String packageName, String relativeName) {
+            log.debug("getFileForInput");
+            return null;
+        }
+        public FileObject getFileForOutput(JavaFileManager.Location location, String packageName, String relativeName, FileObject sibling) {
+            log.debug("getFileForOutput");
+            return null;
+        }
+        public JavaFileObject getJavaFileForInput(JavaFileManager.Location location, String className, JavaFileObject.Kind kind) {
+            log.debug("getJavaFileForInput");
+            return null;
+        }
+        public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, String className, JavaFileObject.Kind kind, FileObject sibling) {
+            log.debug("getJavaFileForOutput");
+            return null;
+        }
+        public int isSupportedOption(String option) {
+            log.debug("isSupportedOption");
+            return 0;
+        }
+        public boolean handleOption(String current, Iterator<String> remaining) {
+            log.debug("handleOption");
+            return false;
+        }
+        public boolean hasLocation(JavaFileManager.Location location) {
+            log.debug("hasLocation");
+            return false;
+        }
+        public String inferBinaryName(JavaFileManager.Location location, JavaFileObject file) {
+            log.debug("inferBinaryName " + file.getName());
+            return file.getName().replaceFirst(".java", ".class");
+        }
+        public Iterable<JavaFileObject> list(JavaFileManager.Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) {
+            log.debug("list " + location + packageName + kinds + recurse);
+            return units;
+        }
+    }
+    
+    public CompilationResult compile( final String[] pResourcePaths, final ResourceReader pReader, final ResourceStore pStore, final ClassLoader classLoader) {
+
+        final Collection<JavaFileObject> units = new ArrayList<JavaFileObject>();
+        for (int i = 0; i < pResourcePaths.length; i++) {
+            final String sourcePath = pResourcePaths[i];
+            log.debug("compiling " + sourcePath);
+            units.add(new CompilationUnit(sourcePath, pReader));
+        }
+
+        final JavaCompilerTool compiler = ToolProvider.getSystemJavaCompilerTool();
+//        final JavaFileManager fileManager = compiler.getStandardFileManager(diagnostics);
+        final JavaFileManager fileManager = new JciJavaFileManager(units, pStore);
+        final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
+
+
+        compiler.getTask(null, fileManager, diagnostics, null, null, units).run();
+
+        try {
+            fileManager.close();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        final List<Diagnostic<? extends JavaFileObject>> jsrProblems = diagnostics.getDiagnostics();
+        final CompilationProblem[] problems = new CompilationProblem[jsrProblems.size()];
+        int i = 0;
+        for (final Diagnostic<? extends JavaFileObject> jsrProblem : jsrProblems) {
+            problems[i++] = new Jsr199CompilationProblem(jsrProblem);
+        }
+
+        return new CompilationResult(problems);
+    }
+
+}
diff --git a/compilers/jsr199/src/main/resources/LICENSE.txt b/compilers/jsr199/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/compilers/jsr199/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/compilers/jsr199/src/main/resources/NOTICE.txt b/compilers/jsr199/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..34ac9bb
--- /dev/null
+++ b/compilers/jsr199/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - JSR 199 Compiler Implementation
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/compilers/jsr199/src/test/java/org/apache/commons/jci/compilers/Jsr199JavaCompilerTestCase.java b/compilers/jsr199/src/test/java/org/apache/commons/jci/compilers/Jsr199JavaCompilerTestCase.java
new file mode 100644
index 0000000..5240ef0
--- /dev/null
+++ b/compilers/jsr199/src/test/java/org/apache/commons/jci/compilers/Jsr199JavaCompilerTestCase.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+ package org.apache.commons.jci.compilers;
+
+public final class Jsr199JavaCompilerTestCase extends AbstractCompilerTestCase {
+
+    public String getCompilerName() {
+        return "jsr199";
+    }
+
+    public JavaCompiler createJavaCompiler() {
+        return new Jsr199JavaCompiler();
+    }
+
+}
diff --git a/compilers/rhino/pom.xml b/compilers/rhino/pom.xml
new file mode 100644
index 0000000..659e3bc
--- /dev/null
+++ b/compilers/rhino/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-rhino</artifactId>
+    <version>1.0</version>
+    <name>compiler-rhino</name>
+    <description>
+        Commons JCI compiler implementation for rhino javascript.
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>rhino</groupId>
+            <artifactId>js</artifactId>
+            <version>1.6R5</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoCompilationProblem.java b/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoCompilationProblem.java
new file mode 100755
index 0000000..bdee2c5
--- /dev/null
+++ b/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoCompilationProblem.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class RhinoCompilationProblem implements CompilationProblem {
+
+    private final String message;
+    private final String fileName;
+    private final int line;
+    private final int column;
+    private final boolean error;
+
+    public RhinoCompilationProblem( final String pMessage, final String pFileName, final int pLine, final String pScript, final int pColumn, final boolean pError ) {
+        message = pMessage;
+        fileName = pFileName;
+        line = pLine;
+        column = pColumn;
+        error = pError;
+    }
+
+    public int getEndColumn() {
+        return column;
+    }
+
+    public int getEndLine() {
+        return line;
+    }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public int getStartColumn() {
+        return column;
+    }
+
+    public int getStartLine() {
+        return line;
+    }
+
+    public boolean isError() {
+        return error;
+    }
+
+}
diff --git a/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoJavaCompiler.java b/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoJavaCompiler.java
new file mode 100644
index 0000000..0d949d7
--- /dev/null
+++ b/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoJavaCompiler.java
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mozilla.javascript.CompilerEnvirons;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ErrorReporter;
+import org.mozilla.javascript.EvaluatorException;
+import org.mozilla.javascript.GeneratedClassLoader;
+import org.mozilla.javascript.ImporterTopLevel;
+import org.mozilla.javascript.JavaScriptException;
+import org.mozilla.javascript.NativeArray;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.optimizer.ClassCompiler;
+
+/**
+ * @author tcurdt
+ */
+public final class RhinoJavaCompiler extends AbstractJavaCompiler {
+
+    private final Log log = LogFactory.getLog(RhinoJavaCompiler.class);
+
+    private final JavaCompilerSettings defaultSettings;
+    
+    
+    public RhinoJavaCompiler() {
+        defaultSettings = new RhinoJavaCompilerSettings();
+    }
+    
+    /**
+     * based on code from dev.helma.org
+     * http://dev.helma.org/source/file/helma/branches/rhinoloader/src/org/helma/javascript/RhinoLoader.java/?revision=95
+     */
+    private final class RhinoCompilingClassLoader extends ClassLoader {
+
+        private final ScriptableObject scope;
+        private final ResourceReader reader;
+        private final ResourceStore store;
+
+        private final Collection problems = new ArrayList();
+        
+        private final class ProblemCollector implements ErrorReporter {
+
+            public void error(String pMessage, String pFileName, int pLine, String pScript, int pColumn) {
+
+                final CompilationProblem problem = new RhinoCompilationProblem(pMessage, pFileName, pLine, pScript, pColumn, true); 
+
+                if (problemHandler != null) {
+                    problemHandler.handle(problem);
+                }
+
+                problems.add(problem); 
+            }
+
+            public void warning(String pMessage, String pFileName, int pLine, String pScript, int pColumn) {
+
+                final CompilationProblem problem = new RhinoCompilationProblem(pMessage, pFileName, pLine, pScript, pColumn, false); 
+
+                if (problemHandler != null) {
+                    problemHandler.handle(problem);
+                }
+
+                problems.add(problem); 
+            }
+
+            public EvaluatorException runtimeError(String pMessage, String pFileName, int pLine, String pScript, int pColumn) {
+                return new EvaluatorException(pMessage, pFileName, pLine, pScript, pColumn);
+            }
+        }
+
+        public RhinoCompilingClassLoader( final ResourceReader pReader, final ResourceStore pStore, final ClassLoader pClassLoader) {
+            super(pClassLoader);
+
+            reader = pReader;
+            store = pStore;
+
+            final Context context = Context.enter();
+            scope = new ImporterTopLevel(context);
+            Context.exit();
+        }
+
+        public Collection getProblems() {
+            return problems;
+        }
+
+        protected Class findClass( final String pName ) throws ClassNotFoundException {
+            final Context context = Context.enter();
+            context.setErrorReporter(new ProblemCollector());
+
+            try {
+                return compileClass(context, pName);
+            } catch( EvaluatorException e ) {
+                throw new ClassNotFoundException(e.getMessage(), e);
+            } catch (IOException e) {
+                throw new ClassNotFoundException(e.getMessage(), e);
+            } finally {
+                Context.exit();
+            }
+        }
+
+
+        private Class compileClass( final Context pContext, final String pClassName) throws IOException, ClassNotFoundException {
+
+            Class superclass = null;
+
+            final String pSourceName = pClassName.replace('.', '/') + ".js";
+
+            final Scriptable target = evaluate(pContext, pSourceName);
+
+            final Object baseClassName = ScriptableObject.getProperty(target, "__extends__");
+
+            if (baseClassName instanceof String) {
+                superclass = Class.forName((String) baseClassName);
+            }
+
+            final ArrayList interfaceClasses = new ArrayList();
+
+            final Object interfaceNames = ScriptableObject.getProperty(target, "__implements__");
+
+            if (interfaceNames instanceof NativeArray) {
+
+                final NativeArray interfaceNameArray = (NativeArray) interfaceNames;
+
+                for (int i=0; i<interfaceNameArray.getLength(); i++) {
+
+                    final Object obj = interfaceNameArray.get(i, interfaceNameArray);
+
+                    if (obj instanceof String) {
+                        interfaceClasses.add(Class.forName((String) obj));
+                    }
+                }
+
+            } else if (interfaceNames instanceof String) {
+
+                interfaceClasses.add(Class.forName((String) interfaceNames));
+
+            }
+
+            final Class[] interfaces;
+
+            if (!interfaceClasses.isEmpty()) {
+                interfaces = new Class[interfaceClasses.size()];
+                interfaceClasses.toArray(interfaces);
+            } else {
+                // FIXME: hm ...really no empty array good enough?
+                interfaces = null;
+            }
+
+            return compileClass(pContext, pSourceName, pClassName, superclass, interfaces);
+
+        }
+
+
+        private Class compileClass( final Context pContext, final String pSourceName, final String pClassName, final Class pSuperClass, final Class[] pInterfaces) throws IOException {
+
+            final CompilerEnvirons environments = new CompilerEnvirons();
+            environments.initFromContext(pContext);
+            final ClassCompiler compiler = new ClassCompiler(environments);
+
+            if (pSuperClass != null) {
+                compiler.setTargetExtends(pSuperClass);
+            }
+
+            if (pInterfaces != null) {
+                compiler.setTargetImplements(pInterfaces);
+            }
+
+            final byte[] sourceBytes = reader.getBytes(pSourceName);
+
+            final Object[] classes = compiler.compileToClassFiles(new String(sourceBytes), getName(pSourceName), 1, pClassName);
+
+            final GeneratedClassLoader loader = pContext.createClassLoader(pContext.getApplicationClassLoader());
+
+            Class clazz = null;
+
+            for (int i = 0; i < classes.length; i += 2) {
+
+                final String clazzName = (String) classes[i];
+                final byte[] clazzBytes = (byte[]) classes[i+1];
+
+                store.write(clazzName.replace('.', '/') + ".class", clazzBytes);
+
+                Class c = loader.defineClass(clazzName, clazzBytes);
+                loader.linkClass(c);
+
+                if (i == 0) {
+                    clazz = c;
+                }
+
+            }
+
+            return clazz;
+        }
+
+        private String getName(String s) {
+            final int i = s.lastIndexOf('/');
+            if (i < 0) {
+                return s;
+            }
+
+            return s.substring(i + 1);
+        }
+
+        private Scriptable evaluate( final Context pContext, final String pSourceName) throws JavaScriptException, IOException {
+
+            if (!reader.isAvailable(pSourceName)) {
+                throw new FileNotFoundException("File " + pSourceName + " not found");
+            }
+
+            final Scriptable target = pContext.newObject(scope);
+
+            final byte[] sourceBytes = reader.getBytes(pSourceName);
+
+            final Reader reader = new InputStreamReader(new ByteArrayInputStream(sourceBytes));
+
+            pContext.evaluateReader(target, reader, getName(pSourceName), 1, null);
+
+            return target;
+        }
+
+    }
+    
+    
+    public CompilationResult compile( final String[] pResourcePaths, final ResourceReader pReader, final ResourceStore pStore, final ClassLoader pClassLoader, final JavaCompilerSettings pSettings ) {
+
+        final RhinoCompilingClassLoader cl = new RhinoCompilingClassLoader(pReader, pStore, pClassLoader);
+
+        for (int i = 0; i < pResourcePaths.length; i++) {
+            log.debug("compiling " + pResourcePaths[i]);
+            
+            final String clazzName = ConversionUtils.convertResourceToClassName(pResourcePaths[i]);
+            try {
+                cl.loadClass(clazzName);
+            } catch (ClassNotFoundException e) {
+            }
+        }
+
+        final Collection problems = cl.getProblems();
+        final CompilationProblem[] result = new CompilationProblem[problems.size()];
+        problems.toArray(result);
+        return new CompilationResult(result);
+    }
+
+
+    public JavaCompilerSettings createDefaultSettings() {
+        return defaultSettings;
+    }
+
+}
diff --git a/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoJavaCompilerSettings.java b/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoJavaCompilerSettings.java
new file mode 100644
index 0000000..4f53477
--- /dev/null
+++ b/compilers/rhino/src/main/java/org/apache/commons/jci/compilers/RhinoJavaCompilerSettings.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+
+package org.apache.commons.jci.compilers;
+
+/**
+ * @author tcurdt
+ * @todo implement rhino settings
+ */
+public final class RhinoJavaCompilerSettings extends JavaCompilerSettings {
+
+}
diff --git a/compilers/rhino/src/main/resources/LICENSE.txt b/compilers/rhino/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/compilers/rhino/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/compilers/rhino/src/main/resources/NOTICE.txt b/compilers/rhino/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..df31aa3
--- /dev/null
+++ b/compilers/rhino/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - Rhino Compiler Implementation
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/compilers/rhino/src/test/java/org/apache/commons/jci/compilers/RhinoJavaCompilerTestCase.java b/compilers/rhino/src/test/java/org/apache/commons/jci/compilers/RhinoJavaCompilerTestCase.java
new file mode 100644
index 0000000..ce23589
--- /dev/null
+++ b/compilers/rhino/src/test/java/org/apache/commons/jci/compilers/RhinoJavaCompilerTestCase.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.MemoryResourceStore;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class RhinoJavaCompilerTestCase extends AbstractCompilerTestCase {
+
+    public JavaCompiler createJavaCompiler() {
+        return new RhinoJavaCompiler();
+    }
+
+    public String getCompilerName() {
+        return "rhino";
+    }
+
+    public void testSimpleCompile() throws Exception {
+        final JavaCompiler compiler = createJavaCompiler(); 
+
+        final ResourceReader reader = new ResourceReader() {
+            final private Map sources = new HashMap() {
+                private static final long serialVersionUID = 1L;
+                {
+                    put("jci/Simple.js", (
+                            " var i = 0;\n" +
+                            "\n"
+                    ).getBytes());
+                }};
+
+            public byte[] getBytes( final String pResourceName ) {
+                return (byte[]) sources.get(pResourceName);
+            }
+
+            public boolean isAvailable( final String pResourceName ) {
+                return sources.containsKey(pResourceName);
+            }
+
+        };
+
+        final MemoryResourceStore store = new MemoryResourceStore();
+        final CompilationResult result = compiler.compile(
+                new String[] {
+                        "jci/Simple.js"
+                }, reader, store);
+
+        assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
+        assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
+
+        final byte[] clazzBytes = store.read("jci/Simple.class");
+        assertNotNull(clazzBytes);
+        assertTrue(clazzBytes.length > 0);
+    }
+
+    public void testExtendedCompile() throws Exception {
+    }
+
+    public void testInternalClassCompile() throws Exception {
+    }
+
+    public void testUppercasePackageNameCompile() throws Exception {
+        final JavaCompiler compiler = createJavaCompiler(); 
+
+        final ResourceReader reader = new ResourceReader() {
+            final private Map sources = new HashMap() {
+                private static final long serialVersionUID = 1L;
+                {
+                    put("Jci/Simple.js", (
+                            " var i = 0;\n" +
+                            "\n"
+                    ).getBytes());
+                }};
+
+            public byte[] getBytes( final String pResourceName ) {
+                return (byte[]) sources.get(pResourceName);
+            }
+
+            public boolean isAvailable( final String pResourceName ) {
+                return sources.containsKey(pResourceName);
+            }
+
+        };
+
+        final MemoryResourceStore store = new MemoryResourceStore();
+        final CompilationResult result = compiler.compile(
+                new String[] {
+                        "Jci/Simple.js"
+                }, reader, store);
+
+        assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
+        assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
+
+        final byte[] clazzBytes = store.read("Jci/Simple.class");
+        assertNotNull(clazzBytes);
+        assertTrue(clazzBytes.length > 0);
+    }
+
+
+
+}
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..3a3a5bd
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-core</artifactId>
+    <version>1.0</version>
+    <name>core</name>
+    <description>
+        Commons JCI core interfaces and implementations.
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-fam</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging-api</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm</artifactId>
+            <version>2.2.1</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java b/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java
new file mode 100644
index 0000000..08e8218
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/ReloadingClassLoader.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci;
+
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.commons.jci.listeners.ReloadNotificationListener;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.stores.ResourceStoreClassLoader;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The ReloadingClassLoader uses a delegation mechansim to allow
+ * classes to be reloaded. That means that loadClass calls may
+ * return different results if the class was change in the underlying
+ * ResoruceStore.
+ * 
+ * @author tcurdt
+ */
+public class ReloadingClassLoader extends ClassLoader implements ReloadNotificationListener {
+    
+    private final Log log = LogFactory.getLog(ReloadingClassLoader.class);
+    
+    private final ClassLoader parent;
+    private ResourceStore[] stores = new ResourceStore[0];
+    private ClassLoader delegate;
+
+    public ReloadingClassLoader( final ClassLoader pParent ) {        
+        super(pParent);
+        parent = pParent;        
+
+        delegate = new ResourceStoreClassLoader(parent, stores);
+    }
+
+    public boolean addResourceStore( final ResourceStore pStore ) {
+        try {        
+            final int n = stores.length;
+            final ResourceStore[] newStores = new ResourceStore[n + 1];
+            System.arraycopy(stores, 0, newStores, 1, n);
+            newStores[0] = pStore;
+            stores = newStores;
+            delegate = new ResourceStoreClassLoader(parent, stores);            
+            return true;
+        } catch ( final Exception e ) {
+            log.error("could not add resource store " + pStore);
+        }
+        return false;
+    }
+
+    public boolean removeResourceStore( final ResourceStore pStore ) {
+
+        final int n = stores.length;
+        int i = 0;
+           
+        // FIXME: this should be improved with a Map
+        // find the pStore and index position with var i
+        while ( ( i < n )  && ( stores[i] != pStore ) ) {
+            i++;
+        }
+                    
+        // pStore was not found
+        if ( i == n ) {
+            return false;
+        }
+        
+        // if stores length > 1 then array copy old values, else create new empty store 
+        final ResourceStore[] newStores = new ResourceStore[n - 1];
+        if (i > 0) {
+            System.arraycopy(stores, 0, newStores, 0, i);
+        }
+        if (i < n - 1) {
+            System.arraycopy(stores, i + 1, newStores, i, (n - i - 1));
+        }
+            
+        stores = newStores;
+        delegate = new ResourceStoreClassLoader(parent, stores);
+        return true;
+    }
+    
+    public void handleNotification() {
+        log.debug("reloading");
+        delegate = new ResourceStoreClassLoader(parent, stores);
+    }
+    
+    public void clearAssertionStatus() {
+        delegate.clearAssertionStatus();
+    }
+    public URL getResource(String name) {
+        return delegate.getResource(name);
+    }
+    public InputStream getResourceAsStream(String name) {
+        return delegate.getResourceAsStream(name);
+    }
+    public Class loadClass(String name) throws ClassNotFoundException {
+        return delegate.loadClass(name);
+    }
+    public void setClassAssertionStatus(String className, boolean enabled) {
+        delegate.setClassAssertionStatus(className, enabled);
+    }
+    public void setDefaultAssertionStatus(boolean enabled) {
+        delegate.setDefaultAssertionStatus(enabled);
+    }
+    public void setPackageAssertionStatus(String packageName, boolean enabled) {
+        delegate.setPackageAssertionStatus(packageName, enabled);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/jci/compilers/AbstractJavaCompiler.java b/core/src/main/java/org/apache/commons/jci/compilers/AbstractJavaCompiler.java
new file mode 100644
index 0000000..916219a
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/compilers/AbstractJavaCompiler.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.apache.commons.jci.problems.CompilationProblemHandler;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+
+
+/**
+ * Base class for compiler implementations. Provides just a few
+ * convenience methods.
+ * 
+ * @author tcurdt
+ */
+public abstract class AbstractJavaCompiler implements JavaCompiler {
+
+    protected CompilationProblemHandler problemHandler;
+
+    public void setCompilationProblemHandler( final CompilationProblemHandler pHandler ) {
+        problemHandler = pHandler;
+    }
+
+    public CompilationResult compile( final String[] pClazzNames, final ResourceReader pReader, final ResourceStore pStore ) {
+
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+        if (classLoader == null) {
+            classLoader = this.getClass().getClassLoader();
+        }
+
+        return compile(pClazzNames, pReader, pStore, classLoader, createDefaultSettings());
+    }
+
+    public CompilationResult compile( final String[] pClazzNames, final ResourceReader pReader, final ResourceStore pStore, final ClassLoader pClassLoader ) {
+        return compile(pClazzNames, pReader, pStore, pClassLoader, createDefaultSettings());
+    }
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/compilers/CompilationResult.java b/core/src/main/java/org/apache/commons/jci/compilers/CompilationResult.java
new file mode 100644
index 0000000..bdc4a70
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/compilers/CompilationResult.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import org.apache.commons.jci.problems.CompilationProblem;
+
+/**
+ * A CompilationResult represents the result of a compilation.
+ * It includes errors (which failed the compilation) or warnings
+ * (that can be ignored and do not affect the creation of the
+ * class files)
+ * 
+ * @author tcurdt
+ */
+public final class CompilationResult {
+    
+    private final CompilationProblem[] errors;
+    private final CompilationProblem[] warnings;
+        
+    public CompilationResult( final CompilationProblem[] pProblems ) {
+        final Collection errorsColl = new ArrayList();
+        final Collection warningsColl = new ArrayList();
+
+        for (int i = 0; i < pProblems.length; i++) {
+            final CompilationProblem problem = pProblems[i];
+            if (problem.isError()) {
+                errorsColl.add(problem);
+            } else {
+                warningsColl.add(problem);
+            }
+        }
+        
+        errors = new CompilationProblem[errorsColl.size()];
+        errorsColl.toArray(errors);
+
+        warnings = new CompilationProblem[warningsColl.size()];
+        warningsColl.toArray(warnings);
+    }
+    
+    public CompilationProblem[] getErrors() {
+        return errors;
+    }
+
+    public CompilationProblem[] getWarnings() {
+        return warnings;
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/jci/compilers/JavaCompiler.java b/core/src/main/java/org/apache/commons/jci/compilers/JavaCompiler.java
new file mode 100644
index 0000000..3babdbc
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/compilers/JavaCompiler.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import org.apache.commons.jci.problems.CompilationProblemHandler;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+
+
+/**
+ * The general compiler interface. All compilers implementing
+ * this interface should read the resources from the reader
+ * and store the java class files into the ResourceStore.
+ * 
+ * The actual compilation language does not matter. But the
+ * contract is that the result of the compilation will be a
+ * class file.
+ * 
+ * If possible the compiler should notify the optional
+ * CompilationProblemHandler as soon as a problem is found.
+ * 
+ * @author tcurdt
+ */
+public interface JavaCompiler {
+
+    /**
+     * Set the the handler that gets the notification of an error
+     * or warning as soon as this information is available from
+     * the compiler.
+     * Note: Some compilers might not support this feature.
+     * 
+     * @param pHandler
+     */
+    void setCompilationProblemHandler( final CompilationProblemHandler pHandler );
+
+    /**
+     * factory method to create the underlying default settings
+     */
+    JavaCompilerSettings createDefaultSettings();
+    
+    /**
+     * uses the default compiler settings and the current classloader
+     */
+    CompilationResult compile( final String[] pResourcePaths, final ResourceReader pReader, final ResourceStore pStore );
+
+    /**
+     * uses the default compiler settings
+     */
+    CompilationResult compile( final String[] pResourcePaths, final ResourceReader pReader, final ResourceStore pStore, final ClassLoader pClassLoader );
+
+    /**
+     * Compiles the java resources "some/path/to/MyJava.java"
+     * read through the ResourceReader and then stores the resulting
+     * classes in the ResourceStore under "some/path/to/MyJava.class".
+     * Note: As these are resource path you always have to use "/" 
+     * 
+     * The result of the compilation run including detailed error
+     * information is returned as CompilationResult. If you need to
+     * get notified already during the compilation process you can
+     * register a CompilationProblemHandler.
+     * Note: Not all compilers might support this notification mechanism.
+     * 
+     * @param pResourcePaths
+     * @param pReader
+     * @param pStore
+     * @param pClassLoader
+     * @param pSettings
+     * @return always a CompilationResult
+     */
+    CompilationResult compile( final String[] pResourcePaths, final ResourceReader pReader, final ResourceStore pStore, final ClassLoader pClassLoader, final JavaCompilerSettings pSettings );
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/compilers/JavaCompilerFactory.java b/core/src/main/java/org/apache/commons/jci/compilers/JavaCompilerFactory.java
new file mode 100644
index 0000000..337e273
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/compilers/JavaCompilerFactory.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.jci.utils.ConversionUtils;
+
+
+/**
+ * Creates JavaCompilers
+ * 
+ * TODO use META-INF discovery mechanism
+ * 
+ * @author tcurdt
+ */
+public final class JavaCompilerFactory {
+
+    /**
+     * @deprecated will be remove after the next release, please create an instance yourself
+     */
+    private static final JavaCompilerFactory INSTANCE = new JavaCompilerFactory();
+
+    private final Map classCache = new HashMap();
+    
+    /**
+     * @deprecated will be remove after the next release, please create an instance yourself
+     */
+    public static JavaCompilerFactory getInstance() {
+        return JavaCompilerFactory.INSTANCE;
+    }
+
+    /**
+     * Tries to guess the class name by convention. So for compilers
+     * following the naming convention
+     * 
+     *   org.apache.commons.jci.compilers.SomeJavaCompiler
+     *   
+     * you can use the short-hands "some"/"Some"/"SOME". Otherwise
+     * you have to provide the full class name. The compiler is
+     * getting instanciated via (cached) reflection.
+     * 
+     * @param pHint
+     * @return JavaCompiler or null
+     */
+    public JavaCompiler createCompiler(final String pHint) {
+        
+        final String className;
+        if (pHint.indexOf('.') < 0) {
+            className = "org.apache.commons.jci.compilers." + ConversionUtils.toJavaCasing(pHint) + "JavaCompiler";
+        } else {
+            className = pHint;
+        }
+        
+        Class clazz = (Class) classCache.get(className);
+        
+        if (clazz == null) {
+            try {
+                clazz = Class.forName(className);
+                classCache.put(className, clazz);
+            } catch (ClassNotFoundException e) {
+                clazz = null;
+            }
+        }
+
+        if (clazz == null) {
+            return null;
+        }
+        
+        try {
+            return (JavaCompiler) clazz.newInstance();
+        } catch (Throwable t) {
+            return null;
+        }
+    }
+    
+}
diff --git a/core/src/main/java/org/apache/commons/jci/compilers/JavaCompilerSettings.java b/core/src/main/java/org/apache/commons/jci/compilers/JavaCompilerSettings.java
new file mode 100644
index 0000000..948a11d
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/compilers/JavaCompilerSettings.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+
+/**
+ * Most common denominator for JavaCompiler settings.
+ * 
+ * If you need more specific settings you have to provide
+ * the native compiler configurations to the compilers.
+ * Writing of a custom factory is suggested. 
+ * 
+ * @author tcurdt
+ */
+public class JavaCompilerSettings {
+
+    private String targetVersion;
+    private String sourceVersion;
+    private String sourceEncoding;
+    private boolean warnings;
+    private boolean deprecations;
+    private boolean verbose;
+
+
+    public void setTargetVersion( final String pTargetVersion ) {
+        targetVersion = pTargetVersion;
+    }
+
+    public String getTargetVersion() {
+        return targetVersion;
+    }
+
+
+    public void setSourceVersion( final String pSourceVersion ) {
+        sourceVersion = pSourceVersion;
+    }
+
+    public String getSourceVersion() {
+        return sourceVersion;
+    }
+
+
+    public void setSourceEncoding( final String pSourceEncoding ) {
+        sourceEncoding = pSourceEncoding;
+    }
+
+    public String getSourceEncoding() {
+        return sourceEncoding;
+    }
+
+
+    public void setWarnings( final boolean pWarnings ) {
+        warnings = pWarnings;
+    }
+
+    public boolean isWarnings() {
+        return warnings;
+    }
+
+
+    public void setDeprecations( final boolean pDeprecations )  {
+        deprecations = pDeprecations;
+    }
+
+    public boolean isDeprecations() {
+        return deprecations;
+    }
+
+
+    public void setVerbose( final boolean pVerbose ) {
+        verbose = pVerbose;
+    }
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/compilers/package.html b/core/src/main/java/org/apache/commons/jci/compilers/package.html
new file mode 100644
index 0000000..5ac10f7
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/compilers/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+Interfaces and abstract classes for the compiler abstraction itself.
+</body></html>
diff --git a/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java b/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java
new file mode 100644
index 0000000..bdf7141
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/listeners/CompilingListener.java
@@ -0,0 +1,185 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.listeners;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.commons.jci.compilers.CompilationResult;
+import org.apache.commons.jci.compilers.JavaCompiler;
+import org.apache.commons.jci.compilers.JavaCompilerFactory;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.FileResourceReader;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.MemoryResourceStore;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.stores.TransactionalResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A CompilingListener is an improved version of the ReloadingListener.
+ * It even compiles the classes from source before doing the reloading.
+ * 
+ * @author tcurdt
+ */
+public class CompilingListener extends ReloadingListener {
+
+    private final Log log = LogFactory.getLog(CompilingListener.class);
+    
+    private final JavaCompiler compiler;
+    private final TransactionalResourceStore transactionalStore;
+    private ResourceReader reader;
+    private CompilationResult lastResult;
+    
+    public CompilingListener() {
+        this(new JavaCompilerFactory().createCompiler("eclipse"));
+    }
+
+    public CompilingListener( final JavaCompiler pCompiler ) {
+        this(pCompiler, new TransactionalResourceStore(new MemoryResourceStore()));
+    }
+    
+    public CompilingListener( final JavaCompiler pCompiler, final TransactionalResourceStore pTransactionalStore ) {
+        super(pTransactionalStore);
+        compiler = pCompiler;
+        transactionalStore = pTransactionalStore;
+        lastResult = null;
+    }
+    
+    public JavaCompiler getCompiler() {
+        return compiler;
+    }
+    
+    public String getSourceFileExtension() {
+        return ".java";
+    }
+
+    public ResourceReader getReader( final FilesystemAlterationObserver pObserver ) {
+        return new FileResourceReader(pObserver.getRootDirectory());
+    }
+
+    public String getSourceNameFromFile( final FilesystemAlterationObserver pObserver, final File pFile ) {
+        return ConversionUtils.stripExtension(ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), pFile))) + getSourceFileExtension();
+    }
+    
+    public ResourceStore getStore() {
+        return transactionalStore;
+    }
+
+    public synchronized CompilationResult getCompilationResult() {
+        return lastResult;
+    }
+    
+    public void onStart( final FilesystemAlterationObserver pObserver ) {
+        super.onStart(pObserver);
+
+        reader = getReader(pObserver);
+
+        transactionalStore.onStart();
+    }
+
+    public String[] getResourcesToCompile( final FilesystemAlterationObserver pObserver ) {
+        final Collection created = getCreatedFiles();
+        final Collection changed = getChangedFiles();
+
+        final Collection resourceNames = new ArrayList();
+        
+        for (final Iterator it = created.iterator(); it.hasNext();) {
+            final File createdFile = (File) it.next();
+            if (createdFile.getName().endsWith(getSourceFileExtension())) {
+                resourceNames.add(getSourceNameFromFile(pObserver, createdFile));
+            }
+        }
+        
+        for (final Iterator it = changed.iterator(); it.hasNext();) {
+            final File changedFile = (File) it.next();
+            if (changedFile.getName().endsWith(getSourceFileExtension())) {
+                resourceNames.add(getSourceNameFromFile(pObserver, changedFile));
+            }
+        }
+
+        final String[] result = new String[resourceNames.size()];
+        resourceNames.toArray(result);
+        return result;
+    }
+    
+    public boolean isReloadRequired( final FilesystemAlterationObserver pObserver ) {
+        boolean reload = false;
+
+        final Collection created = getCreatedFiles();
+        final Collection changed = getChangedFiles();
+        final Collection deleted = getDeletedFiles();
+        
+        log.debug("created:" + created.size() + " changed:" + changed.size() + " deleted:" + deleted.size() + " resources");
+
+        if (deleted.size() > 0) {
+            for (Iterator it = deleted.iterator(); it.hasNext();) {
+                final File deletedFile = (File) it.next();
+
+                final String resourceName = ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), deletedFile));
+                
+                if (resourceName.endsWith(getSourceFileExtension())) {
+                    // if source resource got removed delete the corresponding class 
+                    transactionalStore.remove(ConversionUtils.stripExtension(resourceName) + ".class");
+                } else {
+                    // ordinary resource to be removed
+                    transactionalStore.remove(resourceName);
+                }
+                
+                // FIXME: does not remove nested classes
+                
+            }
+            reload = true;
+        }
+                                
+        final String[] resourcesToCompile = getResourcesToCompile(pObserver);
+
+        if (resourcesToCompile.length > 0) {
+
+            log.debug(resourcesToCompile.length + " classes to compile");
+            
+            final CompilationResult result = compiler.compile(resourcesToCompile, reader, transactionalStore);
+            
+            synchronized(this) {
+                lastResult = result;
+            }
+            
+            final CompilationProblem[] errors = result.getErrors();
+            final CompilationProblem[] warnings = result.getWarnings();
+            
+            log.debug(errors.length + " errors, " + warnings.length + " warnings");
+        
+            if (errors.length > 0) {
+                // FIXME: they need to be marked for re-compilation
+                // and then added as compileables again
+                for (int j = 0; j < resourcesToCompile.length; j++) {
+                    transactionalStore.remove(resourcesToCompile[j]);
+                }
+            }
+            
+            reload = true;
+        }
+        
+        return reload;
+    }    
+}
diff --git a/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java b/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java
new file mode 100644
index 0000000..23c9e41
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/listeners/FileChangeListener.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.listeners;
+
+import java.io.File;
+
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
+
+/**
+ * The most simple implemenation of an FilesystemAlterationListener.
+ * 
+ * @author tcurdt
+ */
+public class FileChangeListener extends AbstractFilesystemAlterationListener {
+
+    private boolean changed;
+    
+    public boolean hasChanged() {
+        return changed;
+    }
+    
+    public void onStart( final FilesystemAlterationObserver pObserver ) {
+        changed = false;
+        super.onStart(pObserver);
+    }
+
+    public void onStop( final FilesystemAlterationObserver pObserver ) {
+        super.onStop(pObserver);
+    }
+
+    
+    public void onFileChange( final File pFile ) {
+        changed = true;
+    }
+
+
+    public void onFileCreate( final File pFile ) {
+        changed = true;
+    }
+
+
+    public void onFileDelete( final File pFile ) {
+        changed = true;
+    }
+
+
+    public void onDirectoryChange( final File pDir ) {
+    }
+
+    public void onDirectoryCreate( final File pDir ) {
+    }
+
+    public void onDirectoryDelete( final File pDir ) {
+    }
+    
+}
diff --git a/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java b/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java
new file mode 100644
index 0000000..c3bc48e
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/listeners/ReloadNotificationListener.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.listeners;
+
+/**
+ * Classes implementing this interface can get notified by ReloadingListeners
+ * 
+ * @author tcurdt
+ */
+public interface ReloadNotificationListener {
+
+    void handleNotification();
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java b/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java
new file mode 100644
index 0000000..15c64eb
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/listeners/ReloadingListener.java
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.listeners;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.jci.ReloadingClassLoader;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
+import org.apache.commons.jci.stores.MemoryResourceStore;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.stores.Transactional;
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This Listener waits for FAM events to trigger a reload of classes
+ * or resources.
+ * 
+ * @author tcurdt
+ */
+public class ReloadingListener extends AbstractFilesystemAlterationListener {
+
+    private final Log log = LogFactory.getLog(ReloadingListener.class);
+    
+    private final Set notificationListeners = new HashSet();
+    private final ResourceStore store;
+    
+    public ReloadingListener() {
+        this(new MemoryResourceStore());
+    }
+
+    public ReloadingListener( final ResourceStore pStore ) {
+        store = pStore;
+    }
+
+    public ResourceStore getStore() {
+        return store;
+    }
+
+    public void addReloadNotificationListener( final ReloadNotificationListener pNotificationListener ) {
+        notificationListeners.add(pNotificationListener);
+
+        if (pNotificationListener instanceof ReloadingClassLoader) {
+            ((ReloadingClassLoader)pNotificationListener).addResourceStore(store);
+        }
+
+    }
+    
+    public boolean isReloadRequired( final FilesystemAlterationObserver pObserver ) {
+        boolean reload = false;
+
+        final Collection created = getCreatedFiles();
+        final Collection changed = getChangedFiles();
+        final Collection deleted = getDeletedFiles();
+        
+        log.debug("created:" + created.size() + " changed:" + changed.size() + " deleted:" + deleted.size() + " resources");
+
+        if (deleted.size() > 0) {
+            for (Iterator it = deleted.iterator(); it.hasNext();) {
+                final File file = (File) it.next();
+                final String resourceName = ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), file));
+                store.remove(resourceName);
+            }
+            reload = true;
+        }
+
+        if (created.size() > 0) {
+            for (Iterator it = created.iterator(); it.hasNext();) {
+                final File file = (File) it.next();
+                FileInputStream is = null;
+                try {
+                    is = new FileInputStream(file);
+                    final byte[] bytes = IOUtils.toByteArray(is);
+                    final String resourceName = ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), file));
+                    store.write(resourceName, bytes);
+                } catch(final Exception e) {
+                    log.error("could not load " + file, e);
+                } finally {
+                    IOUtils.closeQuietly(is);
+                }
+            }
+        }
+
+        if (changed.size() > 0) {
+            for (Iterator it = changed.iterator(); it.hasNext();) {
+                final File file = (File) it.next();
+                FileInputStream is = null;
+                try {
+                    is = new FileInputStream(file);
+                    final byte[] bytes = IOUtils.toByteArray(is);
+                    final String resourceName = ConversionUtils.getResourceNameFromFileName(ConversionUtils.relative(pObserver.getRootDirectory(), file));
+                    store.write(resourceName, bytes);
+                } catch(final Exception e) {
+                    log.error("could not load " + file, e);
+                } finally {
+                    IOUtils.closeQuietly(is);
+                }
+            }
+            reload = true;
+        }
+
+        return reload;
+    }
+    
+    public void onStop( final FilesystemAlterationObserver pObserver ) {
+        
+        
+        if (store instanceof Transactional) {
+            ((Transactional)store).onStart();
+        }
+
+        final boolean reload = isReloadRequired(pObserver);
+
+        if (store instanceof Transactional) {
+            ((Transactional)store).onStop();
+        }
+        
+        if (reload) {
+            notifyReloadNotificationListeners();
+        }
+        
+        super.onStop(pObserver);
+    }
+
+    void notifyReloadNotificationListeners() {
+        
+        for (Iterator it = notificationListeners.iterator(); it.hasNext();) {
+            final ReloadNotificationListener listener = (ReloadNotificationListener) it.next();
+
+            log.debug("notifying listener " + listener);
+
+            listener.handleNotification();
+        }
+    }
+    
+    public void onDirectoryCreate( final File pDir ) {                
+    }
+    public void onDirectoryChange( final File pDir ) {                
+    }
+    public void onDirectoryDelete( final File pDir ) {
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/jci/listeners/package.html b/core/src/main/java/org/apache/commons/jci/listeners/package.html
new file mode 100644
index 0000000..bc063d1
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/listeners/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+Special FAM listeners for just collecting FAM statistics, to compilation or class reloading.
+</body></html>
diff --git a/core/src/main/java/org/apache/commons/jci/package.html b/core/src/main/java/org/apache/commons/jci/package.html
new file mode 100644
index 0000000..a3994e8
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/package.html
@@ -0,0 +1,18 @@
+<!--
+
+   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.
+
+--><html><body></body></html>
diff --git a/core/src/main/java/org/apache/commons/jci/problems/CompilationProblem.java b/core/src/main/java/org/apache/commons/jci/problems/CompilationProblem.java
new file mode 100644
index 0000000..848604c
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/problems/CompilationProblem.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.problems;
+
+/**
+ * An abstract definition of a compilation problem
+ * 
+ * @author tcurdt
+ */
+public interface CompilationProblem {
+
+    /**
+     * is the problem an error and compilation cannot continue
+     * or just a warning and compilation can proceed
+     * 
+     * @return
+     */
+    boolean isError();
+
+    /**
+     * name of the file where the problem occurred
+     * 
+     * @return
+     */
+    String getFileName();
+
+    /**
+     * position of where the problem starts in the source code
+     * 
+     * @return
+     */
+    int getStartLine();
+    int getStartColumn();
+
+    /**
+     * position of where the problem stops in the source code
+     * 
+     * @return
+     */
+    int getEndLine();
+    int getEndColumn();
+
+    /**
+     * the description of the problem
+     * 
+     * @return
+     */
+    String getMessage();
+
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/commons/jci/problems/CompilationProblemHandler.java b/core/src/main/java/org/apache/commons/jci/problems/CompilationProblemHandler.java
new file mode 100644
index 0000000..bf22904
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/problems/CompilationProblemHandler.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.problems;
+
+
+/**
+ * A CompilationProblemHandler gets access to a problem
+ * as soon as the problem is available while the
+ * CompilationResult only represents a summary at the
+ * end.
+ * The handler can be used to asynchronously update a
+ * GUI or stop compilation by returning false (e.g.
+ * when a maximum number of erros has been reached)
+ * 
+ * NOTE:
+ * has to be supported by the compiler implementation!!
+ * 
+ * @author tcurdt
+ */
+public interface CompilationProblemHandler {
+
+    boolean handle( final CompilationProblem pProblem );
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/problems/package.html b/core/src/main/java/org/apache/commons/jci/problems/package.html
new file mode 100644
index 0000000..ecc2281
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/problems/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+Compilation problems and related.
+</body></html>
diff --git a/core/src/main/java/org/apache/commons/jci/readers/FileResourceReader.java b/core/src/main/java/org/apache/commons/jci/readers/FileResourceReader.java
new file mode 100644
index 0000000..c5c86c1
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/readers/FileResourceReader.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.readers;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+
+/**
+ * A simple file system based Reader implementation
+ * 
+ * @author tcurdt
+ */
+public final class FileResourceReader implements ResourceReader {
+
+    private final File root;
+
+    public FileResourceReader( final File pRoot ) {
+        root = pRoot;        
+    }
+    
+    public boolean isAvailable( final String pResourceName ) {
+        return new File(root, pResourceName).exists();
+    }
+
+    public byte[] getBytes( final String pResourceName ) {
+        try {
+            return FileUtils.readFileToString(new File(root, pResourceName), "UTF-8").getBytes();
+        } catch(Exception e) {
+            return null;
+        }
+    }
+    
+    /**
+     * @deprecated
+     */
+    public String[] list() {
+        final List files = new ArrayList();
+        list(root, files);
+        return (String[]) files.toArray(new String[files.size()]);
+    }
+
+    /**
+     * @deprecated
+     */
+    private void list( final File pFile, final List pFiles ) {
+        if (pFile.isDirectory()) {
+            final File[] directoryFiles = pFile.listFiles();
+            for (int i = 0; i < directoryFiles.length; i++) {
+                list(directoryFiles[i], pFiles);
+            }
+        } else {
+            pFiles.add(pFile.getAbsolutePath().substring(root.getAbsolutePath().length()+1));
+        }
+    }   
+}
diff --git a/core/src/main/java/org/apache/commons/jci/readers/MemoryResourceReader.java b/core/src/main/java/org/apache/commons/jci/readers/MemoryResourceReader.java
new file mode 100644
index 0000000..1ecb069
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/readers/MemoryResourceReader.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.readers;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * A memory based reader to compile from memory
+ * 
+ * @author tcurdt
+ */
+public class MemoryResourceReader implements ResourceReader {
+    
+    private Map resources;
+
+    public boolean isAvailable( final String pResourceName ) {
+        if (resources == null) {
+            return false;
+        }
+
+        return resources.containsKey(pResourceName);
+    }
+    
+    public void add( final String pResourceName, final byte[] pContent ) {
+        if (resources == null) {
+            resources = new HashMap();
+        }
+        
+        resources.put(pResourceName, pContent);
+    }
+    
+    public void remove( final String pResourceName ) {
+        if (resources != null) {
+            resources.remove(pResourceName);
+        }    
+    }    
+    
+
+    public byte[] getBytes( final String pResourceName ) {
+        return (byte[]) resources.get(pResourceName);
+    }
+
+    /**
+     * @deprecated
+     */
+    public String[] list() {
+        if (resources == null) {
+            return new String[0];
+        }
+        return (String[]) resources.keySet().toArray(new String[resources.size()]);
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/jci/readers/ResourceReader.java b/core/src/main/java/org/apache/commons/jci/readers/ResourceReader.java
new file mode 100644
index 0000000..638cf2e
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/readers/ResourceReader.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.readers;
+
+/**
+ * A ResourceReader provide acces to resource like e.g. source code
+ * 
+ * @author tcurdt
+ */
+public interface ResourceReader {
+
+    boolean isAvailable( final String pResourceName );
+    byte[] getBytes( final String pResourceName );
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/readers/package.html b/core/src/main/java/org/apache/commons/jci/readers/package.html
new file mode 100644
index 0000000..d7a1b24
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/readers/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+Readers to read resources from.
+</body></html>
diff --git a/core/src/main/java/org/apache/commons/jci/stores/FileResourceStore.java b/core/src/main/java/org/apache/commons/jci/stores/FileResourceStore.java
new file mode 100644
index 0000000..133d7ba
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/stores/FileResourceStore.java
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.stores;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+
+
+/**
+ * Stores the results on disk
+ * 
+ * @author tcurdt
+ */
+public final class FileResourceStore implements ResourceStore {
+
+    private final File root;
+
+    public FileResourceStore( final File pFile ) {
+        root = pFile;
+    }
+    
+    public byte[] read( final String pResourceName ) {
+        InputStream is = null;
+        try {
+            is = new FileInputStream(getFile(pResourceName));
+            final byte[] data = IOUtils.toByteArray(is);
+            return data;
+        } catch (Exception e) {
+            return null;
+        } finally {
+            IOUtils.closeQuietly(is);
+        }
+    }
+    
+    public void write( final String pResourceName, final byte[] pData ) {
+        OutputStream os = null;
+        try {
+            final File file = getFile(pResourceName);
+            final File parent = file.getParentFile();
+            if (!parent.exists()) {
+                if (!parent.mkdirs()) {
+                    throw new IOException("could not create" + parent);
+                }
+            }
+            os = new FileOutputStream(file);
+            os.write(pData);
+        } catch (Exception e) {
+            // FIXME: now what?
+        } finally {
+            IOUtils.closeQuietly(os);
+        }
+    }
+
+    public void remove( final String pResourceName ) {
+        getFile(pResourceName).delete();
+    }
+
+    private File getFile( final String pResourceName ) {
+        final String fileName = pResourceName.replace('/', File.separatorChar);
+        return new File(root, fileName);
+    }
+
+    /**
+     * @deprecated
+     */
+    public String[] list() {
+        final List files = new ArrayList();
+        list(root, files);
+        return (String[]) files.toArray(new String[files.size()]);
+    }
+
+    /**
+     * @deprecated
+     */
+    private void list(final File pFile, final List pFiles) {
+        if (pFile.isDirectory()) {
+            final File[] directoryFiles = pFile.listFiles();
+            for (int i=0; i < directoryFiles.length; i++) {
+                list(directoryFiles[i], pFiles);
+            }
+        } else {
+            pFiles.add(pFile.getAbsolutePath().substring(root.getAbsolutePath().length()+1));
+        }
+    }
+    
+    public String toString() {
+        return this.getClass().getName() + root.toString();
+    }
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java b/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java
new file mode 100644
index 0000000..98d2895
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/stores/MemoryResourceStore.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.stores;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Store just in memory
+ * 
+ * @author tcurdt
+ */
+public final class MemoryResourceStore implements ResourceStore {
+
+    private final Log log = LogFactory.getLog(MemoryResourceStore.class);
+
+    private final Map store = new HashMap();
+
+    public byte[] read( final String pResourceName ) {
+        log.debug("reading resource " + pResourceName);
+        return (byte[]) store.get(pResourceName);
+    }
+
+    public void write( final String pResourceName, final byte[] pData ) {
+        log.debug("writing resource " + pResourceName + "(" + pData.length + ")");
+        store.put(pResourceName, pData);
+    }
+
+    public void remove( final String pResourceName ) {
+        log.debug("removing resource " + pResourceName);
+        store.remove(pResourceName);
+    }
+
+    /**
+     * @deprecated
+     */
+    public String[] list() {
+        if (store == null) {
+            return new String[0];
+        }
+        final List names = new ArrayList();
+        
+        for (final Iterator it = store.keySet().iterator(); it.hasNext();) {
+            final String name = (String) it.next();
+            names.add(name);
+        }
+
+        return (String[]) names.toArray(new String[store.size()]);
+    }
+    
+    public String toString() {
+        return this.getClass().getName() + store.toString();
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/jci/stores/ResourceStore.java b/core/src/main/java/org/apache/commons/jci/stores/ResourceStore.java
new file mode 100644
index 0000000..912f213
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/stores/ResourceStore.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+package org.apache.commons.jci.stores;
+
+/**
+ * A Store is where the compilers are storing the results
+ * 
+ * @author tcurdt
+ */
+public interface ResourceStore {
+
+    void write( final String pResourceName, final byte[] pResourceData );
+    byte[] read( final String pResourceName );
+    void remove( final String pResourceName );
+}
diff --git a/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java b/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java
new file mode 100644
index 0000000..aa63401
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/stores/ResourceStoreClassLoader.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+package org.apache.commons.jci.stores;
+
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * A ClassLoader backed by an array of ResourceStores
+ * 
+ * @author tcurdt
+ */
+public final class ResourceStoreClassLoader extends ClassLoader {
+
+    private final Log log = LogFactory.getLog(ResourceStoreClassLoader.class);
+
+    private final ResourceStore[] stores;
+
+    public ResourceStoreClassLoader( final ClassLoader pParent, final ResourceStore[] pStores ) {
+        super(pParent);
+        stores = pStores;
+    }
+
+    private Class fastFindClass(final String name) {
+        
+        if (stores != null) {
+            for (int i = 0; i < stores.length; i++) {
+                final ResourceStore store = stores[i];
+                final byte[] clazzBytes = store.read(ConversionUtils.convertClassToResourcePath(name));
+                if (clazzBytes != null) {
+                    log.debug(getId() + " found class: " + name  + " (" + clazzBytes.length + " bytes)");
+                    return defineClass(name, clazzBytes, 0, clazzBytes.length);
+                }            
+            }
+        }
+        
+        return null;            
+    }
+    
+    protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        // log.debug(getId() + " looking for: " + name);
+        Class clazz = findLoadedClass(name);
+
+        if (clazz == null) {
+            clazz = fastFindClass(name);
+            
+            if (clazz == null) {
+
+                final ClassLoader parent = getParent();
+                if (parent != null) {
+                    clazz = parent.loadClass(name);
+                    // log.debug(getId() + " delegating loading to parent: " + name);
+                } else {
+                    throw new ClassNotFoundException(name);
+                }
+                
+            } else {
+                log.debug(getId() + " loaded from store: " + name);
+            }
+        }
+
+        if (resolve) {
+            resolveClass(clazz);
+        }
+
+        return clazz;
+    }
+
+    protected Class findClass( final String name ) throws ClassNotFoundException {
+        final Class clazz = fastFindClass(name);
+        if (clazz == null) {
+            throw new ClassNotFoundException(name);
+        }
+        return clazz;
+    }
+    
+    private String getId() {
+        return "" + this + "[" + this.getClass().getClassLoader() + "]";
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/jci/stores/Transactional.java b/core/src/main/java/org/apache/commons/jci/stores/Transactional.java
new file mode 100644
index 0000000..b24afe5
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/stores/Transactional.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.stores;
+
+/**
+ * Receive start/stop events
+ * 
+ * @author tcurdt
+ */
+public interface Transactional {
+
+    void onStart();
+
+    void onStop();
+}
diff --git a/core/src/main/java/org/apache/commons/jci/stores/TransactionalResourceStore.java b/core/src/main/java/org/apache/commons/jci/stores/TransactionalResourceStore.java
new file mode 100644
index 0000000..ec7d2f1
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/stores/TransactionalResourceStore.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.stores;
+
+
+/**
+ * A TransactionalResourceStore get signals of the compilation process as a whole.
+ * When it started and when the compiler finished.
+ * 
+ * @author tcurdt
+ */
+public class TransactionalResourceStore implements ResourceStore, Transactional {
+
+    private final ResourceStore store;
+    
+    public TransactionalResourceStore( final ResourceStore pStore ) {
+        store = pStore;
+    }
+    
+    public void onStart() {
+    }
+    
+    public void onStop() {
+    }
+    
+    public byte[] read( final String pResourceName ) {
+        return store.read(pResourceName);
+    }
+    public void remove( final String pResourceName ) {
+        store.remove(pResourceName);
+    }
+    public void write( final String pResourceName, final byte[] pResourceData ) {
+        store.write(pResourceName, pResourceData);
+    }
+    
+    public String toString() {
+        return store.toString();
+    }
+}
diff --git a/core/src/main/java/org/apache/commons/jci/stores/package.html b/core/src/main/java/org/apache/commons/jci/stores/package.html
new file mode 100644
index 0000000..672cd20
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/stores/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+Stores to store the compilation results in.
+</body></html>
diff --git a/core/src/main/java/org/apache/commons/jci/utils/ConversionUtils.java b/core/src/main/java/org/apache/commons/jci/utils/ConversionUtils.java
new file mode 100644
index 0000000..9414d95
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/utils/ConversionUtils.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.utils;
+
+import java.io.File;
+
+/**
+ * Mainly common path manipultation helper methods
+ * NOT FOR USE OUTSIDE OF JCI
+ * 
+ * @author tcurdt
+ */
+public final class ConversionUtils {
+
+    /**
+     * Please do not use - internal
+     * org/my/Class.xxx -> org.my.Class
+     */
+    public static String convertResourceToClassName( final String pResourceName ) {
+        return ConversionUtils.stripExtension(pResourceName).replace('/', '.');
+    }
+
+    /**
+     * Please do not use - internal
+     * org.my.Class -> org/my/Class.class
+     */
+    public static String convertClassToResourcePath( final String pName ) {
+        return pName.replace('.', '/') + ".class";
+    }
+
+    /**
+     * Please do not use - internal
+     * org/my/Class.xxx -> org/my/Class
+     */
+    public static String stripExtension( final String pResourceName ) {
+        final int i = pResourceName.lastIndexOf('.');
+        if (i < 0) {
+            return pResourceName;
+        }
+        final String withoutExtension = pResourceName.substring(0, i);
+        return withoutExtension;
+    }
+
+    public static String toJavaCasing(final String pName) {
+        final char[] name = pName.toLowerCase().toCharArray();
+        name[0] = Character.toUpperCase(name[0]);
+        return new String(name);
+    }
+
+/*
+    public static String clazzName( final File base, final File file ) {
+        final int rootLength = base.getAbsolutePath().length();
+        final String absFileName = file.getAbsolutePath();
+        final int p = absFileName.lastIndexOf('.');
+        final String relFileName = absFileName.substring(rootLength + 1, p);
+        final String clazzName = relFileName.replace(File.separatorChar, '.');
+        return clazzName;
+    }
+*/
+    public static String relative( final File base, final File file ) {
+        final int rootLength = base.getAbsolutePath().length();
+        final String absFileName = file.getAbsolutePath();
+        final String relFileName = absFileName.substring(rootLength + 1);
+        return relFileName;
+    }
+
+    /**
+     * a/b/c.java -> a/b/c.java
+     * a\b\c.java -> a/b/c.java
+     * @param pFileName
+     * @return
+     */
+    public static String getResourceNameFromFileName( final String pFileName ) {
+        if ('/' == File.separatorChar) {
+            return pFileName;
+        }
+
+        return pFileName.replace(File.separatorChar, '/');
+    }
+
+}
diff --git a/core/src/main/java/org/apache/commons/jci/utils/package.html b/core/src/main/java/org/apache/commons/jci/utils/package.html
new file mode 100644
index 0000000..2f1e28a
--- /dev/null
+++ b/core/src/main/java/org/apache/commons/jci/utils/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+Utilities
+</body></html>
diff --git a/core/src/main/resources/LICENSE.txt b/core/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/core/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/core/src/main/resources/NOTICE.txt b/core/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..123262b
--- /dev/null
+++ b/core/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - Core
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/core/src/site/site.xml b/core/src/site/site.xml
new file mode 100644
index 0000000..8b743ef
--- /dev/null
+++ b/core/src/site/site.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+
+   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.
+
+--><project name="Jakarta Commons JCI">
+
+  <bannerRight>
+    <name>Jakarta Commons JCI ROOT</name>
+    <src>jci-logo-white.png</src>
+    <href>http://jakarta.apache.org/commons/sandbox/jci/</href>
+  </bannerRight>
+
+  <body>
+
+<!--
+    <breadcrumbs> 
+      <item name="Library Homepage" href="http://www.library.jhu.edu"/> 
+    </breadcrumbs>
+-->
+
+    <menu ref="parent" />
+
+  </body>
+</project>
diff --git a/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java b/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java
new file mode 100644
index 0000000..25a0614
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/AbstractTestCase.java
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import junit.framework.TestCase;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public abstract class AbstractTestCase extends TestCase {
+
+    private final Log log = LogFactory.getLog(AbstractTestCase.class);
+    
+    protected File directory;
+
+    protected void setUp() throws Exception {
+
+        System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
+
+        directory = createTempDirectory();
+        assertTrue(directory.exists());
+        assertTrue(directory.isDirectory());
+    }
+    
+    
+    protected File createDirectory( final String pName ) throws Exception {
+        final File newDirectory = new File(directory, pName);
+        assertTrue(newDirectory.mkdir());
+        assertTrue(newDirectory.exists());
+        assertTrue(newDirectory.isDirectory());
+        return newDirectory;
+    }
+    
+    protected File writeFile( final String pName, final byte[] pData ) throws Exception {
+        final File file = new File(directory, pName);
+        final File parent = file.getParentFile();
+        if (!parent.exists()) {
+            if (!parent.mkdirs()) {
+                throw new IOException("could not create" + parent);
+            }
+        }
+        
+        log.debug("writing file " + pName + " (" + pData.length + " bytes)");
+        
+        final FileOutputStream os = new FileOutputStream(file);
+        os.write(pData);
+        os.close();
+        
+        assertTrue(file.exists());
+        assertTrue(file.isFile());
+        
+        return file;
+    }
+
+    protected File writeFile( final String pName, final String pText ) throws Exception {
+        final File file = new File(directory, pName);
+        final File parent = file.getParentFile();
+        if (!parent.exists()) {
+            if (!parent.mkdirs()) {
+                throw new IOException("could not create" + parent);
+            }
+        }
+        log.debug("writing " + file);
+        final FileWriter writer = new FileWriter(file);
+        writer.write(pText);
+        writer.close();
+        
+        assertTrue(file.exists());
+        assertTrue(file.isFile());
+        
+        return file;
+    }
+    
+    protected void delay() {
+        try {
+            Thread.sleep(1500);
+        } catch (final InterruptedException e) {
+        }
+    }
+    
+    protected File createTempDirectory() throws IOException {
+        final File tempFile = File.createTempFile("jci", null);
+        
+        if (!tempFile.delete()) {
+            throw new IOException();
+        }
+        
+        if (!tempFile.mkdir()) {
+            throw new IOException();
+        }
+        
+        return tempFile;         
+    }
+
+
+    protected void tearDown() throws Exception {
+        FileUtils.deleteDirectory(directory);
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java b/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
new file mode 100644
index 0000000..4cdd40a
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/CompilingClassLoaderTestCase.java
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.jci.classes.ExtendedDump;
+import org.apache.commons.jci.classes.SimpleDump;
+import org.apache.commons.jci.compilers.CompilationResult;
+import org.apache.commons.jci.compilers.JavaCompiler;
+import org.apache.commons.jci.compilers.JavaCompilerSettings;
+import org.apache.commons.jci.listeners.CompilingListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.problems.CompilationProblemHandler;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class CompilingClassLoaderTestCase extends AbstractTestCase {
+
+    private final Log log = LogFactory.getLog(CompilingClassLoaderTestCase.class);
+
+    private ReloadingClassLoader classloader;
+    private CompilingListener listener;
+    private FilesystemAlterationMonitor fam;
+        
+    private final static class MockJavaCompiler implements JavaCompiler {
+
+        private final Log log = LogFactory.getLog(MockJavaCompiler.class);
+
+        public CompilationResult compile(String[] pResourcePaths, ResourceReader pReader, ResourceStore pStore, ClassLoader pClassLoader, JavaCompilerSettings pSettings ) {
+
+            for (int i = 0; i < pResourcePaths.length; i++) {
+                final String resourcePath = pResourcePaths[i];
+                final byte[] resourceContent = pReader.getBytes(resourcePath);
+
+                log.debug("resource " + resourcePath + " = " + ((resourceContent!=null)?new String(resourceContent):null) );
+
+                final byte[] data;
+
+                if ("jci/Simple.java".equals(resourcePath)) {
+
+                    try {
+                        data = SimpleDump.dump(new String(resourceContent));
+                    } catch (Exception e) {
+                        throw new RuntimeException("cannot handle resource " + resourcePath, e);
+                    }
+
+                } else if ("jci/Extended.java".equals(resourcePath)) {
+
+                    try {
+                        data = ExtendedDump.dump();
+                    } catch (Exception e) {
+                        throw new RuntimeException("cannot handle resource " + resourcePath, e);
+                    }
+
+                } else {
+                    throw new RuntimeException("cannot handle resource " + resourcePath);
+                }
+
+                log.debug("compiling " + resourcePath + " (" + data.length + ")");
+
+                pStore.write(ConversionUtils.stripExtension(resourcePath) + ".class", data);
+
+            }
+
+            return new CompilationResult(new CompilationProblem[0]);
+        }
+
+        public CompilationResult compile(String[] pResourcePaths, ResourceReader pReader, ResourceStore pStore, ClassLoader pClassLoader) {
+            return compile(pResourcePaths, pReader, pStore, pClassLoader, null);
+        }
+
+        public CompilationResult compile(String[] pResourcePaths, ResourceReader pReader, ResourceStore pStore) {
+            return compile(pResourcePaths, pReader, pStore, null);
+        }
+
+        public void setCompilationProblemHandler(CompilationProblemHandler pHandler) {
+        }
+
+        public JavaCompilerSettings createDefaultSettings() {
+            return null;
+        }
+
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        classloader = new ReloadingClassLoader(this.getClass().getClassLoader());
+        listener = new CompilingListener(new MockJavaCompiler());   
+
+        listener.addReloadNotificationListener(classloader);
+        
+        fam = new FilesystemAlterationMonitor();
+        fam.addListener(directory, listener);
+        fam.start();
+    }
+
+    private void initialCompile() throws Exception {
+        log.debug("initial compile");        
+
+        listener.waitForFirstCheck();
+                
+        writeFile("jci/Simple.java", "Simple1");        
+        writeFile("jci/Extended.java", "Extended");        
+        
+        log.debug("waiting for compile changes to get applied");        
+        listener.waitForCheck();
+        
+        log.debug("*** ready to test");        
+    }
+    
+    public void testCreate() throws Exception {
+        initialCompile();
+        
+        log.debug("loading Simple");        
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        log.debug("loading Extended");        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+    }
+
+    public void testChange() throws Exception {        
+        initialCompile();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+
+        delay();
+        writeFile("jci/Simple.java", "Simple2");
+        listener.waitForCheck();
+    
+        final Object simple2 = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple2", simple2.toString());
+        
+        final Object newExtended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple2", newExtended.toString());
+    }
+
+    public void testDelete() throws Exception {
+        initialCompile();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+                
+        listener.waitForCheck();
+        
+        log.debug("deleting source file");
+        assertTrue(new File(directory, "jci/Extended.java").delete());
+        
+        listener.waitForCheck();
+       
+        log.debug("loading Simple");
+        final Object oldSimple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", oldSimple.toString());
+
+        log.debug("trying to loading Extended");
+        try {
+            classloader.loadClass("jci.Extended").newInstance();
+            fail();
+        } catch(final ClassNotFoundException e) {
+            assertEquals("jci.Extended", e.getMessage());
+        }        
+        
+        log.debug("deleting whole directory");
+        FileUtils.deleteDirectory(new File(directory, "jci"));
+
+        listener.waitForCheck();
+
+        log.debug("trying to loading Simple");
+        try {
+            classloader.loadClass("jci.Simple").newInstance();
+            fail();
+        } catch(final ClassNotFoundException e) {
+            assertEquals("jci.Simple", e.getMessage());
+        }
+
+    }
+
+    public void testDeleteDependency() throws Exception {        
+        initialCompile();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+        
+        log.debug("deleting source file");
+        assertTrue(new File(directory, "jci/Simple.java").delete());
+        listener.waitForCheck();
+
+        log.debug("trying to load dependend class");
+        try {
+            classloader.loadClass("jci.Extended").newInstance();
+            fail();
+        } catch(final NoClassDefFoundError e) {
+            assertEquals("jci/Simple", e.getMessage());
+        }
+        
+    }
+
+    protected void tearDown() throws Exception {
+        fam.removeListener(listener);
+        fam.stop();
+        super.tearDown();
+    }    
+}
diff --git a/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderRemoveTestCase.java b/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderRemoveTestCase.java
new file mode 100644
index 0000000..eb0e9cf
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderRemoveTestCase.java
@@ -0,0 +1,262 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci;
+
+import junit.framework.TestCase;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.jci.classes.SimpleDump;
+import org.apache.commons.jci.stores.ResourceStore;
+import org.apache.commons.jci.stores.MemoryResourceStore;
+
+/**
+ * Test ReloadingClassLoader's <code>removeResourceStore({@link ResourceStore})</code>
+ * method.
+ */
+public class ReloadingClassLoaderRemoveTestCase extends TestCase {
+
+    private final Log log = LogFactory.getLog(ReloadingClassLoaderRemoveTestCase.class);
+    
+    private final byte[] clazzSimpleA;
+    private MemoryResourceStore store1 = new MemoryResourceStore();
+    private MemoryResourceStore store2 = new MemoryResourceStore();
+    private MemoryResourceStore store3 = new MemoryResourceStore();
+    private MemoryResourceStore store4 = new MemoryResourceStore();
+
+    public ReloadingClassLoaderRemoveTestCase() throws Exception {
+        clazzSimpleA = SimpleDump.dump("SimpleA");
+        assertTrue(clazzSimpleA.length > 0);
+    }
+
+    protected void setUp() throws Exception {
+        System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
+    }
+    
+    protected void tearDown() throws Exception {
+    }
+
+    /**
+     * Test trying to remove a ResourceStore from the ReloadingClassLoader
+     * which can't be found - when the ClassLoader contains NO other ResourceStore.
+     *
+     * Bug: The While loop in the removeResourceStore() throws an ArrayOutOfBoundsException
+     */
+    public void testRemoveStoreNotFoundClassLoaderNoStores() {
+        ReloadingClassLoader loader = new ReloadingClassLoader(getClass().getClassLoader());
+        checkRemoveResourceStore("No ResourceStore", loader, store1, false);
+    }
+
+    /**
+     * Test trying to remove a ResourceStore from the ReloadingClassLoader
+     * which can't be found - when the ClassLoader DOES contain other ResourceStore.
+     *
+     * Bug: The While loop in the removeResourceStore() throws an ArrayOutOfBoundsException
+     */
+    public void testRemoveStoreNotFoundClassLoaderHasStores() {
+        ReloadingClassLoader loader = new ReloadingClassLoader(getClass().getClassLoader());
+        loader.addResourceStore(store1);
+        loader.addResourceStore(store2);
+        checkRemoveResourceStore("Has ResourceStore", loader, store3, false);
+    }
+
+    /**
+     * Test trying to remove the first ResourceStore added
+     *
+     * Bug: ReloadingClassLoader addes ResourceStore at the start of the array. Removing the
+     *      first one added (last in array) causes the second System.arraycopy() statement to throw a
+     *      ArrayIndexOutOfBoundsException because the destination array position in the new smaller
+     *      array is too large.
+     */
+    public void testRemoveStoresOne() {
+        ReloadingClassLoader loader = new ReloadingClassLoader(getClass().getClassLoader());
+        loader.addResourceStore(store1);
+        loader.addResourceStore(store2);
+        loader.addResourceStore(store3);
+        loader.addResourceStore(store4);
+
+        checkRemoveResourceStore("One: Remove Store 1", loader, store1, true);
+        checkRemoveResourceStore("One: Store 1 Not Found", loader, store1, false);
+
+        checkRemoveResourceStore("One: Remove Store 2", loader, store2, true);
+        checkRemoveResourceStore("One: Store 2 Not Found", loader, store2, false);
+
+        checkRemoveResourceStore("One: Remove Store 3", loader, store3, true);
+        checkRemoveResourceStore("One: Store 3 Not Found", loader, store3, false);
+
+        checkRemoveResourceStore("One: Remove Store 4", loader, store4, true);
+        checkRemoveResourceStore("One: Store 4 Not Found", loader, store4, false);
+    }
+
+    /**
+     * Test trying to remove the second ResourceStore added
+     *
+     * Bug: ReloadingClassLoader addes ResourceStore at the start of the array. Removing the
+     *      first one added (last in array) causes the second System.arraycopy() statement to throw a
+     *      ArrayIndexOutOfBoundsException (??not sure why??)
+     */
+    public void testRemoveStoresTwo() {
+        ReloadingClassLoader loader = new ReloadingClassLoader(getClass().getClassLoader());
+        loader.addResourceStore(store1);
+        loader.addResourceStore(store2);
+        loader.addResourceStore(store3);
+        loader.addResourceStore(store4);
+
+        checkRemoveResourceStore("Two: Remove Store 2", loader, store2, true);
+        checkRemoveResourceStore("Two: Store 2 Not Found", loader, store2, false);
+
+        checkRemoveResourceStore("Two: Remove Store 4", loader, store4, true);
+        checkRemoveResourceStore("Two: Store 4 Not Found", loader, store4, false);
+
+        checkRemoveResourceStore("Two: Remove Store 3", loader, store3, true);
+        checkRemoveResourceStore("Two: Store 3 Not Found", loader, store3, false);
+
+        checkRemoveResourceStore("Two: Remove Store 1", loader, store1, true);
+        checkRemoveResourceStore("Two: Store 1 Not Found", loader, store1, false);
+    }
+
+    /**
+     * Test trying to remove the third ResourceStore added
+     *
+     * Bug: In this scenario the two System.arraycopy() statements don't copy the correct
+     *      ResourceStore - it creates a new array where the first resource store is null
+     *      and copies store3 and store2 to their same positions
+     */
+    public void testRemoveStoresThree() {
+        ReloadingClassLoader loader = new ReloadingClassLoader(getClass().getClassLoader());
+        loader.addResourceStore(store1);
+        loader.addResourceStore(store2);
+        loader.addResourceStore(store3);
+        loader.addResourceStore(store4);
+
+        checkRemoveResourceStore("Three: Remove Store 3", loader, store3, true);
+        checkRemoveResourceStore("Three: Store 3 Not Found", loader, store3, false);
+
+        checkRemoveResourceStore("Three: Remove Store 1", loader, store1, true);
+        checkRemoveResourceStore("Three: Store 1 Not Found", loader, store1, false);
+
+        checkRemoveResourceStore("Three: Remove Store 4", loader, store4, true);
+        checkRemoveResourceStore("Three: Store 4 Not Found", loader, store4, false);
+
+        checkRemoveResourceStore("Three: Remove Store 2", loader, store2, true);
+        checkRemoveResourceStore("Three: Store 2 Not Found", loader, store2, false);
+    }
+
+    /**
+     * Test trying to remove the fourth ResourceStore added
+     *
+     * Bug: ReloadingClassLoader addes ResourceStore at the start of the array. Removing the
+     *      last one added (first in array) causes the first System.arraycopy() statement to throw a
+     *      ArrayIndexOutOfBoundsException because the length to copy is -1
+     */
+    public void testRemoveStoresFour() {
+        ReloadingClassLoader loader = new ReloadingClassLoader(getClass().getClassLoader());
+        loader.addResourceStore(store1);
+        loader.addResourceStore(store2);
+        loader.addResourceStore(store3);
+        loader.addResourceStore(store4);
+
+        checkRemoveResourceStore("Four: Remove Store 4", loader, store4, true);
+        checkRemoveResourceStore("Four: Store 4 Not Found", loader, store4, false);
+
+        checkRemoveResourceStore("Four: Remove Store 3", loader, store3, true);
+        checkRemoveResourceStore("Four: Store 3 Not Found", loader, store3, false);
+
+        checkRemoveResourceStore("Four: Remove Store 2", loader, store2, true);
+        checkRemoveResourceStore("Four: Store 2 Not Found", loader, store2, false);
+
+        checkRemoveResourceStore("Four: Remove Store 1", loader, store1, true);
+        checkRemoveResourceStore("Four: Store 1 Not Found", loader, store1, false);
+    }
+
+
+    /**
+     * Test that a class can't be loaded after the ResourceStore containing
+     * it has been removed.
+     *
+     * Bug: When theres a single ResourceStore in the ClassLoader and its removed
+     *      a new "delegate" ClassLoader with the new ResourceStore array isn't being
+     *      created - which means that calling loadClass() still returns the classes
+     *      from the removed ResourceStore rather than throwing a ClassNotFoundException
+     */
+    public void testLoadClassAfterResourceStoreRemoved() {
+
+        // Create a class loader & add resource store
+        ReloadingClassLoader loader = new ReloadingClassLoader(this.getClass().getClassLoader());
+        MemoryResourceStore store = new MemoryResourceStore();
+        loader.addResourceStore(store);
+
+        // Check "jci.Simple" class can't be loaded
+        try {
+            Object simple1 = loader.loadClass("jci.Simple").newInstance();        
+            fail("Success loadClass[1]");
+        } catch(ClassNotFoundException e) {
+            // expected not found
+        } catch(Exception e) {
+            log.error(e);
+            fail("Error loadClass[1]: " + e);
+        }
+
+        // Add "jci.Simple" class to the resource store
+        String toStringValue = "FooBar";
+        try {
+            byte[] classBytes = SimpleDump.dump(toStringValue);
+            store.write("jci/Simple.class", classBytes);
+        } catch(Exception e) {
+            log.error(e);
+            fail("Error adding class to store: " + e);
+        }
+
+        // Check "jci.Simple" class can now be loaded
+        try {
+            Object simple2 = loader.loadClass("jci.Simple").newInstance();        
+            assertNotNull("Found loadClass[2]",  simple2);        
+            assertEquals("toString loadClass[2]",  toStringValue, simple2.toString());        
+        } catch(Exception e) {
+            log.error(e);
+            fail("Error loadClass[2]: " + e);
+        }
+
+        // Remove the resource store from the class loader
+        checkRemoveResourceStore("Remove Resource Store", loader, store, true);
+
+        // Test "jci.Simple" class can't be loaded after ResourceStore removed
+        try {
+            Object simple3 = loader.loadClass("jci.Simple").newInstance();        
+            fail("Success loadClass[3]");
+        } catch(ClassNotFoundException e) {
+            // expected not found
+        } catch(Exception e) {
+            log.error(e);
+            fail("Error loadClass[3]: " + e);
+        }
+
+    }
+
+    /**
+     * Check removing a ResourceStore from ReloadingClassLoader
+     */
+    private void checkRemoveResourceStore(String label, ReloadingClassLoader loader, ResourceStore store, boolean expected) {
+        try {
+            assertEquals(label, expected, loader.removeResourceStore(store));
+        } catch(Exception e) {
+            log.error(label, e);
+            fail(label + " failed: " + e);
+        }
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java b/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
new file mode 100644
index 0000000..6e3cc58
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/ReloadingClassLoaderTestCase.java
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci;
+
+import java.io.File;
+
+import org.apache.commons.jci.classes.ExtendedDump;
+import org.apache.commons.jci.classes.SimpleDump;
+import org.apache.commons.jci.listeners.ReloadingListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class ReloadingClassLoaderTestCase extends AbstractTestCase {
+
+    private final Log log = LogFactory.getLog(ReloadingClassLoaderTestCase.class);
+    
+    private ReloadingClassLoader classloader;
+    private ReloadingListener listener;
+    private FilesystemAlterationMonitor fam;
+
+    private final byte[] clazzSimple1;
+    private final byte[] clazzSimple2;
+    private final byte[] clazzExtended;
+    
+    public ReloadingClassLoaderTestCase() throws Exception {
+        clazzSimple1 = SimpleDump.dump("Simple1");
+        clazzSimple2 = SimpleDump.dump("Simple2");
+        clazzExtended = ExtendedDump.dump(); 
+        assertTrue(clazzSimple1.length > 0);
+        assertTrue(clazzSimple2.length > 0);
+        assertTrue(clazzExtended.length > 0);
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        
+        classloader = new ReloadingClassLoader(this.getClass().getClassLoader());
+        listener = new ReloadingListener();
+        
+        listener.addReloadNotificationListener(classloader);
+        
+        fam = new FilesystemAlterationMonitor();
+        fam.addListener(directory, listener);
+        fam.start();
+    }
+
+    public void testCreate() throws Exception {
+        listener.waitForFirstCheck();
+
+        log.debug("creating class");        
+        writeFile("jci/Simple.class", clazzSimple1);
+        listener.waitForCheck();
+        
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());        
+    }
+
+    public void testChange() throws Exception {        
+        listener.waitForFirstCheck();
+
+        log.debug("creating class");
+        writeFile("jci/Simple.class", clazzSimple1);
+        listener.waitForCheck();
+
+        final Object simple1 = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple1.toString());
+        
+        log.debug("changing class");        
+        writeFile("jci/Simple.class", clazzSimple2);
+        listener.waitForEvent();
+    
+        final Object simple2 = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple2", simple2.toString());        
+    }
+
+    public void testDelete() throws Exception {
+        listener.waitForFirstCheck();
+
+        log.debug("creating class");
+        writeFile("jci/Simple.class", clazzSimple1);
+        listener.waitForCheck();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+
+        log.debug("deleting class");        
+        assertTrue(new File(directory, "jci/Simple.class").delete());
+        listener.waitForEvent();
+
+        try {
+            classloader.loadClass("jci.Simple").newInstance();        
+            fail();
+        } catch(final ClassNotFoundException e) {
+            assertEquals("jci.Simple", e.getMessage());
+        }        
+    }
+
+    public void testDeleteDependency() throws Exception {        
+        listener.waitForFirstCheck();
+
+        log.debug("creating classes");
+        writeFile("jci/Simple.class", clazzSimple1);
+        writeFile("jci/Extended.class", clazzExtended);
+        listener.waitForCheck();
+
+        final Object simple = classloader.loadClass("jci.Simple").newInstance();        
+        assertEquals("Simple1", simple.toString());
+        
+        final Object extended = classloader.loadClass("jci.Extended").newInstance();        
+        assertEquals("Extended:Simple1", extended.toString());
+
+        log.debug("deleting class dependency");        
+        assertTrue(new File(directory, "jci/Simple.class").delete());
+        listener.waitForEvent();
+
+        try {
+            classloader.loadClass("jci.Extended").newInstance();
+            fail();
+        } catch(final NoClassDefFoundError e) {
+            assertEquals("jci/Simple", e.getMessage());
+        }
+    }
+
+    public void testClassNotFound() {
+        try {
+            classloader.loadClass("bla");
+            fail();
+        } catch(final ClassNotFoundException e) {
+        }
+    }
+    
+    public void testDelegation() {
+        classloader.clearAssertionStatus();
+        classloader.setClassAssertionStatus("org.apache.commons.jci.ReloadingClassLoader", true);
+        classloader.setDefaultAssertionStatus(false);
+        classloader.setPackageAssertionStatus("org.apache.commons.jci", true);
+        // FIXME: compare with delegation
+    }
+    
+    protected void tearDown() throws Exception {
+        fam.removeListener(listener);
+        fam.stop();
+        super.tearDown();
+    }
+    
+}
diff --git a/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java b/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java
new file mode 100644
index 0000000..4177837
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/classes/ExtendedDump.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.classes;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+
+public class ExtendedDump implements Opcodes {
+
+    public static byte[] dump() throws Exception {
+
+        ClassWriter cw = new ClassWriter(true);
+        MethodVisitor mv;
+
+        cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, "jci/Extended", null, "jci/Simple", null);
+
+        cw.visitSource("Extended.java", null);
+
+        {
+            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+            mv.visitCode();
+            Label l0 = new Label();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(3, l0);
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL, "jci/Simple", "<init>", "()V");
+            mv.visitInsn(RETURN);
+            Label l1 = new Label();
+            mv.visitLabel(l1);
+            mv.visitLocalVariable("this", "Ljci/Extended;", null, l0, l1, 0);
+            mv.visitMaxs(1, 1);
+            mv.visitEnd();
+        }
+        {
+            mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
+            mv.visitCode();
+            Label l0 = new Label();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(6, l0);
+            mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
+            mv.visitInsn(DUP);
+            mv.visitLdcInsn("Extended:");
+            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL, "jci/Simple", "toString", "()Ljava/lang/String;");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
+            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
+            mv.visitInsn(ARETURN);
+            Label l1 = new Label();
+            mv.visitLabel(l1);
+            mv.visitLocalVariable("this", "Ljci/Extended;", null, l0, l1, 0);
+            mv.visitMaxs(3, 1);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java b/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java
new file mode 100644
index 0000000..5e020c1
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/classes/SimpleDump.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.classes;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public class SimpleDump implements Opcodes {
+
+    public static byte[] dump( final String to ) throws Exception {
+
+        ClassWriter cw = new ClassWriter(true);
+        MethodVisitor mv;
+
+        cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, "jci/Simple", null, "java/lang/Object", null);
+
+        cw.visitSource("Simple.java", null);
+
+        {
+            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+            mv.visitCode();
+            Label l0 = new Label();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(3, l0);
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+            mv.visitInsn(RETURN);
+            Label l1 = new Label();
+            mv.visitLabel(l1);
+            mv.visitLocalVariable("this", "Ljci/Simple;", null, l0, l1, 0);
+            mv.visitMaxs(1, 1);
+            mv.visitEnd();
+        }
+        {
+            mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
+            mv.visitCode();
+            Label l0 = new Label();
+            mv.visitLabel(l0);
+            mv.visitLineNumber(6, l0);
+            mv.visitLdcInsn(to);
+            mv.visitInsn(ARETURN);
+            Label l1 = new Label();
+            mv.visitLabel(l1);
+            mv.visitLocalVariable("this", "Ljci/Simple;", null, l0, l1, 0);
+            mv.visitMaxs(1, 1);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+
+        return cw.toByteArray();
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/jci/compilers/AbstractCompilerTestCase.java b/core/src/test/java/org/apache/commons/jci/compilers/AbstractCompilerTestCase.java
new file mode 100644
index 0000000..5f9d411
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/compilers/AbstractCompilerTestCase.java
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.compilers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.MemoryResourceStore;
+
+/**
+ * Providing convenience methods for JavaCompiler TestCases
+ * 
+ * @author tcurdt
+ */
+public abstract class AbstractCompilerTestCase extends TestCase {
+
+    public abstract JavaCompiler createJavaCompiler();
+
+    public abstract String getCompilerName();
+
+    public void testFactoryCreation() {
+        final JavaCompiler factoryCompiler = new JavaCompilerFactory().createCompiler(getCompilerName());
+        assertNotNull(factoryCompiler);
+
+        final JavaCompiler compiler = createJavaCompiler();
+        assertEquals(factoryCompiler.getClass().getName(), compiler.getClass().getName());
+    }
+
+    public void testSimpleCompile() throws Exception {
+        final JavaCompiler compiler = createJavaCompiler(); 
+
+        final ResourceReader reader = new ResourceReader() {
+            final private Map sources = new HashMap() {
+                private static final long serialVersionUID = 1L;
+                {
+                    put("jci/Simple.java", (
+                        "package jci;\n" +
+                        "public class Simple {\n" +
+                        "  public String toString() {\n" +
+                        "    return \"Simple\";\n" +
+                        "  }\n" +
+                        "}").getBytes());
+                }};
+
+            public byte[] getBytes( final String pResourceName ) {
+                return (byte[]) sources.get(pResourceName);
+            }
+
+            public boolean isAvailable( final String pResourceName ) {
+                return sources.containsKey(pResourceName);
+            }
+
+        };
+
+        final MemoryResourceStore store = new MemoryResourceStore();
+        final CompilationResult result = compiler.compile(
+                new String[] {
+                        "jci/Simple.java"
+                }, reader, store);
+
+        assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
+        assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
+
+        final byte[] clazzBytes = store.read("jci/Simple.class");
+        assertNotNull(clazzBytes);
+        assertTrue(clazzBytes.length > 0);
+    }
+
+    public void testExtendedCompile() throws Exception {
+        final JavaCompiler compiler = createJavaCompiler(); 
+
+        final ResourceReader reader = new ResourceReader() {
+            final private Map sources = new HashMap() {
+                private static final long serialVersionUID = 1L;
+                {
+                    put("jci/Simple.java", (
+                            "package jci;\n" +
+                            "public class Simple {\n" +
+                            "  public String toString() {\n" +
+                            "    return \"Simple\";\n" +
+                            "  }\n" +
+                    "}").getBytes());
+                    put("jci/Extended.java", (
+                            "package jci;\n" +
+                            "public class Extended extends Simple {\n" +
+                            "  public String toString() {\n" +
+                            "    return \"Extended\" + super.toString();\n" +
+                            "  }\n" +
+                    "}").getBytes());
+                }};
+
+            public byte[] getBytes( final String pResourceName ) {
+                return (byte[]) sources.get(pResourceName);
+            }
+
+            public boolean isAvailable( final String pResourceName ) {
+                return sources.containsKey(pResourceName);
+            }
+
+        };
+
+        final MemoryResourceStore store = new MemoryResourceStore();
+        final CompilationResult result = compiler.compile(
+                new String[] {
+                        "jci/Extended.java",
+                        "jci/Simple.java"
+                }, reader, store);
+
+        assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
+        assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
+
+        final byte[] clazzBytesSimple = store.read("jci/Simple.class");
+        assertNotNull(clazzBytesSimple);
+        assertTrue(clazzBytesSimple.length > 0);
+
+        final byte[] clazzBytesExtended = store.read("jci/Extended.class");
+        assertNotNull(clazzBytesExtended);
+        assertTrue(clazzBytesExtended.length > 0);
+    }
+
+    public void testInternalClassCompile() throws Exception {
+        final JavaCompiler compiler = createJavaCompiler(); 
+
+        final ResourceReader reader = new ResourceReader() {
+            final private Map sources = new HashMap() {
+                private static final long serialVersionUID = 1L;
+                {
+                    put("jci/Simple.java", (
+                            "package jci;\n" +
+                            "public class Simple {\n" +
+                            "  private class Sub {\n" +
+                            "  }\n" +
+                            "  public String toString() {\n" +
+                            "    new Sub();\n" +
+                            "    return \"Simple\";\n" +
+                            "  }\n" +
+                    "}").getBytes());
+                }};
+
+            public byte[] getBytes( final String pResourceName ) {
+                return (byte[]) sources.get(pResourceName);
+            }
+
+            public boolean isAvailable( final String pResourceName ) {
+                return sources.containsKey(pResourceName);
+            }
+
+        };
+
+        final MemoryResourceStore store = new MemoryResourceStore();
+        final CompilationResult result = compiler.compile(
+                new String[] {
+                        "jci/Simple.java"
+                }, reader, store);
+
+        assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
+        assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
+
+        final byte[] clazzBytes = store.read("jci/Simple.class");
+        assertNotNull(clazzBytes);
+        assertTrue(clazzBytes.length > 0);
+
+        final byte[] subClazzBytes = store.read("jci/Simple$Sub.class");
+        assertNotNull(subClazzBytes);
+        assertTrue(subClazzBytes.length > 0);
+
+    }
+
+    public void testUppercasePackageNameCompile() throws Exception {
+        final JavaCompiler compiler = createJavaCompiler(); 
+
+        final ResourceReader reader = new ResourceReader() {
+            final private Map sources = new HashMap() {
+                private static final long serialVersionUID = 1L;
+                {
+                    put("Jci/Simple.java", (
+                            "package Jci;\n" +
+                            "public class Simple {\n" +
+                            "  public String toString() {\n" +
+                            "    return \"Simple\";\n" +
+                            "  }\n" +
+                    "}").getBytes());
+                }};
+
+            public byte[] getBytes( final String pResourceName ) {
+                return (byte[]) sources.get(pResourceName);
+            }
+
+            public boolean isAvailable( final String pResourceName ) {
+                return sources.containsKey(pResourceName);
+            }
+
+        };
+
+        final MemoryResourceStore store = new MemoryResourceStore();
+        final CompilationResult result = compiler.compile(
+                new String[] {
+                        "Jci/Simple.java"
+                }, reader, store);
+
+        assertEquals(toString(result.getErrors()), 0, result.getErrors().length);
+        assertEquals(toString(result.getWarnings()), 0, result.getWarnings().length);
+
+        final byte[] clazzBytes = store.read("Jci/Simple.class");
+        assertNotNull(clazzBytes);
+        assertTrue(clazzBytes.length > 0);
+    }
+
+
+
+    public final String toString( final CompilationProblem[] pProblems ) {
+        final StringBuffer sb = new StringBuffer();
+
+        for (int i = 0; i < pProblems.length; i++) {
+            final CompilationProblem problem = pProblems[i];
+            sb.append(problem.getMessage()).append(", ");
+        }
+
+        return sb.toString();
+    }
+
+}
diff --git a/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java b/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java
new file mode 100644
index 0000000..d50c186
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/readers/ResourceReaderTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.readers;
+
+import org.apache.commons.jci.AbstractTestCase;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class ResourceReaderTestCase extends AbstractTestCase {
+
+    public void testFileResourceReader() throws Exception {
+        writeFile("test", "test");
+        checkRead(new FileResourceReader(directory));
+    }
+
+    public void testMemoryResourceReader() throws Exception {
+        final MemoryResourceReader reader = new MemoryResourceReader();
+        reader.add("test", "test".getBytes());
+        checkRead(reader);
+    }
+
+    private void checkRead( final ResourceReader reader ) throws Exception {
+        assertTrue(reader.isAvailable("test"));
+        final byte[] content = reader.getBytes("test");
+        assertTrue(content != null);
+        assertTrue("test".equals(new String(content)));        
+
+        assertTrue(!reader.isAvailable("bla"));
+        assertTrue(reader.getBytes("bla") == null);
+    }
+}
diff --git a/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java b/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java
new file mode 100644
index 0000000..cfa1149
--- /dev/null
+++ b/core/src/test/java/org/apache/commons/jci/stores/ResourceStoreTestCase.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.stores;
+
+import org.apache.commons.jci.AbstractTestCase;
+import org.apache.commons.lang.ArrayUtils;
+
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class ResourceStoreTestCase extends AbstractTestCase {
+
+    public void testMemoryResourceStore() {
+        checkReadWrite(new MemoryResourceStore());
+        checkRemove(new MemoryResourceStore());
+    }
+
+    public void testFileResourceStore() {
+        checkReadWrite(new FileResourceStore(directory));
+        checkRemove(new FileResourceStore(directory));
+    }
+
+    public void testTransactionalFileResourceStore() {
+        checkReadWrite(new TransactionalResourceStore(new FileResourceStore(directory)));
+        checkRemove(new TransactionalResourceStore(new FileResourceStore(directory)));
+    }
+
+    private void checkReadWrite( final ResourceStore pStore ) {
+        final byte[] data = { 1, 2, 3 };
+        pStore.write("key", data);
+        
+        final byte[] read = pStore.read("key");
+        
+        assertTrue(read != null);
+        assertTrue(ArrayUtils.isEquals(data, read));
+    }
+
+    private void checkRemove( final ResourceStore pStore ) {
+        final byte[] data = { 1, 2, 3 };
+        pStore.write("key", data);
+        
+        final byte[] read = pStore.read("key");
+        
+        assertTrue(read != null);
+        assertTrue(ArrayUtils.isEquals(data, read));
+
+        pStore.remove("key");
+
+        final byte[] empty = pStore.read("key");
+        
+        assertTrue(empty == null);
+    }    
+}
diff --git a/core/src/test/resources/simplelog.properties b/core/src/test/resources/simplelog.properties
new file mode 100644
index 0000000..6bd0ec9
--- /dev/null
+++ b/core/src/test/resources/simplelog.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.simplelog.defaultlog=debug
+org.apache.commons.logging.simplelog.showdatetime=true
\ No newline at end of file
diff --git a/examples/pom.xml b/examples/pom.xml
new file mode 100644
index 0000000..e8ebc91
--- /dev/null
+++ b/examples/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-examples</artifactId>
+    <version>1.0</version>
+    <name>examples</name>
+    <description>
+        Commons JCI examples.
+    </description>
+    <reporting>
+        <excludeDefaults>true</excludeDefaults>
+    </reporting>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-core</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-jci-eclipse</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.4</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.mortbay.jetty</groupId>
+                <artifactId>maven-jetty-plugin</artifactId>
+                <configuration>
+                    <systemProperties>
+                        <systemProperty>
+                            <name>org.apache.commons.logging.Log</name>
+                            <value>org.apache.commons.logging.impl.SimpleLog</value>
+                        </systemProperty>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/commandline/CommandlineCompiler.java b/examples/src/main/java/org/apache/commons/jci/examples/commandline/CommandlineCompiler.java
new file mode 100644
index 0000000..8bae395
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/commandline/CommandlineCompiler.java
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.commandline;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Iterator;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.jci.compilers.CompilationResult;
+import org.apache.commons.jci.compilers.JavaCompiler;
+import org.apache.commons.jci.compilers.JavaCompilerFactory;
+import org.apache.commons.jci.compilers.JavaCompilerSettings;
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.problems.CompilationProblemHandler;
+import org.apache.commons.jci.readers.FileResourceReader;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.FileResourceStore;
+import org.apache.commons.jci.stores.ResourceStore;
+
+/**
+ * A simple front end to jci mimicking the javac command line
+ *
+ * @author tcurdt
+ */
+public final class CommandlineCompiler {
+    
+    public static void main( String[] args ) throws Exception {
+
+        final Options options = new Options();
+
+        options.addOption(
+                OptionBuilder.withArgName("a.jar:b.jar")
+                    .hasArg()
+                    .withValueSeparator( ':' )
+                    .withDescription("Specify where to find user class files")
+                    .create( "classpath" ));
+
+        options.addOption(
+                OptionBuilder.withArgName("release")
+                    .hasArg()
+                    .withDescription("Provide source compatibility with specified release")
+                    .create( "source" ));
+
+        options.addOption(
+                OptionBuilder.withArgName("release")
+                    .hasArg()
+                    .withDescription("Generate class files for specific VM version")
+                    .create( "target" ));
+
+        options.addOption(
+                OptionBuilder.withArgName("path")
+                    .hasArg()
+                    .withDescription("Specify where to find input source files")
+                    .create( "sourcepath" ));
+
+        options.addOption(
+                OptionBuilder.withArgName("directory")
+                    .hasArg()
+                    .withDescription("Specify where to place generated class files")
+                    .create( "d" ));
+
+        options.addOption(
+                OptionBuilder.withArgName("num")
+                    .hasArg()
+                    .withDescription("Stop compilation after these number of errors")
+                    .create( "Xmaxerrs" ));
+
+        options.addOption(
+                OptionBuilder.withArgName("num")
+                    .hasArg()
+                    .withDescription("Stop compilation after these number of warning")
+                    .create( "Xmaxwarns" ));
+
+        options.addOption(
+                OptionBuilder.withDescription("Generate no warnings")
+                    .create( "nowarn" ));
+
+//        final HelpFormatter formatter = new HelpFormatter();
+//        formatter.printHelp("jci", options);
+
+        final CommandLineParser parser = new GnuParser();
+        final CommandLine cmd = parser.parse(options, args, true);
+
+        ClassLoader classloader = CommandlineCompiler.class.getClassLoader();
+        File sourcepath = new File(".");
+        File targetpath = new File(".");
+        int maxerrs = 10;
+        int maxwarns = 10;
+        final boolean nowarn = cmd.hasOption("nowarn");
+
+
+        final JavaCompiler compiler = new JavaCompilerFactory().createCompiler("eclipse");
+        final JavaCompilerSettings settings = compiler.createDefaultSettings();
+
+
+        for (Iterator it = cmd.iterator(); it.hasNext();) {
+            final Option option = (Option) it.next();
+
+            if ("classpath".equals(option.getOpt())) {
+                final String[] values = option.getValues();
+                final URL[] urls = new URL[values.length];
+                for (int i = 0; i < urls.length; i++) {
+                    urls[i] = new File(values[i]).toURL();
+                }
+                classloader = new URLClassLoader(urls);
+            } else if ("source".equals(option.getOpt())) {
+                settings.setSourceVersion(option.getValue());
+            } else if ("target".equals(option.getOpt())) {
+                settings.setTargetVersion(option.getValue());
+            } else if ("sourcepath".equals(option.getOpt())) {
+                sourcepath = new File(option.getValue());
+            } else if ("d".equals(option.getOpt())) {
+                targetpath = new File(option.getValue());
+            } else if ("Xmaxerrs".equals(option.getOpt())) {
+                maxerrs = Integer.parseInt(option.getValue());
+            } else if ("Xmaxwarns".equals(option.getOpt())) {
+                maxwarns = Integer.parseInt(option.getValue());
+            }
+        }
+
+        final ResourceReader reader = new FileResourceReader(sourcepath);
+        final ResourceStore store = new FileResourceStore(targetpath);
+        
+        final int maxErrors = maxerrs;
+        final int maxWarnings = maxwarns;
+        compiler.setCompilationProblemHandler(new CompilationProblemHandler() {
+            int errors = 0;
+            int warnings = 0;
+            public boolean handle(final CompilationProblem pProblem) {
+
+                if (pProblem.isError()) {
+                    System.err.println(pProblem);
+
+                    errors++;
+
+                    if (errors >= maxErrors) {
+                        return false;
+                    }
+                } else {
+                    if (!nowarn) {
+                        System.err.println(pProblem);
+                    }
+
+                    warnings++;
+
+                    if (warnings >= maxWarnings) {
+                        return false;
+                    }
+                }
+
+                return true;
+            }
+        });
+        
+        final String[] resource = cmd.getArgs();
+        
+        for (int i = 0; i < resource.length; i++) {
+            System.out.println("compiling " + resource[i]);
+        }
+        
+        final CompilationResult result = compiler.compile(resource, reader, store, classloader);
+        
+        System.out.println( result.getErrors().length + " errors");
+        System.out.println( result.getWarnings().length + " warnings");
+
+    }
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/commandline/package.html b/examples/src/main/java/org/apache/commons/jci/examples/commandline/package.html
new file mode 100644
index 0000000..47b2e6c
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/commandline/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+    Example demonstrating a simple front end to jci mimicking the javac command line.
+</body></html>
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/configuration/Configurable.java b/examples/src/main/java/org/apache/commons/jci/examples/configuration/Configurable.java
new file mode 100644
index 0000000..8d7450e
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/configuration/Configurable.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.configuration;
+
+import java.util.Properties;
+
+public interface Configurable {
+
+    void configure( Properties properties ) throws ConfigurationException;
+
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/configuration/ConfigurationException.java b/examples/src/main/java/org/apache/commons/jci/examples/configuration/ConfigurationException.java
new file mode 100644
index 0000000..0e1bdfa
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/configuration/ConfigurationException.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.configuration;
+
+public class ConfigurationException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/configuration/ConfigurationReloading.java b/examples/src/main/java/org/apache/commons/jci/examples/configuration/ConfigurationReloading.java
new file mode 100644
index 0000000..18c1156
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/configuration/ConfigurationReloading.java
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.configuration;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.apache.commons.jci.listeners.FileChangeListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class ConfigurationReloading {
+
+    private final FilesystemAlterationMonitor fam = new FilesystemAlterationMonitor();
+
+    private void run(String[] args) {
+
+        final File configFile = new File("some.properties");
+
+        System.out.println("Watching " + configFile.getAbsolutePath());
+
+        final Collection configurables = new ArrayList();
+
+        final FilesystemAlterationListener listener = new FileChangeListener() {
+            public void onStop(FilesystemAlterationObserver pObserver) {
+                super.onStop(pObserver);
+
+                if (hasChanged()) {
+                    System.out.println("Configuration change detected " + configFile);
+
+                    final Properties props = new Properties();
+                    try {
+
+                        props.load(new FileInputStream(configFile));
+
+                        System.out.println("Notifying about configuration change " + configFile);
+
+                        for (Iterator it = configurables.iterator(); it.hasNext();) {
+                            final Configurable configurable = (Configurable) it.next();
+                            configurable.configure(props);
+                        }
+
+                    } catch (Exception e) {
+                        System.err.println("Failed to load configuration " + configFile);
+                    }
+
+                }
+            }
+        };
+
+        fam.addListener(configFile, listener);
+		fam.start();
+
+		configurables.add(new Something());
+
+        while(true) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        new ConfigurationReloading().run(args);
+    }
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/configuration/Something.java b/examples/src/main/java/org/apache/commons/jci/examples/configuration/Something.java
new file mode 100644
index 0000000..76fa01a
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/configuration/Something.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.configuration;
+
+import java.util.Properties;
+
+public class Something implements Configurable {
+
+    public void configure( Properties properties ) throws ConfigurationException {
+        System.out.println("Configuration changed");
+    }
+
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/configuration/package.html b/examples/src/main/java/org/apache/commons/jci/examples/configuration/package.html
new file mode 100644
index 0000000..5d29896
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/configuration/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+    Example demonstrating auto-reloading of configurations.
+</body></html>
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/package.html b/examples/src/main/java/org/apache/commons/jci/examples/package.html
new file mode 100644
index 0000000..98aeed5
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+    Examples showing how to use jci.
+</body></html>
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/serverpages/JspGenerator.java b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/JspGenerator.java
new file mode 100644
index 0000000..c85c2c1
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/JspGenerator.java
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.serverpages;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.apache.commons.jci.utils.ConversionUtils;
+
+/**
+ * @author tcurdt
+ */
+public final class JspGenerator {
+
+    private String quote( final String s ) {
+
+        final StringBuffer sb = new StringBuffer();
+        final char[] input = s.toCharArray();
+
+        for (int i = 0; i < input.length; i++) {
+            final char c = input[i];
+            if (c == '"') {
+                sb.append('\\');
+            }
+            if (c == '\\') {
+                sb.append('\\');
+            }
+
+            if (c == '\n') {
+                sb.append("\");\n").append("    out.write(\"");
+                continue;
+            }
+            sb.append(c);
+        }
+
+        return sb.toString();
+    }
+
+    private void wrap( final StringBuffer pInput, final Writer pOutput ) throws IOException {
+
+        pOutput.append("    out.write(\"");
+
+        pOutput.append(quote(pInput.toString()));
+
+        pOutput.append("\");").append('\n');
+    }
+
+    public byte[] generateJavaSource( final  String pResourceName, final File pFile ) {
+
+        try {
+            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            final Reader input = new InputStreamReader(new FileInputStream(pFile));
+            final Writer output = new OutputStreamWriter(outputStream);
+
+            final int p = pResourceName.lastIndexOf('/');
+
+            final String className;
+            final String packageName;
+
+            if (p < 0) {
+                className = ConversionUtils.stripExtension(pResourceName);
+                packageName = "";
+            } else {
+                className = ConversionUtils.stripExtension(pResourceName.substring(p+1));
+                packageName = pResourceName.substring(0, p).replace('/', '.');
+                output.append("package ").append(packageName).append(";").append('\n');
+            }
+
+
+            output.append("import java.io.PrintWriter;").append('\n');
+            output.append("import java.io.IOException;").append('\n');
+            output.append("import javax.servlet.http.HttpServlet;").append('\n');
+            output.append("import javax.servlet.http.HttpServletRequest;").append('\n');
+            output.append("import javax.servlet.http.HttpServletResponse;").append('\n');
+            output.append("import javax.servlet.ServletException;").append('\n');
+            output.append("public class ").append(className).append(" extends HttpServlet {").append('\n');
+            output.append("  protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {").append('\n');
+            output.append("    final PrintWriter out = response.getWriter();").append('\n');
+
+
+            final char[] open = "<?".toCharArray();
+            final char[] close = "?>".toCharArray();
+
+            StringBuffer sb = new StringBuffer();
+            char[] watch = open;
+            int w = 0;
+            while(true) {
+                int c = input.read();
+
+                if (c < 0) {
+                    break;
+                }
+
+                if (c == watch[w]) {
+                    w++;
+                    if (watch.length == w) {
+                        if (watch == open) {
+                            // found open
+
+                            wrap(sb, output);
+
+                            sb = new StringBuffer();
+                            watch = close;
+                        } else if (watch == close) {
+                            // found close
+
+                            // <? ... ?> is java
+                            output.append(sb.toString());
+
+                            sb = new StringBuffer();
+                            watch = open;
+                        }
+                        w = 0;
+                    }
+                } else {
+                    if (w > 0) {
+                        sb.append(watch, 0, w);
+                    }
+
+                    sb.append((char)c);
+
+                    w = 0;
+                }
+            }
+
+            if (watch == open) {
+                wrap(sb, output);
+            }
+
+
+            output.append("    out.close();").append('\n');
+            output.append("    out.flush();").append('\n');
+            output.append("  }").append('\n');
+            output.append("}").append('\n');
+
+
+            output.close();
+
+            return outputStream.toByteArray();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/serverpages/JspReader.java b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/JspReader.java
new file mode 100644
index 0000000..207d923
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/JspReader.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.serverpages;
+
+import java.util.Map;
+
+import org.apache.commons.jci.readers.ResourceReader;
+
+/**
+ * @author tcurdt
+ */
+public final class JspReader implements ResourceReader {
+
+    private final Map sources;
+    private final ResourceReader reader;
+
+
+    public JspReader( final Map pSources, final ResourceReader pReader ) {
+        reader = pReader;
+        sources = pSources;
+    }
+
+
+    public byte[] getBytes( String pResourceName ) {
+
+        final byte[] bytes = (byte[]) sources.get(pResourceName);
+
+        if (bytes != null) {
+            return bytes;
+        }
+
+        return reader.getBytes(pResourceName);
+    }
+
+    public boolean isAvailable( String pResourceName ) {
+
+        if (sources.containsKey(pResourceName)) {
+            return true;
+        }
+
+        return reader.isAvailable(pResourceName);
+    }
+
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/serverpages/ServerPageServlet.java b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/ServerPageServlet.java
new file mode 100644
index 0000000..acb6331
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/ServerPageServlet.java
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.examples.serverpages;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.jci.ReloadingClassLoader;
+import org.apache.commons.jci.compilers.CompilationResult;
+import org.apache.commons.jci.compilers.JavaCompilerFactory;
+import org.apache.commons.jci.listeners.CompilingListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationMonitor;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
+import org.apache.commons.jci.problems.CompilationProblem;
+import org.apache.commons.jci.readers.ResourceReader;
+import org.apache.commons.jci.stores.MemoryResourceStore;
+import org.apache.commons.jci.stores.TransactionalResourceStore;
+import org.apache.commons.jci.utils.ConversionUtils;
+
+
+/**
+ * A mini JSP servlet that monitors a certain directory and
+ * recompiles and then instantiates the JSP pages as soon as
+ * they have changed.
+ *
+ * @author tcurdt
+ */
+public final class ServerPageServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+
+    private final ReloadingClassLoader classloader = new ReloadingClassLoader(ServerPageServlet.class.getClassLoader());
+    private FilesystemAlterationMonitor fam;
+    private CompilingListener jspListener; 
+
+    private Map servletsByClassname = new HashMap();
+
+    public void init() throws ServletException {
+        super.init();
+
+        final File serverpagesDir = new File(getServletContext().getRealPath("/") + getInitParameter("serverpagesDir"));
+
+        log("Monitoring serverpages in " + serverpagesDir);
+
+        final TransactionalResourceStore store = new TransactionalResourceStore(new MemoryResourceStore()) {
+
+            private Set newClasses;
+            private Map newServletsByClassname;
+
+            public void onStart() {
+                super.onStart();
+
+                newClasses = new HashSet();
+                newServletsByClassname = new HashMap(servletsByClassname);
+            }
+
+            public void onStop() {
+                super.onStop();
+
+                boolean reload = false;
+                for (Iterator it = newClasses.iterator(); it.hasNext();) {
+                    final String clazzName = (String) it.next();
+
+                    try {
+                        final Class clazz = classloader.loadClass(clazzName);
+
+                        if (!HttpServlet.class.isAssignableFrom(clazz)) {
+                            log(clazzName + " is not a servlet");
+                            continue;
+                        }
+
+                        // create new instance of jsp page
+                        final HttpServlet servlet = (HttpServlet) clazz.newInstance();
+                        newServletsByClassname.put(clazzName, servlet);
+
+                        reload = true;
+                    } catch(Exception e) {
+                        log("", e);
+                    }
+                }
+
+                if (reload) {
+                    log("Activating new map of servlets "+ newServletsByClassname);
+                    servletsByClassname = newServletsByClassname;
+                }
+            }
+
+            public void write(String pResourceName, byte[] pResourceData) {
+                super.write(pResourceName, pResourceData);
+
+                if (pResourceName.endsWith(".class")) {
+
+                    // compiler writes a new class, remember the classes to reload
+                    newClasses.add(pResourceName.replace('/', '.').substring(0, pResourceName.length() - ".class".length()));
+                }
+            }
+
+        };
+
+        // listener that generates the java code from the jsp page and provides that to the compiler
+        jspListener = new CompilingListener(new JavaCompilerFactory().createCompiler("eclipse"), store) {
+
+            private final JspGenerator transformer = new JspGenerator();
+            private final Map sources = new HashMap();
+            private final Set resourceToCompile = new HashSet();
+
+            public void onStart(FilesystemAlterationObserver pObserver) {
+                super.onStart(pObserver);
+
+                resourceToCompile.clear();
+            }
+
+
+            public void onFileChange(File pFile) {
+                if (pFile.getName().endsWith(".jsp")) {
+                    final String resourceName = ConversionUtils.stripExtension(getSourceNameFromFile(observer, pFile)) + ".java";
+
+                    log("Updating " + resourceName);
+
+                    sources.put(resourceName, transformer.generateJavaSource(resourceName, pFile));
+
+                    resourceToCompile.add(resourceName);
+                }
+                super.onFileChange(pFile);
+            }
+
+
+            public void onFileCreate(File pFile) {
+                if (pFile.getName().endsWith(".jsp")) {
+                    final String resourceName = ConversionUtils.stripExtension(getSourceNameFromFile(observer, pFile)) + ".java";
+
+                    log("Creating " + resourceName);
+
+                    sources.put(resourceName, transformer.generateJavaSource(resourceName, pFile));
+
+                    resourceToCompile.add(resourceName);
+                }
+                super.onFileCreate(pFile);
+            }
+
+
+            public String[] getResourcesToCompile(FilesystemAlterationObserver pObserver) {
+                // we only want to compile the jsp pages
+                final String[] resourceNames = new String[resourceToCompile.size()];
+                resourceToCompile.toArray(resourceNames);
+                return resourceNames;
+            }
+
+
+            public ResourceReader getReader( final FilesystemAlterationObserver pObserver ) {
+                return new JspReader(sources, super.getReader(pObserver));
+            }
+        };
+        jspListener.addReloadNotificationListener(classloader);
+        
+        fam = new FilesystemAlterationMonitor();
+        fam.addListener(serverpagesDir, jspListener);
+        fam.start();
+    }
+
+    private String convertRequestToServletClassname( final HttpServletRequest request ) {
+
+        final String path = request.getPathInfo().substring(1);
+
+        final String clazz = ConversionUtils.stripExtension(path).replace('/', '.');
+
+        return clazz;
+    }
+
+    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+        log("Request " + request.getRequestURI());
+
+        final CompilationResult result = jspListener.getCompilationResult();
+        final CompilationProblem[] errors = result.getErrors();
+
+        if (errors.length > 0) {
+
+            // if there are errors we provide the compilation errors instead of the jsp page
+
+            final PrintWriter out = response.getWriter();
+
+            out.append("<html><body>");
+
+            for (int i = 0; i < errors.length; i++) {
+                final CompilationProblem problem = errors[i];
+                out.append(problem.toString()).append("<br/>").append('\n');
+            }
+
+            out.append("</body></html>");
+
+            out.flush();
+            out.close();
+            return;
+        }
+
+        final String servletClassname = convertRequestToServletClassname(request);
+
+        log("Checking for serverpage " + servletClassname);
+
+        final HttpServlet servlet = (HttpServlet) servletsByClassname.get(servletClassname);
+
+        if (servlet == null) {
+            log("No servlet  for " + request.getRequestURI());
+            response.sendError(404);
+            return;
+        }
+
+        log("Delegating request to " + servletClassname);
+
+        servlet.service(request, response);
+    }
+
+    public void destroy() {
+
+        fam.stop();
+
+        super.destroy();
+    }
+}
diff --git a/examples/src/main/java/org/apache/commons/jci/examples/serverpages/package.html b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/package.html
new file mode 100644
index 0000000..7ab564b
--- /dev/null
+++ b/examples/src/main/java/org/apache/commons/jci/examples/serverpages/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+    Example how to use jci to build a simple JSP servlet.
+</body></html>
diff --git a/examples/src/main/resources/LICENSE.txt b/examples/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/examples/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/examples/src/main/resources/NOTICE.txt b/examples/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..69b7e67
--- /dev/null
+++ b/examples/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - Examples
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/examples/src/main/webapp/WEB-INF/jsp/Test.jsp b/examples/src/main/webapp/WEB-INF/jsp/Test.jsp
new file mode 100644
index 0000000..e7b5b8c
--- /dev/null
+++ b/examples/src/main/webapp/WEB-INF/jsp/Test.jsp
@@ -0,0 +1,23 @@
+<!--
+
+   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.
+
+--><html><body>
+    
+<? for(int i=0; i<3; i++) { ?>
+   line <br/>      
+<? } ?>
+</body></html>
\ No newline at end of file
diff --git a/examples/src/main/webapp/WEB-INF/jsp/org/vafer/Test.jsp b/examples/src/main/webapp/WEB-INF/jsp/org/vafer/Test.jsp
new file mode 100644
index 0000000..37340df
--- /dev/null
+++ b/examples/src/main/webapp/WEB-INF/jsp/org/vafer/Test.jsp
@@ -0,0 +1,18 @@
+<!--
+
+   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.
+
+--><html><body>org.vafer.Test</body></html>
\ No newline at end of file
diff --git a/examples/src/main/webapp/WEB-INF/web.xml b/examples/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..c73f2a0
--- /dev/null
+++ b/examples/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+
+   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.
+
+--><web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee          http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
+    <servlet>
+        <servlet-name>serverpages</servlet-name>
+        <servlet-class>org.apache.commons.jci.examples.serverpages.ServerPageServlet</servlet-class>
+        <init-param>
+            <param-name>serverpagesDir</param-name>
+            <param-value>/WEB-INF/jsp</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>serverpages</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/fam/pom.xml b/fam/pom.xml
new file mode 100644
index 0000000..e5e36fd
--- /dev/null
+++ b/fam/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-jci</artifactId>
+        <version>1.0</version>
+    </parent>
+    <packaging>jar</packaging>
+    <artifactId>commons-jci-fam</artifactId>
+    <version>1.0</version>
+    <name>fam</name>
+    <description>
+        Commons JCI FileAlterationMonitor (FAM) to monitor local filesystems and get notified about changes.
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging-api</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>3.8.2</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java b/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java
new file mode 100644
index 0000000..d76a7f9
--- /dev/null
+++ b/fam/src/main/java/org/apache/commons/jci/listeners/AbstractFilesystemAlterationListener.java
@@ -0,0 +1,200 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.listeners;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.jci.monitor.FilesystemAlterationListener;
+import org.apache.commons.jci.monitor.FilesystemAlterationObserver;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * AbstractFilesystemAlterationListener provides some convenience methods helping to
+ * implement a FilesystemAlterationListener.
+ * @author tcurdt
+ */
+public abstract class AbstractFilesystemAlterationListener implements FilesystemAlterationListener {
+
+    private final Log log = LogFactory.getLog(AbstractFilesystemAlterationListener.class);
+
+    private final Collection createdFiles = new ArrayList();
+    private final Collection changedFiles = new ArrayList();
+    private final Collection deletedFiles = new ArrayList();
+    private final Collection createdDirectories = new ArrayList();
+    private final Collection changedDirectories = new ArrayList();
+    private final Collection deletedDirectories = new ArrayList();
+
+    
+    private final static class Signal {
+        public boolean triggered;
+    }
+
+    private final Signal eventSignal = new Signal();
+    private final Signal checkSignal = new Signal();
+    
+    protected FilesystemAlterationObserver observer;
+
+    public void onDirectoryCreate( final File pDir ) {
+        createdDirectories.add(pDir);
+    }
+    public void onDirectoryChange( final File pDir ) {
+        changedDirectories.add(pDir);
+    }
+    public void onDirectoryDelete( final File pDir ) {
+        deletedDirectories.add(pDir);
+    }
+
+    public void onFileCreate( final File pFile) {
+        createdFiles.add(pFile);
+    }
+    public void onFileChange( final File pFile ) {
+        changedFiles.add(pFile);
+    }
+    public void onFileDelete( final File pFile ) {
+        deletedFiles.add(pFile);
+    }
+
+
+    public Collection getChangedDirectories() {
+        return changedDirectories;
+    }
+
+    public Collection getChangedFiles() {
+        return changedFiles;
+    }
+
+    public Collection getCreatedDirectories() {
+        return createdDirectories;
+    }
+
+    public Collection getCreatedFiles() {
+        return createdFiles;
+    }
+
+    public Collection getDeletedDirectories() {
+        return deletedDirectories;
+    }
+
+    public Collection getDeletedFiles() {
+        return deletedFiles;
+    }
+
+    protected void signals() {
+        if (createdFiles.size() > 0 || createdDirectories.size() > 0 ||
+            changedFiles.size() > 0 || changedDirectories.size() > 0 ||
+            deletedFiles.size() > 0 || deletedDirectories.size() > 0) {
+
+            log.debug("event signal");
+
+            synchronized(eventSignal) {
+                eventSignal.triggered = true;
+                eventSignal.notifyAll();
+            }
+        }
+
+        log.debug("check signal");
+
+        synchronized(checkSignal) {
+            checkSignal.triggered = true;
+            checkSignal.notifyAll();
+        }
+    }
+
+    public void onStart( final FilesystemAlterationObserver pObserver ) {
+        observer = pObserver;
+
+        createdFiles.clear();
+        changedFiles.clear();
+        deletedFiles.clear();
+        createdDirectories.clear();
+        changedDirectories.clear();
+        deletedDirectories.clear();
+    }
+
+    public void onStop( final FilesystemAlterationObserver pObserver ) {
+        signals();
+        observer = null;
+    }
+        
+    public void waitForEvent() throws Exception {
+        synchronized(eventSignal) {
+            eventSignal.triggered = false;
+        }
+        log.debug("waiting for change");
+        if (!waitForSignal(eventSignal, 10)) {
+            throw new Exception("timeout");
+        }
+    }
+    
+    /**
+     * we don't reset the signal so if there was a check it is
+     * already true and exit immediatly otherwise it will behave just
+     * like waitForCheck()
+     * 
+     * @throws Exception in case of a timeout
+     */
+    public void waitForFirstCheck() throws Exception {
+        log.debug("waiting for first check");
+        if (!waitForSignal(checkSignal, 10)) {
+            throw new Exception("timeout");
+        }        
+    }
+
+    /**
+     * wait for the next filesystem check to happen
+     * 
+     * @throws Exception in case of a timeout
+     */
+    public void waitForCheck() throws Exception {
+        synchronized(checkSignal) {
+            checkSignal.triggered = false;
+        }
+        log.debug("waiting for check");
+        if (!waitForSignal(checkSignal, 10)) {
+            throw new Exception("timeout");
+        }
+    }
+    
+    private boolean waitForSignal(final Signal pSignal, final int pSecondsTimeout) {
+        int i = 0;
+        while(true) {
+            synchronized(pSignal) {
+                if (!pSignal.triggered) {
+                    try {
+                        pSignal.wait(1000);
+                    } catch (InterruptedException e) {
+                    }
+
+                    if (++i > pSecondsTimeout) {
+                        log.error("timeout after " + pSecondsTimeout + "s");
+                        return false;
+                    }
+                    
+                } else {
+                    pSignal.triggered = false;
+                    break;
+                }
+            }
+        }        
+        return true;
+    }
+
+}
diff --git a/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java
new file mode 100644
index 0000000..0dda2fc
--- /dev/null
+++ b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationListener.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.monitor;
+
+import java.io.File;
+
+/**
+ * A listener that receives events of filesystem modifications.
+ * The observer basically represents the source of the events.
+ * The file root and its state. (see FilesystemAlterationObserver)
+ * 
+ * @author tcurdt
+ */
+public interface FilesystemAlterationListener {
+
+    void onStart( final FilesystemAlterationObserver pObserver );
+    void onFileCreate( final File pFile );
+    void onFileChange( final File pFile );
+    void onFileDelete( final File pFile );
+    void onDirectoryCreate( final File pDir );
+    void onDirectoryChange( final File pDir );
+    void onDirectoryDelete( final File pDir );
+    void onStop( final FilesystemAlterationObserver pObserver );
+}
diff --git a/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java
new file mode 100644
index 0000000..7b6e36a
--- /dev/null
+++ b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitor.java
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.monitor;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * It's a runnable that spawns of a monitoring thread triggering the
+ * the observers and managing the their listeners.
+ * 
+ * @author tcurdt
+ */
+public final class FilesystemAlterationMonitor implements Runnable {
+
+    private final Log log = LogFactory.getLog(FilesystemAlterationMonitor.class);
+
+    private final Object observersLock = new Object();
+    private Map observers = Collections.unmodifiableMap(new HashMap());    
+    private long delay = 3000;
+    private Thread thread;
+
+    private volatile boolean running = true;
+        
+    public FilesystemAlterationMonitor() {
+    }
+
+
+    public void start() {
+        thread = new Thread(this);
+        thread.start();
+    }
+
+
+    public void stop() {
+        running = false;
+
+        try {
+            thread.join(delay);
+        } catch (InterruptedException e) {
+        }
+    }
+
+
+    public void setInterval( final long pDelay ) {
+        delay = pDelay;
+    }
+
+
+    public void addListener( final File pRoot, final FilesystemAlterationListener pListener ) {
+
+        FilesystemAlterationObserver observer;
+
+        synchronized (observersLock) {
+            observer = (FilesystemAlterationObserver)observers.get(pRoot);
+
+            if (observer == null) {
+                final Map newObservers = new HashMap(observers);
+                observer = new FilesystemAlterationObserverImpl(pRoot);
+                newObservers.put(pRoot, observer);
+                observers = Collections.unmodifiableMap(newObservers);
+            }
+        }
+
+        observer.addListener(pListener);
+    }
+   
+    public void removeListener( final FilesystemAlterationListener pListener ) {
+        synchronized (observersLock) {
+            for (Iterator it = observers.values().iterator(); it.hasNext();) {
+                final FilesystemAlterationObserver observer = (FilesystemAlterationObserver) it.next();
+                observer.removeListener(pListener);
+                // FIXME: remove observer if there are no listeners?
+            }
+        }
+    }
+
+    public FilesystemAlterationListener[] getListenersFor( final File pRoot  ) {
+        final FilesystemAlterationObserver observer = (FilesystemAlterationObserver)observers.get(pRoot);
+
+        if (observer == null) {
+            return new FilesystemAlterationListener[0];
+        }
+
+        return observer.getListeners();
+    }
+
+
+    public void run() {
+        log.debug("fam running");
+        
+        while (true) {
+            if (!running) {
+                break;
+            }
+
+            final Map currentObservers = observers;
+            
+            for (Iterator it = currentObservers.values().iterator(); it.hasNext();) {
+                final FilesystemAlterationObserver observer = (FilesystemAlterationObserver) it.next();
+                observer.checkAndNotify();
+            }
+
+            try {
+                Thread.sleep(delay);
+            } catch (final InterruptedException e) {
+            }
+        }
+        
+        log.debug("fam exiting");
+    }
+
+}
diff --git a/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java
new file mode 100644
index 0000000..9227a2f
--- /dev/null
+++ b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserver.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.monitor;
+
+import java.io.File;
+
+/**
+ * FilesystemAlterationObserver represents the state of files
+ * below a certain root directory. It implements the code to
+ * check the filesystem and notify listeners.
+ * 
+ * @author tcurdt
+ */
+public interface FilesystemAlterationObserver {
+
+    File getRootDirectory();
+
+    void checkAndNotify();
+
+    void addListener( final FilesystemAlterationListener pListener );
+
+    void removeListener( final FilesystemAlterationListener pListener );
+
+    FilesystemAlterationListener[] getListeners();
+
+}
\ No newline at end of file
diff --git a/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserverImpl.java b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserverImpl.java
new file mode 100644
index 0000000..c511dac
--- /dev/null
+++ b/fam/src/main/java/org/apache/commons/jci/monitor/FilesystemAlterationObserverImpl.java
@@ -0,0 +1,374 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.monitor;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Implementation of a FilesystemAlterationObserver
+ * 
+ * @author tcurdt
+ */
+public class FilesystemAlterationObserverImpl implements FilesystemAlterationObserver {
+
+    private final Log log = LogFactory.getLog(FilesystemAlterationObserverImpl.class);
+    
+    private interface MonitorFile {
+
+        long lastModified();
+        MonitorFile[] listFiles();
+        boolean isDirectory();
+        boolean exists();
+        String getName();
+
+    }
+    
+    private final static class MonitorFileImpl implements MonitorFile {
+
+        private final File file;
+
+        public MonitorFileImpl( final File pFile ) {
+            file = pFile;
+        }
+
+        public boolean exists() {
+            return file.exists();
+        }
+
+        public MonitorFile[] listFiles() {
+            final File[] childs = file.listFiles();
+
+            final MonitorFile[] providers = new MonitorFile[childs.length];
+            for (int i = 0; i < providers.length; i++) {
+                providers[i] = new MonitorFileImpl(childs[i]);
+            }
+            return providers;
+        }
+
+        public String getName() {
+            return file.getName();
+        }
+
+        public boolean isDirectory() {
+            return file.isDirectory();
+        }
+
+        public long lastModified() {
+            return file.lastModified();
+        }
+
+        public String toString() {
+            return file.toString();
+        }
+
+    }
+
+    private final class Entry {
+
+        private final static int TYPE_UNKNOWN = 0;
+        private final static int TYPE_FILE = 1;
+        private final static int TYPE_DIRECTORY = 2;
+
+        private final MonitorFile file;
+        private long lastModified = -1;
+        private int lastType = TYPE_UNKNOWN;
+        private Map childs = new HashMap();
+
+        public Entry(final MonitorFile pFile) {
+            file = pFile;
+        }
+
+        public String getName() {
+            return file.getName();
+        }
+        
+        
+        public String toString() {
+            return file.toString();
+        }
+
+
+        private void compareChilds() {
+            if (!file.isDirectory()) {
+                return;
+            }
+
+            final MonitorFile[] files = file.listFiles();
+            final Set deleted = new HashSet(childs.values());
+            for (int i = 0; i < files.length; i++) {
+                final MonitorFile f = files[i];
+                final String name = f.getName();
+                final Entry entry = (Entry)childs.get(name);
+                if (entry != null) {
+                    // already recognized as child
+                    deleted.remove(entry);
+
+                    if(entry.needsToBeDeleted()) {
+                        // we have to delete this one
+                        childs.remove(name);
+                    }
+                } else {
+                    // a new child
+                    final Entry newChild = new Entry(f);
+                    childs.put(name, newChild);
+                    newChild.needsToBeDeleted();
+                }
+            }
+
+            // the ones not found on disk anymore
+
+            for (Iterator it = deleted.iterator(); it.hasNext();) {
+                final Entry entry = (Entry) it.next();
+                entry.deleteChildsAndNotify();
+                childs.remove(entry.getName());
+            }
+        }
+
+
+        private void deleteChildsAndNotify() {
+            for (Iterator it = childs.values().iterator(); it.hasNext();) {
+                final Entry entry = (Entry) it.next();
+
+                entry.deleteChildsAndNotify();
+            }
+            childs.clear();
+
+            if(lastType == TYPE_DIRECTORY) {
+                notifyOnDirectoryDelete(this);
+            } else if (lastType == TYPE_FILE) {
+                notifyOnFileDelete(this);
+            }
+        }
+
+        public boolean needsToBeDeleted() {
+
+            if (!file.exists()) {
+                // deleted or has never existed yet
+
+//                log.debug(file + " does not exist or has been deleted");
+
+                deleteChildsAndNotify();
+
+                // mark to be deleted by parent
+                return true;
+            } else {
+                // exists
+                final long currentModified = file.lastModified(); 
+
+                if (currentModified != lastModified) {
+                    // last modified has changed
+                    lastModified = currentModified;
+
+//                    log.debug(file + " has new last modified");
+
+                    // types only changes when also the last modified changes
+                    final int newType = (file.isDirectory()?TYPE_DIRECTORY:TYPE_FILE); 
+
+                    if (lastType != newType) {
+                        // the type has changed
+
+//                        log.debug(file + " has a new type");
+
+                        deleteChildsAndNotify();
+
+                        lastType = newType;
+
+                        // and then an add as the new type
+
+                        if (newType == TYPE_DIRECTORY) {
+                            notifyOnDirectoryCreate(this);
+                            compareChilds();
+                        } else {
+                            notifyOnFileCreate(this);
+                        }
+
+                        return false;
+                    }
+
+                    if (newType == TYPE_DIRECTORY) {
+                        notifyOnDirectoryChange(this);
+                        compareChilds();
+                    } else {
+                        notifyOnFileChange(this);
+                    }
+
+                    return false;
+
+                } else {
+
+                    // so exists and has not changed
+
+//                    log.debug(file + " does exist and has not changed");
+
+                    compareChilds();
+
+                    return false;
+                }
+            }
+        }
+        
+        public MonitorFile getFile() {
+            return file;
+        }
+
+        public void markNotChanged() {
+            lastModified = file.lastModified();
+        }
+
+    }
+
+    private final File rootDirectory;
+    private final Entry rootEntry;
+
+    private FilesystemAlterationListener[] listeners = new FilesystemAlterationListener[0];
+    private Set listenersSet = new HashSet();
+
+    public FilesystemAlterationObserverImpl( final File pRootDirectory ) {
+        rootDirectory = pRootDirectory;
+        rootEntry = new Entry(new MonitorFileImpl(pRootDirectory));
+    }
+
+
+
+    private void notifyOnStart() {
+        log.debug("onStart " + rootEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onStart(this);
+        }
+    }
+    private void notifyOnStop() {
+        log.debug("onStop " + rootEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onStop(this);
+        }
+    }
+
+    private void notifyOnFileCreate( final Entry pEntry ) {
+        log.debug("onFileCreate " + pEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onFileCreate(((MonitorFileImpl)pEntry.getFile()).file );
+        }
+    }
+    private void notifyOnFileChange( final Entry pEntry ) {
+        log.debug("onFileChange " + pEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onFileChange(((MonitorFileImpl)pEntry.getFile()).file );
+        }
+    }
+    private void notifyOnFileDelete( final Entry pEntry ) {
+        log.debug("onFileDelete " + pEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onFileDelete(((MonitorFileImpl)pEntry.getFile()).file );
+        }
+    }
+
+    private void notifyOnDirectoryCreate( final Entry pEntry ) {
+        log.debug("onDirectoryCreate " + pEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onDirectoryCreate(((MonitorFileImpl)pEntry.getFile()).file );
+        }
+    }
+    private void notifyOnDirectoryChange( final Entry pEntry ) {
+        log.debug("onDirectoryChange " + pEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onDirectoryChange(((MonitorFileImpl)pEntry.getFile()).file );
+        }
+    }
+    private void notifyOnDirectoryDelete( final Entry pEntry ) {
+        log.debug("onDirectoryDelete " + pEntry);
+        for (int i = 0; i < listeners.length; i++) {
+            final FilesystemAlterationListener listener = listeners[i];
+            listener.onDirectoryDelete(((MonitorFileImpl)pEntry.getFile()).file );
+        }
+    }
+
+
+    private void checkEntries() {
+        if(rootEntry.needsToBeDeleted()) {
+            // root not existing
+            rootEntry.lastType = Entry.TYPE_UNKNOWN;
+        }
+    }
+
+    
+    public synchronized void checkAndNotify() {
+        if (listeners.length == 0) {
+            return;
+        }
+
+        notifyOnStart();
+        
+        checkEntries();
+        
+        notifyOnStop();
+    }
+
+    
+    public File getRootDirectory() {
+        return rootDirectory;
+    }
+
+    public synchronized void addListener( final FilesystemAlterationListener pListener ) {
+        if (listenersSet.add(pListener)) {
+            createArrayFromSet();
+        }
+    }
+
+    public synchronized void removeListener( final FilesystemAlterationListener pListener ) {
+        if (listenersSet.remove(pListener)) {
+            createArrayFromSet();
+        }
+    }
+
+    private void createArrayFromSet() {
+        final FilesystemAlterationListener[] newListeners = new FilesystemAlterationListener[listenersSet.size()];
+        listenersSet.toArray(newListeners);
+        listeners = newListeners;
+    }
+
+    public FilesystemAlterationListener[] getListeners() {
+        return listeners;
+    }
+
+
+    public static void main( String[] args ) {
+        final FilesystemAlterationObserverImpl observer = new FilesystemAlterationObserverImpl(new File(args[0]));
+        while(true) {
+            observer.checkEntries();
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+}
diff --git a/fam/src/main/java/org/apache/commons/jci/monitor/package.html b/fam/src/main/java/org/apache/commons/jci/monitor/package.html
new file mode 100644
index 0000000..eb195e7
--- /dev/null
+++ b/fam/src/main/java/org/apache/commons/jci/monitor/package.html
@@ -0,0 +1,20 @@
+<!--
+
+   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.
+
+--><html><body>
+Monitor to keep track of changes on the local filesystem.
+</body></html>
diff --git a/fam/src/main/resources/LICENSE.txt b/fam/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/fam/src/main/resources/LICENSE.txt
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/fam/src/main/resources/NOTICE.txt b/fam/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..4f834aa
--- /dev/null
+++ b/fam/src/main/resources/NOTICE.txt
@@ -0,0 +1,5 @@
+Apache Jakarta Commons JCI - File Access Monitor
+Copyright 2004-2007 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java b/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java
new file mode 100644
index 0000000..7c7e62f
--- /dev/null
+++ b/fam/src/test/java/org/apache/commons/jci/monitor/FilesystemAlterationMonitorTestCase.java
@@ -0,0 +1,322 @@
+/*
+ * 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.
+ */
+
+package org.apache.commons.jci.monitor;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.jci.listeners.AbstractFilesystemAlterationListener;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * 
+ * @author tcurdt
+ */
+public final class FilesystemAlterationMonitorTestCase extends TestCase {
+
+    private final Log log = LogFactory.getLog(FilesystemAlterationMonitorTestCase.class);
+
+    private FilesystemAlterationMonitor fam;
+    private MyFilesystemAlterationListener listener;
+
+    private File directory;
+
+    
+    protected void setUp() throws Exception {
+        directory = createTempDirectory();
+        assertTrue(directory.exists());
+        assertTrue(directory.isDirectory());
+    }
+    
+    protected void tearDown() throws Exception {
+        FileUtils.deleteDirectory(directory);
+    }
+    
+    
+    protected File createDirectory( final String pName ) throws Exception {
+        final File newDirectory = new File(directory, pName);
+        assertTrue(newDirectory.mkdir());
+        assertTrue(newDirectory.exists());
+        assertTrue(newDirectory.isDirectory());
+        return newDirectory;
+    }
+    
+    protected File writeFile( final String pName, final byte[] pData ) throws Exception {
+        final File file = new File(directory, pName);
+        final File parent = file.getParentFile();
+        if (!parent.exists()) {
+            if (!parent.mkdirs()) {
+                throw new IOException("could not create" + parent);
+            }
+        }
+        
+        log.debug("writing file " + pName + " (" + pData.length + " bytes)");
+        
+        final FileOutputStream os = new FileOutputStream(file);
+        os.write(pData);
+        os.close();
+        
+        assertTrue(file.exists());
+        assertTrue(file.isFile());
+        
+        return file;
+    }
+
+    protected File writeFile( final String pName, final String pText ) throws Exception {
+        final File file = new File(directory, pName);
+        final File parent = file.getParentFile();
+        if (!parent.exists()) {
+            if (!parent.mkdirs()) {
+                throw new IOException("could not create" + parent);
+            }
+        }
+        log.debug("writing " + file);
+        final FileWriter writer = new FileWriter(file);
+        writer.write(pText);
+        writer.close();
+        
+        assertTrue(file.exists());
+        assertTrue(file.isFile());
+        
+        return file;
+    }
+
+    protected File createTempDirectory() throws IOException {
+        final File tempFile = File.createTempFile("jci", null);
+        
+        if (!tempFile.delete()) {
+            throw new IOException();
+        }
+        
+        if (!tempFile.mkdir()) {
+            throw new IOException();
+        }
+        
+        return tempFile;         
+    }
+
+
+    protected void delay() {
+        try {
+            Thread.sleep(1500);
+        } catch (final InterruptedException e) {
+        }
+    }
+
+
+    
+    private static class MyFilesystemAlterationListener extends AbstractFilesystemAlterationListener {
+    }
+
+    private void start() throws Exception {
+        fam = new FilesystemAlterationMonitor();
+        listener = new MyFilesystemAlterationListener();
+        fam.addListener(directory, listener);
+        fam.start();
+        listener.waitForFirstCheck();
+    }
+    
+    private void stop() {
+        fam.stop();
+    }
+    
+    public void testListenerDoublication() throws Exception {
+        fam = new FilesystemAlterationMonitor();
+        listener = new MyFilesystemAlterationListener();
+        
+        fam.addListener(directory, listener);
+        assertTrue(fam.getListenersFor(directory).length == 1);
+        
+        fam.addListener(directory, listener); 
+        assertTrue(fam.getListenersFor(directory).length == 1);
+    }
+
+    public void testDirectoryDoublication() throws Exception {
+        fam = new FilesystemAlterationMonitor();
+
+        fam.addListener(directory, new MyFilesystemAlterationListener()); 
+        assertTrue(fam.getListenersFor(directory).length == 1);
+        
+        fam.addListener(directory, new MyFilesystemAlterationListener()); 
+        assertTrue(fam.getListenersFor(directory).length == 2);
+    }
+
+    public void testCreateFileDetection() throws Exception {
+        start();
+        
+        writeFile("file", "file");
+        
+        listener.waitForCheck();
+        
+        assertTrue(listener.getCreatedFiles().size() == 1);
+        
+        stop();
+    }
+
+    public void testCreateDirectoryDetection() throws Exception {
+        start();
+
+        createDirectory("dir");
+        
+        listener.waitForCheck();
+        
+        assertTrue(listener.getCreatedDirectories().size() == 1);
+        
+        stop();
+    }
+
+    public void testDeleteFileDetection() throws Exception {
+        start();
+
+        final File file = writeFile("file", "file");
+        
+        listener.waitForCheck();
+        
+        assertTrue(listener.getCreatedFiles().size() == 1);
+        
+        file.delete();
+        assertTrue(!file.exists());
+
+        listener.waitForCheck();
+        
+        assertTrue(listener.getDeletedFiles().size() == 1);
+        
+        stop();        
+    }
+    public void testDeleteDirectoryDetection() throws Exception {
+        start();
+
+        final File dir = createDirectory("dir");
+        createDirectory("dir/sub");
+        final File file = writeFile("dir/sub/file", "file");
+
+        listener.waitForCheck();
+        
+        assertEquals(2, listener.getCreatedDirectories().size());
+        assertEquals(1, listener.getCreatedFiles().size());
+
+        delay();
+        
+        FileUtils.deleteDirectory(dir);
+        assertTrue(!dir.exists());
+        assertTrue(!file.exists());
+
+        listener.waitForCheck();
+        
+        assertEquals(2, listener.getDeletedDirectories().size());
+        assertEquals(1, listener.getDeletedFiles().size());
+
+        stop();
+    }
+
+    public void testModifyFileDetection() throws Exception {
+        start();
+
+        writeFile("file", "file");
+        
+        listener.waitForCheck();
+        
+        assertTrue(listener.getCreatedFiles().size() == 1);
+
+        delay();
+
+        writeFile("file", "changed file");
+
+        listener.waitForCheck();
+        
+        assertTrue(listener.getChangedFiles().size() == 1);
+        
+        stop();
+    }
+
+    public void testCreatingLocalDirectoryChangesLastModified() throws Exception {
+        final long modified = directory.lastModified();
+
+        delay();
+        
+        createDirectory("directory");
+
+        delay();
+               
+        assertTrue(directory.lastModified() != modified);
+    }
+
+    public void testCreatingLocalFileChangesLastModified() throws Exception {
+        final long modified = directory.lastModified();
+
+        delay();
+        
+        writeFile("file", "file");
+
+        delay();
+
+        assertTrue(directory.lastModified() != modified);
+    }
+
+    public void testCreatingSubDirectoryChangesLastModified() throws Exception {
+        createDirectory("dir");
+
+        final long modified = directory.lastModified();
+
+        delay();
+
+        createDirectory("dir/sub");
+
+        assertTrue(directory.lastModified() == modified);
+    }
+
+    public void testCreatingFileInSubDirectoryChangesLastModified() throws Exception {
+        createDirectory("dir");
+
+        final long modified = directory.lastModified();
+
+        delay();
+                
+        writeFile("dir/file", "file");
+
+        assertTrue(directory.lastModified() == modified);
+    }
+    
+    public void testInterval() throws Exception {
+
+        final long interval = 1000;
+
+        start();
+        fam.setInterval(interval);
+
+        listener.waitForCheck();
+        long t1 = System.currentTimeMillis();
+
+        listener.waitForCheck();
+        long t2 = System.currentTimeMillis();
+        
+        long diff = t2-t1;
+        
+        // interval should be at around the same interval
+        assertTrue("the interval was set to " + interval + " but the time difference was " + diff, (diff > (interval-50)) && (diff < (interval+50)));
+        
+        stop();
+    }    
+}
diff --git a/fam/src/test/resources/simplelog.properties b/fam/src/test/resources/simplelog.properties
new file mode 100644
index 0000000..6bd0ec9
--- /dev/null
+++ b/fam/src/test/resources/simplelog.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.simplelog.defaultlog=debug
+org.apache.commons.logging.simplelog.showdatetime=true
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..2ef8ab5
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+   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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-parent</artifactId>
+        <version>2</version>
+    </parent>
+    <packaging>pom</packaging>
+    <groupId>org.apache.commons</groupId>
+    <artifactId>commons-jci</artifactId>
+    <version>1.0</version>
+    <name>Commons JCI</name>
+    <description>
+        Commons JCI is a java compiler interface. It can be used to either compile java (or any other language that can be compiled to java classes like e.g. groovy or javascript) to java. It is well integrated with a FAM (FilesystemAlterationMonitor) that can be used with the JCI compiling/reloading classloader. All the currently supported compilers (even javac before java6) feature in-memory compilation.
+    </description>
+    <url>http://jakarta.apache.org/commons/jci/</url>
+    <inceptionYear>2004</inceptionYear>
+    <issueManagement>
+        <system>JIRA</system>
+        <url>https://issues.apache.org/jira/browse/JCI</url>
+    </issueManagement>
+    <modules>
+        <module>core</module>
+        <module>fam</module>
+        <module>compilers/eclipse</module>
+        <module>compilers/janino</module>
+        <module>compilers/groovy</module>
+        <module>compilers/javac</module>
+        <module>compilers/rhino</module>
+        <module>examples</module>
+    </modules>
+    <distributionManagement>
+        <site>
+            <id>website</id>
+            <url>scpexe://people.apache.org/www/jakarta.apache.org/commons/jci/</url>
+        </site>
+    </distributionManagement>
+    <developers>
+        <developer>
+            <id>tcurdt</id>
+            <name>Torsten Curdt</name>
+            <email>tcurdt at apache.org</email>
+            <organization>ASF</organization>
+            <organizationUrl>http://www.apache.org/</organizationUrl>
+            <timezone>+1</timezone>
+        </developer>
+    </developers>
+    <contributors>
+        <contributor>
+            <name>Don Brown</name>
+            <email>mrdon at apache.org</email>
+            <organization>ASF</organization>
+            <organizationUrl>http://www.apache.org/</organizationUrl>
+        </contributor>
+        <contributor>
+            <name>Joerk Heinicke</name>
+            <email>joerg.heinicke at gmx.de</email>
+        </contributor>
+        <contributor>
+            <name>Mark Proctor</name>
+            <email>mproctor at codehaus.org</email>
+        </contributor>
+    </contributors>
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/jakarta/commons/proper/jci/tags/1.0-RC4</connection>
+        <developerConnection>scn:svn:https://svn.apache.org/repos/asf/jakarta/commons/proper/jci/tags/1.0-RC4</developerConnection>
+        <url>http://svn.apache.org/viewvc/jakarta/commons/proper/jci/tags/1.0-RC4</url>
+    </scm>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.3</version>
+                <configuration>
+                    <systemProperties>
+                        <property>
+                            <name>org.apache.commons.logging.Log</name>
+                            <value>org.apache.commons.logging.impl.SimpleLog</value>
+                        </property>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>2.0</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>clean</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <extensions>
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-ssh-external</artifactId>
+                <version>1.0-beta-2</version>
+            </extension>
+        </extensions>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>cobertura-maven-plugin</artifactId>
+                <version>2.0</version>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <version>1.0.0</version>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>taglist-maven-plugin</artifactId>
+                <version>2.0</version>
+                <configuration>
+                    <tags>
+                        <tag>TODO</tag>
+                        <tag>@todo</tag>
+                        <tag>FIXME</tag>
+                        <tag>@deprecated</tag>
+                    </tags>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-report-plugin</artifactId>
+                <version>2.3</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-pmd-plugin</artifactId>
+                <version>2.2</version>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jxr-plugin</artifactId>
+                <version>2.0</version>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.2</version>
+                <configuration>
+                    <aggregate>true</aggregate>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>2.0.1</version>
+                <inherited>false</inherited>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>project-team</report>
+                            <report>mailing-list</report>
+                            <report>dependencies</report>
+                            <report>issue-tracking</report>
+                            <report>license</report>
+                            <report>scm</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+    <profiles>
+        <profile>
+            <id>release</id>
+            <distributionManagement>
+                <repository>
+                    <id>apache.staging</id>
+                    <name>Apache Release Staging Repository</name>
+                    <url>${commons.deployment.protocol}://people.apache.org/www/people.apache.org/builds/jakarta-commons/jci/${release.tag}/</url>
+                </repository>
+            </distributionManagement>
+            <build>
+                <pluginManagement>
+                    <plugins>
+                        <plugin>
+                            <groupId>org.apache.maven.plugins</groupId>
+                            <artifactId>maven-source-plugin</artifactId>
+                            <version>2.0.3</version>
+                        </plugin>
+                    </plugins>
+                </pluginManagement>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <version>1.0-alpha-3</version>
+                        <configuration>
+                            <useAgent>true</useAgent>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>sign-artifacts</id>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-source-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>create-source-jar</id>
+                                <goals>
+                                    <goal>jar</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>create-javadoc-jar</id>
+                                <goals>
+                                    <goal>jar</goal>
+                                </goals>
+                                <configuration>
+                                    <source>${maven.compile.source}</source>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-release-plugin</artifactId>
+                        <version>2.0-beta-4</version>
+                        <configuration>
+                            <generateReleasePoms>true</generateReleasePoms>
+                            <preparationGoals>clean install</preparationGoals>
+                            <autoVersionSubmodules>true</autoVersionSubmodules>
+                            <tag>${release.tag}</tag>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+    <properties>
+        <gpg.useAgent>true</gpg.useAgent>
+        <maven.compile.source>1.4</maven.compile.source>
+        <maven.compile.target>1.4</maven.compile.target>
+        <commons.deployment.protocol>scpexe</commons.deployment.protocol>
+        <release.tag>1.0-RC4</release.tag>
+    </properties>
+</project>
diff --git a/src/site/resources/jci-logo-white.png b/src/site/resources/jci-logo-white.png
new file mode 100644
index 0000000..d9a7b7d
Binary files /dev/null and b/src/site/resources/jci-logo-white.png differ
diff --git a/src/site/site.xml b/src/site/site.xml
new file mode 100644
index 0000000..d168dfd
--- /dev/null
+++ b/src/site/site.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+
+   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.
+
+--><project name="Jakarta Commons JCI">
+    <bannerRight>
+        <name>Jakarta Commons JCI</name>
+        <src>jci-logo-white.png</src>
+        <href>http://jakarta.apache.org/commons/sandbox/jci/</href>
+    </bannerRight>
+    <body>
+        <menu name="Jakarta Commons JCI">
+            <item name="About" href="http://jakarta.apache.org/commons/jci/index.html"/>
+            <item name="Usage" href="http://jakarta.apache.org/commons/jci/usage.html"/>
+            <item name="FAQ" href="http://jakarta.apache.org/commons/jci/faq.html"/>
+            <item name="Downloads" href="http://jakarta.apache.org/commons/jci/downloads.html"/>
+        </menu>
+        <menu ref="modules"/>
+    </body>
+</project>
diff --git a/src/site/xdoc/downloads.xml b/src/site/xdoc/downloads.xml
new file mode 100644
index 0000000..5cbef7c
--- /dev/null
+++ b/src/site/xdoc/downloads.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<!--
+
+   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.
+
+--><document>
+   <properties>
+      <title>Jakarta Commons JCI - Downloads</title>
+      <author email="commons-dev at jakarta.apache.org">Commons Development Team</author>
+   </properties>
+
+   <body>
+      <section name="Releases">
+         <p>There are no releases available yet.</p>
+
+<!--
+         <p>The following releases are available:</p>
+         <ul>
+           <li>Version 1.1 - 20 October 2003</li>
+           <li>Version 1.0 - 12 August 2002</li>
+         </ul>
+         <br/>
+         <p>
+            The latest binary release is always available on the 
+            <a href="http://jakarta.apache.org/site/binindex.cgi#commons-jci">
+            Jakarta Binary Downloads page</a>,
+            its source is available from 
+            <a href="http://jakarta.apache.org/site/sourceindex.cgi#commons-jci">
+            Jakarta Source Downloads page</a>.
+         </p>
+         <p>
+            Older releases are retained by the Apache Software Foundation but are 
+            moved into a
+            <a href="http://archive.apache.org/dist/jakarta/commons/jci/">
+            special archive area</a>.
+         </p>
+         <p>
+           <a href="http://people.apache.org/builds/jakarta-commons/nightly/commons-jci/">
+           Nightly source and binary drops</a> are available.
+         </p>
+-->
+         <p>
+            Access to the source tree to see the latest and greatest code is possible
+            through <a href="source-repository.html">anonymous SVN access</a>.
+         </p>
+      </section>
+
+<!--
+      <section name="Release Candidate">
+         <p>
+            Release candidates for the upcoming 1.0 release can be downloaded 
+            <a href="http://people.apache.org/~tcurdt/jci/rc/">here</a>.
+         </p>
+         <p>
+            Please review and report any problem on the 
+            <a href="mail-lists.html">mailing list</a>.
+         </p>
+         <p>
+            Planet release target is 10 April 2007.
+         </p>
+      </section>
+-->
+   </body>
+</document>
diff --git a/src/site/xdoc/faq.xml b/src/site/xdoc/faq.xml
new file mode 100644
index 0000000..bfaffa4
--- /dev/null
+++ b/src/site/xdoc/faq.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+
+   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.
+
+--><document>
+    <properties>
+        <title>Commons JCI - FAQ</title>
+        <author email="commons-dev at jakarta.apache.org">Commons Development Team</author>
+    </properties>
+    <body>
+        <section name="FAQ">
+            <subsection name="Isn't compiler support integrated with Java6 (JSR199)?">
+                Yes, it is now. JSR199 in the end brought the official java compiler tools that
+                now come with Mustang. Progress on this had stalled for many years. This is how
+                JCI was born. JCI provided what was missing from the JDK. And it still provides
+                it also for earlier versions. The main author of JCI has later on joined the EG
+                and will make sure there is a bridge to the JSR199 API. 
+            </subsection>
+            <subsection name="Doesn't JSR199 already deprecate JCI?">
+                Well, as said before ...there are no backports so far. And if you give the
+                the final java tools API in Mustang a try you might well come back and
+                enjoy JCI :)
+            </subsection>
+            <subsection name="How well tested is the code?">
+                Well, there are a couple of projects out there using this code already for
+                quite some time in production. Drools and Cocoon to name just a few well known Open
+                Source projects. Code coverage is not bad at all ...but there still a few things
+                on the TODO list and contributions are always welcome.
+            </subsection>
+            <subsection name="Will the ... compiler be supported?">
+                There is always room for new implementations. And if the compiler supports compilation to
+                java bytecode, there is also a good chance it can be added. There are currently already a
+                few potential candidates out there. But it all comes down to the need and the time to implement.
+            </subsection>
+        </section>
+    </body>
+</document>
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
new file mode 100644
index 0000000..4c552b0
--- /dev/null
+++ b/src/site/xdoc/index.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+
+   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.
+
+--><document>
+    <properties>
+        <title>Jakarta Commons JCI - About</title>
+        <author email="commons-dev at jakarta.apache.org">Commons Documentation Team</author>
+    </properties>
+    <body>
+        <section name="The JCI Component">
+            <p>
+                JCI is a java compiler interface. It can be used to either compile java (or any other language that can be
+                compiled to java classes like e.g. groovy or javascript) to java. It is well integrated with a FAM (FilesystemAlterationMonitor)
+                that can be used with the JCI compiling/reloading classloader. All the currently supported compilers (even javac before java6)
+                feature in-memory compilation.
+            </p>
+            <p>The current implementation supports compilation via the following compilers:</p>
+            <ul>
+                <li>eclipse</li>
+                <li>janino</li>
+                <li>groovy</li>
+                <li>javac</li>
+                <li>rhino</li>
+            </ul>
+        </section>
+        <section name="Releases">
+            <p>
+                See the <a href="downloads.html">downloads</a> page for information on obtaining releases.
+            </p>
+        </section>
+        <section name="Documentation">
+            <p>
+                The <a href="apidocs/index.html">JavaDoc API documents</a> are available online.
+            </p>
+        </section>
+    </body>
+</document>
diff --git a/src/site/xdoc/usage.xml b/src/site/xdoc/usage.xml
new file mode 100644
index 0000000..aef6ec9
--- /dev/null
+++ b/src/site/xdoc/usage.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+
+   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.
+
+--><document>
+    <properties>
+        <title>Jakarta Commons JCI - Usage</title>
+        <author email="commons-dev at jakarta.apache.org">Commons Development Team</author>
+    </properties>
+    <body>
+        <section name="Compilation">
+            <p>
+                The <code>JavaCompiler</code> is quite simple. You have to provide the paths to
+                the sources, where to get the sources from and where to store the classes. Then
+                you just pick one of the compilers to do the work. The result of the compilation
+                is returned as <code>CompilationResult</code>.
+            </p>
+            
+<source><![CDATA[
+JavaCompiler compiler = new JavaCompilerFactory().createCompiler("eclipse");
+CompilationResult result = compiler.compile(sources, new FileResourceReader(sourceDir), new FileResourceStore(targetDir));
+
+System.out.println( result.getErrors().length + " errors");
+System.out.println( result.getWarnings().length + " warnings");
+]]></source>
+            <p>
+                Information like line numbers of errors etc are accessible in a consistent way.
+                If supported by the compiler you can even get notified about error before the
+                end of the compilation. (see the <code>CompilationProblemHandler</code>) for that.
+                The <a href="http://jakarta.apache.org/commons/sandbox/jci/commons-jci-examples/index.html">example subproject</a>
+                provides a simple <a href="http://jakarta.apache.org/commons/sandbox/jci/xref/org/apache/commons/jci/examples/serverpages/ServerPageServlet.html">JSP servlet</a>
+                and a javac-like <a href="http://jakarta.apache.org/commons/sandbox/jci/xref/org/apache/commons/jci/examples/commandline/CommandlineCompiler.html">command line interface</a>.
+            </p>
+            
+        </section>
+        <section name="Filesystem monitoring">
+            <p>
+                A subproject of JCI provides a <code>FilesystemAlterationMonitor</code> that can
+                be used to get notified when files change on the local filesystem. If you attach
+                a <code>ReloadingListener</code> or a <code>CompilingListener</code> it can even
+                trigger the reload of a class in the <code>ReloadingClassLoader</code>.
+            </p>
+<source><![CDATA[
+ReloadingClassLoader classloader = new ReloadingClassLoader(this.getClass().getClassLoader());
+ReloadingListener listener = new ReloadingListener();
+
+listener.addReloadNotificationListener(classloader);
+
+FilesystemAlterationMonitor fam = new FilesystemAlterationMonitor();
+fam.addListener(directory, listener);
+fam.start();
+]]></source>
+            <p>
+                But you can also just implement a simple <code>FilesystemAlterationListener</code>
+                yourself and just use it to get notified about configuration files changes
+                <a href="http://jakarta.apache.org/commons/sandbox/jci/xref/org/apache/commons/jci/examples/configuration/ConfigurationReloading.html">for example</a>.
+                The example just extends the <code>FileChangeListener</code> that provides a few convenience methods.
+            </p>
+
+        </section>
+    </body>
+</document>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/commons-jci.git



More information about the pkg-java-commits mailing list