Index: /FCKeditor.Java/tags/2.4-beta-1/LICENSE.txt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/LICENSE.txt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/LICENSE.txt	(revision 2015)
@@ -0,0 +1,1247 @@
+FCKeditor - The text editor for Internet - http://www.fckeditor.net
+Copyright (C) 2003-2008 Frederico Caldeira Knabben
+
+Licensed under the terms of any of the following licenses at your
+choice:
+
+ - GNU General Public License Version 2 or later (the "GPL")
+   http://www.gnu.org/licenses/gpl.html
+   (See Appendix A)
+
+ - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+   http://www.gnu.org/licenses/lgpl.html
+   (See Appendix B)
+
+ - Mozilla Public License Version 1.1 or later (the "MPL")
+   http://www.mozilla.org/MPL/MPL-1.1.html
+   (See Appendix C)
+
+You are not required to, but if you want to explicitly declare the
+license you have chosen to be bound to when using, reproducing,
+modifying and distributing this software, just include a text file
+titled "legal.txt" in your version of this software, indicating your
+license choice. In any case, your choice will not restrict any
+recipient of your version of this software to use, reproduce, modify
+and distribute this software under any of the above licenses.
+
+Appendix A: The GPL License
+===========================
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+Appendix B: The LGPL License
+============================
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+Appendix C: The MPL License
+===========================
+
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (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.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
Index: /FCKeditor.Java/tags/2.4-beta-1/build.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/build.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/build.xml	(revision 2015)
@@ -0,0 +1,72 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==  
+-->
+<project name="fckeditor-java" basedir=".">
+
+	<target name="deploy-fckeditor"
+	        description="Deploys the FCKeditor into the webapp for testing purposes"
+	>
+		<copy todir="java-demo/src/main/webapp/fckeditor">
+			<fileset dir="../fckeditor">
+				<include name="_samples/_plugins/" />
+				<include name="editor/" />
+				<include name="fckconfig.js" />
+				<include name="*.xml" />
+				<exclude name="editor/filemanager/connectors/" />
+			</fileset>
+		</copy>
+	</target>
+
+	<target name="clean-fckeditor"
+	        description="Creates a clean FCKeditor distribution"
+	>
+		<property name="fckeditor-tmp" location="fckeditor-tmp" />
+		<property name="fckeditor-basename" value="FCKeditor_2.6" />
+		<property name="fckeditor-destfile"
+		          value="${fckeditor-basename}_clean.zip"
+		/>
+		<delete file="${fckeditor-destfile}" />
+		<unzip dest="${fckeditor-tmp}" src="${fckeditor-basename}.zip" />
+		<zip destfile="${fckeditor-destfile}">
+			<zipfileset dir="${fckeditor-tmp}/fckeditor" prefix="fckeditor">
+				<include name="_samples/_plugins/" />
+				<include name="editor/" />
+				<include name="fckconfig.js" />
+				<include name="*.xml" />
+				<exclude name="editor/filemanager/connectors/" />
+			</zipfileset>
+		</zip>
+		<delete dir="${fckeditor-tmp}" />
+	</target>
+
+	<!-- Do NOT remove this target. This is for link rewrite testing purposes -->
+	<!--
+	<target name="rewrite-links" description="rewrites plain links in real links">
+
+		<replaceregexp byline="true" flags="m" file="target/site/tagreference.html">
+
+			<regexp pattern="&amp;lt;a href=&amp;quot;(\p{Graph}+)&amp;quot;\s*&amp;gt;(\p{Graph}+)&amp;lt;/a&amp;gt;" />
+			<substitution expression="&lt;a href=&quot;\1&quot;&gt;\2&lt;/a&gt;" />
+
+		</replaceregexp>
+	</target>
+	-->
+
+</project>
Index: /FCKeditor.Java/tags/2.4-beta-1/eclipse-format-profile.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/eclipse-format-profile.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/eclipse-format-profile.xml	(revision 2015)
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<profiles version="11">
+<profile kind="CodeFormatterProfile" name="FCKeditor Conventions" version="11">
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="100"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+</profile>
+</profiles>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/pom.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/pom.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/pom.xml	(revision 2015)
@@ -0,0 +1,126 @@
+<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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>java-core</artifactId>
+	<packaging>jar</packaging>
+	<dependencies>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+			<version>2.4</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet.jsp</groupId>
+			<artifactId>jsp-api</artifactId>
+			<version>2.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.4</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-nop</artifactId>
+			<version>1.5.0</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+	<parent>
+		<groupId>net.fckeditor</groupId>
+		<artifactId>fckeditor-java</artifactId>
+		<version>2.4-beta-1</version>
+	</parent>
+
+	<build>
+		<finalName>fckeditor-${artifactId}-${version}</finalName>
+		<plugins>
+			<plugin>
+				<artifactId>maven-antrun-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>rewrite-tagreference-links</id>
+						<phase>site</phase>
+						<goals>
+							<goal>run</goal>
+						</goals>
+						<configuration>
+							<tasks>
+								<property name="ant.regexp.regexpimpl" value="org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp" />
+								<replaceregexp byline="true" flags="m" file="target/site/tagreference.html">
+									<regexp pattern="&amp;lt;a href=&amp;quot;(\p{Graph}+)&amp;quot;\s*&amp;gt;(\p{Graph}+)&amp;lt;/a&amp;gt;" />
+									<substitution expression="&lt;a href=&quot;\1&quot;&gt;\2&lt;/a&gt;" />
+								</replaceregexp>
+							</tasks>
+						</configuration>
+					</execution>
+				</executions>
+				<!--<dependencies>
+					<dependency>
+					<groupId>ant</groupId>
+					<artifactId>ant-nodeps</artifactId>
+					<version>1.6.5</version>
+					</dependency>
+					</dependencies>-->
+			</plugin>
+		</plugins>
+	</build>
+
+	<reporting>
+		<plugins>
+			<plugin>
+				<groupId>net.sourceforge.maven-taglib</groupId>
+				<artifactId>maven-taglib-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<artifactId>maven-surefire-report-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<artifactId>maven-jxr-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<artifactId>maven-pmd-plugin</artifactId>
+				<configuration>
+					<targetJdk>1.5</targetJdk>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>cobertura-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>taglist-maven-plugin</artifactId>
+				<configuration>
+					<tags>
+						<tag>TODO</tag>
+						<tag>FIXME</tag>
+					</tags>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>
+					maven-project-info-reports-plugin
+				</artifactId>
+				<reportSets>
+					<reportSet>
+						<reports>
+							<report>dependencies</report>
+							<report>summary</report>
+						</reports>
+					</reportSet>
+				</reportSets>
+			</plugin>
+		</plugins>
+	</reporting>
+
+	<name>FCKeditor.Java Integration Core</name>
+	<description>
+		This Java library enables the FCKeditor to be used in a
+		Servlet/J2EE environment. It provides JSP tags for creating a FCKeditor
+		instance and a Servlet handling server-side user files and folders.
+	</description>
+	<url>http://java.fckeditor.net</url>
+</project>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/FCKeditor.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/FCKeditor.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/FCKeditor.java	(revision 2015)
@@ -0,0 +1,275 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+
+package net.fckeditor;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.fckeditor.handlers.PropertiesLoader;
+import net.fckeditor.tool.Compatibility;
+import net.fckeditor.tool.Utils;
+import net.fckeditor.tool.XHtmlTagTool;
+
+/**
+ * FCKeditor control class.<br>
+ * 
+ * It creates the html code for the FCKeditor based on the following things:
+ * <ul>
+ * <li>browser's capabilities</li>
+ * <li>different properties settings managed by the {@link PropertiesLoader}</li>
+ * <li>settings from the 'caller', eg. jsp-pages</li>
+ * </ul>
+ * 
+ * @version $Id$
+ */
+public class FCKeditor {
+
+	private FCKeditorConfig config;
+	private String instanceName;
+	private String value;
+	private String basePath;
+	private HttpServletRequest request;
+
+	// defaults
+	private String toolbarSet = PropertiesLoader.getProperty("fckeditor.toolbarSet");
+	private String width = PropertiesLoader.getProperty("fckeditor.width");
+	private String height = PropertiesLoader.getProperty("fckeditor.height");
+	private String defaultBasePath = PropertiesLoader.getProperty("fckeditor.basePath");
+
+	/**
+	 * Main constructor.<br>
+	 * All important settings are done here and will be preset by there defaults taken from
+	 * {@link PropertiesLoader}.
+	 * 
+	 * @param request
+	 *            request object
+	 * @param instanceName
+	 *            unique name
+	 * @param width
+	 *            width
+	 * @param height
+	 *            height
+	 * @param toolbarSet
+	 *            toolbarSet name
+	 */
+	public FCKeditor(final HttpServletRequest request, final String instanceName,
+	        final String width, final String height, final String toolbarSet, final String value,
+	        final String basePath) {
+		this.request = request;
+		this.instanceName = instanceName;
+		if (Utils.isNotEmpty(width))
+			this.width = width;
+		if (Utils.isNotEmpty(height))
+			this.height = height;
+		if (Utils.isNotEmpty(toolbarSet))
+			this.toolbarSet = toolbarSet;
+		if (Utils.isNotEmpty(value))
+			this.value = value;
+		if (Utils.isNotEmpty(basePath))
+			this.basePath = request.getContextPath().concat(basePath);
+		else
+			this.basePath = request.getContextPath().concat(defaultBasePath);
+
+		config = new FCKeditorConfig();
+	}
+
+	/**
+	 * Just a wrapper to {@link FCKeditor}.
+	 * 
+	 * @param request
+	 *            request object
+	 * @param instanceName
+	 *            unique name
+	 */
+
+	public FCKeditor(final HttpServletRequest request, final String instanceName) {
+		this(request, instanceName, null, null, null, null, null);
+	}
+
+	/**
+	 * Set the unique name of the editor
+	 * 
+	 * @param value
+	 *            name
+	 */
+	public void setInstanceName(final String value) {
+		instanceName = value;
+	}
+
+	/**
+	 * Set the initial value to be edited.<br>
+	 * In HTML code
+	 * 
+	 * @param value
+	 *            value
+	 */
+	public void setValue(final String value) {
+		this.value = value;
+	}
+
+	/**
+	 * Set the dir where the FCKeditor files reside on the server.<br>
+	 * <b>Remarks</b>:<br>
+	 * Avoid using relative paths. It is preferable to set the base path starting from the root (/).<br>
+	 * Always finish the path with a slash (/).
+	 * 
+	 * @param value
+	 *            path
+	 */
+	public void setBasePath(final String value) {
+		basePath = value;
+	}
+
+	/**
+	 * Set the name of the toolbar to display
+	 * 
+	 * @param value
+	 *            toolbar name
+	 */
+	public void setToolbarSet(final String value) {
+		toolbarSet = value;
+	}
+
+	/**
+	 * Set the width of the textarea
+	 * 
+	 * @param value
+	 *            width
+	 */
+	public void setWidth(final String value) {
+		width = value;
+	}
+
+	/**
+	 * Set the height of the textarea
+	 * 
+	 * @param value
+	 *            height
+	 */
+	public void setHeight(final String value) {
+		height = value;
+	}
+
+	/**
+	 * Get the advanced configuation set.<br>
+	 * Adding element to this collection you can override the settings specified in the config.js
+	 * file.
+	 * 
+	 * @return configuration collection
+	 */
+	public FCKeditorConfig getConfig() {
+		return config;
+	}
+
+	/**
+	 * Set the advanced configuation set.
+	 * 
+	 * @param value
+	 *            configuration collection
+	 */
+	public void setConfig(FCKeditorConfig value) {
+		config = value;
+	}
+
+	private String escapeXml(String txt) {
+		if (Utils.isEmpty(txt))
+			return txt;
+		txt = txt.replaceAll("&", "&#38;");
+		txt = txt.replaceAll("<", "&#60;");
+		txt = txt.replaceAll(">", "&#62;");
+		txt = txt.replaceAll("\"", "&#34;");
+		txt = txt.replaceAll("'", "&#39;");
+		return txt;
+	}
+
+	/**
+	 * Minimum implementation, see ticket #27 for detailed information.
+	 */
+	public String create() {
+		return createHtml();
+	}
+
+	@Override
+	public String toString() {
+		return createHtml();
+	}
+
+	/**
+	 * Generate the HTML Code for the editor. <br>
+	 * Evalute the browser capabilities and generate the editor if compatible, or a simple textarea
+	 * otherwise.
+	 * 
+	 * @return html code
+	 */
+	public String createHtml() {
+		StringBuffer strEditor = new StringBuffer();
+
+		strEditor.append("<div>");
+		String encodedValue = escapeXml(value.replaceAll("((\r?\n)+|\t*)", ""));
+
+		if (Compatibility.check(request.getHeader("user-agent"))) {
+			strEditor.append(createInputForVariable(instanceName, instanceName, encodedValue));
+
+			// create config html
+			String configStr = config.getUrlParams();
+			if (Utils.isNotEmpty(configStr))
+				// configStr = configStr.substring(1);
+				strEditor.append(createInputForVariable(null, instanceName.concat("___Config"),
+				        configStr));
+
+			// create IFrame
+			String sLink = basePath.concat("/editor/fckeditor.html?InstanceName=").concat(
+			        instanceName);
+			if (Utils.isNotEmpty(toolbarSet))
+				sLink += "&Toolbar=".concat(toolbarSet);
+			XHtmlTagTool iframeTag = new XHtmlTagTool("iframe", XHtmlTagTool.SPACE);
+			iframeTag.addAttribute("id", instanceName.concat("___Frame"));
+			iframeTag.addAttribute("src", sLink);
+			iframeTag.addAttribute("width", width);
+			iframeTag.addAttribute("height", height);
+			iframeTag.addAttribute("frameborder", "no");
+			iframeTag.addAttribute("scrolling", "no");
+			strEditor.append(iframeTag);
+
+		} else {
+			XHtmlTagTool textareaTag = new XHtmlTagTool("textarea", encodedValue);
+			textareaTag.addAttribute("name", instanceName);
+			textareaTag.addAttribute("rows", "4");
+			textareaTag.addAttribute("cols", "40");
+			textareaTag.addAttribute("wrap", "virtual");
+			textareaTag.addAttribute("style", "width: ".concat(width).concat("; height: ").concat(
+			        height));
+		}
+		strEditor.append("</div>");
+		return strEditor.toString();
+	}
+
+	private String createInputForVariable(final String name, final String id, final String value) {
+		XHtmlTagTool tag = new XHtmlTagTool("input");
+		if (Utils.isNotEmpty(id))
+			tag.addAttribute("id", id);
+		if (Utils.isNotEmpty(name))
+			tag.addAttribute("name", name);
+		tag.addAttribute("value", value);
+		tag.addAttribute("type", "hidden");
+		return tag.toString();
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/FCKeditorConfig.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/FCKeditorConfig.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/FCKeditorConfig.java	(revision 2015)
@@ -0,0 +1,79 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+
+package net.fckeditor;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.fckeditor.tool.Utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Contains the configuration settings for the FCKEditor.<br>
+ * Adding element to this collection you can override the settings specified in
+ * the config.js file.
+ * 
+ * @version $Id$
+ */
+public class FCKeditorConfig extends HashMap<String, String> {
+
+	private static final long serialVersionUID = -4831190504944866644L;
+	private final Logger logger = LoggerFactory.getLogger(FCKeditorConfig.class);
+
+	/**
+	 * Initialize the configuration collection
+	 */
+	public FCKeditorConfig() {
+		super();
+	}
+
+	/**
+	 * Generate the url parameter sequence used to pass this configuration to
+	 * the editor.
+	 * 
+	 * @return html endocode sequence of configuration parameters
+	 */
+	public String getUrlParams() {
+		StringBuffer osParams = new StringBuffer();
+		try {
+			for (Map.Entry<String, String> entry : this.entrySet()) {
+				if (Utils.isNotEmpty(entry.getValue())) {
+					osParams.append("&");
+					osParams.append(URLEncoder.encode(entry.getKey(),"UTF-8"));
+					osParams.append("=");
+					osParams.append(URLEncoder.encode(entry.getValue(),"UTF-8"));
+				}
+			}
+			
+		} catch (UnsupportedEncodingException e) {
+			logger.error("Configuration parameters could not be encoded", e);
+		}
+		
+		if (osParams.length() > 0)
+			osParams.deleteCharAt(0);
+		return osParams.toString();
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/connector/ConnectorServlet.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/connector/ConnectorServlet.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/connector/ConnectorServlet.java	(revision 2015)
@@ -0,0 +1,302 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.connector;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.fckeditor.handlers.CommandHandler;
+import net.fckeditor.handlers.ConnectorHandler;
+import net.fckeditor.handlers.ExtensionsHandler;
+import net.fckeditor.handlers.RequestCycleHandler;
+import net.fckeditor.handlers.ResourceTypeHandler;
+import net.fckeditor.response.UploadResponse;
+import net.fckeditor.response.XmlResponse;
+import net.fckeditor.tool.Utils;
+import net.fckeditor.tool.UtilsFile;
+import net.fckeditor.tool.UtilsResponse;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.io.FilenameUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Servlet to upload and browse files.<br>
+ * 
+ * This servlet accepts 4 commands used to retrieve and create files and folders from a server
+ * directory. The allowed commands are:
+ * <ul>
+ * <li>GetFolders: Retrieve the list of directory under the current folder
+ * <li>GetFoldersAndFiles: Retrive the list of files and directory under the current folder
+ * <li>CreateFolder: Create a new directory under the current folder
+ * <li>FileUpload: Send a new file to the server (must be sent with a POST)
+ * </ul>
+ * 
+ * @version $Id$
+ */
+public class ConnectorServlet extends HttpServlet {
+
+	private static final long serialVersionUID = -5742008970929377161L;
+	private static final Logger logger = LoggerFactory.getLogger(ConnectorServlet.class);
+
+	/**
+	 * Initialize the servlet.<br>
+	 * The default directory for user files will be constructed.
+	 */
+	public void init() throws ServletException, IllegalArgumentException {
+		// check, if 'baseDir' exists
+		String realDefaultUserFilesPath = getServletContext().getRealPath(
+		        ConnectorHandler.getDefaultUserFilesPath());
+
+		File defaultUserFilesDir = new File(realDefaultUserFilesPath);
+		UtilsFile.checkDirAndCreate(defaultUserFilesDir);
+
+		logger.info("ConnectorServlet successful initialized!");
+	}
+
+	/**
+	 * Manage the Get requests (GetFolders, GetFoldersAndFiles, CreateFolder).<br>
+	 * 
+	 * The servlet accepts commands sent in the following format:<br>
+	 * connector?Command=CommandName&Type=ResourceType&CurrentFolder=FolderPath<br>
+	 * <br>
+	 * It executes the commands and then return the results to the client in XML format.
+	 * 
+	 */
+	public void doGet(HttpServletRequest request, HttpServletResponse response)
+	        throws ServletException, IOException {
+		logger.debug("Entering ConnectorServlet#doGet");
+
+		response.setCharacterEncoding("UTF-8");
+		response.setContentType("application/xml; charset=UTF-8");
+		response.setHeader("Cache-Control", "no-cache");
+		PrintWriter out = response.getWriter();
+
+		String commandStr = request.getParameter("Command");
+		String typeStr = request.getParameter("Type");
+		String currentFolderStr = request.getParameter("CurrentFolder");
+
+		logger.debug("Parameter Command: {}", commandStr);
+		logger.debug("Parameter Type: {}", typeStr);
+		logger.debug("Parameter CurrentFolder: {}", currentFolderStr);
+
+		XmlResponse xr;
+
+		if (!RequestCycleHandler.isEnabledForFileBrowsing(request))
+			xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.NOT_AUTHORIZED_FOR_BROWSING);
+		else if (!CommandHandler.isValidForGet(commandStr))
+			xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.INVALID_COMMAND);
+		else if (typeStr != null && !ResourceTypeHandler.isValid(typeStr))
+			xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.INVALID_TYPE);
+		else if (!UtilsFile.isValidPath(currentFolderStr))
+			xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.INVALID_CURRENT_FOLDER);
+		else {
+			CommandHandler command = CommandHandler.getCommand(commandStr);
+			ResourceTypeHandler resourceType = ResourceTypeHandler.getDefaultResourceType(typeStr);
+
+			String typePath = UtilsResponse.constructResponseUrl(request, resourceType,
+			        currentFolderStr, false, false);
+			String typeDirPath = getServletContext().getRealPath(typePath);
+
+			File typeDir = new File(typeDirPath);
+			UtilsFile.checkDirAndCreate(typeDir);
+
+			File currentDir = new File(typeDir, currentFolderStr);
+
+			if (!currentDir.exists())
+				xr = new XmlResponse(XmlResponse.EN_INVALID_FOLDER_NAME);
+			else {
+
+				xr = new XmlResponse(command, resourceType, currentFolderStr, UtilsResponse
+				        .constructResponseUrl(request, resourceType, currentFolderStr, true,
+				                ConnectorHandler.isFullUrl()));
+
+				if (command.equals(CommandHandler.GET_FOLDERS))
+					xr.setFolders(currentDir);
+				else if (command.equals(CommandHandler.GET_FOLDERS_AND_FILES))
+					xr.setFoldersAndFiles(currentDir);
+				else if (command.equals(CommandHandler.CREATE_FOLDER)) {
+					String newFolderStr = UtilsFile.sanitizeFolderName(request
+					        .getParameter("NewFolderName"));
+					logger.debug("Parameter NewFolderName: {}", newFolderStr);
+
+					File newFolder = new File(currentDir, newFolderStr);
+					int errorNumber = XmlResponse.EN_UKNOWN;
+
+					if (newFolder.exists())
+						errorNumber = XmlResponse.EN_ALREADY_EXISTS;
+					else {
+						try {
+							errorNumber = (newFolder.mkdir()) ? XmlResponse.EN_OK
+							        : XmlResponse.EN_INVALID_FOLDER_NAME;
+						} catch (SecurityException e) {
+							errorNumber = XmlResponse.EN_SECURITY_ERROR;
+						}
+					}
+					xr.setError(errorNumber);
+				}
+			}
+		}
+
+		out.print(xr);
+		out.flush();
+		out.close();
+		logger.debug("Exiting ConnectorServlet#doGet");
+	}
+
+	/**
+	 * Manage the Post requests (FileUpload).<br>
+	 * 
+	 * The servlet accepts commands sent in the following format:<br>
+	 * connector?Command=FileUpload&Type=ResourceType&CurrentFolder=FolderPath<br>
+	 * <br>
+	 * It store the file (renaming it in case a file with the same name exists) and then return an
+	 * HTML file with a javascript command in it.
+	 */
+	@SuppressWarnings("unchecked")
+	public void doPost(HttpServletRequest request, HttpServletResponse response)
+	        throws ServletException, IOException {
+		logger.debug("Entering Connector#doPost");
+
+		response.setCharacterEncoding("UTF-8");
+		response.setContentType("text/html; charset=UTF-8");
+		response.setHeader("Cache-Control", "no-cache");
+		PrintWriter out = response.getWriter();
+
+		String commandStr = request.getParameter("Command");
+		String typeStr = request.getParameter("Type");
+		String currentFolderStr = request.getParameter("CurrentFolder");
+
+		logger.debug("Parameter Command: {}", commandStr);
+		logger.debug("Parameter Type: {}", typeStr);
+		logger.debug("Parameter CurrentFolder: {}", currentFolderStr);
+
+		UploadResponse ur;
+
+		// if this is a QuickUpload-Request, 'commandStr' and 'currentFolderStr' are empty
+		if (Utils.isEmpty(commandStr) && Utils.isEmpty(currentFolderStr)) {
+			commandStr = "QuickUpload";
+			currentFolderStr = "/";
+		}
+
+		if (!RequestCycleHandler.isEnabledForFileUpload(request))
+			ur = new UploadResponse(UploadResponse.EN_SECURITY_ERROR, null, null,
+			        Messages.NOT_AUTHORIZED_FOR_UPLOAD);
+		else if (!CommandHandler.isValidForPost(commandStr))
+			ur = new UploadResponse(UploadResponse.EN_ERROR, null, null, Messages.INVALID_COMMAND);
+		else if (typeStr != null && !ResourceTypeHandler.isValid(typeStr))
+			ur = new UploadResponse(UploadResponse.EN_ERROR, null, null, Messages.INVALID_TYPE);
+		else if (!UtilsFile.isValidPath(currentFolderStr))
+			ur = UploadResponse.UR_INVALID_CURRENT_FOLDER;
+		else {
+			ResourceTypeHandler resourceType = ResourceTypeHandler.getDefaultResourceType(typeStr);
+
+			String typePath = UtilsResponse.constructResponseUrl(request, resourceType,
+			        currentFolderStr, false, false);
+			String typeDirPath = getServletContext().getRealPath(typePath);
+
+			File typeDir = new File(typeDirPath);
+			UtilsFile.checkDirAndCreate(typeDir);
+
+			File currentDir = new File(typeDir, currentFolderStr);
+
+			if (!currentDir.exists())
+				ur = UploadResponse.UR_INVALID_CURRENT_FOLDER;
+			else {
+
+				String newFilename = null;
+				FileItemFactory factory = new DiskFileItemFactory();
+				ServletFileUpload upload = new ServletFileUpload(factory);
+
+				try {
+
+					List<FileItem> items = upload.parseRequest(request);
+
+					// We upload only one file at the same time
+					FileItem uplFile = items.get(0);
+					String rawName = UtilsFile.sanitizeFileName(uplFile.getName());
+					String filename = FilenameUtils.getName(rawName);
+					String baseName = FilenameUtils.removeExtension(filename);
+					String extension = FilenameUtils.getExtension(filename);
+
+					if (!ExtensionsHandler.isAllowed(resourceType, extension))
+						ur = new UploadResponse(UploadResponse.EN_INVALID_EXTENSION);
+					else {
+
+						// construct an unique file name
+						File pathToSave = new File(currentDir, filename);
+						int counter = 1;
+						while (pathToSave.exists()) {
+							newFilename = baseName.concat("(").concat(String.valueOf(counter))
+							        .concat(")").concat(".").concat(extension);
+							pathToSave = new File(currentDir, newFilename);
+							counter++;
+						}
+
+						if (Utils.isEmpty(newFilename))
+							ur = new UploadResponse(UploadResponse.EN_OK, UtilsResponse
+							        .constructResponseUrl(request, resourceType, currentFolderStr,
+							                true, ConnectorHandler.isFullUrl()).concat(filename));
+						else
+							ur = new UploadResponse(UploadResponse.EN_RENAMED,
+							        UtilsResponse.constructResponseUrl(request, resourceType,
+							                currentFolderStr, true, ConnectorHandler.isFullUrl())
+							                .concat(newFilename), newFilename);
+
+						// secure image check
+						if (resourceType.equals(ResourceTypeHandler.IMAGE)
+						        && ConnectorHandler.isSecureImageUploads()) {
+							if (UtilsFile.isImage(uplFile.getInputStream()))
+								uplFile.write(pathToSave);
+							else {
+								uplFile.delete();
+								ur = new UploadResponse(UploadResponse.EN_INVALID_EXTENSION);
+							}
+						} else
+							uplFile.write(pathToSave);
+
+					}
+				} catch (Exception e) {
+					ur = new UploadResponse(UploadResponse.EN_SECURITY_ERROR);
+				}
+			}
+
+		}
+
+		out.print(ur);
+		out.flush();
+		out.close();
+
+		logger.debug("Exiting Connector#doPost");
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/connector/Messages.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/connector/Messages.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/connector/Messages.java	(revision 2015)
@@ -0,0 +1,45 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.connector;
+
+/**
+ * Some messages for the {@link ConnectorServlet}.
+ *  
+ * @version $Id$
+ */
+public class Messages {
+
+	/** Error message NOT AUTHORIZED FOR FILE UPLOAD */
+	public static final String NOT_AUTHORIZED_FOR_UPLOAD = "The current user isn't authorized for file upload!";
+
+	/** Error message NOT AUTHORIZED FOR FILE BROWSING */
+	public static final String NOT_AUTHORIZED_FOR_BROWSING = "The current user isn't authorized for file browsing!";
+
+	/** Error message INVALID COMMAND SUPPLIED */
+	public static final String INVALID_COMMAND = "Invalid command specified";
+
+	/** Error message INVALID TYPE SUPPLIED */
+	public static final String INVALID_TYPE = "Invalid resource type specified";
+
+	/** Error message INVALID CURRENT FOLDER */
+	public static final String INVALID_CURRENT_FOLDER = "Invalid current folder specified";
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/CommandHandler.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/CommandHandler.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/CommandHandler.java	(revision 2015)
@@ -0,0 +1,157 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Handler for the get and post commands.
+ * 
+ * @version $Id$
+ */
+public class CommandHandler {
+
+	private String name;
+	private static Map<String, CommandHandler> getCommands = new HashMap<String, CommandHandler>(
+	        3);
+	private static Map<String, CommandHandler> postCommands = new HashMap<String, CommandHandler>(
+	        2);
+	public static final CommandHandler GET_FOLDERS = new CommandHandler("GetFolders");
+	public static final CommandHandler GET_FOLDERS_AND_FILES = new CommandHandler("GetFoldersAndFiles");
+	public static final CommandHandler CREATE_FOLDER = new CommandHandler("CreateFolder");
+	public static final CommandHandler FILE_UPLOAD = new CommandHandler("FileUpload");
+	public static final CommandHandler QUICK_UPLOAD = new CommandHandler("QuickUpload");
+
+	static {
+		// initialize the get commands
+		getCommands.put(GET_FOLDERS.getName(), GET_FOLDERS);
+		getCommands.put(GET_FOLDERS_AND_FILES.getName(), GET_FOLDERS_AND_FILES);
+		getCommands.put(CREATE_FOLDER.getName(), CREATE_FOLDER);
+		
+		// initialize the post commands
+		postCommands.put(FILE_UPLOAD.getName(), FILE_UPLOAD);
+		postCommands.put(QUICK_UPLOAD.getName(), QUICK_UPLOAD);
+	}
+
+	private CommandHandler(final String name) {
+		this.name = name;
+	}
+
+	/**
+	 * Getter for the name.
+	 * 
+	 * @return name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Getter for an {@link CommandHandler} of a specified string.
+	 * 
+	 * @param name
+	 * @return A {@link CommandHandler} object holding the value represented by the string
+	 *         argument.
+	 * @throws IllegalArgumentException
+	 *             If 'name' is null or can't be parsed.
+	 */
+	public static CommandHandler valueOf(final String name) throws IllegalArgumentException {
+		if (name == null)
+			throw new IllegalArgumentException();
+
+		if (!isValidForGet(name) && !isValidForPost(name))
+			throw new IllegalArgumentException();
+		return (getCommands.get(name) != null) ? getCommands.get(name) : postCommands.get(name);
+	}
+	
+
+	/**
+	 * Checks, if a specfied string is a valid representation of a get command.
+	 * 
+	 * @param name
+	 * @return True, if the string representation is valid, or false.
+	 */
+	public static boolean isValidForGet(final String name) {
+		return getCommands.containsKey(name);
+	}
+
+	/**
+	 * Checks, if a specfied string is a valid representation of a post command.
+	 * 
+	 * @param name
+	 * @return True, if the string representation is valid, or false.
+	 */
+	public static boolean isValidForPost(final String name) {
+		return postCommands.containsKey(name);
+	}
+	
+	
+	/**
+	 * A wrapper for {@link #valueOf(String)}. It returns null instead of throwing an exception.
+	 * 
+	 * @param name
+	 * @return A {@link CommandHandler} object holding the value represented by the string
+	 *         argument, or null.
+	 */
+	public static CommandHandler getCommand(final String name) {
+		try {
+			return CommandHandler.valueOf(name);
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		try {
+			CommandHandler rt = (CommandHandler) obj;
+			return name.equals(rt.getName());
+		} catch (ClassCastException e) {
+			return false;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public int hashCode() {
+		return name.hashCode();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return name;
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ConnectorHandler.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ConnectorHandler.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ConnectorHandler.java	(revision 2015)
@@ -0,0 +1,82 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.fckeditor.requestcycle.UserPathBuilder;
+
+/**
+ * Handler for some base properties.<br>
+ * It's a kind of wrapper to some basic properties handled by the {@link PropertiesLoader}.
+ * 
+ * @version $Id$
+ */
+public class ConnectorHandler {
+
+	/**
+     * Getter for the base dir (using for user files).
+     * 
+     * @return {@link UserPathBuilder#getUserFilesPath(HttpServletRequest)} or the default base dir, if
+     *         {@link UserPathBuilder}} isn't set.
+     */
+    public static String getUserFilesPath(final HttpServletRequest servletRequest) {
+    	String userFilePath = RequestCycleHandler.getUserFilePath(servletRequest);
+    	return (userFilePath != null) ? userFilePath : getDefaultUserFilesPath();
+    }
+
+	/**
+	 * Getter for the default handling of single extensions.
+	 * 
+	 * @return the forceSingleExtension
+	 */
+	public static boolean isForceSingleExtension() {
+		return Boolean.valueOf(PropertiesLoader.getProperty("connector.forceSingleExtension"));
+	}
+
+	/**
+	 * Getter for the value to instruct the connector to return the full URL of a file/folder in the
+	 * XML response rather than the absolute URL.
+	 * 
+	 * @return Boolean value of the property 'connector.fullUrl'.
+	 */
+	public static boolean isFullUrl() {
+		return Boolean.valueOf(PropertiesLoader.getProperty("connector.fullUrl"));
+	}
+
+	/**
+	 * Getter for the default userFilesPath.
+	 * 
+	 * @return Default userfiles path (/userfiles)
+	 */
+	public static String getDefaultUserFilesPath() {
+		return PropertiesLoader.getProperty("connector.userFilesPath");
+	}
+	
+	/**
+	 * Getter for the value to instruct the Connector to check, if the uploaded image is really one.
+	 * 
+	 * @return Boolean value of the property 'connector.secureImageUploads'.
+	 */
+	public static boolean isSecureImageUploads() {
+		return Boolean.valueOf(PropertiesLoader.getProperty("connector.secureImageUploads"));
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ExtensionsHandler.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ExtensionsHandler.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ExtensionsHandler.java	(revision 2015)
@@ -0,0 +1,137 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import net.fckeditor.tool.Utils;
+
+/**
+ * Handler which manages the allowed and denied extensions for each resource type. The
+ * extensions are preset by the properties managed by {@link PropertiesLoader}.<br>
+ * <br>
+ * Hint: It's recommend to use either allowed or denied extensions for one file type.
+ * Never use both at the same time! That's why denied extensions of a file type will be 
+ * deleted, if you set the allowed one and vice versa.
+ * 
+ * @version $Id$
+ */
+public class ExtensionsHandler {
+
+	private static Map<ResourceTypeHandler, Set<String>> extensionsAllowed = new HashMap<ResourceTypeHandler, Set<String>>();
+	private static Map<ResourceTypeHandler, Set<String>> extensionsDenied = new HashMap<ResourceTypeHandler, Set<String>>();
+
+	static {
+		// load defaults
+		extensionsAllowed.put(ResourceTypeHandler.FILE, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.file.extensions.allowed")));
+		extensionsDenied.put(ResourceTypeHandler.FILE, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.file.extensions.denied")));
+		extensionsAllowed.put(ResourceTypeHandler.MEDIA, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.media.extensions.allowed")));
+		extensionsDenied.put(ResourceTypeHandler.MEDIA, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.media.extensions.denied")));
+		extensionsAllowed.put(ResourceTypeHandler.IMAGE, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.image.extensions.allowed")));
+		extensionsDenied.put(ResourceTypeHandler.IMAGE, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.image.extensions.denied")));
+		extensionsAllowed.put(ResourceTypeHandler.FLASH, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.flash.extensions.allowed")));
+		extensionsDenied.put(ResourceTypeHandler.FLASH, Utils.getSet(PropertiesLoader
+		    .getProperty("connector.resourceType.flash.extensions.denied")));
+	}
+
+	/**
+	 * Getter for the allowed extensions of a file type.
+	 * 
+	 * @param type
+	 *          The file type.
+	 * @return Set of allowed extensions or an empty set.
+	 */
+	public static Set<String> getExtensionsAllowed(final ResourceTypeHandler type) {
+		return extensionsAllowed.get(type);
+	}
+
+	/**
+	 * Setter for the allowed extensions of a file type. The denied extensions will be cleared.<br>
+	 * If 'extensionsList' is null, allowed extensions kept untouched.
+	 * 
+	 * @param type
+	 *          The file type.
+	 * @param extensionsList
+	 *          Required format: <code>ext1&#124;ext2&#124;ext3</code>
+	 */
+	public static void setExtensionsAllowed(final ResourceTypeHandler type, final String extensionsList) {
+		if (extensionsList != null) {
+			extensionsAllowed.put(type, Utils.getSet(extensionsList));
+			extensionsDenied.get(type).clear();
+		}
+	}
+
+	/**
+	 * Getter for the denied extensions of a file type.
+	 * 
+	 * @param type
+	 *          The file type.
+	 * @return Set of denied extensions or an empty set.
+	 */
+	public static Set<String> getExtensionsDenied(final ResourceTypeHandler type) {
+		return extensionsDenied.get(type);
+	}
+
+	/**
+	 * Setter for the denied extensions of a file type. The allowed extensions will be cleared.<br>
+	 * If 'extensionsList' is null, denied extensions kept untouched.
+	 * 
+	 * @param type
+	 *          The file type.
+	 * @param extensionsList
+	 *          Required format: <code>ext1&#124;ext2&#124;ext3</code>
+	 */
+	public static void setExtensionsDenied(final ResourceTypeHandler type, final String extensionsList) {
+		if (extensionsList != null) {
+			extensionsDenied.put(type, Utils.getSet(extensionsList));
+			extensionsAllowed.get(type).clear();
+		}
+	}
+
+	/**
+	 * Checks, if an extension is allowed for a file type.
+	 * 
+	 * @param type
+	 * @param extension
+	 * @return True, false. False is returned too, if 'type' or 'extensions' is null.
+	 */
+	public static boolean isAllowed(final ResourceTypeHandler type, final String extension) {
+		if (type == null || extension == null)
+			return false;
+		String ext = extension.toLowerCase();
+		Set<String> allowed = extensionsAllowed.get(type);
+		Set<String> denied = extensionsDenied.get(type);
+		if (allowed.isEmpty())
+			return !denied.contains(ext);
+		if (denied.isEmpty())
+			return allowed.contains(ext);
+		return false;
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/PropertiesLoader.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/PropertiesLoader.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/PropertiesLoader.java	(revision 2015)
@@ -0,0 +1,101 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import net.fckeditor.tool.Utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handler to hold the basic properties.<br>
+ * The main default file is 'default.properties' in the deepth of the classpath and should be
+ * untouched. If there is a file named 'fckeditor.properties' in the root of the classpath, it will
+ * be loaded. Values which are loaded before, will be overwritten.<br>
+ * If you won't use an extra properties file to adjust the defaults, you can use
+ * {@link #setProperty(String, String)} instead.
+ * 
+ * @version $Id$
+ */
+public class PropertiesLoader {
+	private static final Logger logger = LoggerFactory.getLogger(PropertiesLoader.class);
+	private static Properties properties = new Properties();
+
+	static {
+		try {
+			// 1. load system defaults
+			properties.load(new BufferedInputStream(PropertiesLoader.class
+			        .getResourceAsStream("default.properties")));
+
+			// 2. load user defaults
+			InputStream in = PropertiesLoader.class.getResourceAsStream("/fckeditor.properties");
+			if (in == null)
+				logger.warn("Can't find user properties!");
+			else {
+				try {
+					properties.load(new BufferedInputStream(in));
+					logger.info("User's properties loaded successfully!");
+				} catch (IOException e) {
+					logger.error("Error while loading user properties!", e);
+					throw new RuntimeException("Can't load user properties!", e);
+				}
+			}
+		} catch (IOException e) {
+			logger.error("Error while loading default properties!", e);
+			throw new RuntimeException("Can't load default properties!", e);
+		}
+	}
+
+	/**
+	 * Getter for a property of 'key'.
+	 * 
+	 * @param key
+	 *            the propery key
+	 * @return the value in this property list with the specified key value.
+	 * @see Properties#getProperty(String)
+	 */
+	public static String getProperty(final String key) {
+		return properties.getProperty(key);
+	}
+
+	/**
+	 * Setter for a property. If the property already exists, the value will be overwritten.<br>
+	 * Hint: This method is intended for an alternative way to set user defaults programmatically
+	 * instead of using the 'fckeditor.properties'. It should never used inside FCKeditor.Java !!!
+	 * 
+	 * @param key
+	 *            key the propery key
+	 * @param value
+	 * @throws IllegalArgumentException
+	 *             if 'key' is empty.
+	 * @see Properties#setProperty(String, String)
+	 */
+	public static void setProperty(final String key, final String value) {
+		if (Utils.isEmpty(key))
+			new IllegalArgumentException("The 'key' of a property schouldn't be null!");
+		properties.setProperty(key, value);
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/RequestCycleHandler.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/RequestCycleHandler.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/RequestCycleHandler.java	(revision 2015)
@@ -0,0 +1,110 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.fckeditor.requestcycle.UserAction;
+import net.fckeditor.requestcycle.UserPathBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handler for classes which implement the interfaces from the package
+ * {@link net.fckeditor.requestcycle}.
+ * 
+ * @version $Id$
+ */
+public class RequestCycleHandler {
+	private static Logger logger = LoggerFactory.getLogger(RequestCycleHandler.class);
+	private static UserAction userAction = null;
+	private static UserPathBuilder userPathBuilder = null;
+
+	static {
+		// If there are more objects to instantiate in future, we could solve the following by reflection!
+		
+		// 1. try to instantiate the UserAction object
+		String fqcn = PropertiesLoader.getProperty("connector.userActionImpl");
+		if (fqcn == null)
+			logger.warn("No property found for UserAction implementation, any user action is disabled!");
+		else {
+			try {
+				Class<?> clazz = Class.forName(fqcn);
+				userAction = (UserAction) clazz.newInstance();
+				logger.info("UserAction object successful instanciated!");
+			} catch (Exception e) {
+				logger.error("Couldn't instanciate the class [".concat(fqcn).concat(
+				        "], any user action of the ConnectorServlet is disabled!"), e);
+			}
+		}
+
+		// 2. try to instantiate the UserPathBuilder object
+		fqcn = PropertiesLoader.getProperty("connector.userPathBuilderImpl");
+		if (fqcn == null)
+			logger.warn("No property found for UserPathBuilder implementation! "
+					.concat("The default of users's 'BaseDir' will be used in the ConnectorServlet!"));
+		else {
+			try {
+				Class<?> clazz = Class.forName(fqcn);
+				userPathBuilder = (UserPathBuilder) clazz.newInstance();
+				logger.info("UserPathBuilder object successfull instanciated!");
+			} catch (Exception e) {
+				logger.error("Couldn't instanciate the class [".concat(fqcn)
+				        .concat("], The default of users's 'BaseDir' will be used in the ConnectorServlet!"), e);
+			}
+		}
+	}
+
+	/**
+	 * Just a wrapper to {@link UserAction#isEnabledForFileBrowsing(HttpServletRequest)}.
+	 * 
+	 * @param servletRequest
+	 * @return {@link UserAction#isEnabledForFileBrowsing(HttpServletRequest)} or false, if
+	 *         sessionData isn't set.
+	 */
+	public static boolean isEnabledForFileBrowsing(final HttpServletRequest servletRequest) {
+		return (userAction != null && userAction.isEnabledForFileBrowsing(servletRequest));
+	}
+
+	/**
+	 * Just a wrapper to {@link UserAction#isEnabledForFileUpload(HttpServletRequest)}.
+	 * 
+	 * @param request
+	 * @return {@link UserAction#isEnabledForFileUpload(HttpServletRequest)} or false, if userAction
+	 *         isn't set.
+	 */
+	public static boolean isEnabledForFileUpload(final HttpServletRequest request) {
+		return (userAction != null && userAction.isEnabledForFileUpload(request));
+	}
+
+	/**
+	 * Getter for the user's file path.<br>
+	 * Method is used by other handlers only!
+	 * 
+	 * @param request
+	 * @return {@link UserPathBuilder#getUserFilesPath(HttpServletRequest)} or null, if
+	 *         userPathBuilder is null.
+	 */
+	protected static String getUserFilePath(final HttpServletRequest request) {
+		return (userPathBuilder != null) ? userPathBuilder.getUserFilesPath(request) : null;
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ResourceTypeHandler.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ResourceTypeHandler.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/handlers/ResourceTypeHandler.java	(revision 2015)
@@ -0,0 +1,162 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Handler for the different resource types.
+ * 
+ * @version $Id$
+ */
+public class ResourceTypeHandler {
+
+	private String name;
+	private static Map<String, ResourceTypeHandler> types = new HashMap<String, ResourceTypeHandler>(
+	        4);
+	private static Map<ResourceTypeHandler, String> paths = new HashMap<ResourceTypeHandler, String>(
+	        4);
+	public static final ResourceTypeHandler FILE = new ResourceTypeHandler("File");
+	public static final ResourceTypeHandler FLASH = new ResourceTypeHandler("Flash");
+	public static final ResourceTypeHandler IMAGE = new ResourceTypeHandler("Image");
+	public static final ResourceTypeHandler MEDIA = new ResourceTypeHandler("Media");
+
+	static {
+		// initialize the resource types
+		types.put(FILE.getName(), FILE);
+		types.put(FLASH.getName(), FLASH);
+		types.put(IMAGE.getName(), IMAGE);
+		types.put(MEDIA.getName(), MEDIA);
+
+		// initialize the sub folders for each resource type
+		paths.put(FILE, PropertiesLoader.getProperty("connector.resourceType.file.path"));
+		paths.put(IMAGE, PropertiesLoader.getProperty("connector.resourceType.image.path"));
+		paths.put(FLASH, PropertiesLoader.getProperty("connector.resourceType.flash.path"));
+		paths.put(MEDIA, PropertiesLoader.getProperty("connector.resourceType.media.path"));
+	}
+
+	private ResourceTypeHandler(final String name) {
+		this.name = name;
+	}
+
+	/**
+	 * Getter for the name.
+	 * 
+	 * @return name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Getter for the path (sub folder).
+	 * 
+	 * @return The path (sub folder).
+	 */
+	public String getPath() {
+		return paths.get(this);
+	}
+
+	/**
+	 * Getter for an {@link ResourceTypeHandler} of a specified string.
+	 * 
+	 * @param name
+	 * @return A {@link ResourceTypeHandler} object holding the value represented by the string
+	 *         argument.
+	 * @throws IllegalArgumentException
+	 *             If 'name' is null can't be parsed.
+	 */
+	public static ResourceTypeHandler valueOf(final String name) throws IllegalArgumentException {
+		if (name == null)
+			throw new IllegalArgumentException();
+
+		ResourceTypeHandler rt = types.get(name);
+		if (rt == null)
+			throw new IllegalArgumentException();
+		return rt;
+	}
+
+	/**
+	 * Checks, if a specfied string is valid representation of a {@link ResourceTypeHandler}.
+	 * 
+	 * @param name
+	 * @return True, if the string represrntation is valid, or false.
+	 */
+	public static boolean isValid(final String name) {
+		return types.containsKey(name);
+	}
+
+	public static ResourceTypeHandler getDefaultResourceType(final String name) {
+		ResourceTypeHandler rt = getResourceType(name);
+		return rt == null ? FILE : rt;
+	}
+
+	/**
+	 * A wrapper for {@link #valueOf(String)}. It returns null instead of throwing an exception.
+	 * 
+	 * @param name
+	 * @return A {@link ResourceTypeHandler} object holding the value represented by the string
+	 *         argument, or null.
+	 */
+	public static ResourceTypeHandler getResourceType(final String name) {
+		try {
+			return ResourceTypeHandler.valueOf(name);
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		try {
+			ResourceTypeHandler rt = (ResourceTypeHandler) obj;
+			return name.equals(rt.getName());
+		} catch (ClassCastException e) {
+			return false;
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public int hashCode() {
+		return name.hashCode();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return name;
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/UserAction.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/UserAction.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/UserAction.java	(revision 2015)
@@ -0,0 +1,58 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.requestcycle;
+
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * Interface that provides the authorization of the following file based user actions:
+ * <ul>
+ * <li>{@link #isEnabledForFileBrowsing(HttpServletRequest)}: Enables the user to browse/select
+ * file.</li>
+ * <li>{@link #isEnabledForFileUpload(HttpServletRequest)}: Enables the user to upload files.</li>
+ * </ul>
+ * 
+ * @version $Id$
+ */
+public interface UserAction {
+
+	/**
+	 * Authenticates/enables the current user for uploading file.<br>
+	 * If the implementation doesn't bother you, just return <code>true</code>.
+	 * 
+	 * @param request
+	 *            Servlet request from user
+	 * @return <code>true</code> if user can upload to the server else <code>false</code>
+	 */
+	public boolean isEnabledForFileUpload(final HttpServletRequest request);
+
+	/**
+	 * Authenticates/enables the current user for browsing files.<br>
+	 * If the implementation doesn't bother you, just return <code>true</code>.
+	 * 
+	 * @param request
+	 *            Servlet request from user
+	 * @return <code>true</code> if user can browse the server else <code>false</code>
+	 */
+	public boolean isEnabledForFileBrowsing(final HttpServletRequest request);
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/UserPathBuilder.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/UserPathBuilder.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/UserPathBuilder.java	(revision 2015)
@@ -0,0 +1,48 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.requestcycle;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.fckeditor.handlers.ConnectorHandler;
+
+/**
+ * Interface to provide a way to build a user dependent 'BaseDir.
+ *
+ * @version $Id$
+ */
+public interface UserPathBuilder {
+
+	/**
+	 * Getter for the user dependent 'BaseDir'.<br>
+	 * <b>Important:</b>
+	 * <ul>
+	 * <li> If the implementation returns <code>null</code>, {@link ConnectorHandler} will used
+	 * the default one! That's useful, if the implementation doesn't bother you.</li>
+	 * <li>The returned directory string has to start with '/', but has to end without '/'.</li>
+	 * <li>The dir has to be within the context</li>
+	 * </ul>
+	 * 
+	 * @param request
+	 * @return <code>null</code> or the 'BaseDir' string for the current user.
+	 */
+	public String getUserFilesPath(final HttpServletRequest request);
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/impl/UserActionImpl.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/impl/UserActionImpl.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/requestcycle/impl/UserActionImpl.java	(revision 2015)
@@ -0,0 +1,48 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.requestcycle.impl;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.fckeditor.requestcycle.UserAction;
+
+/**
+ * Standard implementation for {@link UserAction}.
+ *
+ * @version $Id$
+ */
+public class UserActionImpl implements UserAction {
+
+	/* (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileBrowsing(javax.servlet.http.HttpServletRequest)
+	 */
+	public boolean isEnabledForFileBrowsing(final HttpServletRequest request) {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see net.fckeditor.requestcycle.UserAction#isEnabledForFileUpload(javax.servlet.http.HttpServletRequest)
+	 */
+	public boolean isEnabledForFileUpload(final HttpServletRequest request) {
+		return true;
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/response/UploadResponse.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/response/UploadResponse.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/response/UploadResponse.java	(revision 2015)
@@ -0,0 +1,163 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.response;
+
+import net.fckeditor.connector.Messages;
+import net.fckeditor.tool.Utils;
+
+/**
+ * Simply abstracts from the javascript callback to a java class.
+ * 
+ * <p>
+ * The usage is quite easy but can be tricky since varargs are used in the class
+ * constructor.<br/> The requestor expects a JS method callback with variable
+ * arguments size.
+ * </p>
+ * <p>
+ * e.g.
+ * <code>window.parent.OnUploadCompleted(101,'some/url/file.img','file.img','no error');</code>
+ * </p>
+ * <p>
+ * The UploadResponse constructor behaves the same way by simply calling it
+ * with:<br/>
+ * <code>UploadResponse ur = new UploadResonse(EN_SOME_ERROR,"/some/url/file.img","file.img","no error"):</code>
+ * </p>
+ * 
+ * @since 2.4
+ * @version $Id$
+ */
+public class UploadResponse {
+
+	private Object[] parameters;
+
+	// TODO Rename 'En_'-constants to something more intuitive like 'CODE_'
+	/** Error number OK */
+	public static final int EN_OK = 0;
+
+	/** Error number ERROR */
+	public static final int EN_ERROR = 1;
+
+	/** Error number RENAMED */
+	public static final int EN_RENAMED = 201;
+
+	/** Error number INVALID EXTENSION */
+	public static final int EN_INVALID_EXTENSION = 202;
+
+	/** Error number SECURITY ERROR */
+	public static final int EN_SECURITY_ERROR = 203;
+	
+	/** UploadResponse INVALID CURRENT FOLDER */
+	public static final UploadResponse UR_INVALID_CURRENT_FOLDER = new UploadResponse(
+			UploadResponse.EN_ERROR, null, null,
+			Messages.INVALID_CURRENT_FOLDER);
+
+	/**
+	 * Constructs the response with variable amount of parameters.
+	 * <p>
+	 * Put the desired parameters in the constructor. You may omit them from
+	 * right to left but you have to remain the order.<br/> e.g.
+	 * <code>UploadResponse(EN_OK,"/some/url/to/pic.jpg","pic")</code> or
+	 * <code>UploadResponse(EN_OK)</code> but <b>not</b>
+	 * <code>UploadResponse(EN_OK,"some error message")</code>
+	 * </p>
+	 * <p>
+	 * Use, if possible, the pre-defined error numbers or upload responses.
+	 * </p>
+	 * <p>
+	 * If you need to set error number and message only, use constructor with
+	 * one parameter and call {@link UploadResponse#setCustomMessage(String)}.
+	 * 
+	 * @param arguments
+	 *            possible argument order:
+	 *            <code>int errorNumber, String fileUrl, String filename, String customMessage</code>
+	 * @throws IllegalArgumentException
+	 *             if amount of arguments is less than 1 and above 4
+	 * @throws IllegalArgumentException
+	 *             if the first argument is not an error number (int)
+	 */
+
+	public UploadResponse(Object... arguments) throws IllegalArgumentException {
+		if (arguments.length < 1 || arguments.length > 4)
+			throw new IllegalArgumentException(
+					"The amount of arguments has to be between 1 and 4");
+
+		parameters = new Object[arguments.length];
+
+		if (!(arguments[0] instanceof Integer))
+			throw new IllegalArgumentException(
+					"The first argument has to be an error number (int)");
+
+		System.arraycopy(arguments, 0, parameters, 0, arguments.length);
+	}
+
+	/**
+	 * Sets the message in the UploadResponse.
+	 * 
+	 * Methods automatically determines how many arguments are set and puts the
+	 * message at the end.
+	 * 
+	 * @param customMassage
+	 *            the message you want to pass to the user
+	 */
+	public void setCustomMessage(final String customMassage) {
+		if (Utils.isNotEmpty(customMassage)) {
+			if (parameters.length == 1) {
+				Object errorNumber = parameters[0];
+				parameters = new Object[4];
+				parameters[0] = errorNumber;
+				parameters[1] = null;
+				parameters[2] = null;
+			}
+			parameters[3] = customMassage;
+		}
+	}
+
+	/**
+	 * Assembles the JavaScript method for the user callback
+	 */
+	@Override
+	public String toString() {
+		StringBuffer sb = new StringBuffer(150);
+		sb.append("<script type=\"text/javascript\">\n");
+        // Minified version of the document.domain automatic fix script.
+		// The original script can be found at _dev/domain_fix_template.js
+		sb.append("(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n");
+		sb.append("window.parent.OnUploadCompleted(");
+
+		for (Object parameter : parameters) {
+			if (parameter instanceof Integer) {
+				sb.append(parameter);
+			} else {
+				sb.append("'");
+				if (parameter != null)
+					sb.append(parameter);
+				sb.append("'");
+			}
+			sb.append(",");
+		}
+
+		sb.deleteCharAt(sb.length() - 1);
+		sb.append(");\n");
+		sb.append("</script>");
+
+		return sb.toString();
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/response/XmlResponse.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/response/XmlResponse.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/response/XmlResponse.java	(revision 2015)
@@ -0,0 +1,223 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.response;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.StringWriter;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import net.fckeditor.handlers.CommandHandler;
+import net.fckeditor.handlers.ResourceTypeHandler;
+import net.fckeditor.tool.Utils;
+
+import org.apache.commons.io.filefilter.DirectoryFileFilter;
+import org.apache.commons.io.filefilter.FileFileFilter;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * static error objects won't probably provided due to performance reasons of 
+ * Document instance creation
+ * 
+ * TODO document me!
+ * @author mosipov
+ *
+ */
+public class XmlResponse {
+
+	private Document document;
+	private Element errorElement;
+	private Element foldersElement;
+	private Element filesElement;
+	
+	/** Error number OK */
+	public static final int EN_OK = 0;
+	
+	/** Error number ERROR */
+	public static final int EN_ERROR = 1;
+
+	/** Error number ALREADY EXISTS */
+	public static final int EN_ALREADY_EXISTS = 101;
+
+	/** Error number INVALID FOLDER NAME */
+	public static final int EN_INVALID_FOLDER_NAME = 102;
+
+	/** Error number SECURITY ERROR */
+	public static final int EN_SECURITY_ERROR = 103;
+
+	/** Error number UNKNOWN ERROR */
+	public static final int EN_UKNOWN = 110;
+
+	/**
+	 * 
+	 * @param command
+	 * @param resourceType
+	 * @param currentFolder
+	 * @param constructedUrl
+	 */
+	public XmlResponse(CommandHandler command, ResourceTypeHandler resourceType, 
+			String currentFolder, String constructedUrl) {
+
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory
+					.newInstance();
+			DocumentBuilder builder = factory.newDocumentBuilder();
+			document = builder.newDocument();
+		} catch (ParserConfigurationException e) {
+			throw new RuntimeException(e);
+		}
+
+		Element root = document.createElement("Connector");
+		document.appendChild(root);
+		root.setAttribute("command", command.toString());
+		root.setAttribute("resourceType", resourceType.toString());
+
+		Element currentFolderElement = document.createElement("CurrentFolder");
+		currentFolderElement.setAttribute("path", currentFolder);
+
+		currentFolderElement.setAttribute("url", constructedUrl);
+		root.appendChild(currentFolderElement);
+
+	}
+	
+	/**
+	 * TODO document me!
+	 * @param number
+	 * @param text
+	 */
+	public XmlResponse(int number, String text) {
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory
+					.newInstance();
+			DocumentBuilder builder = factory.newDocumentBuilder();
+			document = builder.newDocument();
+		} catch (ParserConfigurationException e) {
+			throw new RuntimeException(e);
+		}
+
+		Element root = document.createElement("Connector");
+		document.appendChild(root);
+		setError(number, text);
+	}
+	
+	/***
+	 * TODO document me!
+	 * @param number
+	 */
+	public XmlResponse(int number) {
+		this(number, null);
+	}
+
+	public void setError(int number, String text) {
+
+		if (errorElement == null) {
+			errorElement = document.createElement("Error");
+			document.getDocumentElement().appendChild(errorElement);
+		}
+
+		errorElement.setAttribute("number", String.valueOf(number));
+		if (Utils.isNotEmpty(text))
+			errorElement.setAttribute("text", text);
+
+	}
+
+	public void setError(int number) {
+		setError(number, null);
+	}
+
+	public void setFolders(File dir) {
+
+		if (foldersElement != null) {
+			Element parent = (Element) foldersElement.getParentNode();
+			parent.removeChild(foldersElement);
+		}
+
+		foldersElement = document.createElement("Folders");
+		document.getDocumentElement().appendChild(foldersElement);
+
+		String[] fileList = dir.list(DirectoryFileFilter.DIRECTORY);
+		for (String file : fileList) {
+			Element folderElement = document.createElement("Folder");
+			folderElement.setAttribute("name", file);
+			foldersElement.appendChild(folderElement);
+		}
+	}
+	
+	public void setFiles(File dir) {
+		
+		if (filesElement != null) {
+			Element parent = (Element) filesElement.getParentNode();
+			parent.removeChild(filesElement);
+		}
+
+		filesElement = document.createElement("Files");
+		document.getDocumentElement().appendChild(filesElement);
+		
+		File[] fileList = dir.listFiles((FileFilter) FileFileFilter.FILE);
+		long length;
+		for (File file : fileList) {
+			Element fileElement = document.createElement("File");
+			fileElement.setAttribute("name", file.getName());
+			if (file.length() < 1024)
+				length = 1L;
+			else 
+				length = file.length()/1024;
+			fileElement.setAttribute("size", String.valueOf(length));
+			filesElement.appendChild(fileElement);
+		}
+	}
+	
+	public void setFoldersAndFiles(File dir) {
+		setFolders(dir);
+		setFiles(dir);
+	}
+	
+	@Override
+	public String toString() {
+		document.getDocumentElement().normalize();
+		TransformerFactory factory = TransformerFactory.newInstance();
+
+		StringWriter sw = new StringWriter();
+
+		try {
+			Transformer transformer = factory.newTransformer();
+
+			DOMSource source = new DOMSource(document);
+			StreamResult result = new StreamResult(sw);
+
+			transformer.transform(source, result);
+		} catch (TransformerException e) {
+			throw new RuntimeException(e);
+		}
+
+		return sw.toString();
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/CheckTag.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/CheckTag.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/CheckTag.java	(revision 2015)
@@ -0,0 +1,114 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tags;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspTagException;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.tagext.TagSupport;
+
+import net.fckeditor.handlers.PropertiesLoader;
+import net.fckeditor.handlers.RequestCycleHandler;
+import net.fckeditor.tool.Compatibility;
+
+/**
+ * CheckTag.java - TODO DOCUMENTME!
+ *
+ * @version $Id$
+ */
+public class CheckTag extends TagSupport {
+
+	private static final long serialVersionUID = -6834095891675681686L;
+
+	private static final String FILE_UPLOAD = "FileUpload";
+	private static final String FILE_BROWSING = "FileBrowsing";
+	private static final String COMPATIBLE_BROWSER = "CompatibleBrowser";
+	private static final String PROPERTY_MESSAGE_FILE_BROWSING_DISABLED = "message.enabled_tag.connector.file_browsing.disabled";
+	private static final String PROPERTY_MESSAGE_FILE_BROWSING_ENABLED = "message.enabled_tag.connector.file_browsing.enabled";
+	private static final String PROPERTY_MESSAGE_FILE_UPLOAD_DISABLED = "message.enabled_tag.connector.file_upload.disalbed";
+	private static final String PROPERTY_MESSAGE_FILE_UPLOAD_ENABLED = "message.enabled_tag.connector.file_upload.enabled";
+	private static final String PROPERTY_MESSAGE_NOT_COMPATIBLE_BROWSER = "message.enabled_tag.compatible_browser.no";
+	private static final String PROPERTY_MESSAGE_COMPATIBLE_BROWSER = "message.enabled_tag.compatible_browser.yes";
+	private static Set<String> commands = new HashSet<String>(3);
+
+	static {
+		commands.add(FILE_UPLOAD);
+		commands.add(FILE_BROWSING);
+		commands.add(COMPATIBLE_BROWSER);
+	}
+
+	private String command;
+
+	public void setCommand(String command) throws JspTagException {
+		if (!commands.contains(command))
+			throw new JspTagException("You have to provide one of the following commands: "
+			        + commands);
+		this.command = command;
+	}
+
+	@Override
+	public int doStartTag() throws JspException {
+		JspWriter out = pageContext.getOut();
+
+		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
+		String response = new String();
+
+		if (command.equals(FILE_UPLOAD)) {
+			if (RequestCycleHandler.isEnabledForFileUpload(request))
+				response = PropertiesLoader
+				        .getProperty(CheckTag.PROPERTY_MESSAGE_FILE_UPLOAD_ENABLED);
+			else
+				response = PropertiesLoader
+				        .getProperty(CheckTag.PROPERTY_MESSAGE_FILE_UPLOAD_DISABLED);
+		}
+
+		if (command.equals(FILE_BROWSING)) {
+			if (RequestCycleHandler.isEnabledForFileBrowsing(request))
+				response = PropertiesLoader
+				        .getProperty(CheckTag.PROPERTY_MESSAGE_FILE_BROWSING_ENABLED);
+			else
+				response = PropertiesLoader
+				        .getProperty(CheckTag.PROPERTY_MESSAGE_FILE_BROWSING_DISABLED);
+		}
+		if (command.equals(COMPATIBLE_BROWSER)) {
+			if (Compatibility.isCompatibleBrowser(request))
+				response = PropertiesLoader
+				        .getProperty(CheckTag.PROPERTY_MESSAGE_COMPATIBLE_BROWSER);
+			else
+				response = PropertiesLoader
+				        .getProperty(CheckTag.PROPERTY_MESSAGE_NOT_COMPATIBLE_BROWSER);
+		}
+
+		try {
+			out.print(response);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		return SKIP_BODY;
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/ConfigTag.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/ConfigTag.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/ConfigTag.java	(revision 2015)
@@ -0,0 +1,61 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tags;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.DynamicAttributes;
+import javax.servlet.jsp.tagext.Tag;
+import javax.servlet.jsp.tagext.TagSupport;
+
+/**
+ * ConfigTag.java - TODO DOCUMENTME!
+ *
+ * @version $Id$
+ */
+public class ConfigTag extends TagSupport implements DynamicAttributes {
+
+	private Map<String, String> params = new HashMap<String, String>();
+	
+	private static final long serialVersionUID = -5282810094404700422L;
+
+	@Override
+	public int doStartTag() throws JspException {
+
+		Tag ancestor = findAncestorWithClass(this, EditorTag.class);
+		if (ancestor == null)
+			throw new JspException(
+					"the config tag can only be nested within an editor tag");
+		EditorTag editorTag = (EditorTag) ancestor;
+		editorTag.setConfigParamAll(params);
+		
+		return SKIP_BODY;
+	}
+
+	public void setDynamicAttribute(String arg0, String arg1, Object arg2)
+			throws JspException {
+		if (arg2 != null)
+			params.put(arg1, arg2.toString());
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/EditorTag.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/EditorTag.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tags/EditorTag.java	(revision 2015)
@@ -0,0 +1,180 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+
+package net.fckeditor.tags;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.tagext.TagSupport;
+
+import net.fckeditor.FCKeditor;
+
+/**
+ * TODO check, if usage sample in comment is correct !!! (Advanced usage) <br><br>
+ * 
+ * FCKeditor Tag class to access the
+ * {@linkplain net.fckeditor.FCKeditor container}.<br>
+ * <p>
+ * <b>Simple usage</b>:
+ * 
+ * <pre>
+ * &lt;FCK:editor
+ * 	instanceName=&quot;EditorAccessibility&quot;
+ * 	width=&quot;80%&quot;
+ * 	height=&quot;120&quot;
+ * 	toolbarSet=&quot;Accessibility&quot;
+ * &quot;&gt;This is another test. &lt;BR&gt;&lt;BR&gt;The &quot;Second&quot; row.&lt;/BR&gt;&lt;/FCK:editor&quot;&gt;
+ * </pre>
+ * 
+ * <p>
+ * In this example we set all the attribute for the fckedit tag.
+ * 
+ * <p>
+ * <b>Advanced usage of the tag</b>:
+ * 
+ * <pre>
+ * &lt;FCK:editor instanceName=&quot;EditorDefault&quot; basePath=&quot;/fckeditor/&quot;
+ * 	styleNames=&quot;;Style 1;Style 2; Style 3&quot; 
+ * 	fontNames=&quot;;Arial;Courier New;Times New Roman;Verdana&quot; &gt;
+ * 	This is some &lt;B&gt;sample text&lt;/B&gt;.
+ * &lt;/FCK:editor&gt;
+ * </pre>
+ * 
+ * In this example we set the id and the basePath of the editor (since it is
+ * /fckeditor/ we could have omitted it because it's already the default value).<br>
+ * Then we used the the optional attributes to set some advanced configuration
+ * settings.
+ * 
+ * @version $Id$
+ */
+public class EditorTag extends TagSupport {
+
+	private static final long serialVersionUID = -173091731589866140L;
+
+	private String instanceName;
+	private String width;
+	private String height;
+	private String toolbarSet;
+	private String value;
+	private String basePath;
+
+	/** The underlying FCKeditor object */
+	private FCKeditor fckEditor;
+
+	/**
+	 * Sets the name for the given editor instance
+	 * 
+	 * @param instanceName
+	 *            some name without whitespaces
+	 */
+	public void setInstanceName(String instanceName) {
+		this.instanceName = instanceName;
+	}
+
+	/**
+	 * Sets the width of the textarea
+	 * 
+	 * @param width
+	 *            width of the editor instance
+	 * 
+	 */
+	public void setWidth(String width) {
+		this.width = width;
+	}
+
+	/**
+	 * Sets the height of the textarea
+	 * 
+	 * @param height
+	 *            height of the editor instance
+	 */
+	public void setHeight(String height) {
+		this.height = height;
+	}
+
+	/**
+	 * Sets the name of the toolbar to display
+	 * 
+	 * @param toolbarSet
+	 *            toolbar set of the editor instance
+	 */
+	public void setToolbarSet(String toolbarSet) {
+		this.toolbarSet = toolbarSet;
+	}
+
+	/**
+	 * Sets the editor document content
+	 * 
+	 * @param value
+	 *            any HTML string
+	 */
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	/**
+	 * Sets the dir where the FCKeditor files reside on the server
+	 * 
+	 * @param basePath
+	 *            basePath of the editor instance (e.g. /fckeditor)
+	 */
+	public void setBasePath(String basePath) {
+		this.basePath = basePath;
+	}
+
+	void setConfigParamAll(Map<String, String> map) {
+		fckEditor.getConfig().putAll(map);
+	}
+
+	/**
+	 * Initializes the FCKeditor container and Sets attributes
+	 * 
+	 * @return EVAL_BODY_INCLUDE
+	 */
+	public int doStartTag() throws JspException {
+		fckEditor = new FCKeditor(
+				(HttpServletRequest) pageContext.getRequest(), instanceName,
+				width, height, toolbarSet, value, basePath);
+		fckEditor.setValue(value);
+
+		return EVAL_BODY_INCLUDE;
+	}
+
+	@Override
+	public int doEndTag() throws JspException {
+
+		JspWriter out = pageContext.getOut();
+
+		try {
+			out.println(fckEditor);
+		} catch (IOException ioe) {
+			throw new JspException(
+					"Error: IOException while writing to the user");
+		}
+
+		return EVAL_PAGE;
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/Compatibility.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/Compatibility.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/Compatibility.java	(revision 2015)
@@ -0,0 +1,107 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Compatibility check.
+ * 
+ * @version $Id$
+ */
+public class Compatibility {
+
+	/**
+	 * Checks, if a browser's user agent string is compatible for the FCKeditor. <br>
+	 * Adapted from: http://dev.fckeditor.net/browser/FCKeditor/releases/stable/fckeditor.php
+	 * 
+	 * @param userAgentString
+	 * @return true, if compatible, otherwise false
+	 */
+	public static boolean check(final String userAgentString) {
+		if (Utils.isEmpty(userAgentString))
+			return false;
+
+		float version;
+
+		// IE 5.5+, check special keys like 'Opera' and 'mac', because there are some
+		// other browsers, containing 'MSIE' in there agent string!
+		if (userAgentString.indexOf("Opera") < 0 && userAgentString.indexOf("mac") < 0) {
+			version = getBrowserVersion(userAgentString, ".*MSIE ([\\d]+.[\\d]+).*");
+			if (version != -1f && version >= 5.5f)
+				return true;
+		}
+
+		// for mozilla only, because all firefox versions are supported
+		version = getBrowserVersion(userAgentString, ".*Gecko/([\\d]+).*");
+		if (version != -1f && version >= 20030210f)
+			return true;
+
+		// Opera 9.5+
+		version = getBrowserVersion(userAgentString, "Opera/([\\d]+.[\\d]+).*");
+		if (version != -1f && version >= 9.5f)
+			return true;
+		version = getBrowserVersion(userAgentString, ".*Opera ([\\d]+.[\\d]+)");
+		if (version != -1f && version >= 9.5f)
+			return true;
+
+		// Safari 3+
+		version = getBrowserVersion(userAgentString, ".*AppleWebKit/([\\d]+).*");
+		if (version != -1f && version >= 522f)
+			return true;
+
+		return false;
+	}
+
+	/**
+	 * Just a wrapper to {@link #check(String)}.
+	 * 
+	 * @param request
+	 */
+	public static boolean isCompatibleBrowser(final HttpServletRequest request) {
+		return (request == null) ? false : check(request.getHeader("user-agent"));
+	}
+
+	/**
+	 * Helper method to get the the browser version from 'userAgent' with the regular expression
+	 * 'regex'. The first group of the matches has to be the version number!
+	 * 
+	 * @param userAgent
+	 * @param regex
+	 * @return The browser version, or -1f, if version con't find out.
+	 */
+	private static float getBrowserVersion(final String userAgent, final String regex) {
+		Pattern pattern = Pattern.compile(regex);
+		Matcher matcher = pattern.matcher(userAgent);
+		if (matcher.matches()) {
+			try {
+				return Float.parseFloat(matcher.group(1));
+			} catch (NumberFormatException e) {
+				return -1f;
+			}
+		}
+		return -1f;
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/Utils.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/Utils.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/Utils.java	(revision 2015)
@@ -0,0 +1,129 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+
+
+
+/**
+ * Some static helper methods.
+ * 
+ * @version $Id$
+ */
+public class Utils {
+
+	/**
+	 * Constructs a set of uppercased strings from a 'delimiter' separated
+	 * string.
+	 * 
+	 * @param stringList
+	 * @param delimiter
+	 *            The delimiter. It shouldn't be empty!
+	 * @return An emtpy list, if 'stringList' is empty, or an lowercased set of
+	 *         strings.
+	 * @throws IllegalArgumentException
+	 *             if 'delimiter' is empty.
+	 */
+	public static Set<String> getSet(final String stringList,
+			final String delimiter) {
+		if (isEmpty(delimiter))
+			throw new IllegalArgumentException(
+					"Argument 'delimiter' shouldn't be empty!");
+		if (isEmpty(stringList))
+			return new HashSet<String>();
+
+		Set<String> set = new HashSet<String>();
+		StringTokenizer st = new StringTokenizer(stringList, delimiter);
+		while (st.hasMoreTokens()) {
+			String tmp = st.nextToken();
+			if (isNotEmpty(tmp)) // simple empty filter
+				set.add(tmp.toLowerCase());
+		}
+		return set;
+	}
+
+	/**
+	 * Just a wrapper to {@link #getSet(String, String)} for using '&#124;' as
+	 * delimiter.
+	 */
+	public static Set<String> getSet(final String stringlist) {
+		return getSet(stringlist, "|");
+	}
+
+	/**
+	 * Checks if a string is null or empty.
+	 * 
+	 * @param str
+	 *            to check
+	 * @return <code>true</code> if the String is empty or null
+	 */
+	public static boolean isEmpty(final String str) {
+		return str == null || str.length() == 0;
+	}
+
+	/**
+	 * Just a wrapper to {@link #isEmpty(String)}.
+	 * 
+	 * @param str
+	 * @return <code>true</code> if the String is not empty and not null.
+	 */
+	public static boolean isNotEmpty(final String str) {
+		return !isEmpty(str);
+	}
+
+	/**
+	 * Replaces all 'search' with 'replacement' in 'string'.<br>
+	 * Usage:
+	 * 
+	 * <pre>
+	 * Utils.replaceAll(null, *, *)		= &quot;&quot;
+	 * Utils.replaceAll(&quot;&quot;, *, *)		= &quot;&quot;
+	 * Utils.replaceAll(&quot;foo&quot;, null, *)	= &quot;foo&quot;
+	 * Utils.replaceAll(&quot;foo&quot;, &quot;o&quot;, &quot;a&quot;)	= &quot;faa&quot;
+	 * </pre>
+	 * 
+	 * @param string
+	 * @param search
+	 * @param replacement
+	 * @return replaced String
+	 */
+	public static String replaceAll(final String string, final String search,
+			final String replacement) {
+		if (isEmpty(string))
+			return "";
+		if (isEmpty(search))
+			return string;
+		if (string.indexOf(search) == -1)
+			return string;
+		StringBuffer sb = new StringBuffer(string);
+		int pos = sb.indexOf(search);
+
+		while (pos != -1) {
+			sb.replace(pos, pos + search.length(), replacement);
+			pos = sb.indexOf(search);
+		}
+		return sb.toString();
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/UtilsFile.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/UtilsFile.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/UtilsFile.java	(revision 2015)
@@ -0,0 +1,144 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import java.io.File;
+import java.io.InputStream;
+
+import org.apache.commons.io.FilenameUtils;
+import org.devlib.schmidt.imageinfo.ImageInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.fckeditor.handlers.ConnectorHandler;
+
+/**
+ * Some static helper methods in conjunction with files.
+ *
+ * @version $Id$
+ */
+public class UtilsFile {
+	
+	private static final Logger logger = LoggerFactory.getLogger(UtilsFile.class);
+
+	/**
+     * Do a cleanup of the file name to avoid possible problems. <br>
+     * The force single Extension property will be respected!
+     * 
+     * @param fileName
+     * @return folder name where \ / | : ? * &quot; &lt; &gt; 'control chars' replaced by '_'
+     */
+    public static String sanitizeFileName(final String fileName) {
+    	if (fileName == null)
+    		return null;
+    	if (fileName.equals(""))
+    		return "";
+    
+    	String name = (ConnectorHandler.isForceSingleExtension()) ? UtilsFile.forceSingleExtension(fileName)
+    	        : fileName;
+    
+    	// Remove \ / | : ? * " < > with _
+    	return name.replaceAll("\\/|\\/|\\||:|\\?|\\*|\"|<|>|\\p{Cntrl}", "_");
+    }
+
+	/**
+     * Do a cleanup of the folder name to avoid possible problems.
+     * 
+     * @param folderName
+     * @return folder name where . \ / | : ? * &quot; &lt; &gt; 'control chars' replaced by '_'
+     */
+    public static String sanitizeFolderName(final String folderName) {
+    	if (folderName == null)
+    		return null;
+    	if (folderName.equals(""))
+    		return "";
+    
+    	// Remove . \ / | : ? * " < > with _
+    	return folderName.replaceAll("\\.|\\/|\\/|\\||:|\\?|\\*|\"|<|>|\\p{Cntrl}", "_");
+    }
+
+	/**
+	 * Checks if the underlying file of the InputStrem is an image.
+	 * 
+	 * @param in
+	 * @return <code>True</code>, if the underlying file is an image, or <code>false</code>.
+	 */
+	public static boolean isImage(final InputStream in) {
+    	ImageInfo ii = new ImageInfo();
+    	ii.setInput(in);
+    	return ii.check();
+    }
+
+	/**
+     * TODO - document me!
+     * 
+     * @param path
+     * @return <code>true</code> if path corresponds to rules or
+     *         <code>false</code>.
+     */
+    public static boolean isValidPath(final String path) {
+    	if (Utils.isEmpty(path))
+    		return false;
+    	if (!path.startsWith("/"))
+    		return false;
+    	if (!path.endsWith("/"))
+    		return false;
+    	
+    	if (!path.equals(FilenameUtils.separatorsToUnix(FilenameUtils
+    			.normalize(path))))
+    		return false;
+    	
+    	return true;
+    }
+
+	/**
+     * TODO - document me!
+     * 
+     * @param filename
+     * @return string with a single dot only
+     */
+    public static String forceSingleExtension(final String filename) {
+    	return filename.replaceAll("\\.(?![^.]+$)", "_");
+    }
+
+	/**
+     * TODO - document me!
+     * 
+     * @param filename
+     * @return <code>true</code> if filename contains severals dots else
+     *         <code>false</code>
+     */
+    public static boolean isSingleExtension(final String filename) {
+    	return filename.matches("[^\\.]+\\.[^\\.]+");
+    }
+    
+    /**
+	 * TODO - document me!
+	 * @param dir
+	 */
+	public static void checkDirAndCreate(File dir) {
+		if (!dir.exists()) {
+			dir.mkdirs();
+			logger.debug("Dir '{}' successfully created", dir);
+		}
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/UtilsResponse.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/UtilsResponse.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/UtilsResponse.java	(revision 2015)
@@ -0,0 +1,85 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import javax.servlet.http.HttpServletRequest;
+
+import net.fckeditor.handlers.ConnectorHandler;
+import net.fckeditor.handlers.ResourceTypeHandler;
+
+/**
+ * Some static helper methods in conjunction with the servlet response.
+ *
+ * @version $Id$
+ */
+public class UtilsResponse {
+
+	/**
+	 * TODO - document me!
+     * 
+     * @param request
+     * @param resourceType
+     * @param urlPath TODO
+     * @param prependContextPath
+     * @param fullUrl
+     * @return constructed url
+     */
+    public static String constructResponseUrl(HttpServletRequest request,
+    		ResourceTypeHandler resourceType, String urlPath,
+    		boolean prependContextPath, boolean fullUrl) {
+    		
+    	StringBuffer sb = new StringBuffer();
+    	
+    	if (fullUrl) {
+    		String address = request.getRequestURL().toString();
+    		sb.append(address.substring(0, address.indexOf('/', 8))
+    				+ request.getContextPath());
+    	}
+    	
+    	if (prependContextPath && !fullUrl)
+    		sb.append(request.getContextPath());
+    	
+    	sb.append(ConnectorHandler.getUserFilesPath(request));
+    	sb.append(resourceType.getPath());
+    	
+    	if (Utils.isNotEmpty(urlPath))
+    		sb.append(urlPath);
+    	
+    	return sb.toString();
+    }
+
+	/**
+	 * TODO - document me!
+	 * 
+	 * @param request
+	 * @param resourceType
+	 * @param prependContextPath
+	 * @param fullUrl
+	 * @return constructed url
+	 */
+	public static String constructResponseUrl(HttpServletRequest request,
+    		ResourceTypeHandler resourceType, boolean prependContextPath, 
+    		boolean fullUrl) {
+    	return constructResponseUrl(request, resourceType, null, 
+    			prependContextPath, fullUrl);
+    }
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/XHtmlTagTool.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/XHtmlTagTool.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/net/fckeditor/tool/XHtmlTagTool.java	(revision 2015)
@@ -0,0 +1,135 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tool to construct a XHTML-tag.<br>
+ * <br>
+ * Usage:
+ * <pre>
+ * XHtmlTagTool tag = XHtmlTagTool(&quot;a&quot;, &quot;link&quot;);
+ * tag.addAttribute(&quot;href&quot;, &quot;http://google.com&quot;);
+ * tag.toString();	: &lt;a href=&quot;http://google.com&quot;&gt;link&lt;/a&gt;
+ * </pre>
+ * 
+ * Hint:
+ * <ul>
+ * <li>Attributes are not ordered.</li>
+ * <li>If your tag shouldn't have a value but the tag has to close with '&lt;/[tagname]&gt;', set
+ * the value to {@link XHtmlTagTool#SPACE}.</li>
+ * </ul>
+ * 
+ * @version $Id$
+ */
+public class XHtmlTagTool {
+
+	/** Name of the tag. */
+	private String name;
+
+	/** Container for the attributes. */
+	private Map<String, String> attributes = new HashMap<String, String>();
+
+	/** Value of the tag. */
+	private String value = null;
+	
+	/** Indicator to uses non self-closing tag. */
+	public static final String SPACE = " ";
+
+	public XHtmlTagTool(final String name, final String value) throws IllegalArgumentException {
+		if (Utils.isEmpty(name))
+			throw new IllegalArgumentException("Parameter 'name' shouldn't be empty!");
+		this.name = name;
+		this.value = value;
+	}
+
+	public XHtmlTagTool(final String name) {
+		this(name, null);
+	}
+
+	/**
+	 * Setter for the value of the tag.
+	 * 
+	 * @param value
+	 */
+	public void setValue(final String value) {
+		this.value = value;
+	}
+
+	/**
+	 * Adds an attribute to the tag.
+	 * 
+	 * @param key
+	 * @param value
+	 * @throws IllegalArgumentException if 'key' is empty.
+	 */
+	public void addAttribute(final String key, final String value) {
+		if (Utils.isEmpty(key))
+			throw new IllegalArgumentException("Parameter 'key' shouldn't be empty!");
+		attributes.put(key, value);
+	}
+
+	/**
+	 * Constructs the tag.
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		StringBuffer tag = new StringBuffer();
+
+		// open tag
+		tag.append("<").append(name);
+
+		// add attributes
+		for (String key : attributes.keySet()) {
+			String val = attributes.get(key);
+			tag.append(' ').append(key).append('=').append('\"').append(val).append('\"');
+		}
+
+		// close the tag
+		if (Utils.isNotEmpty(value)) {
+			tag.append(">").append(value).append("</").append(name).append('>');
+		} else
+			tag.append(" />");
+
+		return tag.toString();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		try {
+			XHtmlTagTool tag = (XHtmlTagTool) obj;
+			return value.equals(tag.value) && name.equals(tag.name)
+					&& attributes.equals(tag.attributes);
+		} catch (ClassCastException e) {
+			return false;
+		}
+	}
+	
+	@Override
+	public int hashCode() {
+		
+		return name.hashCode() + value.hashCode() + attributes.hashCode();
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/org/devlib/schmidt/imageinfo/ImageInfo.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/org/devlib/schmidt/imageinfo/ImageInfo.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/java/org/devlib/schmidt/imageinfo/ImageInfo.java	(revision 2015)
@@ -0,0 +1,1232 @@
+/*
+ * ImageInfo.java
+ *
+ * Version 1.9
+ *
+ * A Java class to determine image width, height and color depth for
+ * a number of image file formats.
+ *
+ * Written by Marco Schmidt 
+ *
+ * Contributed to the Public Domain.
+ */
+package org.devlib.schmidt.imageinfo;
+
+import java.io.DataInput;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Vector;
+
+/**
+ * Get file format, image resolution, number of bits per pixel and optionally 
+ * number of images, comments and physical resolution from 
+ * JPEG, GIF, BMP, PCX, PNG, IFF, RAS, PBM, PGM, PPM and PSD files 
+ * (or input streams).
+ * <p>
+ * Use the class like this:
+ * <pre>
+ * ImageInfo ii = new ImageInfo();
+ * ii.setInput(in); // in can be InputStream or RandomAccessFile
+ * ii.setDetermineImageNumber(true); // default is false
+ * ii.setCollectComments(true); // default is false
+ * if (!ii.check()) {
+ *   System.err.println("Not a supported image file format.");
+ *   return;
+ * }
+ * System.out.println(ii.getFormatName() + ", " + ii.getMimeType() + 
+ *   ", " + ii.getWidth() + " x " + ii.getHeight() + " pixels, " + 
+ *   ii.getBitsPerPixel() + " bits per pixel, " + ii.getNumberOfImages() +
+ *   " image(s), " + ii.getNumberOfComments() + " comment(s).");
+ *  // there are other properties, check out the API documentation
+ * </pre>
+ * You can also use this class as a command line program.
+ * Call it with a number of image file names and URLs as parameters:
+ * <pre>
+ *   java ImageInfo *.jpg *.png *.gif http://somesite.tld/image.jpg
+ * </pre>
+ * or call it without parameters and pipe data to it:
+ * <pre>
+ *   java ImageInfo &lt; image.jpg  
+ * </pre>
+ * <p>
+ * Known limitations:
+ * <ul>
+ * <li>When the determination of the number of images is turned off, GIF bits 
+ *  per pixel are only read from the global header.
+ *  For some GIFs, local palettes change this to a typically larger
+ *  value. To be certain to get the correct color depth, call
+ *  setDetermineImageNumber(true) before calling check().
+ *  The complete scan over the GIF file will take additional time.</li>
+ * <li>Transparency information is not included in the bits per pixel count.
+ *  Actually, it was my decision not to include those bits, so it's a feature! ;-)</li>
+ * </ul>
+ * <p>
+ * Requirements:
+ * <ul>
+ * <li>Java 1.1 or higher</li>
+ * </ul>
+ * <p>
+ * The latest version can be found at <a href="http://schmidt.devlib.org/image-info/">http://schmidt.devlib.org/image-info/</a>.
+ * <p>
+ * Written by Marco Schmidt.
+ * <p>
+ * This class is contributed to the Public Domain.
+ * Use it at your own risk.
+ * <p>
+ * <a name="history">History</a>:
+ * <ul>
+ * <li><strong>2001-08-24</strong> Initial version.</li>
+ * <li><strong>2001-10-13</strong> Added support for the file formats BMP and PCX.</li>
+ * <li><strong>2001-10-16</strong> Fixed bug in read(int[], int, int) that returned
+ * <li><strong>2002-01-22</strong> Added support for file formats Amiga IFF and Sun Raster (RAS).</li>
+ * <li><strong>2002-01-24</strong> Added support for file formats Portable Bitmap / Graymap / Pixmap (PBM, PGM, PPM) and Adobe Photoshop (PSD).
+ *   Added new method getMimeType() to return the MIME type associated with a particular file format.</li>
+ * <li><strong>2002-03-15</strong> Added support to recognize number of images in file. Only works with GIF.
+ *   Use {@link #setDetermineImageNumber} with <code>true</code> as argument to identify animated GIFs
+ *   ({@link #getNumberOfImages()} will return a value larger than <code>1</code>).</li>
+ * <li><strong>2002-04-10</strong> Fixed a bug in the feature 'determine number of images in animated GIF' introduced with version 1.1.
+ *   Thanks to Marcelo P. Lima for sending in the bug report. 
+ *   Released as 1.1.1.</li>
+ * <li><strong>2002-04-18</strong> Added {@link #setCollectComments(boolean)}. 
+ *  That new method lets the user specify whether textual comments are to be  
+ *  stored in an internal list when encountered in an input image file / stream.
+ *  Added two methods to return the physical width and height of the image in dpi: 
+ *   {@link #getPhysicalWidthDpi()} and {@link #getPhysicalHeightDpi()}.
+ *  If the physical resolution could not be retrieved, these methods return <code>-1</code>.
+ *  </li>
+ * <li><strong>2002-04-23</strong> Added support for the new properties physical resolution and
+ *   comments for some formats. Released as 1.2.</li>
+ * <li><strong>2002-06-17</strong> Added support for SWF, sent in by Michael Aird.
+ *  Changed checkJpeg() so that other APP markers than APP0 will not lead to a failure anymore.
+ *  Released as 1.3.</li>
+ * <li><strong>2003-07-28</strong> Bug fix - skip method now takes return values into consideration.
+ *  Less bytes than necessary may have been skipped, leading to flaws in the retrieved information in some cases.
+ *  Thanks to Bernard Bernstein for pointing that out.
+ *  Released as 1.4.</li>
+ * <li><strong>2004-02-29</strong> Added support for recognizing progressive JPEG and
+ *  interlaced PNG and GIF. A new method {@link #isProgressive()} returns whether ImageInfo
+ *  has found that the storage type is progressive (or interlaced). 
+ *  Thanks to Joe Germuska for suggesting the feature.
+ *  Bug fix: BMP physical resolution is now correctly determined.
+ *  Released as 1.5.</li>
+ * <li><strong>2004-11-30</strong> Bug fix: recognizing progressive GIFs 
+ * (interlaced in GIF terminology) did not work (thanks to Franz Jeitler for 
+ *   pointing this out). Now it should work, but only if the number of images is determined.
+ *  This is because information on interlacing is stored in a local image header.
+ *  In theory, different images could be stored interlaced and non-interlaced in one 
+ *  file. However, I think  that's unlikely. Right now, the last image in the GIF file 
+ *  that is examined by ImageInfo is used for the "progressive" status.</li>
+ * <li><strong>2005-01-02</strong> Some code clean up (unused methods and variables
+ *  commented out, missing javadoc comments, etc.). Thanks to George Sexton for a long list.
+ *  Removed usage of Boolean.toString because
+ *  it's a Java 1.4+ feature (thanks to Gregor Dupont).
+ *  Changed delimiter character in compact output from semicolon to tabulator
+ * (for better integration with cut(1) and other Unix tools).
+ *  Added some points to the <a href="http://schmidt.devlib.org/image-info/index.html#knownissues">'Known
+ *  issues' section of the website</a>. 
+ *  Released as 1.6.</li>
+ * <li><strong>2005-07-26</strong> Removed code to identify Flash (SWF) files.
+ *  Has repeatedly led to problems and support requests, and I don't know the
+ *  format and don't have the time and interest to fix it myself.
+ *  I repeatedly included fixes by others which didn't work for some people.
+ *  I give up on SWF. Please do not contact me about it anymore.
+ *  Set package of ImageInfo class to org.devlib.schmidt.imageinfo (a package
+ *  was repeatedly requested by some users).
+ *  Released as 1.7.</li>
+ *  <li><strong>2006-02-23</strong> Removed Flash helper methods which weren't used elsewhere.
+ *   Updated skip method which tries "read" whenever "skip(Bytes)" returns a result of 0.
+ *   The old method didn't work with certain input stream types on truncated data streams.
+ *   Thanks to Martin Leidig for reporting this and sending in code.
+ *   Released as 1.8.</li>
+ *  </li>
+ *  <li><strong>2006-11-13</strong> Removed check that made ImageInfo report JPEG APPx
+ *   markers smaller than 14 bytes as files in unknown format. Such JPEGs seem to be
+ *   generated by Google's Picasa application. First reported with fix by 
+ *   Karl von Randow. Released as 1.9.</li>  
+ * </ul>
+ * @author Marco Schmidt
+ */
+@SuppressWarnings("unchecked")
+public class ImageInfo {
+	/**
+	 * Return value of {@link #getFormat()} for JPEG streams.
+	 * ImageInfo can extract physical resolution and comments
+	 * from JPEGs (only from APP0 headers).
+	 * Only one image can be stored in a file.
+	 * It is determined whether the JPEG stream is progressive 
+	 * (see {@link #isProgressive()}).
+	 */
+	public static final int FORMAT_JPEG = 0;
+
+	/**
+	 * Return value of {@link #getFormat()} for GIF streams.
+	 * ImageInfo can extract comments from GIFs and count the number
+	 * of images (GIFs with more than one image are animations).
+	 * It is determined whether the GIF stream is interlaced (see {@link #isProgressive()}).
+	 */
+	public static final int FORMAT_GIF = 1;
+
+	/**
+	 * Return value of {@link #getFormat()} for PNG streams.
+	 * PNG only supports one image per file.
+	 * Both physical resolution and comments can be stored with PNG,
+	 * but ImageInfo is currently not able to extract those.
+	 * It is determined whether the PNG stream is interlaced (see {@link #isProgressive()}).
+	 */
+	public static final int FORMAT_PNG = 2;
+
+	/**
+	 * Return value of {@link #getFormat()} for BMP streams.
+	 * BMP only supports one image per file.
+	 * BMP does not allow for comments.
+	 * The physical resolution can be stored.
+	 */
+	public static final int FORMAT_BMP = 3;
+
+	/**
+	 * Return value of {@link #getFormat()} for PCX streams.
+	 * PCX does not allow for comments or more than one image per file.
+	 * However, the physical resolution can be stored.
+	 */
+	public static final int FORMAT_PCX = 4;
+
+	/**
+	 * Return value of {@link #getFormat()} for IFF streams.
+	 */
+	public static final int FORMAT_IFF = 5;
+
+	/**
+	 * Return value of {@link #getFormat()} for RAS streams.
+	 * Sun Raster allows for one image per file only and is not able to
+	 * store physical resolution or comments.
+	 */
+	public static final int FORMAT_RAS = 6;
+
+	/** Return value of {@link #getFormat()} for PBM streams. */
+	public static final int FORMAT_PBM = 7;
+
+	/** Return value of {@link #getFormat()} for PGM streams. */
+	public static final int FORMAT_PGM = 8;
+
+	/** Return value of {@link #getFormat()} for PPM streams. */
+	public static final int FORMAT_PPM = 9;
+
+	/** Return value of {@link #getFormat()} for PSD streams. */
+	public static final int FORMAT_PSD = 10;
+
+/*	public static final int COLOR_TYPE_UNKNOWN = -1;
+	public static final int COLOR_TYPE_TRUECOLOR_RGB = 0;
+	public static final int COLOR_TYPE_PALETTED = 1;
+	public static final int COLOR_TYPE_GRAYSCALE= 2;
+	public static final int COLOR_TYPE_BLACK_AND_WHITE = 3;*/
+
+	/**
+	 * The names of all supported file formats.
+	 * The FORMAT_xyz int constants can be used as index values for
+	 * this array.
+	 */
+	private static final String[] FORMAT_NAMES =
+		{"JPEG", "GIF", "PNG", "BMP", "PCX", 
+		 "IFF", "RAS", "PBM", "PGM", "PPM", 
+		 "PSD"};
+
+	/**
+	 * The names of the MIME types for all supported file formats.
+	 * The FORMAT_xyz int constants can be used as index values for
+	 * this array.
+	 */
+	private static final String[] MIME_TYPE_STRINGS =
+		{"image/jpeg", "image/gif", "image/png", "image/bmp", "image/pcx", 
+		 "image/iff", "image/ras", "image/x-portable-bitmap", "image/x-portable-graymap", "image/x-portable-pixmap", 
+		 "image/psd"};
+
+	private int width;
+	private int height;
+	private int bitsPerPixel;
+	//private int colorType = COLOR_TYPE_UNKNOWN;
+	private boolean progressive;
+	private int format;
+	private InputStream in;
+	private DataInput din;
+	private boolean collectComments = true;
+	private Vector comments;
+	private boolean determineNumberOfImages;
+	private int numberOfImages;
+	private int physicalHeightDpi;
+	private int physicalWidthDpi;
+
+	private void addComment(String s) {
+		if (comments == null) {
+			comments = new Vector();
+		}
+		comments.addElement(s);
+	}
+
+	/**
+	 * Call this method after you have provided an input stream or file
+	 * using {@link #setInput(InputStream)} or {@link #setInput(DataInput)}.
+	 * If true is returned, the file format was known and information
+	 * on the file's content can be retrieved using the various getXyz methods.
+	 * @return if information could be retrieved from input
+	 */
+	public boolean check() {
+		format = -1;
+		width = -1;
+		height = -1;
+		bitsPerPixel = -1;
+		numberOfImages = 1;
+		physicalHeightDpi = -1;
+		physicalWidthDpi = -1;
+		comments = null;
+		try {
+			int b1 = read() & 0xff;
+			int b2 = read() & 0xff;
+			if (b1 == 0x47 && b2 == 0x49) {
+				return checkGif();
+			}
+			else
+			if (b1 == 0x89 && b2 == 0x50) {
+				return checkPng();
+			}
+			else
+			if (b1 == 0xff && b2 == 0xd8) {
+				return checkJpeg();
+			}
+			else
+			if (b1 == 0x42 && b2 == 0x4d) {
+				return checkBmp();
+			}
+			else
+			if (b1 == 0x0a && b2 < 0x06) {
+				return checkPcx();
+			}
+			else
+			if (b1 == 0x46 && b2 == 0x4f) {
+				return checkIff();
+			}
+			else
+			if (b1 == 0x59 && b2 == 0xa6) {
+				return checkRas();
+			}
+			else
+			if (b1 == 0x50 && b2 >= 0x31 && b2 <= 0x36) {
+				return checkPnm(b2 - '0');
+			}
+			else
+			if (b1 == 0x38 && b2 == 0x42) {
+				return checkPsd();
+			}
+			else {
+				return false;
+			}
+		} catch (IOException ioe) {
+			return false;
+		}
+	}
+
+	private boolean checkBmp() throws IOException {
+		byte[] a = new byte[44];
+		if (read(a) != a.length) {
+			return false;
+		}
+		width = getIntLittleEndian(a, 16);
+		height = getIntLittleEndian(a, 20);
+		if (width < 1 || height < 1) {
+			return false;
+		}
+		bitsPerPixel = getShortLittleEndian(a, 26);
+		if (bitsPerPixel != 1 && bitsPerPixel != 4 &&
+		    bitsPerPixel != 8 && bitsPerPixel != 16 &&
+		    bitsPerPixel != 24 && bitsPerPixel != 32) {
+		    return false;
+		}
+		int x = (int)(getIntLittleEndian(a, 36) * 0.0254);
+		if (x > 0) {
+			setPhysicalWidthDpi(x);
+		}
+		int y = (int)(getIntLittleEndian(a, 40) * 0.0254);
+		if (y > 0) {
+			setPhysicalHeightDpi(y);
+		}
+		format = FORMAT_BMP;
+		return true;
+	}
+
+	private boolean checkGif() throws IOException {
+		final byte[] GIF_MAGIC_87A = {0x46, 0x38, 0x37, 0x61};
+		final byte[] GIF_MAGIC_89A = {0x46, 0x38, 0x39, 0x61};
+		byte[] a = new byte[11]; // 4 from the GIF signature + 7 from the global header
+		if (read(a) != 11) {
+			return false;
+		}
+		if ((!equals(a, 0, GIF_MAGIC_89A, 0, 4)) &&
+			(!equals(a, 0, GIF_MAGIC_87A, 0, 4))) {
+			return false;
+		}
+		format = FORMAT_GIF;
+		width = getShortLittleEndian(a, 4);
+		height = getShortLittleEndian(a, 6);
+		int flags = a[8] & 0xff;
+		bitsPerPixel = ((flags >> 4) & 0x07) + 1;
+		//progressive = (flags & 0x02) != 0;
+		if (!determineNumberOfImages) {
+			return true;
+		}
+		// skip global color palette
+		if ((flags & 0x80) != 0) {
+			int tableSize = (1 << ((flags & 7) + 1)) * 3;
+			skip(tableSize);
+		}
+		numberOfImages = 0;
+		int blockType;
+		do
+		{
+			blockType = read();
+			switch(blockType)
+			{
+				case(0x2c): // image separator
+				{
+					if (read(a, 0, 9) != 9) {
+						return false;
+					}
+					flags = a[8] & 0xff;
+					progressive = (flags & 0x40) != 0;
+					/*int locWidth = getShortLittleEndian(a, 4);
+					int locHeight = getShortLittleEndian(a, 6);
+					System.out.println("LOCAL: " + locWidth + " x " + locHeight);*/
+					int localBitsPerPixel = (flags & 0x07) + 1;
+					if (localBitsPerPixel > bitsPerPixel) {
+						bitsPerPixel = localBitsPerPixel;
+					}
+					if ((flags & 0x80) != 0) {
+						skip((1 << localBitsPerPixel) * 3);
+					}
+					skip(1); // initial code length
+					int n;
+					do
+					{
+						n = read();
+						if (n > 0) {
+							skip(n);
+						}
+						else
+						if (n == -1) {
+							return false;
+						}
+					}
+					while (n > 0);
+					numberOfImages++;
+					break;
+				}
+				case(0x21): // extension
+				{
+					int extensionType = read();
+					if (collectComments && extensionType == 0xfe) {
+						StringBuffer sb = new StringBuffer();
+						int n;
+						do
+						{
+							n = read();
+							if (n == -1) {
+								return false;
+							}
+							if (n > 0) {
+								for (int i = 0; i < n; i++) {
+									int ch = read();
+									if (ch == -1) {
+										return false;
+									}
+									sb.append((char)ch);
+								}
+							}
+						}
+						while (n > 0);
+					} else {
+						int n;
+						do
+						{
+							n = read();
+							if (n > 0) {
+								skip(n);
+							}
+							else
+							if (n == -1) {
+								return false;
+							}
+						}
+						while (n > 0);
+					}
+					break;
+				}
+				case(0x3b): // end of file
+				{
+					break;
+				}
+				default:
+				{
+					return false;
+				}
+			}
+		}
+		while (blockType != 0x3b);
+		return true;
+	}
+
+	private boolean checkIff() throws IOException {
+		byte[] a = new byte[10];
+		// read remaining 2 bytes of file id, 4 bytes file size 
+		// and 4 bytes IFF subformat
+		if (read(a, 0, 10) != 10) {
+			return false;
+		}
+		final byte[] IFF_RM = {0x52, 0x4d};
+		if (!equals(a, 0, IFF_RM, 0, 2)) {
+			return false;
+		}
+		int type = getIntBigEndian(a, 6);
+		if (type != 0x494c424d && // type must be ILBM...
+		    type != 0x50424d20) { // ...or PBM
+		    return false;
+		}
+		// loop chunks to find BMHD chunk
+		do {
+			if (read(a, 0, 8) != 8) {
+				return false;
+			}
+			int chunkId = getIntBigEndian(a, 0);
+			int size = getIntBigEndian(a, 4);
+			if ((size & 1) == 1) {
+				size++;
+			}
+			if (chunkId == 0x424d4844) { // BMHD chunk
+				if (read(a, 0, 9) != 9) {
+					return false;
+				}
+				format = FORMAT_IFF;
+				width = getShortBigEndian(a, 0);
+				height = getShortBigEndian(a, 2);
+				bitsPerPixel = a[8] & 0xff;
+				return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel < 33);
+			} else {
+				skip(size);
+			}
+		} while (true);
+	}
+
+	private boolean checkJpeg() throws IOException {
+		byte[] data = new byte[12];
+		while (true) {
+			if (read(data, 0, 4) != 4) {
+				return false;
+			}
+			int marker = getShortBigEndian(data, 0);
+			int size = getShortBigEndian(data, 2);
+			if ((marker & 0xff00) != 0xff00) {
+				return false; // not a valid marker
+			}
+			if (marker == 0xffe0) { // APPx 
+				if (size < 14) {
+					// not an APPx header as we know it, skip
+					skip(size - 2);
+					continue;
+				}
+				if (read(data, 0, 12) != 12) {
+					return false;
+				}
+				final byte[] APP0_ID = {0x4a, 0x46, 0x49, 0x46, 0x00};
+				if (equals(APP0_ID, 0, data, 0, 5)) {
+					//System.out.println("data 7=" + data[7]);
+					if (data[7] == 1) {
+						setPhysicalWidthDpi(getShortBigEndian(data, 8));
+						setPhysicalHeightDpi(getShortBigEndian(data, 10));
+					}
+					else
+					if (data[7] == 2) {
+						int x = getShortBigEndian(data, 8);
+						int y = getShortBigEndian(data, 10);
+						setPhysicalWidthDpi((int)(x * 2.54f));
+						setPhysicalHeightDpi((int)(y * 2.54f));
+					}
+				}
+				skip(size - 14);
+			}
+			else
+			if (collectComments && size > 2 && marker == 0xfffe) { // comment
+				size -= 2;
+				byte[] chars = new byte[size];
+				if (read(chars, 0, size) != size) {
+					return false;
+				}
+				String comment = new String(chars, "iso-8859-1");
+				comment = comment.trim();
+				addComment(comment);
+			}
+			else
+			if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8) {
+				if (read(data, 0, 6) != 6) {
+					return false;
+				}
+				format = FORMAT_JPEG;
+				bitsPerPixel = (data[0] & 0xff) * (data[5] & 0xff);
+				progressive = marker == 0xffc2 || marker == 0xffc6 ||
+					marker == 0xffca || marker == 0xffce;
+				width = getShortBigEndian(data, 3);
+				height = getShortBigEndian(data, 1);
+				return true;
+			} else {
+				skip(size - 2);
+			}
+		}
+	}
+
+	private boolean checkPcx() throws IOException {
+		byte[] a = new byte[64];
+		if (read(a) != a.length) {
+			return false;
+		}
+		if (a[0] != 1) { // encoding, 1=RLE is only valid value
+			return false;
+		}
+		// width / height
+		int x1 = getShortLittleEndian(a, 2);
+		int y1 = getShortLittleEndian(a, 4);
+		int x2 = getShortLittleEndian(a, 6);
+		int y2 = getShortLittleEndian(a, 8);
+		if (x1 < 0 || x2 < x1 || y1 < 0 || y2 < y1) {
+			return false;
+		}
+		width = x2 - x1 + 1;
+		height = y2 - y1 + 1;
+		// color depth
+		int bits = a[1];
+		int planes = a[63];
+		if (planes == 1 &&
+		    (bits == 1 || bits == 2 || bits == 4 || bits == 8)) {
+			// paletted
+			bitsPerPixel = bits;
+		} else
+		if (planes == 3 && bits == 8) {
+			// RGB truecolor
+			bitsPerPixel = 24;
+		} else {
+			return false;
+		}
+		setPhysicalWidthDpi(getShortLittleEndian(a, 10));
+		setPhysicalHeightDpi(getShortLittleEndian(a, 10));
+		format = FORMAT_PCX;
+		return true;
+	}
+
+	private boolean checkPng() throws IOException {
+		final byte[] PNG_MAGIC = {0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
+		byte[] a = new byte[27];
+		if (read(a) != 27) {
+			return false;
+		}
+		if (!equals(a, 0, PNG_MAGIC, 0, 6)) {
+			return false;
+		}
+		format = FORMAT_PNG;
+		width = getIntBigEndian(a, 14);
+		height = getIntBigEndian(a, 18);
+		bitsPerPixel = a[22] & 0xff;
+		int colorType = a[23] & 0xff;
+		if (colorType == 2 || colorType == 6) {
+			bitsPerPixel *= 3;
+		}
+		progressive = (a[26] & 0xff) != 0;
+		return true;
+	}
+
+	private boolean checkPnm(int id) throws IOException {
+		if (id < 1 || id > 6) {
+			return false;
+		}
+		final int[] PNM_FORMATS = {FORMAT_PBM, FORMAT_PGM, FORMAT_PPM};
+		format = PNM_FORMATS[(id - 1) % 3];
+		boolean hasPixelResolution = false;
+		String s;
+		while (true)
+		{
+			s = readLine();
+			if (s != null) {
+				s = s.trim();
+			}
+			if (s == null || s.length() < 1) {
+				continue;
+			}
+			if (s.charAt(0) == '#') { // comment
+				if (collectComments && s.length() > 1) {
+					addComment(s.substring(1));
+				}
+				continue;
+			}
+			if (!hasPixelResolution) { // split "343 966" into width=343, height=966
+				int spaceIndex = s.indexOf(' ');
+				if (spaceIndex == -1) {
+					return false;
+				}
+				String widthString = s.substring(0, spaceIndex);
+				spaceIndex = s.lastIndexOf(' ');
+				if (spaceIndex == -1) {
+					return false;
+				}
+				String heightString = s.substring(spaceIndex + 1);
+				try {
+					width = Integer.parseInt(widthString);
+					height = Integer.parseInt(heightString);
+				} catch (NumberFormatException nfe) {
+					return false;
+				}
+				if (width < 1 || height < 1) {
+					return false;
+				}
+				if (format == FORMAT_PBM) {
+					bitsPerPixel = 1;
+					return true;
+				}
+				hasPixelResolution = true;
+			}
+			else
+			{
+				int maxSample;
+				try {
+					maxSample = Integer.parseInt(s);
+				} catch (NumberFormatException nfe) {
+					return false;
+				}
+				if (maxSample < 0) {
+					return false;
+				}
+				for (int i = 0; i < 25; i++) {
+					if (maxSample < (1 << (i + 1))) {
+						bitsPerPixel = i + 1;
+						if (format == FORMAT_PPM) {
+							bitsPerPixel *= 3;
+						}
+						return true;
+					}
+				}
+				return false;
+			}
+		}
+	}
+
+	private boolean checkPsd() throws IOException {
+		byte[] a = new byte[24];
+		if (read(a) != a.length) {
+			return false;
+		}
+		final byte[] PSD_MAGIC = {0x50, 0x53};
+		if (!equals(a, 0, PSD_MAGIC, 0, 2)) {
+			return false;
+		}
+		format = FORMAT_PSD;
+		width = getIntBigEndian(a, 16);
+		height = getIntBigEndian(a, 12);
+		int channels = getShortBigEndian(a, 10);
+		int depth = getShortBigEndian(a, 20);
+		bitsPerPixel = channels * depth;
+		return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 64);
+	}
+
+	private boolean checkRas() throws IOException {
+		byte[] a = new byte[14];
+		if (read(a) != a.length) {
+			return false;
+		}
+		final byte[] RAS_MAGIC = {0x6a, (byte)0x95};
+		if (!equals(a, 0, RAS_MAGIC, 0, 2)) {
+			return false;
+		}
+		format = FORMAT_RAS;
+		width = getIntBigEndian(a, 2);
+		height = getIntBigEndian(a, 6);
+		bitsPerPixel = getIntBigEndian(a, 10);
+		return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 24);
+	}
+
+	/**
+	 * Run over String list, return false iff at least one of the arguments
+	 * equals <code>-c</code>.
+	 * @param args string list to check
+	 */
+	private static boolean determineVerbosity(String[] args) {
+		if (args != null && args.length > 0) {
+			for (int i = 0; i < args.length; i++) {
+				if ("-c".equals(args[i])) {
+					return false;
+				}
+			}
+		}
+		return true;
+	}
+
+	private static boolean equals(byte[] a1, int offs1, byte[] a2, int offs2, int num) {
+		while (num-- > 0) {
+			if (a1[offs1++] != a2[offs2++]) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/** 
+	 * If {@link #check()} was successful, returns the image's number of bits per pixel.
+	 * Does not include transparency information like the alpha channel.
+	 * @return number of bits per image pixel
+	 */
+	public int getBitsPerPixel() {
+		return bitsPerPixel;
+	}
+
+	/**
+	 * Returns the index'th comment retrieved from the file.
+	 * @param index int index of comment to return
+	 * @throws IllegalArgumentException if index is smaller than 0 or larger than or equal
+	 * to the number of comments retrieved
+	 * @see #getNumberOfComments
+	 */
+	public String getComment(int index) {
+		if (comments == null || index < 0 || index >= comments.size()) {
+			throw new IllegalArgumentException("Not a valid comment index: " + index);
+		}
+		return (String)comments.elementAt(index);
+	}
+
+	/**
+	 * If {@link #check()} was successful, returns the image format as one
+	 * of the FORMAT_xyz constants from this class.
+	 * Use {@link #getFormatName()} to get a textual description of the file format.
+	 * @return file format as a FORMAT_xyz constant
+	 */
+	public int getFormat() {
+		return format;
+	}
+
+	/**
+	 * If {@link #check()} was successful, returns the image format's name.
+	 * Use {@link #getFormat()} to get a unique number.
+	 * @return file format name
+	 */
+	public String getFormatName() {
+		if (format >= 0 && format < FORMAT_NAMES.length) {
+			return FORMAT_NAMES[format];
+		} else {
+			return "?";
+		}
+	}
+
+	/** 
+	 * If {@link #check()} was successful, returns one the image's vertical
+	 * resolution in pixels.
+	 * @return image height in pixels
+	 */
+	public int getHeight() {
+		return height;
+	}
+
+	private static int getIntBigEndian(byte[] a, int offs) {
+		return
+			(a[offs] & 0xff) << 24 | 
+			(a[offs + 1] & 0xff) << 16 | 
+			(a[offs + 2] & 0xff) << 8 | 
+			a[offs + 3] & 0xff;
+	}
+
+	private static int getIntLittleEndian(byte[] a, int offs) {
+		return
+			(a[offs + 3] & 0xff) << 24 | 
+			(a[offs + 2] & 0xff) << 16 | 
+			(a[offs + 1] & 0xff) << 8 | 
+			a[offs] & 0xff;
+	}
+
+	/** 
+	 * If {@link #check()} was successful, returns a String with the
+	 * MIME type of the format.
+	 * @return MIME type, e.g. <code>image/jpeg</code>
+	 */
+	public String getMimeType() {
+		if (format >= 0 && format < MIME_TYPE_STRINGS.length) {
+			if (format == FORMAT_JPEG && progressive)
+			{
+				return "image/pjpeg";
+			}
+			return MIME_TYPE_STRINGS[format];
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * If {@link #check()} was successful and {@link #setCollectComments(boolean)} was called with
+	 * <code>true</code> as argument, returns the number of comments retrieved 
+	 * from the input image stream / file.
+	 * Any number &gt;= 0 and smaller than this number of comments is then a
+	 * valid argument for the {@link #getComment(int)} method.
+	 * @return number of comments retrieved from input image
+	 */
+	public int getNumberOfComments()
+	{
+		if (comments == null) {
+			return 0;
+		} else {
+			return comments.size();
+		}
+	}
+
+	/**
+	 * Returns the number of images in the examined file.
+	 * Assumes that <code>setDetermineImageNumber(true);</code> was called before
+	 * a successful call to {@link #check()}.
+	 * This value can currently be only different from <code>1</code> for GIF images.
+	 * @return number of images in file
+	 */
+	public int getNumberOfImages()
+	{
+		return numberOfImages;
+	}
+
+	/**
+	 * Returns the physical height of this image in dots per inch (dpi).
+	 * Assumes that {@link #check()} was successful.
+	 * Returns <code>-1</code> on failure.
+	 * @return physical height (in dpi)
+	 * @see #getPhysicalWidthDpi()
+	 * @see #getPhysicalHeightInch()
+	 */
+	public int getPhysicalHeightDpi() {
+		return physicalHeightDpi;
+	}
+
+	/**
+	 * If {@link #check()} was successful, returns the physical width of this image in dpi (dots per inch)
+	 * or -1 if no value could be found.
+	 * @return physical height (in dpi)
+	 * @see #getPhysicalHeightDpi()
+	 * @see #getPhysicalWidthDpi()
+	 * @see #getPhysicalWidthInch()
+	 */
+	public float getPhysicalHeightInch() {
+		int h = getHeight();
+		int ph = getPhysicalHeightDpi();
+		if (h > 0 && ph > 0) {
+			return ((float)h) / ((float)ph);
+		} else {
+			return -1.0f;
+		}
+	}
+
+	/**
+	 * If {@link #check()} was successful, returns the physical width of this image in dpi (dots per inch)
+	 * or -1 if no value could be found.
+	 * @return physical width (in dpi)
+	 * @see #getPhysicalHeightDpi()
+	 * @see #getPhysicalWidthInch()
+	 * @see #getPhysicalHeightInch()
+	 */
+	public int getPhysicalWidthDpi() {
+		return physicalWidthDpi;
+	}
+
+	/**
+	 * Returns the physical width of an image in inches, or
+	 * <code>-1.0f</code> if width information is not available.
+	 * Assumes that {@link #check} has been called successfully.
+	 * @return physical width in inches or <code>-1.0f</code> on failure
+	 * @see #getPhysicalWidthDpi
+	 * @see #getPhysicalHeightInch
+	 */
+	public float getPhysicalWidthInch() {
+		int w = getWidth();
+		int pw = getPhysicalWidthDpi();
+		if (w > 0 && pw > 0) {
+			return ((float)w) / ((float)pw);
+		} else {
+			return -1.0f;
+		}
+	}
+
+	private static int getShortBigEndian(byte[] a, int offs) {
+		return
+			(a[offs] & 0xff) << 8 | 
+			(a[offs + 1] & 0xff);
+	}
+
+	private static int getShortLittleEndian(byte[] a, int offs) {
+		return (a[offs] & 0xff) | (a[offs + 1] & 0xff) << 8;
+	}
+
+	/** 
+	 * If {@link #check()} was successful, returns one the image's horizontal
+	 * resolution in pixels.
+	 * @return image width in pixels
+	 */
+	public int getWidth() {
+		return width;
+	}
+
+	/**
+	 * Returns whether the image is stored in a progressive (also called: interlaced) way.
+	 * @return true for progressive/interlaced, false otherwise
+	 */
+	public boolean isProgressive()
+	{
+		return progressive;
+	}
+
+	/**
+	 * To use this class as a command line application, give it either 
+	 * some file names as parameters (information on them will be
+	 * printed to standard output, one line per file) or call
+	 * it with no parameters. It will then check data given to it
+	 * via standard input.
+	 * @param args the program arguments which must be file names
+	 */
+	public static void main(String[] args) {
+		ImageInfo imageInfo = new ImageInfo();
+		imageInfo.setDetermineImageNumber(true);
+		boolean verbose = determineVerbosity(args);
+		if (args.length == 0) {
+			run(null, System.in, imageInfo, verbose);
+		} else {
+			int index = 0;
+			while (index < args.length) {
+				InputStream in = null;
+				try {
+					String name = args[index++];
+					System.out.print(name + ";");
+					if (name.startsWith("http://")) {
+						in = new URL(name).openConnection().getInputStream();
+					} else {
+						in = new FileInputStream(name);
+					}
+					run(name, in, imageInfo, verbose);
+					in.close();
+				} catch (IOException e) {
+					System.out.println(e);
+					try {
+						if (in != null) {
+							in.close();
+						}
+					} catch (IOException ee) {
+					}
+				}
+			}
+		}
+	}
+
+	private static void print(String sourceName, ImageInfo ii, boolean verbose) {
+		if (verbose) {
+			printVerbose(sourceName, ii);
+		} else {
+			printCompact(sourceName, ii);
+		}
+	}
+
+	private static void printCompact(String sourceName, ImageInfo imageInfo) {
+		final String SEP = "\t";
+		System.out.println(
+			sourceName + SEP + 
+			imageInfo.getFormatName() + SEP +
+			imageInfo.getMimeType() + SEP +
+			imageInfo.getWidth() + SEP +
+			imageInfo.getHeight() + SEP +
+			imageInfo.getBitsPerPixel() + SEP +
+			imageInfo.getNumberOfImages() + SEP +
+			imageInfo.getPhysicalWidthDpi() + SEP +
+			imageInfo.getPhysicalHeightDpi() + SEP +
+			imageInfo.getPhysicalWidthInch() + SEP +
+			imageInfo.getPhysicalHeightInch() + SEP +
+			imageInfo.isProgressive()
+		);
+	}
+
+	private static void printLine(int indentLevels, String text, float value, float minValidValue) {
+		if (value < minValidValue) {
+			return;
+		}
+		printLine(indentLevels, text, Float.toString(value));
+	}
+
+	private static void printLine(int indentLevels, String text, int value, int minValidValue) {
+		if (value >= minValidValue) {
+			printLine(indentLevels, text, Integer.toString(value));
+		}
+	}
+
+	private static void printLine(int indentLevels, String text, String value) {
+		if (value == null || value.length() == 0) {
+			return;
+		}
+		while (indentLevels-- > 0) {
+			System.out.print("\t");
+		}
+		if (text != null && text.length() > 0) {
+			System.out.print(text);
+			System.out.print(" ");
+		}
+		System.out.println(value);
+	}
+
+	private static void printVerbose(String sourceName, ImageInfo ii) {
+		printLine(0, null, sourceName);
+		printLine(1, "File format: ", ii.getFormatName());
+		printLine(1, "MIME type: ", ii.getMimeType());
+		printLine(1, "Width (pixels): ", ii.getWidth(), 1);
+		printLine(1, "Height (pixels): ", ii.getHeight(), 1);
+		printLine(1, "Bits per pixel: ", ii.getBitsPerPixel(), 1);
+		printLine(1, "Progressive: ", ii.isProgressive() ? "yes" : "no");
+		printLine(1, "Number of images: ", ii.getNumberOfImages(), 1);
+		printLine(1, "Physical width (dpi): ", ii.getPhysicalWidthDpi(), 1);
+		printLine(1, "Physical height (dpi): ", ii.getPhysicalHeightDpi(), 1);
+		printLine(1, "Physical width (inches): ", ii.getPhysicalWidthInch(), 1.0f);
+		printLine(1, "Physical height (inches): ", ii.getPhysicalHeightInch(), 1.0f);
+		int numComments = ii.getNumberOfComments();
+		printLine(1, "Number of textual comments: ", numComments, 1);
+		if (numComments > 0) {
+			for (int i = 0; i < numComments; i++) {
+				printLine(2, null, ii.getComment(i));
+			}
+		}
+	}
+
+	private int read() throws IOException {
+		if (in != null) {
+			return in.read();
+		} else {
+			return din.readByte();
+		}
+	}
+
+	private int read(byte[] a) throws IOException {
+		if (in != null) {
+			return in.read(a);
+		} else {
+			din.readFully(a);
+			return a.length;
+		}
+	}
+
+	private int read(byte[] a, int offset, int num) throws IOException {
+		if (in != null) {
+			return in.read(a, offset, num);
+		} else {
+			din.readFully(a, offset, num);
+			return num;
+		}
+	}
+
+	private String readLine() throws IOException {
+		return readLine(new StringBuffer());
+	}
+
+	private String readLine(StringBuffer sb) throws IOException {
+		boolean finished;
+		do {
+			int value = read();
+			finished = (value == -1 || value == 10);
+			if (!finished) {
+				sb.append((char)value);
+			}
+		} while (!finished);
+		return sb.toString();
+	}
+
+	private static void run(String sourceName, InputStream in, ImageInfo imageInfo, boolean verbose) {
+		imageInfo.setInput(in);
+		imageInfo.setDetermineImageNumber(true);
+		imageInfo.setCollectComments(verbose);
+		if (imageInfo.check()) {
+			print(sourceName, imageInfo, verbose);
+		}
+	}
+
+	/**
+	 * Specify whether textual comments are supposed to be extracted from input.
+	 * Default is <code>false</code>.
+	 * If enabled, comments will be added to an internal list.
+	 * @param newValue if <code>true</code>, this class will read comments
+	 * @see #getNumberOfComments
+	 * @see #getComment
+	 */
+	public void setCollectComments(boolean newValue)
+	{
+		collectComments = newValue;
+	}
+
+	/**
+	 * Specify whether the number of images in a file is to be
+	 * determined - default is <code>false</code>.
+	 * This is a special option because some file formats require running over
+	 * the entire file to find out the number of images, a rather time-consuming
+	 * task.
+	 * Not all file formats support more than one image.
+	 * If this method is called with <code>true</code> as argument,
+	 * the actual number of images can be queried via 
+	 * {@link #getNumberOfImages()} after a successful call to
+	 * {@link #check()}.
+	 * @param newValue will the number of images be determined?
+	 * @see #getNumberOfImages
+	 */
+	public void setDetermineImageNumber(boolean newValue)
+	{
+		determineNumberOfImages = newValue;
+	}
+
+	/**
+	 * Set the input stream to the argument stream (or file). 
+	 * Note that {@link java.io.RandomAccessFile} implements
+	 * {@link java.io.DataInput}.
+	 * @param dataInput the input stream to read from
+	 */
+	public void setInput(DataInput dataInput) {
+		din = dataInput;
+		in = null;
+	}
+
+	/**
+	 * Set the input stream to the argument stream (or file).
+	 * @param inputStream the input stream to read from
+	 */
+	public void setInput(InputStream inputStream) {
+		in = inputStream;
+		din = null;
+	}
+
+	private void setPhysicalHeightDpi(int newValue) {
+		physicalWidthDpi = newValue;
+	}
+
+	private void setPhysicalWidthDpi(int newValue) {
+		physicalHeightDpi = newValue;
+	}
+
+    private void skip(int num) throws IOException {
+        while (num > 0) {
+            long result;
+            if (in != null) {
+                result = in.skip(num);
+            } else {
+                result = din.skipBytes(num);
+            }
+            if (result > 0) {
+                num -= result;
+            } else {
+                if (in != null) {
+                    result = in.read();
+                } else {
+                    result = din.readByte();
+                }
+                if (result == -1) {
+                	throw new IOException("Premature end of input.");
+                } else {
+                	num--;
+                }
+            }
+        }
+    }
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/connector/package.html
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/connector/package.html	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/connector/package.html	(revision 2015)
@@ -0,0 +1,72 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Connector used by the FCKeditor to list and create resources on the server.
+
+<h2>Package Specification</h2>
+
+This servlet is access directly from the file browser in the FCKeditor.<br>
+To make everything work correctly you have to add the following piece of code in your application's web.xml
+<br>
+<pre>
+	&lt;servlet&gt;
+		&lt;servlet-name&gt;Connector&lt;/servlet-name&gt;
+		&lt;servlet-class&gt;net.fckeditor.connector.ConnectorServlet&lt;/servlet-class&gt;
+		&lt;init-param&gt;
+			&lt;param-name&gt;baseDir&lt;/param-name&gt;
+			&lt;param-value&gt;/UserFiles/&lt;/param-value&gt;
+		&lt;/init-param&gt;
+		&lt;init-param&gt;
+			&lt;param-name&gt;debug&lt;/param-name&gt;
+			&lt;param-value&gt;false&lt;/param-value&gt;
+		&lt;/init-param&gt;
+		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
+	&lt;/servlet&gt;
+
+	&lt;servlet-mapping&gt;
+		&lt;servlet-name&gt;Connector&lt;/servlet-name&gt;
+		&lt;url-pattern&gt;/editor/filemanager/browser/default/connectors/jsp/connector&lt;/url-pattern&gt;
+	&lt;/servlet-mapping&gt;
+</pre>
+<br>
+And put in the fckconfig.js the following line:
+<pre>
+FCKConfig.LinkBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Connector=connectors/jsp/connector" ;
+FCKConfig.ImageBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Image&Connector=connectors/jsp/connector" ;
+FCKConfig.FlashBrowserURL = FCKConfig.BasePath + "filemanager/browser/default/browser.html?Type=Flash&Connector=connectors/jsp/connector" ;
+</pre>
+Also, since the servlet manage a file upload using the Jakarta Common fileupload library, you need to put in your <code>WEB-INF/lib/</code> the <code>commons-fileupload.jar</code>.
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+  <li>_sample/jsp directory for example of how to implement FCKeditor in your application
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/package.html
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/package.html	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/package.html	(revision 2015)
@@ -0,0 +1,41 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Core objects to manage the FCKeditor text input form.
+Java Integration Module 2.4.
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+  <li><a href="http://www.fckeditor.net/">Official web site of FCKeditor</a>
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/tags/package.html
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/tags/package.html	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/javadoc/net/fckeditor/tags/package.html	(revision 2015)
@@ -0,0 +1,49 @@
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+JSP Tag to access and modify the FCKeditor objects.
+
+
+<h2>Package Specification</h2>
+
+This taglibrary is compliant to the taglib 1.1 specification.<br>
+To use it put the FCKeditor.jar inside the <code>WEB-INF/lib</code> dir and FCKeditor.tld inside the <code>WEB-INF</code> directory of your website.<br>
+Put the following declaration in each page that use the tags:<br>
+<pre>
+&lt;%@ taglib uri="http://fckeditor.net/tags-fckeditor" prefix="FCK" %&gt;
+</pre>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+  <li>_sample/jsp directory for example of how to implement FCKeditor in your application
+</ul>
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/resources/META-INF/FCKeditor.tld
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/resources/META-INF/FCKeditor.tld	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/resources/META-INF/FCKeditor.tld	(revision 2015)
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<taglib 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-jsptaglibrary_2_0.xsd"
+	version="2.0"
+>
+	<description>
+		The FCKeditor Tag Library offers a very convenient way to create
+		several FCKeditor instances with different configurations.
+		Additionally, you can check for user-based capabilities.
+	</description>
+	<display-name>FCKeditor Tag Library</display-name>
+	<small-icon>fckeditor.gif</small-icon>
+	<tlib-version>2.4</tlib-version>
+	<short-name>FCK</short-name>
+	<uri>http://java.fckeditor.net</uri>
+	<tag>
+		<description>
+			Creates a FCKeditor instance with the given parameters.
+		</description>
+		<display-name>editor</display-name>
+		<name>editor</name>
+		<tag-class>net.fckeditor.tags.EditorTag</tag-class>
+		<body-content>JSP</body-content>
+		<attribute>
+			<description>
+				The unique instance name under which the editor can be
+				retrieved through the API.
+			</description>
+			<name>instanceName</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+			<type>java.lang.String</type>
+		</attribute>
+		<attribute>
+			<description>
+				Width of the FCKeditor instance in the browser window.
+			</description>
+			<name>width</name>
+			<rtexprvalue>true</rtexprvalue>
+			<type>java.lang.String</type>
+		</attribute>
+		<attribute>
+			<description>
+				Height of the FCKeditor instance in the browser window.
+			</description>
+			<name>height</name>
+			<rtexprvalue>true</rtexprvalue>
+			<type>java.lang.String</type>
+		</attribute>
+		<attribute>
+			<description>
+				The toolbar set which shall be displayed to the user.
+			</description>
+			<name>toolbarSet</name>
+			<rtexprvalue>true</rtexprvalue>
+			<type>java.lang.String</type>
+		</attribute>
+		<attribute>
+			<description>
+				The path/folder in which the editor is deployed under
+				the given context. The context path will be attached
+				automatically. (e.g. '/fckeditor')
+			</description>
+			<name>basePath</name>
+			<rtexprvalue>true</rtexprvalue>
+			<type>java.lang.String</type>
+		</attribute>
+		<attribute>
+			<description>
+				Passes any content to the FCKeditor document. Use the
+				jsp:attribute tag for large inline content. \r, \n, and
+				\t will be truncated.
+			</description>
+			<name>value</name>
+			<rtexprvalue>true</rtexprvalue>
+			<type>java.lang.String</type>
+		</attribute>
+		<example><![CDATA[
+<FCK:editor instanceName="editorDefault" height="500px" />]]>
+		</example>
+	</tag>
+	<tag>
+		<description>
+			Sets a config property of the editor to the supplied value.
+			You may provide any attribute you want for the editor. Set
+			at least one attribute per tag or several attributes with
+			one tag. This tag can only be nested within an editor tag.
+			For all configuration options click
+			<![CDATA[<a href="http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options">here</a>]]>.
+		</description>
+		<display-name>config</display-name>
+		<name>config</name>
+		<tag-class>net.fckeditor.tags.ConfigTag</tag-class>
+		<body-content>empty</body-content>
+		<dynamic-attributes>true</dynamic-attributes>
+		<example>
+			<![CDATA[
+<FCK:config SkinPath="/skins/silver/" AutoDetectLanguage="true" />]]>
+		</example>
+	</tag>
+	<tag>
+		<description>
+			Displays session-dependent and compatibility-related
+			information. This tag is intended for developers only.
+			Response messages cannot be localized, they are English
+			only.
+		</description>
+		<display-name>check</display-name>
+		<name>check</name>
+		<tag-class>net.fckeditor.tags.CheckTag</tag-class>
+		<body-content>empty</body-content>
+		<attribute>
+			<description>
+				Provide the feature name you want to check. Valid
+				features are [FileUpload, FileBrowsing,
+				CompatibleBrowser]
+			</description>
+			<name>command</name>
+			<required>true</required>
+			<type>java.lang.String</type>
+		</attribute>
+		<example><![CDATA[
+<FCK:check command="FileUpload" />
+<FCK:check command="CompatibleBrowser" />]]>
+		</example>
+	</tag>
+</taglib>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/resources/net/fckeditor/handlers/default.properties
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/resources/net/fckeditor/handlers/default.properties	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/main/resources/net/fckeditor/handlers/default.properties	(revision 2015)
@@ -0,0 +1,69 @@
+#
+# FCKeditor - The text editor for Internet - http://www.fckeditor.net
+# Copyright (C) 2003-2008 Frederico Caldeira Knabben
+#
+# == BEGIN LICENSE ==
+#
+# Licensed under the terms of any of the following licenses at your
+# choice:
+#
+#  - GNU General Public License Version 2 or later (the "GPL")
+#    http://www.gnu.org/licenses/gpl.html
+#
+#  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+#    http://www.gnu.org/licenses/lgpl.html
+#
+#  - Mozilla Public License Version 1.1 or later (the "MPL")
+#    http://www.mozilla.org/MPL/MPL-1.1.html
+#
+# == END LICENSE ==
+#
+# Default properties for FCKeditor.Java
+#
+# @version $Id$ 
+
+# default allowed extensions settings
+connector.resourceType.file.extensions.allowed = 7z|aiff|asf|avi|bmp|csv|doc|fla|flv|gif|gz|gzip|jpeg|jpg|mid|mov|mp3|mp4|mpc|mpeg|mpg|ods|odt|pdf|png|ppt|pxd|qt|ram|rar|rm|rmi|rmvb|rtf|sdc|sitd|swf|sxc|sxw|tar|tgz|tif|tiff|txt|vsd|wav|wma|wmv|xls|xml|zip
+connector.resourceType.image.extensions.allowed = bmp|gif|jpeg|jpg|png
+connector.resourceType.flash.extensions.allowed = swf|fla
+connector.resourceType.media.extensions.allowed = aiff|asf|avi|bmp|fla|flv|gif|jpeg|jpg|mid|mov|mp3|mp4|mpc|mpeg|mpg|png|qt|ram|rm|rmi|rmvb|swf|tif|tiff|wav|wma|wmv
+
+# default resource type paths
+connector.resourceType.file.path = /file
+connector.resourceType.image.path = /image
+connector.resourceType.flash.path = /flash
+connector.resourceType.media.path = /media
+
+# Due to security issues with Apache modules, it is recommended to leave this 
+# setting enabled.
+connector.forceSingleExtension = true
+
+# base directory for the user files relative to the context root
+connector.userFilesPath = /userfiles
+
+# Instructs the Connector to return the full URL of a file/folder in the XML
+# response rather than the absolute URL
+connector.fullUrl = false
+
+# Instructs the Connector to check, if the uploaded image is really one
+connector.secureImageUploads = true
+
+# directory of the editor relative to the context root
+fckeditor.basePath = /fckeditor
+
+# default height of the editor
+fckeditor.height = 200
+
+# default toolbar set of the editor
+fckeditor.toolbarSet = Default
+
+# default width of the editor
+fckeditor.width = 100%
+
+# some messages
+message.enabled_tag.compatible_browser.no = Your browser is not compatible
+message.enabled_tag.compatible_browser.yes = Your browser is fully compatible
+message.enabled_tag.connector.file_browsing.disabled = The Connector is disabled for FileBrowsing
+message.enabled_tag.connector.file_browsing.enabled = The Connector is enabled for FileBrowsing
+message.enabled_tag.connector.file_upload.disabled = The Connector is disabled for FileUpload
+message.enabled_tag.connector.file_upload.enabled = The Connector is enabled for FileUpload
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/site/resources/css/site.css
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/site/resources/css/site.css	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/site/resources/css/site.css	(revision 2015)
@@ -0,0 +1,1 @@
+@import url(../../css/site.css);
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/CommandHandlerTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/CommandHandlerTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/CommandHandlerTest.java	(revision 2015)
@@ -0,0 +1,119 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+/**
+ * Tests for {@link CommandHandler}.
+ * 
+ * @version $Id$
+ */
+public class CommandHandlerTest {
+
+	@Test
+	public void valueOf01() {
+		assertEquals(CommandHandler.FILE_UPLOAD, CommandHandler
+				.valueOf("FileUpload"));
+	}
+
+	@Test
+	public void valueOf02() {
+		assertEquals(CommandHandler.QUICK_UPLOAD, CommandHandler
+				.valueOf("QuickUpload"));
+	}
+
+	@Test
+	public void valueOf03() {
+		assertEquals(CommandHandler.CREATE_FOLDER, CommandHandler
+				.valueOf("CreateFolder"));
+	}
+
+	@Test
+	public void valueOf04() {
+		assertEquals(CommandHandler.GET_FOLDERS, CommandHandler
+				.valueOf("GetFolders"));
+	}
+
+	@Test
+	public void valueOf05() {
+		assertEquals(CommandHandler.GET_FOLDERS_AND_FILES, CommandHandler
+				.valueOf("GetFoldersAndFiles"));
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void valueOfStringNull() {
+		CommandHandler.valueOf(null);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void valueOfInvalidCommand() {
+		CommandHandler.valueOf("GetAll");
+	}
+
+	@Test
+	public void getCommandNull() {
+		CommandHandler command = CommandHandler.getCommand(null);
+		assertNull(command);
+	}
+
+	@Test
+	public void getCommandInvalid() {
+		CommandHandler command = CommandHandler.getCommand("DeleteFolders");
+		assertNull(command);
+	}
+
+	@Test
+	public void getCommandValid() {
+		CommandHandler actual = CommandHandler.getCommand("FileUpload");
+		assertEquals(CommandHandler.FILE_UPLOAD, actual);
+	}
+
+	@Test
+	public void equalsNot01() {
+		assertFalse(CommandHandler.GET_FOLDERS
+				.equals(CommandHandler.FILE_UPLOAD));
+	}
+
+	@Test
+	public void equalsNot02() {
+		assertFalse(CommandHandler.GET_FOLDERS.equals(new Object()));
+	}
+
+	@Test
+	public void hashCode01() {
+		assertEquals("GetFoldersAndFiles".hashCode(),
+				CommandHandler.GET_FOLDERS_AND_FILES.hashCode());
+	}
+
+	@Test
+	public void hashCode02() {
+		assertNotSame(-1, CommandHandler.FILE_UPLOAD.hashCode());
+	}
+
+	@Test
+	public void toString01() {
+		assertEquals("GetFoldersAndFiles", CommandHandler.GET_FOLDERS_AND_FILES
+				.toString());
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/ExtensionsHandlerTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/ExtensionsHandlerTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/ExtensionsHandlerTest.java	(revision 2015)
@@ -0,0 +1,57 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link ExtensionsHandler};
+ *
+ * @version $Id$
+ */
+public class ExtensionsHandlerTest {
+	
+	@Test
+	public void testIsAllowed01() {
+		ResourceTypeHandler type = ResourceTypeHandler.FILE;
+		ExtensionsHandler.setExtensionsAllowed(type, "a");
+		ExtensionsHandler.setExtensionsDenied(type, "b");
+		assertTrue(ExtensionsHandler.getExtensionsAllowed(type).isEmpty());
+		assertTrue(ExtensionsHandler.getExtensionsDenied(type).contains("b"));
+		assertFalse(ExtensionsHandler.isAllowed(type, "b"));
+		assertTrue(ExtensionsHandler.isAllowed(type, "a"));
+		assertTrue(ExtensionsHandler.isAllowed(type, "c"));
+	}
+	
+	@Test
+	public void testIsAllowed02() {
+		ResourceTypeHandler type = ResourceTypeHandler.FILE;
+		ExtensionsHandler.setExtensionsAllowed(type, "a|b|c");
+		assertTrue(ExtensionsHandler.isAllowed(type, "a"));
+		assertTrue(ExtensionsHandler.isAllowed(type, "b"));
+		assertTrue(ExtensionsHandler.isAllowed(type, "c"));
+		assertFalse(ExtensionsHandler.isAllowed(type, "d"));
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeHandlerTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeHandlerTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/handlers/ResourceTypeHandlerTest.java	(revision 2015)
@@ -0,0 +1,89 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.handlers;
+
+import static org.junit.Assert.*;
+import net.fckeditor.handlers.PropertiesLoader;
+import net.fckeditor.handlers.ResourceTypeHandler;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link ResourceTypeHandler}.
+ * 
+ * @version $Id: ResourceTypeHandlerTest.java 1585 2008-02-21 18:13:09Z th-schwarz $
+ */
+public class ResourceTypeHandlerTest {
+
+	@Test
+	public void getType01() throws Exception {
+		assertNull(ResourceTypeHandler.getResourceType("xyz"));
+	}
+
+	@Test
+	public void getType02() throws Exception {
+		assertEquals(ResourceTypeHandler.FILE, ResourceTypeHandler.getResourceType("File"));
+	}
+
+	@Test
+	public void getType03() throws Exception {
+		assertEquals(ResourceTypeHandler.IMAGE, ResourceTypeHandler.getResourceType("Image"));
+	}
+
+	@Test
+	public void isValid01() throws Exception {
+		assertFalse(ResourceTypeHandler.isValid("1234"));
+	}
+
+	@Test
+	public void isValid02() throws Exception {
+		assertFalse(ResourceTypeHandler.isValid("fLash"));
+	}
+
+	@Test
+	public void isValid03() throws Exception {
+		assertFalse(ResourceTypeHandler.isValid("MeDiA"));
+	}
+
+	@Test
+	public void getTypeDefault01() throws Exception {
+		assertEquals(ResourceTypeHandler.FILE, ResourceTypeHandler
+				.getDefaultResourceType("wrong-type"));
+	}
+
+	@Test
+	public void getTypeDefault02() throws Exception {
+		assertNotSame(ResourceTypeHandler.FLASH, ResourceTypeHandler
+				.getDefaultResourceType("flAsh"));
+	}
+
+	@Test
+	public void getSubDirForType01() throws Exception {
+		assertEquals(PropertiesLoader.getProperty("connector.resourceType.file.path"), 
+				ResourceTypeHandler.getDefaultResourceType(null).getPath());
+	}
+
+	@Test
+	public void getSubDirForType02() throws Exception {
+		assertEquals(PropertiesLoader.getProperty("connector.resourceType.image.path"), 
+				ResourceTypeHandler.getResourceType("Image").getPath());
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/response/UploadResponseTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/response/UploadResponseTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/response/UploadResponseTest.java	(revision 2015)
@@ -0,0 +1,74 @@
+package net.fckeditor.response;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import net.fckeditor.response.UploadResponse;
+
+public class UploadResponseTest {
+
+	@Test(expected = IllegalArgumentException.class)
+	public void noArguments() throws Exception {
+		new UploadResponse();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void tooManyArguments() throws Exception {
+		new UploadResponse(101, "/some/url/file.txt", "file.txt",
+				"something's wrong", "arg no. 5");
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void notANumber() throws Exception {
+		new UploadResponse("1");
+	}
+
+	@Test
+	public void onlyErrorNumber() throws Exception {
+		UploadResponse actual = new UploadResponse(
+				UploadResponse.EN_INVALID_EXTENSION);
+		String expected = new String("<script type=\"text/javascript\">\n"
+				+ "(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n"
+				+ "window.parent.OnUploadCompleted(202);\n</script>");
+		assertEquals(expected, actual.toString());
+	}
+	
+	@Test
+	public void fourArguments() throws Exception {
+		UploadResponse actual = new UploadResponse(UploadResponse.EN_OK,"/fckeditor-java/userfiles/image/fredck.jpg");
+		String expected = new String("<script type=\"text/javascript\">\n"
+				+ "(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n"
+				+ "window.parent.OnUploadCompleted(0,'/fckeditor-java/userfiles/image/fredck.jpg');\n</script>");
+		assertEquals(expected, actual.toString());
+	}
+	
+	@Test
+	public void renamedFile() throws Exception {
+		UploadResponse actual = new UploadResponse(UploadResponse.EN_RENAMED,"/fckeditor-java/userfiles/image/hacked_php.txt","hacked_php.txt");
+		String expected = new String("<script type=\"text/javascript\">\n"
+				+ "(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n"
+				+ "window.parent.OnUploadCompleted(201,'/fckeditor-java/userfiles/image/hacked_php.txt','hacked_php.txt');\n</script>");
+		assertEquals(expected, actual.toString());
+	}
+
+	@Test
+	public void customMessage() throws Exception {
+		UploadResponse actual = new UploadResponse(UploadResponse.EN_ERROR);
+		actual.setCustomMessage("some error");
+		String expected = new String("<script type=\"text/javascript\">\n"
+				+ "(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n"
+				+ "window.parent.OnUploadCompleted(1,'','','some error');\n</script>");
+		assertEquals(expected, actual.toString());
+	}
+
+
+	@Test
+	public void nullArguments() throws Exception {
+		UploadResponse actual = new UploadResponse(UploadResponse.EN_ERROR,null,null,null);
+		String expected = new String("<script type=\"text/javascript\">\n"
+				+ "(function(){var d=document.domain;while (true){try{var A=window.top.opener.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})();\n"
+				+ "window.parent.OnUploadCompleted(1,'','','');\n</script>");
+		assertEquals(expected, actual.toString());
+	}
+
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/CompatibilityTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/CompatibilityTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/CompatibilityTest.java	(revision 2015)
@@ -0,0 +1,113 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link Compatibility}.<br>
+ * User-Agent-Strings are taken from: http://www.useragentstring.com/pages/useragentstring.php <br>
+ * 
+ * @version $Id$
+ */
+public class CompatibilityTest {
+
+	@Test
+	public void testIE4Win() throws Exception {
+	    assertFalse(Compatibility.check("Mozilla/4.0 (compatible; MSIE 4.01; Windows NT 5.0)"));
+    }
+	
+	@Test
+	public void testIE522Mac() throws Exception {
+	    assertFalse(Compatibility.check("Mozilla/4.0 (compatible; MSIE 5.22; Mac_PowerPC)"));
+    }
+	
+	@Test
+	public void testIE55Win98() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)"));
+    }
+
+	@Test
+	public void testIE60WinNT() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1)"));
+    }
+	
+	@Test
+	public void testIE70WinVista() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0;)"));
+    }
+
+	@Test
+	public void testIE70bWinVista() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)"));
+    }
+	
+	@Test
+	public void testSafari204OSX() throws Exception {
+	    assertFalse(Compatibility.check("Mozilla/5.0 (Macintosh; U; PPC Mac OS X; sv-se) AppleWebKit/419 (KHTML, like Gecko) Safari/419.3"));
+    }
+
+	@Test
+	public void testSafari30WinXP() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/5.0 (Windows; U; Windows NT 5.2; pt) AppleWebKit/522.11.3 (KHTML, like Gecko) Version/3.0 Safari/522.11.3"));
+    }
+
+	@Test
+	public void testSafari302OSX() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/522+ (KHTML, like Gecko) Version/3.0.2 Safari/522.12"));
+    }
+
+	@Test
+	public void testSafari31OSX() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_2; en-au) AppleWebKit/525.8+ (KHTML, like Gecko) Version/3.1 Safari/525.6"));
+    }
+
+	@Test
+	public void testFirefox200112OSX() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12"));
+    }
+
+	@Test
+	public void testFirefox1509LinuxDebian() throws Exception {
+	    assertTrue(Compatibility.check("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/1.5.0.9 (Debian-2.0.0.9-2)"));
+    }
+	
+	@Test
+	public void testOper925Win2k() throws Exception {
+	    assertFalse(Compatibility.check("Opera/9.25 (Windows NT 5.0; U; en)"));
+    }
+	
+	@Test
+	public void testOpera854WinNT() throws Exception {
+	    assertFalse(Compatibility.check("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; de) Opera 8.54"));
+    }
+	
+	@Test
+	public void testOpera95OSX() throws Exception {
+		assertTrue(Compatibility.check("Opera/9.50 (Macintosh; Intel Mac OS X; U; en)"));   
+    }
+	
+	@Test
+	public void testOpera95WinVista() throws Exception {
+		assertTrue(Compatibility.check("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.0; en) Opera 9.50"));   
+    }
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/UtilsFileTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/UtilsFileTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/UtilsFileTest.java	(revision 2015)
@@ -0,0 +1,199 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+
+/**
+ * Tests for {@link UtilsFile}.
+ *
+ * @version $Id$
+ */
+public class UtilsFileTest {
+
+	@Test
+    public void isSingleExtension01() {
+    	boolean condition = UtilsFile.isSingleExtension("hacked.txt");
+    	assertTrue(condition);
+    }
+
+	@Test
+    public void isSingleExtension02() {
+    	boolean condition = UtilsFile.isSingleExtension("hacked.php_txt");
+    	assertTrue(condition);
+    }
+
+	@Test
+    public void isSingleExtension03() {
+    	boolean condition = UtilsFile.isSingleExtension("hacked.php.txt");
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isSingleExtension04() {
+    	boolean condition = UtilsFile.isSingleExtension("hacked.txt.");
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isSingleExtension05() {
+    	boolean condition = UtilsFile.isSingleExtension("hacked..txt");
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void forceSingleExtension01() {
+    	String actual = UtilsFile.forceSingleExtension("hacked.txt");
+    	assertEquals("hacked.txt", actual);
+    }
+
+	@Test
+    public void forceSingleExtension02() {
+    	String actual = UtilsFile.forceSingleExtension("hacked.php_txt");
+    	assertEquals("hacked.php_txt", actual);
+    }
+
+	@Test
+    public void forceSingleExtension03() {
+    	String actual = UtilsFile.forceSingleExtension("hacked.php.txt");
+    	assertEquals("hacked_php.txt", actual);
+    }
+
+	@Test
+    public void forceSingleExtension04() {
+    	String actual = UtilsFile.forceSingleExtension("hacked..txt");
+    	assertEquals("hacked_.txt", actual);
+    }
+
+	@Test
+    public void isValidPath01() {
+    	String path = "";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isValidPath02() {
+    	String path = "/";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertTrue(condition);
+    }
+
+	@Test
+    public void isValidPath03() {
+    	String path = "/./";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isValidPath04() {
+    	String path = "/newf/..";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isValidPath05() {
+    	String path = "/../";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isValidPath06() {
+    	String path = "/stuff/../..";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isValidPath07() {
+    	String path = "/my/stuff/../";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isValidPath08() {
+    	String path = "/my/stuff/";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertTrue(condition);
+    }
+
+	@Test
+    public void isValidPath09() {
+    	String path = "/my/stuff";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void isValidPath10() {
+    	String path = "my/stuff/";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+	
+	@Test
+    public void isValidPath11() {
+    	String path = "/some/pa\\th/";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+	
+	@Test
+    public void isValidPath12() {
+    	String path = "/\\/";
+    	boolean condition = UtilsFile.isValidPath(path);
+    	assertFalse(condition);
+    }
+
+	@Test
+    public void sanitizeFolder01() {
+    	assertEquals("a_b_c_d_e_f_g_h_i_", UtilsFile.sanitizeFolderName("a.b|c<d>e:f?g*h<i>"));
+    }
+	
+	@Test
+	public void sanitizeFolder02() {
+		assertEquals("a_b_c_d_e_f_g_h_i_", UtilsFile.sanitizeFolderName("a.b|c\u007Fd>e:f\u0005g*h<i>"));
+	}
+
+	@Test
+    public void sanitizeFile01() {
+    	assertEquals("b_c_d_e_f_g_h_i_", UtilsFile.sanitizeFileName("b|c<d>e:f?g*h<i>"));
+    }
+
+	@Test
+    public void sanitizeFile02() {
+    	assertEquals("name_ext1.ext2", UtilsFile.sanitizeFileName("name.ext1.ext2"));
+    }
+
+	@Test
+	public void sanitizeFile03() {
+		assertEquals("b_c_d_e_f_g_h_i_", UtilsFile.sanitizeFileName("b|c\u007Fd>e:f\u0005g*h<i>"));
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/UtilsTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/UtilsTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/UtilsTest.java	(revision 2015)
@@ -0,0 +1,101 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link Utils};
+ * 
+ * @version $Id$
+ */
+public class UtilsTest {
+
+	@Test
+	public void getSet01() {
+		Set<String> set = new HashSet<String>();
+		set.add("a");
+		set.add("ab");
+		set.add("c");
+
+		Set<String> newSet = Utils.getSet("a|Ab|c", "|");
+		for (String string : newSet) {
+			assertTrue(set.contains(string));
+		}
+	}
+
+	@Test
+	public void getSet02() {
+		Set<String> set = new HashSet<String>();
+		set.add("png");
+		set.add("jpg");
+		set.add("gif");
+
+		Set<String> newSet = Utils.getSet("png|jpg|gif");
+		for (String string : newSet) {
+			assertTrue(set.contains(string));
+		}
+	}
+	
+	@Test
+	public void getSet03() {
+		Set<String> set = Utils.getSet(null);
+		assertTrue(set != null);
+		assertTrue(set.isEmpty());
+	}
+
+	@Test
+	public void getSet04() {
+		Set<String> set = Utils.getSet("");
+		assertTrue(set != null);
+		assertTrue(set.isEmpty());
+	}
+
+	@Test
+	public void replaceAll01() {
+		String str = Utils.replaceAll("//a/b//c", "//", "/");
+		assertEquals(str, "/a/b/c");
+	}
+
+	@Test
+	public void replaceAll02() {
+		String str = Utils.replaceAll(null, "a", "c");
+		assertEquals(str, "");
+	}
+
+	@Test
+	public void replaceAll03() {
+		String str = Utils.replaceAll("foo", null, "c");
+		assertEquals(str, "foo");
+	}
+
+	@Test
+	public void replaceAll04() {
+		String str = Utils.replaceAll("foo", "o", "a");
+		assertEquals(str, "faa");
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/XHtmlTagToolTest.java
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/XHtmlTagToolTest.java	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-core/src/test/java/net/fckeditor/tool/XHtmlTagToolTest.java	(revision 2015)
@@ -0,0 +1,103 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+package net.fckeditor.tool;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link XHtmlTagTool}.
+ *
+ * @version $Id$
+ */
+public class XHtmlTagToolTest {
+
+	@Test
+	public void testClosingTag01() throws Exception {
+	    XHtmlTagTool tag = new XHtmlTagTool("test");
+	    assertEquals("<test />", tag.toString());
+    }
+	
+	@Test
+	public void testClosingTag02() throws Exception {
+	    XHtmlTagTool tag = new XHtmlTagTool("test", "");
+	    assertEquals("<test />", tag.toString());
+    }
+
+	@Test
+	public void testClosingTag03() throws Exception {
+	    XHtmlTagTool tag = new XHtmlTagTool("test", "val");
+	    assertEquals("<test>val</test>", tag.toString());
+    }
+	
+	@Test
+	public void testClosingTag04() throws Exception {
+	    XHtmlTagTool tag = new XHtmlTagTool("test", XHtmlTagTool.SPACE);
+	    assertEquals("<test> </test>", tag.toString());
+    }
+	
+	@Test
+	public void deepEquals01() throws Exception {
+		XHtmlTagTool expected = new XHtmlTagTool("tag", "some text");
+		XHtmlTagTool actual = new XHtmlTagTool("tag", "some text");
+		assertEquals(expected, actual);
+	}
+	
+	@Test
+	public void deepEquals02() throws Exception {
+		XHtmlTagTool unexpected = new XHtmlTagTool("tag", "");
+		XHtmlTagTool actual = new XHtmlTagTool("tag", XHtmlTagTool.SPACE);
+		assertNotSame(unexpected, actual);
+	}
+	
+	@Test
+	public void deepEquals03() throws Exception {
+		XHtmlTagTool expected = new XHtmlTagTool("tag", "some text");
+		expected.addAttribute("id", "some_tag_id");
+		expected.addAttribute("class", "grayShadow");
+		expected.addAttribute("style", "color: red");
+		
+		XHtmlTagTool actual = new XHtmlTagTool("tag", "some text");
+		
+		actual.addAttribute("style", "color: red");
+		actual.addAttribute("id", "some_tag_id");
+		actual.addAttribute("class", "grayShadow");
+		
+		assertEquals(expected, actual);
+	}
+	
+	@Test
+	public void deepEquals04() throws Exception {
+		XHtmlTagTool unexpected = new XHtmlTagTool("tag");
+		unexpected.addAttribute("id", "some_tag_id");
+		unexpected.addAttribute("class", "grayShadow");
+		unexpected.addAttribute("style", "color: red");
+		
+		XHtmlTagTool actual = new XHtmlTagTool("tag");
+		
+		actual.addAttribute("id", "some_tag_id");
+		actual.addAttribute("class", "grayShadow");
+		actual.addAttribute("style", "color: blue");
+		
+		assertNotSame(unexpected, actual);
+	}
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/pom.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/pom.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/pom.xml	(revision 2015)
@@ -0,0 +1,115 @@
+<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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>java-demo</artifactId>
+	<packaging>war</packaging>
+	<dependencies>
+		<dependency>
+			<groupId>net.fckeditor</groupId>
+			<artifactId>java-core</artifactId>
+			<version>2.4-beta-1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-simple</artifactId>
+			<version>1.5.0</version>
+			<scope>runtime</scope>
+		</dependency>
+	</dependencies>
+	<parent>
+		<groupId>net.fckeditor</groupId>
+		<artifactId>fckeditor-java</artifactId>
+		<version>2.4-beta-1</version>
+	</parent>
+
+	<build>
+		<finalName>fckeditor-${artifactId}-${version}</finalName>
+		<plugins>
+			<plugin>
+				<groupId>org.mortbay.jetty</groupId>
+				<artifactId>maven-jetty-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<artifactId>maven-war-plugin</artifactId>
+				<configuration>
+					<webResources>
+						<resource>
+							<targetPath>fckeditor</targetPath>
+							<directory>../../fckeditor</directory>
+							<filtering>false</filtering>
+							<includes>
+								<include>_samples/_plugins/</include>
+								<include>editor/</include>
+								<include>fckconfig.js</include>
+								<include>*.xml</include>
+							</includes>
+							<excludes>
+								<exclude>
+									editor/filemanager/connectors/
+								</exclude>
+							</excludes>
+						</resource>
+						<resource>
+							<directory>..</directory>
+							<filtering>false</filtering>
+							<includes>
+								<include>LICENSE.txt</include>
+							</includes>
+						</resource>
+					</webResources>
+					<archive>
+						<addMavenDescriptor>false</addMavenDescriptor>
+						<manifest>
+							<addDefaultImplementationEntries>
+								true
+							</addDefaultImplementationEntries>
+						</manifest>
+						<manifestEntries>
+							<Implementation-URL>
+								${project.url}
+							</Implementation-URL>
+							<Built-By>${organization.name}</Built-By>
+						</manifestEntries>
+					</archive>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-clean-plugin</artifactId>
+				<configuration>
+					<filesets>
+						<fileset>
+							<directory>src/main/webapp</directory>
+							<includes>
+								<include>fckeditor/</include>
+								<include>userfiles/</include>
+							</includes>
+						</fileset>
+					</filesets>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<reporting>
+		<plugins>
+			<plugin>
+				<artifactId>
+					maven-project-info-reports-plugin
+				</artifactId>
+				<reportSets>
+					<reportSet>
+						<reports>
+							<report>dependencies</report>
+							<report>summary</report>
+						</reports>
+					</reportSet>
+				</reportSets>
+			</plugin>
+		</plugins>
+	</reporting>
+	<name>FCKeditor.Java Integration Demo Webapp</name>
+	<description>
+		This is a drop-in demo of the FCKeditor.Java Integration. It's
+		preconfigured with the Java library and a recent FCKeditor version.
+	</description>
+	<url>http://java.fckeditor.net</url>
+</project>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/resources/fckeditor.properties
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/resources/fckeditor.properties	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/resources/fckeditor.properties	(revision 2015)
@@ -0,0 +1,1 @@
+connector.userActionImpl=net.fckeditor.requestcycle.impl.UserActionImpl
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/resources/log4j.properties
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/resources/log4j.properties	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/resources/log4j.properties	(revision 2015)
@@ -0,0 +1,7 @@
+log4j.rootLogger=DEBUG, SOCKET
+
+log4j.appender.SOCKET=org.apache.log4j.net.SocketAppender
+log4j.appender.SOCKET.RemoteHost=localhost
+log4j.appender.SOCKET.Port=4445
+
+log4j.logger.org.apache=WARN
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/WEB-INF/web.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/WEB-INF/web.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/WEB-INF/web.xml	(revision 2015)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4" id="fckeditor-java" 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"
+>
+<display-name>FCKeditor.Java Sample Web Application</display-name>
+	<description>FCKeditor.Java Sample Web Application</description>
+
+	<servlet>
+		<servlet-name>Connector</servlet-name>
+		<servlet-class>
+			net.fckeditor.connector.ConnectorServlet
+		</servlet-class>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>Connector</servlet-name>
+		<url-pattern>
+			/fckeditor/editor/filemanager/connectors/*
+		</url-pattern>
+	</servlet-mapping>
+</web-app>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/index.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/index.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/index.jsp	(revision 2015)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8"%>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - Samples</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link rel="shortcut icon" href="fckeditor.gif"
+				type="image/x-icon" />
+	</head>
+	<frameset rows="60,*">
+		<frame src="sampleslist.jsp" noresize ="noresize" scrolling="no" />
+		<frame name="Sample" src="jsp/sample01.jsp" noresize="noresize" />
+	</frameset>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample01.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample01.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample01.jsp	(revision 2015)
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" import="net.fckeditor.*" %>
+<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - JSP Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+		<script type="text/javascript">
+			function FCKeditor_OnComplete(editorInstance) {
+				window.status = editorInstance.Description;
+			}
+		</script>
+	</head>
+	<%
+		FCKeditor fckEditor = new FCKeditor(request, "EditorDefault");
+	%>
+	<body>
+		<h1>FCKeditor - JSP - Sample 1</h1>
+		<p>This sample displays a normal HTML form with an FCKeditor with
+		full features enabled.</p>
+		<p>Basic FCKeditor informations:</p>
+		<ul>
+			<li><FCK:check command="CompatibleBrowser" /></li>
+			<li><FCK:check command="FileBrowsing" /></li>
+			<li><FCK:check command="FileUpload" /></li>
+		</ul>
+		<hr />
+		<form action="sampleposteddata.jsp" method="get" target="_blank">
+		<%
+			fckEditor.setValue("This is some <strong>sample text</strong>. You are using <a href=\"http://www.fckeditor.net\">FCKeditor</a>.");
+			out.println(fckEditor);
+		%>
+		<br />
+		<input type="submit" value="Submit" /></form>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample02.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample02.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample02.jsp	(revision 2015)
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" %>
+<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - JSP Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+		<script type="text/javascript">
+			function FCKeditor_OnComplete(editorInstance) {
+				window.status = editorInstance.Description;
+			}
+		</script>
+	</head>
+	<body>
+		<h1>FCKeditor - JSP - Sample 2</h1>
+		This sample displays a normal HTML form with an FCKeditor with full 
+		features enabled.<br />
+		This sample uses the FCKeditor Taglib: this method is preferred to 
+		<a href="sample01.jsp">the API version</a><br />
+		All other sample pages will use this method.
+		<hr />
+		<form action="sampleposteddata.jsp" method="get" target="_blank">
+			<FCK:editor instanceName="EditorDefault">
+				<jsp:attribute name="value">This is some <strong>sample text
+					</strong>. You are using <a href="http://www.fckeditor.net">
+					FCKeditor</a>.
+				</jsp:attribute>
+			</FCK:editor>
+			<br />
+			<input type="submit" value="Submit" />
+		</form>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample03.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample03.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample03.jsp	(revision 2015)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" %>
+<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - JSP Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+		<script type="text/javascript">
+			function FCKeditor_OnComplete(editorInstance) {
+				var oCombo = document.getElementById( 'cmbLanguages' );
+				for (code in editorInstance.Language.AvailableLanguages) {
+					AddComboOption( oCombo,	editorInstance.Language.AvailableLanguages[code] + '(' + code + ')', code);
+				}
+
+				oCombo.value = editorInstance.Language.ActiveLanguage.Code;
+			}
+
+			function AddComboOption(combo, optionText, optionValue) {
+				var oOption = document.createElement("OPTION");
+				combo.options.add(oOption);
+
+				oOption.innerHTML = optionText;
+				oOption.value = optionValue;
+	
+				return oOption;
+			}
+
+			function ChangeLanguage(languageCode) {
+				if (languageCode != "-1")
+					window.location.href = window.location.pathname + "?code=" + languageCode;
+			}
+		</script>
+	</head>
+	<body>
+		<h1>FCKeditor - JSP - Sample 3</h1>
+		This sample shows the editor in all it's available languages.<br />
+		The Language dropdown is populated with JavaScript API.
+		<hr />
+		<table cellpadding="0" cellspacing="0" border="0">
+			<tr>
+				<td>
+					Select a language:&nbsp;
+				</td>
+				<td>
+					<select id="cmbLanguages" onchange="ChangeLanguage(this.value);" >
+						<option value="-1">none selected</option>
+					</select>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<form action="sampleposteddata.jsp" method="get" target="_blank">
+			<FCK:editor instanceName="EditorDefault">
+				<jsp:attribute name="value">This is some <strong>sample text
+					</strong>. You are using <a href="http://www.fckeditor.net">
+					FCKeditor</a>.
+				</jsp:attribute>
+				<jsp:body>
+					<FCK:config AutoDetectLanguage="${empty param.code ? true : false}"
+						DefaultLanguage="${empty param.code ? 'en' : param.code}" />
+				</jsp:body>
+			</FCK:editor>
+			<br />
+			<input type="submit" value="Submit" />
+		</form>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample04.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample04.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample04.jsp	(revision 2015)
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" %>
+<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - JSP Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+		<script type="text/javascript">
+			function FCKeditor_OnComplete(editorInstance) {
+				var oCombo = document.getElementById('cmbToolbars');
+				oCombo.value = editorInstance.ToolbarSet.Name;
+				oCombo.style.visibility = '';
+			}
+
+			function ChangeToolbarSet(toolbarSet) {
+				window.location.href = window.location.pathname + "?toolbar=" + toolbarSet;
+			}
+			</script>
+	</head>
+	<body>
+		<h1>FCKeditor - JSP - Sample 4</h1>
+		This sample shows how to change the editor toolbar.
+		<hr />
+		<table cellpadding="0" cellspacing="0" border="0">
+			<tr>
+				<td>
+					Select the toolbar to load:&nbsp;
+				</td>
+				<td>
+					<select id="cmbToolbars" onchange="ChangeToolbarSet(this.value);" style="visibility: hidden">
+						<option value="Default" selected="selected">Default</option>
+						<option value="Basic">Basic</option>
+					</select>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<form action="sampleposteddata.jsp" method="get" target="_blank">
+			<FCK:editor instanceName="EditorDefault" toolbarSet="${param.toolbar}">
+				<jsp:attribute name="value">This is some <strong>sample text
+					</strong>. You are using <a href="http://www.fckeditor.net">
+					FCKeditor</a>.
+				</jsp:attribute>
+			</FCK:editor>
+			<br />
+			<input type="submit" value="Submit" />
+		</form>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample05.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample05.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample05.jsp	(revision 2015)
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" %>
+<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - JSP Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+		<script type="text/javascript">
+			function FCKeditor_OnComplete(editorInstance) {
+				var oCombo = document.getElementById('cmbSkins') ;
+	
+				// Get the active skin.
+				var sSkin = editorInstance.Config['SkinPath'] ;
+				sSkin = sSkin.match( /[^\/]+(?=\/$)/g ) ;
+	
+				oCombo.value = sSkin ;
+				oCombo.style.visibility = '' ;
+			}
+
+			function ChangeSkin(skinName) {
+				window.location.href = window.location.pathname + "?skin=" + skinName ;
+			}
+		</script>
+	</head>
+	<%
+		String skinStr=request.getParameter("skin");
+		if(skinStr!=null) 
+			skinStr= "skins/" + skinStr + "/"; 	//basePath +  constant relative skin path + skinName
+		pageContext.setAttribute("skin",skinStr);
+	%>	
+	<body>
+		<h1>FCKeditor - JSP - Sample 5</h1>
+		This sample shows how to change the editor skin.
+		<hr />
+		<table cellpadding="0" cellspacing="0" border="0">
+			<tr>
+				<td>
+					Select the skin to load:&nbsp;
+				</td>
+				<td>
+					<select id="cmbSkins" onchange="ChangeSkin(this.value);" style="visibility: hidden">
+						<option value="default" selected="selected">Default</option>
+						<option value="office2003">Office 2003</option>
+						<option value="silver">Silver</option>
+					</select>
+				</td>
+			</tr>
+		</table>
+		<br />
+		<form action="sampleposteddata.jsp" method="get" target="_blank">
+			<FCK:editor instanceName="EditorDefault">
+				<jsp:attribute name="value">This is some <strong>sample text
+					</strong>. You are using <a href="http://www.fckeditor.net">
+					FCKeditor</a>.
+				</jsp:attribute>
+				<jsp:body>
+					<FCK:config SkinPath="${skin}"/>
+				</jsp:body>
+			</FCK:editor>
+			<br />
+			<input type="submit" value="Submit" />
+		</form>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample06.config.js
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample06.config.js	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample06.config.js	(revision 2015)
@@ -0,0 +1,42 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ * 
+ * == BEGIN LICENSE ==
+ * 
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ * 
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ * 
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ * 
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ * 
+ * == END LICENSE ==
+ */
+
+// Set our sample toolbar.
+FCKConfig.ToolbarSets['PluginTest'] = [
+	['Source'],
+	['My_Find','My_Replace','-','Placeholder'],
+	//['Table','-','TableInsertRow','TableDeleteRows','TableInsertColumn','TableDeleteColumns','TableInsertCell','TableDeleteCells','TableMergeCells','TableSplitCell'],
+	['Bold','Italic','-','OrderedList','UnorderedList','-','Link','Unlink','-','About']
+] ;
+
+// Change the default plugin path.
+FCKConfig.PluginsPath = FCKConfig.BasePath.substr(0, FCKConfig.BasePath.length - 7) + '_samples/_plugins/' ;
+
+// Add our plugin to the plugins list.
+//		FCKConfig.Plugins.Add( pluginName, availableLanguages )
+//			pluginName: The plugin name. The plugin directory must match this name.
+//			availableLanguages: a list of available language files for the plugin (separated by a comma).
+FCKConfig.Plugins.Add( 'findreplace', 'en,it' ) ;
+
+// If you want to use plugins found on other directories, just use the third parameter.
+var sOtherPluginPath = FCKConfig.BasePath.substr(0, FCKConfig.BasePath.length - 7) + 'editor/plugins/' ;
+FCKConfig.Plugins.Add( 'placeholder', 'en,it', sOtherPluginPath ) ;
+//FCKConfig.Plugins.Add( 'tablecommands', 'en,it', sOtherPluginPath ) ;
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample06.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample06.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample06.jsp	(revision 2015)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" %>
+<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+		<script type="text/javascript">
+			function FCKeditor_OnComplete(editorInstance) {
+				window.status = editorInstance.Description;
+			}
+		</script>
+	</head>
+	<body>
+		<h1>FCKeditor - JSP - Sample 6</h1>
+		This sample shows a sample plugin implementation.
+		<br />
+		These are sample "Find" and "Replace" plugin that do exactly the same 
+		thing that the built in ones do. Use the green toolbar buttons the test then.
+		<br />
+		There is also another sample plugin that is available in the package: 
+		the "Placeholder" command (use the yellow icon).
+		<hr />
+		<form action="sampleposteddata.jsp" method="post" target="_blank">
+			<FCK:editor instanceName="EditorDefault" toolbarSet="PluginTest">
+				<jsp:attribute name="value">This is some <strong>sample text
+					</strong>. You are using <a href="http://www.fckeditor.net">
+					FCKeditor</a>.
+				</jsp:attribute>
+				<jsp:body>
+					<FCK:config CustomConfigurationsPath="${pageContext.request.contextPath}/jsp/sample06.config.js" />
+				</jsp:body>
+			</FCK:editor>
+			<br />
+			<input type="submit" value="Submit" />
+		</form>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample07.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample07.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sample07.jsp	(revision 2015)
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" %>
+<%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - Sample</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+		<script type="text/javascript">
+			function FCKeditor_OnComplete(editorInstance) {
+				window.status = editorInstance.Description;
+			}
+		</script>
+	</head><body>
+		<h1>FCKeditor - JSP - Sample 7</h1>
+		In this sample the user can edit the complete page contents and header (from 
+		&lt;HTML&gt; to &lt;/HTML&gt;).
+		<hr />
+		<form action="sampleposteddata.jsp" method="post" target="_blank">
+			<FCK:editor instanceName="EditorDefault">
+				<jsp:attribute name="value">
+					<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+						<html>
+							<head>
+								<title>Full Page Test</title>
+								<meta content="text/html; charset=utf-8" 
+									http-equiv="Content-Type"/>
+							</head>
+							<body>This is some <strong>sample text</strong>. You are 
+								using <a href="http://www.fckeditor.net/">FCKeditor
+								</a>.
+							</body>
+						</html>
+				</jsp:attribute>
+				<jsp:body>
+					<FCK:config FullPage="true"/>
+				</jsp:body>
+			</FCK:editor>
+			<br />
+			<input type="submit" value="Submit" />
+		</form>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sampleposteddata.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sampleposteddata.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/jsp/sampleposteddata.jsp	(revision 2015)
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8" import="java.util.Enumeration;"%>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - Samples - Posted Data</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="../sample.css" rel="stylesheet" type="text/css" />
+		<link rel="shortcut icon" href="../fckeditor.gif"
+				type="image/x-icon" />
+	</head>
+	<%
+		Enumeration<String> params = (Enumeration<String>) request.getParameterNames();
+	%>
+	<body>
+		<h1>FCKeditor - Samples - Posted Data</h1>
+		This page lists all data posted by the form.
+		<hr />
+		<table width="100%" border="1" cellspacing="0">
+			<tr style="FONT-WEIGHT: bold; COLOR: #dddddd; BACKGROUND-COLOR: #999999">
+				<td nowrap="nowrap">Field Name&nbsp;&nbsp;</td>
+				<td>Value</td>
+			</tr>
+			<%
+				String parameter;
+				while(params.hasMoreElements()) {
+					parameter = params.nextElement();
+			%>
+			<tr>
+				<td valign="top" nowrap="nowrap"><b><%=parameter%></b></td>
+				<td width="100%"><%=request.getParameter(parameter)%></td>
+			</tr>
+			<%
+				}
+			%>
+		</table>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/sample.css
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/sample.css	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/sample.css	(revision 2015)
@@ -0,0 +1,24 @@
+/* @Packager.Header
+<FileDescription>
+	Styles used in the samples pages.
+</FileDescription>
+*/
+
+body, td, input, select, textarea
+{
+	font-size: 12px;
+	font-family: Arial, Verdana, Sans-Serif;
+}
+
+h1
+{
+	font-weight: bold;
+	font-size: 180%;
+	margin-bottom: 10px;
+}
+
+form
+{
+	margin: 0px 0px 0px 0px;
+	padding: 0px 0px 0px 0px;
+}
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/sampleslist.jsp
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/sampleslist.jsp	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/main/webapp/sampleslist.jsp	(revision 2015)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8"%>
+<%--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<title>FCKeditor - Sample Selection</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="robots" content="noindex, nofollow" />
+		<link href="sample.css" rel="stylesheet" type="text/css" />
+		<script type="text/javascript">
+			if (window.top == window)
+				document.location = 'index.jsp' ;
+
+			function OpenSample(sample) {
+				if (sample.length > 0)
+					window.open( sample, 'Sample' );
+			}
+		</script>
+	</head>
+	<body>
+		<table border="0" cellpadding="0" cellspacing="0">
+			<tr>
+				<td>Please select the sample you want to view: <br />
+				<select onchange="OpenSample(this.value);">
+					<option value="jsp/sample01.jsp" selected="selected">
+					Sample 01: Editor with all features generated via API</option>
+					<option value="jsp/sample02.jsp">Sample 02: Editor with all 
+					features generated with JSP Taglib</option>
+					<option value="jsp/sample03.jsp">Sample 03:	Multi-language 
+					support</option>
+					<option value="jsp/sample04.jsp">Sample 04: Toolbar
+					selection</option>
+					<option value="jsp/sample05.jsp">Sample 05: Skins
+					support</option>
+					<option value="jsp/sample06.jsp">Sample 06: Plugins
+					support</option>
+					<option value="jsp/sample07.jsp">Sample 07: Full Page
+					editing</option>
+				</select></td>
+			</tr>
+		</table>
+	</body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/site/resources/css/site.css
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/site/resources/css/site.css	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/java-demo/src/site/resources/css/site.css	(revision 2015)
@@ -0,0 +1,1 @@
+@import url(../../css/site.css);
Index: /FCKeditor.Java/tags/2.4-beta-1/pom.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/pom.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/pom.xml	(revision 2015)
@@ -0,0 +1,325 @@
+<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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>net.fckeditor</groupId>
+	<artifactId>fckeditor-java</artifactId>
+	<version>2.4-beta-1</version>
+	<packaging>pom</packaging>
+	<dependencies>
+		<dependency>
+			<groupId>commons-fileupload</groupId>
+			<artifactId>commons-fileupload</artifactId>
+			<version>1.2</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>1.3.2</version>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.5.0</version>
+		</dependency>
+	</dependencies>
+	<modules>
+		<module>java-core</module>
+		<module>java-demo</module>
+	</modules>
+	<build>
+		<defaultGoal>package</defaultGoal>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.5</source>
+					<target>jsr14</target>
+				</configuration>
+				<executions>
+					<execution>
+						<id>test-compiler</id>
+						<phase>process-test-sources</phase>
+						<goals>
+							<goal>testCompile</goal>
+						</goals>
+						<configuration>
+							<source>1.5</source>
+							<target>1.5</target>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<version>2.2-beta-1</version>
+				<configuration>
+					<descriptors>
+						<descriptor>
+							src/main/assembly/src.xml
+						</descriptor>
+						<descriptor>
+							src/main/assembly/bin.xml
+						</descriptor>
+					</descriptors>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>attach-javadocs</id>
+						<goals>
+							<goal>jar</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<addDefaultImplementationEntries>
+								true
+							</addDefaultImplementationEntries>
+						</manifest>
+						<manifestEntries>
+							<Implementation-URL>
+								${project.url}
+							</Implementation-URL>
+							<Built-By>${organization.name}</Built-By>
+						</manifestEntries>
+					</archive>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-site-plugin</artifactId>
+				<version>2.0-beta-5</version>
+				<configuration>
+					<outputEncoding>utf-8</outputEncoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-antrun-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>rewrite-site-links</id>
+						<phase>pre-site</phase>
+						<goals>
+							<goal>run</goal>
+						</goals>
+						<configuration>
+							<tasks>
+								<copy overwrite="true" todir="src/site" flatten="true">
+									<fileset dir="..">
+										<include name="src/site/site.xml" />
+									</fileset>
+								</copy>
+								<replace value="&lt;src&gt;../" token="&lt;src&gt;/" dir="..">
+									<include name="${pom.artifactId}/src/site/site.xml" />
+									<exclude name="fckeditor-java/src/site/site.xml" />
+								</replace>
+								<replace value="href=&quot;../" token="href=&quot;/" dir="..">
+									<include name="${pom.artifactId}/src/site/site.xml" />
+									<exclude name="fckeditor-java/src/site/site.xml" />
+								</replace>
+								<replace value="href=&quot;" token="href=&quot;../${pom.artifactId}/" dir="..">
+									<include name="${pom.artifactId}/src/site/site.xml" />
+									<exclude name="fckeditor-java/src/site/site.xml" />
+								</replace>
+								<replace value="href=&quot;../images" token="href=&quot;images" dir="..">
+									<include name="${pom.artifactId}/src/site/site.xml" />
+									<exclude name="fckeditor-java/src/site/site.xml" />
+								</replace>
+							</tasks>
+						</configuration>
+					</execution>
+				</executions>
+				<dependencies>
+					<dependency>
+						<groupId>ant</groupId>
+						<artifactId>ant-nodeps</artifactId>
+						<version>1.6.5</version>
+					</dependency>
+				</dependencies>
+			</plugin>
+		</plugins>
+	</build>
+
+	<reporting>
+		<plugins>
+			<plugin>
+				<artifactId>
+					maven-project-info-reports-plugin
+				</artifactId>
+				<reportSets>
+					<reportSet>
+						<reports>
+							<report>dependencies</report>
+							<report>issue-tracking</report>
+							<report>mailing-list</report>
+							<report>license</report>
+							<report>summary</report>
+							<report>project-team</report>
+							<report>scm</report>
+						</reports>
+					</reportSet>
+				</reportSets>
+			</plugin>
+			<!-- Postponed to beyond 2.4 -->
+			<!--
+			<plugin>
+				<artifactId>maven-changes-plugin</artifactId>
+				<configuration>
+					<issueLinkTemplate>
+						%URL%/ticket/%ISSUE%
+					</issueLinkTemplate>
+				</configuration>
+				<reportSets>
+					<reportSet>
+						<reports>
+							<report>changes-report</report>
+						</reports>
+					</reportSet>
+				</reportSets>
+			</plugin>
+			-->
+			<plugin>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<configuration>
+					<quiet>true</quiet>
+				</configuration>
+			</plugin>
+		</plugins>
+	</reporting>
+
+	<name>FCKeditor.Java Integration</name>
+	<description>
+		The FCKeditor.Java Integration fosters the entire project
+		documentation, the Java library, and a drop-in demo webapp. All
+		three depict and enable you to learn and to integrate the
+		FCKeditor in your web environment.
+	</description>
+	<url>http://java.fckeditor.net</url>
+	<inceptionYear>2004</inceptionYear>
+	<licenses>
+		<license>
+			<name>GPL, LGPL, MPL</name>
+			<url>LICENSE.txt</url>
+		</license>
+	</licenses>
+	<organization>
+		<name>Frederico Caldeira Knabben</name>
+		<url>http://www.fredck.com</url>
+	</organization>
+	<developers>
+		<developer>
+			<id>fredck</id>
+			<name>Frederico Caldeira Knabben</name>
+			<url>http://www.fredck.com</url>
+			<organization>FredCK.com</organization>
+			<organizationUrl>http://www.fredck.com</organizationUrl>
+			<roles>
+				<role>Head Project Manager</role>
+			</roles>
+			<timezone>+1</timezone>
+		</developer>
+		<developer>
+			<id>th-schwarz</id>
+			<name>Thilo Schwarz</name>
+			<email>thilo.schwarz AT gmail.com</email>
+			<url>http://www.s-th.info</url>
+			<organization>Poor Man's CMS</organization>
+			<organizationUrl>http://poormans.sf.net</organizationUrl>
+			<roles>
+				<role>Project Manager</role>
+				<role>Developer</role>
+			</roles>
+			<timezone>+1</timezone>
+		</developer>
+		<developer>
+			<id>mosipov</id>
+			<name>Michael Osipov</name>
+			<email>michael-o AT users.sourceforge.net</email>
+			<roles>
+				<role>Project Manager</role>
+				<role>Developer</role>
+			</roles>
+			<timezone>+1</timezone>
+		</developer>
+	</developers>
+	<issueManagement>
+		<system>Trac</system>
+		<url>http://dev.fckeditor.net/</url>
+	</issueManagement>
+	<mailingLists>
+		<mailingList>
+			<name>FCKeditor Developers List</name>
+			<subscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-developers
+			</subscribe>
+			<unsubscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-developers
+			</unsubscribe>
+			<archive>
+				http://sourceforge.net/mailarchive/forum.php?forum_name=fckeditor-developers
+			</archive>
+		</mailingList>
+		<mailingList>
+			<name>FCKeditor Testers List</name>
+			<subscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-testers
+			</subscribe>
+			<unsubscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-testers
+			</unsubscribe>
+			<archive>
+				http://sourceforge.net/mailarchive/forum.php?forum_name=fckeditor-testers
+			</archive>
+		</mailingList>
+		<mailingList>
+			<name>FCKeditor Trac Activity</name>
+			<subscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-trac
+			</subscribe>
+			<unsubscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-trac
+			</unsubscribe>
+		</mailingList>
+		<mailingList>
+			<name>FCKeditor Commits List</name>
+			<subscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-commits
+			</subscribe>
+			<unsubscribe>
+				https://lists.sourceforge.net/lists/listinfo/fckeditor-commits
+			</unsubscribe>
+		</mailingList>
+	</mailingLists>
+	<scm>
+		<connection>scm:svn:http://svn.fckeditor.net/FCKeditor.Java/tags/2.4-beta-1</connection>
+		<url>http://dev.fckeditor.net/browser/FCKeditor.Java/tags/2.4-beta-1</url>
+	</scm>
+	<prerequisites>
+		<maven>2.0.8</maven>
+	</prerequisites>
+	<distributionManagement>
+		<repository>
+			<id>local</id>
+			<url>
+				file:///home/mosipov/public_html/m2repo
+			</url>
+		</repository>
+		<snapshotRepository>
+			<id>local</id>
+			<url>
+				file:///home/mosipov/public_html/m2repo-snapshots
+			</url>
+		</snapshotRepository>
+		<site>
+			<id>local</id>
+			<url>
+				file:///home/mosipov/public_html/docs
+			</url>
+		</site>
+	</distributionManagement>
+</project>
Index: /FCKeditor.Java/tags/2.4-beta-1/src/changes/changes.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/changes/changes.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/changes/changes.xml	(revision 2015)
@@ -0,0 +1,17 @@
+<document>
+
+	<properties>
+		<title>Changes Report</title>
+		<author email="jruiz@exist.com">Johnny R. Ruiz III</author>
+	</properties>
+
+	<body>
+		<release version="2.4" date="in SVN"
+			description="Complete integration overhaul"
+		>
+			<action dev="mosipov" type="add">TBD</action>
+			<action dev="th-schwarz" type="fix">TBD</action>
+		</release>
+	</body>
+
+</document>
Index: /FCKeditor.Java/tags/2.4-beta-1/src/main/assembly/bin.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/main/assembly/bin.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/main/assembly/bin.xml	(revision 2015)
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assembly>
+	<id>bin</id>
+	<formats>
+		<format>zip</format>
+		<format>tar.gz</format>
+	</formats>
+	<includeSiteDirectory>true</includeSiteDirectory>
+	<moduleSets>
+		<moduleSet>
+			<includes>
+				<include>*:jar</include>
+			</includes>
+			<binaries>	
+				<includeDependencies>false</includeDependencies>
+				<outputFileNameMapping>
+					fckeditor-${artifactId}-${version}.${extension}
+				</outputFileNameMapping>
+				<unpack>false</unpack>
+			</binaries>
+		</moduleSet>
+		<moduleSet>
+			<includes>
+				<include>*:jar</include>
+			</includes>
+			<binaries>
+				<attachmentClassifier>javadoc</attachmentClassifier>
+				<includeDependencies>false</includeDependencies>
+				<outputFileNameMapping>
+					fckeditor-${artifactId}-${version}-${classifier}.${extension}
+				</outputFileNameMapping>
+				<unpack>false</unpack>
+			</binaries>
+		</moduleSet>
+		<moduleSet>
+			<sources>
+				<includeModuleDirectory>false</includeModuleDirectory>
+				<fileSets>
+					<fileSet>
+						<outputDirectory>
+							site/${artifactId}
+						</outputDirectory>
+						<directory>target/site</directory>
+					</fileSet>
+				</fileSets>
+			</sources>
+		</moduleSet>
+	</moduleSets>
+	<fileSets>
+		<fileSet>
+			<includes>
+				<include>*.txt</include>
+			</includes>
+		</fileSet>
+	</fileSets>
+	<dependencySets>
+		<dependencySet>
+			<outputDirectory>lib</outputDirectory>
+		</dependencySet>
+	</dependencySets>
+</assembly>
Index: /FCKeditor.Java/tags/2.4-beta-1/src/main/assembly/src.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/main/assembly/src.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/main/assembly/src.xml	(revision 2015)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assembly>
+	<id>src</id>
+	<formats>
+		<format>zip</format>
+		<format>tar.gz</format>
+	</formats>
+	<moduleSets>
+		<moduleSet>
+			<sources>
+				<fileSets>
+					<fileSet>
+						<excludes>
+							<exclude>target/</exclude>
+						</excludes>
+					</fileSet>
+				</fileSets>
+			</sources>
+		</moduleSet>
+	</moduleSets>
+	<fileSets>
+		<fileSet>
+			<includes>
+				<include>src/</include>
+				<include>*.txt</include>
+				<include>*.xml</include>
+			</includes>
+		</fileSet>
+	</fileSets>
+</assembly>
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/connector.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/connector.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/connector.apt	(revision 2015)
@@ -0,0 +1,110 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~
+~~ == BEGIN LICENSE ==
+~~
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~
+~~ == END LICENSE ==
+~~ @version $Id$
+                        ------------------------------
+                           File Browser Connector
+                        ------------------------------
+
+Connector activation
+
+  The Connector is not mandatory. If you do <not> plan to provide userfile
+  interaction, you can skip this section.
+
+    [Hint:] The Connector by default is not present and disabled for security
+            reasons!
+
+  It takes two steps to enable it:
+
+  [[1]]  Declare the ConnectorServlet in your <<<web.xml>>>
+
++--------------------------------------------------+
+  <web-app version="2.4">
+    ...
+    <servlet>
+      <servlet-name>Connector</servlet-name>
+        <servlet-class>
+          net.fckeditor.connector.ConnectorServlet
+      </servlet-class>
+      <load-on-startup>1</load-on-startup>
+    </servlet>
+    ...
+    <servlet-mapping>
+      <servlet-name>Connector</servlet-name>
+      <url-pattern>
+        /fckeditor/editor/filemanager/connectors/*
+      </url-pattern>
+    </servlet-mapping>
+    ...
+  </web-app>
++--------------------------------------------------+
+
+  Assuming you installed the editor in the <<</fckeditor>>> folder in your webapp.\
+  The Connector is now declared but <still> disabled. The response is going to
+  be an error message.
+
+  [[2]] Create a <<<fckeditor.properties>>> file in your classpath and add:
+
++------------------------------------------------------------------------+
+  connector.userActionImpl=net.fckeditor.requestcycle.impl.UserActionImpl
++------------------------------------------------------------------------+
+
+  []
+
+  The Connector is now enabled.
+
+Extending the Connector
+
+    [Hint:]  Skip this section if you are not interested in extending the
+             Connector.
+
+  The basic idea of extending the Connector is to provide interfaces for user-dependent
+  interactions which can be implemented by the web application developer. All
+  methods are passed the current <<<HttpServletRequest>>> instance in order to
+  retrieve request and/or session attributes to assemble a user-specific
+  return value. We intentionally do not impose any constraints or indorse any
+  particular implementation approach to give you the freedom to implement the
+  interfaces the way it fits best in your environment.
+
+  Supply the fully-qualified class names of the implemented classes as described in
+  the {{{properties.html}Configuration settings}}.
+
+  Right now, the integration pack provides two interfaces to extend the Connector:
+
+  [[1]] {{{java-core/apidocs/net/fckeditor/requestcycle/UserPathBuilder.html}<<<net.fckeditor.requestcycle.UserPathBuilder>>>}}
+
+        This interface consists only of one method <<<#getUserFilesPath(final HttpServletRequest)>>>
+        which returns a string. You are able to construct a user-dependent 
+        <<<UserFilesPath>>>, e.g. <<</userfiles/johndoe>>>.
+
+  [[2]] {{{java-core/apidocs/net/fckeditor/requestcycle/UserAction.html}<<<net.fckeditor.requestcycle.UserAction>>>}}
+
+        There are two methods to authorize users to do file-based actions:
+
+        * <<<#isEnabledForFileBrowsing(HttpServletRequest)>>> which returns a 
+          <<<boolean>>> denoting the user's ability to browse files on the server.
+  
+        * <<<#isEnabledForFileUpload(HttpServletRequest)>>> which returns a 
+          <<<boolean>>> denoting the user's ability to upload files to the server.
+
+        []
+
+        For those who want to enable all users to browse and upload files, there 
+        is a ready-to-use implementation <<<{{{java-core/apidocs/net/fckeditor/requestcycle/impl/UserActionImpl.html}UserActionImpl}}>>>.
+
+  []
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/demo.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/demo.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/demo.apt	(revision 2015)
@@ -0,0 +1,46 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~ 
+~~ == BEGIN LICENSE ==
+~~ 
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~ 
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~ 
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~ 
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~ 
+~~ == END LICENSE ==
+~~ @version $$Id$$
+                                    ------------------------------
+                                           		Demo
+                                    ------------------------------
+
+Demo Web Application
+
+    [Requirements:] You need at least JRE 1.4 and a Servlet 2.4/JSP 2.0 compliant 
+                    server implementation to run the library and the demo webapp.
+
+  The demo is intended for novices, beginners and for everyone who wants to see
+  the FCKeditor (version 2.6) in action right out of the box. It's also a good 
+  reference for you to see how all integral parts work together.
+
+  It takes three simple steps to see the demo in action:
+
+   [[1]] Download the <<<fckeditor-java-demo-2.4-beta-1.war>>> from the
+         {{{http://www.fckeditor.net/download}download area}}.
+
+   [[2]] Deploy the <<<fckeditor-java-demo-2.4-beta-1.war>>> in your servlet container 
+         or application server and make sure that the context is enabled.
+        
+   [[3]] Open up your browser and point to <<<http://localhost:8080/fckeditor-java-demo-2.4-beta-1>>>.
+         (assuming your server is running local at port 8080 for testing purposes)
+
+   []
+
+  You are now ready to explore the FCKeditor!
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/index.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/index.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/index.apt	(revision 2015)
@@ -0,0 +1,52 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~
+~~ == BEGIN LICENSE ==
+~~
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~
+~~ == END LICENSE ==
+~~ @version $Id$
+                                    ------------------------------
+												About
+                                    ------------------------------
+
+FCKeditor.Java Integration
+
+  The FCKeditor.Java Integration makes the deployment of the FCKeditor in your
+  Java environment a piece of cake.
+
+  A rich documentation, a well-designed Java library, and an out of the box demo 
+  webapp will show you how to get started quickly and deploy the FCKeditor within
+  minutes without juggling with cryptic JSP scriptlets or any JavaScript API.
+  Although it's targeted to be used as a tag library within JSPs, it's a snap
+  within a template engine like {{{http://velocity.apache.org}Velocity}} or 
+  {{{http://freemarker.org}Freemaker}} too.
+
+* Documentation Guideline
+  
+  This documentation is straight forward to use!\
+  Start with {{{whatsnew.html}What's new}} to see what has changed since 2.3 and
+  there is a lot! Go over and checkout the {{{demo.html}Demo}} and if you are 
+  ready to deploy the FCKeditor in your webapp follow the 
+  {{{installation.html}Installation Guide}} and the {{{overview.html}Integration Overview}}.
+  
+
+Call To Action
+
+  Help us to improve the FCKeditor.Java Integration!
+
+  If you think this documentation, the Java library or anything else is lacking 
+  something, contains errors, or can be improved do <not> hesitate to open a 
+  thread in our {{{http://www.fckeditor.net/forums}forums}} or file a ticket in 
+  our {{{issue-tracking.html}issue tracker}}.
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/installation.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/installation.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/installation.apt	(revision 2015)
@@ -0,0 +1,151 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~ 
+~~ == BEGIN LICENSE ==
+~~ 
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~ 
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~ 
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~ 
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~ 
+~~ == END LICENSE ==
+~~ @version $Id$
+                        ------------------------------
+                                Installation
+                        ------------------------------
+
+Installation Guide
+
+    [Requirements:] You need at least JRE 1.4 and a Servlet 2.4/JSP 2.0 compliant 
+                    server implementation to run the library and the demo webapp.
+
+* Using Maven 2
+
+    [Attention:]  The integration pack will be available on the central repo
+                  after it has gone gold, from then on the additional repository
+                  location will be obsolete!
+
+  Include a dependency reference to the library in the dependencies section of 
+  your POM:
+
++-------------------------------------------------------+
+<project>
+  ...
+  <repositories>
+    <repository>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+      <id>fckeditor-java-releases</id>
+      <name>FCKeditor.Java Releases</name>
+      <url>http://java.fckeditor.net/m2repo</url>
+      <layout>default</layout>
+    </repository>
+  </repositories>
+  ...
+  <dependencies>
+    <dependency>
+      <groupId>net.fckeditor</groupId>
+      <artifactId>java-core</artifactId>
+      <version>2.4-beta-1</version>
+    </dependency>
+  </dependencies>
+  ...
+</project>
++-------------------------------------------------------+
+
+* Manual installation
+
+  The distribution comes in three flavors, pick one from the 
+  {{{http://www.fckeditor.net/download}download area}} which fits best in your
+  environment.
+
+  * <<<fckeditor-java-core-2.4-beta-1.jar>>>
+
+    If you already have all dependencies on your classpath, simply put this jar
+    on your classpath (usually <<<WEB-INF/lib>>>) and you are ready to go.
+
+  * <<<fckeditor-java-2.4-beta-1-bin.zip>>> (or <<<tar.gz>>>)
+
+    If you are starting from scratch, this distribution fits best. This package
+    comes with pre-built jars, all dependencies, the entire documentation for
+    offline usage and the license file.
+
+    The pre-built jars are:
+
+*--------------------------------------------+----------------------------------+
+|| File                                      || Description                    ||
+*--------------------------------------------+----------------------------------+
+| fckeditor-java-core-2.4-beta-1.jar         | main jar                         |
+*--------------------------------------------+----------------------------------+
+| fckeditor-java-core-2.4-beta-1-javadoc.jar | optional javadoc for IDE integration |
+*--------------------------------------------+----------------------------------+
+
+    The <<<lib>>> folder contains the following dependencies:
+
+*--------------------------------------------+----------------------------------+
+|| File                                      || Description                    ||
+*--------------------------------------------+----------------------------------+
+| commons-fileupload-1.2.jar                 | Apache Commons FileUpload library|
+*--------------------------------------------+----------------------------------+
+| commons-io-1.3.2.jar                       | Apache Commons IO library        |
+*--------------------------------------------+----------------------------------+
+| slf4j-api-1.5.0.jar                        | Simple logging facade library    |
+*--------------------------------------------+----------------------------------+
+
+    Drop the main jar and the dependencies in your classpath (usually
+    <<<WEB-INF/lib>>>) and you are ready to go.
+
+  * <<<fckeditor-java-2.4-beta-1-src.zip>>>  (or <<<tar.gz>>>)
+
+    If you want to check out the integration's source code, refit to your needs
+    (obeying the license terms) or compile yourself, this is the perfect
+    distribution for you. Building the WAR yourself requires having the a <<<fckeditor>>>
+    folder at the same level as the <<<fckeditor-java-2.4-beta-1>>> folder.
+
+  []
+
+* FCKeditor installation
+
+  Although the public distribution is fine, it still contains a lot of superfluous
+  files for a Java environment. Use the following <<<Ant>>> target on the FCKeditor
+  zip file (1,25 MiB) to create a cleaner and smaller distribution zip file (986 KiB).
+
++----------------------------------------------------------------------------------+
+<target name="clean-fckeditor" description="Creates a clean FCKeditor distribution">
+  <!-- Adapt properties to your needs -->
+  <property name="fckeditor-tmp" location="fckeditor-tmp" />
+  <property name="fckeditor-basename" value="FCKeditor_2.6" />
+  <property name="fckeditor-destfile" value="${fckeditor-basename}_clean.zip" />
+
+  <delete file="${fckeditor-destfile}" />
+  <unzip dest="${fckeditor-tmp}" src="${fckeditor-basename}.zip" />
+  <zip destfile="${fckeditor-destfile}">
+    <zipfileset dir="${fckeditor-tmp}/fckeditor" prefix="fckeditor">
+      <include name="_samples/_plugins/" />
+      <include name="editor/" />
+      <include name="fckconfig.js" />
+      <include name="*.xml" />
+      <exclude name="editor/filemanager/connectors/" />
+    </zipfileset>
+  </zip>
+  <delete dir="${fckeditor-tmp}" />
+</target>
++----------------------------------------------------------------------------------+
+
+A word on Logging
+
+    [Attention:] Do <not> skip this section otherwise your application will <<fail>>!
+
+  We use the state-of-the-art logging facade <<<SLF4J>>>. To make SFL4J work at runtime, 
+  you have to add <<one>> binding and the appropriate  backend (may be optional) into 
+  your classpath.\
+  Please check the {{{http://slf4j.org}SLF4J website}} for more information on bindings
+  and the API itself.
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/overview.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/overview.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/overview.apt	(revision 2015)
@@ -0,0 +1,36 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~ 
+~~ == BEGIN LICENSE ==
+~~ 
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~ 
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~ 
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~ 
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~ 
+~~ == END LICENSE ==
+~~ @version $Id$
+				---------------
+					Overview
+				---------------
+
+Overview
+
+  The Java integration pack consists of two main components:
+  
+  * <<JSP tag library>>: Easy integration of the FCKeditor in your JSPs.
+    
+  * <<Connector>>: A servlet to manage resources like images, documents, and other files.
+  
+  []
+  
+  Please read the integration parts carefully! Both the tag library and the connector
+  have been completely restructured.
+  
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/properties.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/properties.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/properties.apt	(revision 2015)
@@ -0,0 +1,143 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~ 
+~~ == BEGIN LICENSE ==
+~~ 
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~ 
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~ 
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~ 
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~ 
+~~ == END LICENSE ==
+~~ @version $Id$
+                   ------------------------------
+                       Configuration reference
+                   ------------------------------
+
+Configuration setting
+
+  In the meaning of 'convention over configuration' all properties are optional.
+  Define only those you intend to override for the <entire> web application.
+
+  There are two ways to override the default properties: 
+
+  * By creating a <<<fckeditor.properties>>> file in the classpath (usually 
+    <<<WEB-INF/classes>>>):
+
++-------------------------------------------------------+
+  ...
+  fckeditor.toolbarSet=Silver
+  connector.userActionImpl=net.fckeditor.requestcycle.impl.UserActionImpl
+  ...
++-------------------------------------------------------+
+
+  * By calling dynamically the <<<PropertiesHolder>>> class:
+
++-------------------------------------------------------+
+  ...
+  import net.fckeditor.handlers.PropertiesLoader;
+  ...
+  PropertiesLoader.setProperty("fckeditor.toolbarSet", "Silver");
+  PropertiesLoader.setProperty("connector.userActionImpl", 
+                   "net.fckeditor.requestcycle.impl.UserActionImpl");
+  ...
++-------------------------------------------------------+   
+
+    [Attention:] It is essential to know how to use the <<<PropertiesHolder>>>. Like 
+                 the common properties usage, you should use it only at 
+                 the start of your web application. If you don't have a kind of 
+                 an 'initialization' servlet, where you could place the 
+                 PropertiesLoader calls, we suggest you to write your own 
+                 ServletContextListener. So you guarantee, you call the 
+                 PropertiesLoader <before> the ConnectorServlet is initialized.
+
+  []
+
+  As you can see, setting a property is equal in both ways. The tables below 
+  list all configurable properties for the integration pack.
+
+Configuration properties
+
+* FCKeditor
+
+*------------------------------------+--------------------------------+-----------------------------+-----------------------------------+
+|| Property                          || Default                       || Valid Values               || Description                     ||
+||                                   ||                               ||                            ||                                 ||
+*------------------------------------+--------------------------------+-----------------------------+-----------------------------------+
+| fckeditor.toolbarSet \ \ \ \ \ \ 	 | Default                		  | any string \ \ \ \ \ \      | Indicates the toolbar set you want to load. If you provide a name which does not exist, the editor will fail to load. |
+*------------------------------------+--------------------------------+-----------------------------+-----------------------------------+
+| fckeditor.width	                 | 200	                          | any string					| Indicates the editor width. 		|
+*------------------------------------+--------------------------------+-----------------------------+-----------------------------------+
+| fckeditor.height	                 | 100%						      | any string                  | Indicates the editor height. 		|
+*------------------------------------+--------------------------------+-----------------------------+-----------------------------------+
+| fckeditor.basePath		         | /fckeditor \ \ \ \ \ \         | any path                    | The default path of the editor installation resides within your webapp. |
+|                                    | 							      |                             | Change this value only if you install the editor under a different name or maintain several editor installations. |
+*------------------------------------+--------------------------------+-----------------------------+-----------------------------------+
+
+* Connector
+
+  The integration library supports file, flash, image, and media resource types.
+  Replace <type name> in the property name with "file", "flash", "image", or 
+  "media".
+
+  Define <<either>> an allowed <<or>> denied list. If an allowed list is pre-defined
+  overwrite it with an empty list and define your denied list as you wish.
+
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+|| Property                     || Default                       || Valid Values               || Description                                      ||
+||	                            ||                               ||                            ||                                                  ||
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.resourceType.<type	| /<type name>  	             | any path                    | Indicates the resource type path to retrieve and store files. |
+| name>.path					|								 |							   |													|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.resourceType.<type	|                        		 | any extension			   | List with extensions which should be denied.	  	|
+| name>.extensions.denied		|								 | 							   | separate extensions with a \| (pipe symbol).		|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.resourceType.file.	| 7z\|aiff\|asf\|avi\|bmp\|csv\| | any extension			   | List with extensions which should be allowed.		|
+| extensions.allowed			| doc\|fla\|flv\|gif\|gz\|gzip\| |							   | separate extensions with a \| (pipe symbol).		|
+|								| jpeg\|jpg\|mid\|mov\|mp3\|mp4\||							   |													|
+|								| mpc\|mpeg\|mpg\|ods\|odt\|pdf\||							   |													|
+|								| png\|ppt\|pxd\|qt\|ram\|rar\|  |							   |													|
+|								| rm\|rmi\|rmvb\|rtf\|sdc\|sitd\||							   |													|
+|								| swf\|sxc\|sxw\|tar\|tgz\|tif\| |							   |													|
+|								| tiff\|txt\|vsd\|wav\|wma\|wmv\||							   |													|
+|								| xls\|xml\|zip				   	 |							   |													|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.resourceType.flash. | swf\|fla					   	 | any extension		 	   | See above.										 	|
+| extensions.allowed			|						 		 |							   |													|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.resourceType.image.	| bmp\|gif\|jpeg\|jpg\|png		 | any extension			   | See above.										 	|
+| extensions.allowed			|								 |							   |													|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.resourceType.media.	| aiff\|asf\|avi\|bmp\|fla\|flv\|| any extension			   | See above.										 	|
+| extensions.allowed			| gif\|jpeg\|jpg\|mid\|mov\|mp3\||							   |													|
+|								| mp4\|mpc\|mpeg\|mpg\|png\|qt\| |							   |													|
+|								| ram\|rm\|rmi\|rmvb\|swf\|tif\| |							   |													|
+|								| tiff\|wav\|wma\|wmv			 |							   |													|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.userFilesPath		| /userfiles					 | any path					   | Indicates the path where files are stored.			|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.forceSingleExtension| true							 | true, false (boolean)	   | Indicates whether file names with multiple extensions are sanitzed.|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.fullUrl      		| false                          | true, false (boolean)	   | Indicates whether the server url will be prepended.|
+|								|								 |							   | I.e. prepending http://www.yourdomain.com/			|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.secureImageUploads	|true							 | true, false (boolean)	   | Checks uploaded images for validity.				|
+|								|								 |							   | I.e. the uploaded file is a real image and not any |
+|								|								 |							   | other renamed file type.							|
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.userActionImpl		|								 | any class implementing the  | Provides custom security functions for the File	|
+|								|								 | {{{java-core/apidocs/net/fckeditor/requestcycle/UserAction.html}<<<net.fckeditor.requestcycle.UserAction>>>}} | Browser Connector. For more details see		|
+|								|								 | interface			   | {{{connector.html}here}}. |
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
+| connector.userPathBuilderImpl |								 | any class implementing the  | Provides a custom function to construct a user-dependent 'UserFilesPath' for the |
+|								|								 | {{{java-core/apidocs/net/fckeditor/requestcycle/UserPathBuilder.html}<<<net.fckeditor.requestcycle.UserPathBuilder>>>}} | File Browser Connector. For more details see		|
+|								|								 | interface			   | {{{connector.html}here}}. |
+*-------------------------------+--------------------------------+-----------------------------+----------------------------------------------------+
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/taglibrary.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/taglibrary.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/taglibrary.apt	(revision 2015)
@@ -0,0 +1,51 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~ 
+~~ == BEGIN LICENSE ==
+~~ 
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~ 
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~ 
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~ 
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~ 
+~~ == END LICENSE ==
+~~ @version $Id$
+                    ---------------------
+                         Tag Library
+                    ---------------------
+
+Tag library
+
+  Declare the tag extension in each JSP page that uses the FCKeditor.Java taglib.
+  The uri directive must match the uri defined in the {{{java-core/tagreference.html}tag reference}}.
+  The prefix identifies the tags in the tag library within the JSP page.
+
++--------------------------------------------------------------------+
+  <%@ taglib uri="http://java.fckeditor.net" prefix="FCK" %>
++--------------------------------------------------------------------+
+
+  The declaration, if you are using a JSP XML syntax, looks like:
+
++--------------------------------------------------------------------+
+  <jsp:root version="2.0" xmlns:jsp="http://java.sun.com/JSP/Page"
+     xmlns:FCK="http://java.fckeditor.net">
++--------------------------------------------------------------------+
+
+  Now you are set to use the taglib. A brief declaration would be:
+
++--------------------------------------------------------------------+
+  <FCK:editor instanceName="EditorDefault">
+    <jsp:attribute name="value">This is some <strong>sample text</strong>.
+      You are using <a href="http://www.fckeditor.net">FCKeditor</a>.
+    </jsp:attribute>
+  </FCK:editor>
++--------------------------------------------------------------------+
+
+  For a more complete overview, take a look at the {{{java-core/tagreference.html}tag reference}}.
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/whatsnew.apt
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/whatsnew.apt	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/apt/whatsnew.apt	(revision 2015)
@@ -0,0 +1,68 @@
+~~ FCKeditor - The text editor for Internet - http://www.fckeditor.net
+~~ Copyright (C) 2003-2008 Frederico Caldeira Knabben
+~~
+~~ == BEGIN LICENSE ==
+~~
+~~ Licensed under the terms of any of the following licenses at your
+~~ choice:
+~~
+~~  - GNU General Public License Version 2 or later (the "GPL")
+~~    http://www.gnu.org/licenses/gpl.html
+~~
+~~  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+~~    http://www.gnu.org/licenses/lgpl.html
+~~
+~~  - Mozilla Public License Version 1.1 or later (the "MPL")
+~~    http://www.mozilla.org/MPL/MPL-1.1.html
+~~
+~~ == END LICENSE ==
+~~ @version $Id$
+                                    ------------------------------
+												What's New
+                                    ------------------------------
+
+
+What's New
+
+  The FCKeditor.Java integration version 2.4 is a complete rewrite of the last
+  version.\
+  This is a short overview of the changes since version 2.3:
+
+  * The integration pack is now managed by {{{http://maven.apache.org}Maven 2}}
+    with complete documentation and reports.
+    
+  * Automatic creation of release distribution files (assemblies).
+
+  * The library runs now from Servlet 2.4/JSP 2.0 and above.
+
+  * A complete structure and package review has been done. Base package moved from
+    <<<com.fredck.FCKeditor>>> to <<<net.fckeditor>>>.
+
+  * The {{{http://dev.fckeditor.net/wiki/ServerSideStatus}Server Side Integration}}
+    requirements are completely fulfilled.
+
+  * The SimpleUploaderServlet functionality has been merged into the ConnectorServlet.
+
+  * The JSP tag library has been completely restructured.
+
+  * A more complete and reliable browser detection code.
+
+  * New configuration handling:
+
+    * No configuration settings in the <<<web.xml>>> anymore.
+
+    * The configuration properties can be set in a common properties file or programmatically.
+
+    * 'Convention over conversion', just reset the properties which don't meet your
+      requirements.
+
+  * Introduced the state-of-the-art {{{http://www.slf4j.org}SLF4J}} logging facade.
+
+  * Pluggable interfaces have been introduced to extend the ConnectorServlet. This system
+    provides session or request-based functionality.
+
+  * JUnit test coverage on viable classes.
+
+  * Clean and safe parameter handling and abstraction.
+
+  * A lot of code performance improvements and tweaks.
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/resources/css/site.css
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/resources/css/site.css	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/resources/css/site.css	(revision 2015)
@@ -0,0 +1,165 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ * @version $Id$
+ */
+
+/* @override http://page.mi.fu-berlin.de/ossipov/fckeditor-java/css/site.css */
+
+body {
+	background-color: #F9F2DE;
+}
+
+a, a:link, a:visited, a:active, a:hover {
+	color: #FF6600;
+	text-decoration: none;
+}
+a:hover {
+	text-decoration: underline;
+}
+a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
+	padding-right: 18px;
+	color: #FF6600;
+	text-decoration: none;
+}
+a.externalLink:hover {
+	text-decoration: underline;
+}
+
+h2 {
+	background-color: white;
+	border-top: 0;
+	border-right: 0;
+	border-left: 0;
+	border-bottom: 1px solid #E2D8C0;
+	color: #3F2008;
+	font-size: x-large;
+	font-weight: bold;
+}
+
+h3 {
+	background-color: white;
+	border-top: 0;
+	border-right: 0;
+	border-left: 0;
+	border-bottom: 1px solid #E2D8C0;
+	color: #FF7011;
+	font-size: large;
+	font-weight: bold;
+}
+
+h4 {
+	background-color: white;
+	border-top: 0;
+	border-right: 0;
+	border-left: 0;
+	border-bottom: 1px solid #E2D8C0;
+	color: #FF7011;
+	font-size: medium;
+	font-weight: bold;
+}
+
+h2, h3, h4 {
+	margin: 0 0 15px 0;
+	padding: 0 0 5px 0;
+}
+
+dl {
+	background-color:  rgb(247, 247, 247);
+	border: 5px solid #FF7011;
+	padding: 4px 4px 4px 6px;
+	font-size: 90%;
+}
+dl dt {
+	color: #3F2008;
+	font-weight: bold;
+	font-size: small;
+	margin-bottom: 3px;
+}
+
+/* @group banner */
+#banner {
+	height: 68px;
+}
+
+#banner a#bannerLeft img {
+	margin: 15px 0 0 30px !important;
+}
+/* @end */
+
+/* @group breadcrumbs */
+#breadcrumbs {
+	background-color: white;
+	color: black;
+}
+
+#breadcrumbs .xleft {
+	text-shadow: none;
+}
+/* @end */
+
+/* @group footer */
+#footer .xright {
+	text-shadow: none;
+}
+/* @end */
+
+/* @group body */
+#leftColumn {
+	float: left;
+	overflow: auto;
+	width: 200px;
+	margin: 0;
+	border: 0;
+	background-color: #F9F2DE;
+}
+#navcolumn {
+	margin: 15px 0 0 30px;
+}
+
+#bodyColumn {
+	background-color: white;
+	border: 2px solid #E2D8C0;
+	margin: 15px 30px 15px 230px;
+	padding: 10px;
+}
+
+.section {
+	margin-bottom: 35px;
+	padding: 0;
+}
+
+.source {
+	margin: 1em 0px;
+	padding: 12px;
+	font-family: monospace;
+	font-size: 9pt;
+	background-color: rgb(247, 247, 247);
+}
+/* @end */
+
+
+/* @group menu */
+#navcolumn {
+	padding: 8px 4px 0 8px;
+	background-color: white;
+	border: 2px solid #E2D8C0;
+}
+
+/* @end */
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/site.vm
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/site.vm	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/site.vm	(revision 2015)
@@ -0,0 +1,364 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+#macro ( link $href $name )
+  #if ( ( $href.toLowerCase().startsWith("http") || $href.toLowerCase().startsWith("https") ) )
+    <a href="$href" class="externalLink">$name</a>
+  #else
+    <a href="$href">$name</a>
+  #end
+#end
+
+#macro ( banner $banner $id )
+  #if ( $banner )
+    #if( $banner.href )
+      <a href="$banner.href" id="$id">
+    #else
+        <span id="$id">
+    #end
+
+    #if( $banner.src )
+        #set ( $src = $banner.src )
+        #if ( ! ( $src.toLowerCase().startsWith("http") || $src.toLowerCase().startsWith("https") ) )
+            #set ( $src = $PathTool.calculateLink( $src, $relativePath ) )
+            #set ( $src = $src.replaceAll( "\\", "/" ) )
+        #end
+        #if ( $banner.alt )
+            #set ( $alt = $banner.alt )
+        #else
+            #set ( $alt = "" )
+        #end
+        <img src="$src" alt="$alt" />
+    #else
+        $banner.name
+    #end
+
+    #if( $banner.href )
+        </a>
+    #else
+        </span>
+    #end
+  #end
+#end
+
+#macro ( links $links )
+  #set ( $counter = 0 )
+  #foreach( $item in $links )
+    #set ( $counter = $counter + 1 )
+    #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
+    #set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )
+    #link( $currentItemHref $item.name )
+    #if ( $links.size() > $counter )
+      |
+    #end
+  #end
+#end
+
+#macro ( breadcrumbs $breadcrumbs )
+  #set ( $counter = 0 )
+  #foreach( $item in $breadcrumbs )
+    #set ( $counter = $counter + 1 )
+    #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
+    #set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )
+
+    #if ( $currentItemHref == $alignedFileName || $currentItemHref == "" )
+      $item.name
+    #else
+      #link( $currentItemHref $item.name )
+    #end
+    #if ( $breadcrumbs.size() > $counter )
+      &gt;
+    #end
+  #end
+#end
+
+#macro ( displayTree $display $item )
+  #if ( $item && $item.items && $item.items.size() > 0 )
+    #foreach( $subitem in $item.items )
+      #set ( $subitemHref = $PathTool.calculateLink( $subitem.href, $relativePath ) )
+      #set ( $subitemHref = $subitemHref.replaceAll( "\\", "/" ) )
+
+      #if ( $alignedFileName == $subitemHref )
+        #set ( $display = true )
+      #end
+
+      #displayTree( $display $subitem )
+    #end
+  #end
+#end
+
+#macro ( menuItem $item )
+  #set ( $collapse = "none" )
+  #set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
+  #set ( $currentItemHref = $currentItemHref.replaceAll( "\\", "/" ) )
+
+  #if ( $item && $item.items && $item.items.size() > 0 )
+    #if ( $item.collapse == false )
+      #set ( $collapse = "expanded" )
+    #else
+      ## By default collapsed
+      #set ( $collapse = "collapsed" )
+    #end
+
+    #set ( $display = false )
+    #displayTree( $display $item )
+
+    #if ( $alignedFileName == $currentItemHref || $display )
+      #set ( $collapse = "expanded" )
+    #end
+  #end
+  <li class="$collapse">
+    #if ( $item.img )
+      #if ( ! ( $item.img.toLowerCase().startsWith("http") || $item.img.toLowerCase().startsWith("https") ) )
+        #set ( $src = $PathTool.calculateLink( $item.img, $relativePath ) )
+        #set ( $src = $src.replaceAll( "\\", "/" ) )
+        <img src="$src"/>
+      #else
+        <img src="$item.img" align="absbottom" style="border-width: 0"/>
+      #end
+    #end
+    #if ( $alignedFileName == $currentItemHref )
+      <strong>$item.name</strong>
+    #else
+      #link( $currentItemHref $item.name )
+    #end
+  #if ( $item && $item.items && $item.items.size() > 0 )
+    #if ( $collapse == "expanded" )
+      <ul>
+        #foreach( $subitem in $item.items )
+          #menuItem( $subitem )
+        #end
+      </ul>
+    #end
+  #end
+  </li>
+#end
+
+#macro ( mainMenu $menus )
+  #foreach( $menu in $menus )
+    #if ( $menu.name )
+    <h5>$menu.name</h5>
+    #end
+    #if ( $menu.items && $menu.items.size() > 0 )
+    <ul>
+      #foreach( $item in $menu.items )
+        #menuItem( $item )
+      #end
+    </ul>
+    #end
+  #end
+#end
+
+#macro ( copyright )
+  #if ( $project )
+    #if ( ${project.organization} ) 
+      #set ( $period = "" )
+	#else 
+	  #set ( $period = "." )
+	#end
+	#set ( $currentYear = ${currentDate.year} + 1900 )
+    #if ( ${project.inceptionYear} && ( ${project.inceptionYear} != ${currentYear.toString()} ) )
+      ${project.inceptionYear}-${currentYear}${period}
+    #else
+      ${currentYear}${period}
+    #end
+
+    #if ( ${project.organization} )
+      #if ( ${project.organization.name} && ${project.organization.url} )
+          <a href="$project.organization.url">$project.organization.name</a>.
+      #elseif ( ${project.organization.name} )
+        $project.organization.name.
+      #end
+    #end
+  #end
+#end
+
+#macro ( publishDate $position $publishDate $version )
+  #if ( $publishDate && $publishDate.format )
+    #set ( $format = $publishDate.format )
+  #else
+    #set ( $format = "yyyy-MM-dd" )
+  #end
+
+  $dateFormat.applyPattern( $format )
+
+  #set ( $dateToday = $dateFormat.format( $currentDate ) )
+
+  #if ( $publishDate && $publishDate.position )
+    #set ( $datePosition = $publishDate.position )
+  #else
+    #set ( $datePosition = "left" )
+  #end
+
+  #if ( $version )
+    #if ( $version.position )
+      #set ( $versionPosition = $version.position )
+    #else
+      #set ( $versionPosition = "left" )
+    #end
+  #end
+
+  #set ( $breadcrumbs = $decoration.body.breadcrumbs )
+  #set ( $links = $decoration.body.links )
+
+  #if ( $datePosition.equalsIgnoreCase( "right" ) && $links && $links.size() > 0 )
+    #set ( $prefix = "&nbsp;|" )
+  #else
+    #set ( $prefix = "" )
+  #end
+
+  #if ( $datePosition.equalsIgnoreCase( $position ) )
+    #if ( ( $datePosition.equalsIgnoreCase( "right" ) ) || ( $datePosition.equalsIgnoreCase( "bottom" ) ) )
+      $prefix $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday
+      #if ( $versionPosition.equalsIgnoreCase( $position ) )
+        &nbsp;| $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+      #end
+    #elseif ( ( $datePosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $datePosition.equalsIgnoreCase( "navigation-top" ) ) )
+      <div id="lastPublished">
+        $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday
+        #if ( $versionPosition.equalsIgnoreCase( $position ) )
+          &nbsp;| $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+        #end
+      </div>
+    #elseif ( $datePosition.equalsIgnoreCase("left") )
+      <div class="xleft">
+        $i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday
+        #if ( $versionPosition.equalsIgnoreCase( $position ) )
+          &nbsp;| $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+        #end
+        #if ( $breadcrumbs && $breadcrumbs.size() > 0 )
+          | #breadcrumbs( $breadcrumbs )
+        #end
+      </div>
+    #end
+  #elseif ( $versionPosition.equalsIgnoreCase( $position ) )
+    #if ( ( $versionPosition.equalsIgnoreCase( "right" ) ) || ( $versionPosition.equalsIgnoreCase( "bottom" ) ) )
+      $prefix $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+    #elseif ( ( $versionPosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $versionPosition.equalsIgnoreCase( "navigation-top" ) ) )
+      <div id="lastPublished">
+        $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+      </div>
+    #elseif ( $versionPosition.equalsIgnoreCase("left") )
+      <div class="xleft">
+        $i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}
+        #if ( $breadcrumbs && $breadcrumbs.size() > 0 )
+          | #breadcrumbs( $breadcrumbs )
+        #end
+      </div>
+    #end
+  #elseif ( $position.equalsIgnoreCase( "left" ) )
+    #if ( $breadcrumbs && $breadcrumbs.size() > 0 )
+      <div class="xleft">
+        #breadcrumbs( $breadcrumbs )
+      </div>
+    #end
+  #end
+#end
+
+#macro ( poweredByLogo $poweredBy )
+    #if( $poweredBy )
+        #foreach ($item in $poweredBy)
+            #if( $item.href )
+                #set ( $href = $PathTool.calculateLink( $item.href, $relativePath ) )
+                #set ( $href = $href.replaceAll( "\\", "/" ) )
+            #else
+                #set ( $href="http://maven.apache.org/" )
+            #end
+
+            #if( $item.name )
+                #set ( $name = $item.name )
+            #else
+                #set ( $name = $i18n.getString( "site-renderer", $locale, "template.builtby" )  )
+                #set ( $name = "${name} Maven"  )
+            #end
+
+            #if( $item.img )
+                #set ( $img = $item.img )
+            #else
+                #set ( $img = "images/logos/maven-feather.png" )
+            #end
+
+            <a href="$href" title="$name" class="poweredBy">
+              #set ( $img = $PathTool.calculateLink( $img, $relativePath ) )
+              #set ( $img = $img.replaceAll( "\\", "/" ) )
+              <img alt="$name" src="$img" />
+            </a>
+        #end
+        #if( $poweredBy.isEmpty() )
+          <a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
+            <img alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/logos/maven-feather.png"></img>
+          </a>
+        #end
+    #else
+        <a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
+          <img alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/logos/maven-feather.png"></img>
+        </a>
+    #end
+#end
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>$title</title>
+    <style type="text/css" media="all">
+      @import url("$relativePath/css/maven-base.css");
+      @import url("$relativePath/css/maven-theme.css");
+      @import url("$relativePath/css/site.css");
+    </style>
+    <link rel="stylesheet" href="$relativePath/css/print.css" type="text/css" media="print" />
+    #foreach( $author in $authors )
+      <meta name="author" content="$author" />
+    #end
+    <meta http-equiv="Content-Type" content="text/html; charset=${outputEncoding}" />
+    #if ( $decoration.body.head )
+      #foreach( $item in $decoration.body.head.getChildren() )
+        ## Workaround for DOXIA-150 due to a non-desired behaviour in p-u
+        ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toString()
+        ## @see org.codehaus.plexus.util.xml.Xpp3Dom#toUnescapedString()
+        #set ( $documentHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" )
+        #set ( $documentHeader = $documentHeader.replaceAll( "\\", "" ) )
+        #if ( $item.name == "script" )
+          $StringUtils.replace( $item.toUnescapedString(), $documentHeader, "" )
+        #else
+          $StringUtils.replace( $item.toString(), $documentHeader, "" )
+        #end
+      #end
+    #end
+  </head>
+  <body class="composite">
+    <div id="banner">
+      #banner( $decoration.bannerLeft "bannerLeft" )
+      #banner( $decoration.bannerRight "bannerRight" )
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="breadcrumbs">
+      #publishDate( "left" $decoration.publishDate $decoration.version )
+      <div class="xright">#links( $decoration.body.links )#publishDate( "right" $decoration.publishDate $decoration.version )</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+    <div id="leftColumn">
+      <div id="navcolumn">
+       #publishDate( "navigation-top" $decoration.publishDate $decoration.version )
+       #mainMenu( $decoration.body.menus )
+       #poweredByLogo( $decoration.poweredBy )
+       #publishDate( "navigation-bottom" $decoration.publishDate $decoration.version )
+      </div>
+    </div>
+    <div id="bodyColumn">
+      <div id="contentBox">
+        $bodyContent
+      </div>
+    </div>
+    <div class="clear">
+      <hr/>
+    </div>
+    <div id="footer">
+      <div class="xright">Copyright &#169;#copyright()All Rights Reserved.#publishDate( "bottom" $decoration.publishDate $decoration.version )</div>
+      <div class="clear">
+        <hr/>
+      </div>
+    </div>
+  </body>
+</html>
Index: /FCKeditor.Java/tags/2.4-beta-1/src/site/site.xml
===================================================================
--- /FCKeditor.Java/tags/2.4-beta-1/src/site/site.xml	(revision 2015)
+++ /FCKeditor.Java/tags/2.4-beta-1/src/site/site.xml	(revision 2015)
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+
+	<publishDate position="left" format="yyyy-MM-dd" />
+	<version position="left" />
+
+	<bannerLeft>
+		<name>fckeditor</name>
+		<src>/images/fckeditor-logo.gif</src>
+		<href>http://www.fckeditor.net</href>
+	</bannerLeft>
+
+	<body>
+		<head>
+			<link rel="shortcut icon" href="images/favicon.ico"
+				type="image/x-icon"
+			/>
+		</head>
+		<menu name="Introduction">
+			<item name="About" href="/index.html" />
+			<item name="What's new" href="/whatsnew.html" />
+			<item name="Demo" href="/demo.html" />
+			<item name="Installation" href="/installation.html" />
+		</menu>
+		<menu name="Integration">
+			<item name="Overview" href="/overview.html" />
+			<item name="Tag library"
+				href="/taglibrary.html"
+			/>
+			<item name="Connector" href="/connector.html" />
+		</menu>
+		<menu name="Reference">
+			<item name="Tag library"
+				href="/java-core/tagreference.html"
+			/>
+			<item name="Configuration"
+				href="/properties.html"
+			/>
+		</menu>
+		<!--<menu name="Developers">-->
+		<menu name="Project Documentation">
+			<!-- Postponed to beyond 2.4 -->
+			<!--<item name="Changes Report" href="/changes-report.html" />-->
+			<item name="Dependencies" href="/dependencies.html" />
+			<item name="Issue Tracking" href="/issue-tracking.html" />
+			<item name="Mailing Lists" href="/mail-lists.html" />
+			<item name="Project License" href="/license.html" />
+			<item name="Project Summary" href="/project-summary.html" />
+			<item name="Project Team" href="/team-list.html" />
+			<item name="Source Repository"
+				href="/source-repository.html"
+			/>
+		</menu>
+		<menu name="Modules Documentation">
+			<item name="Integration Pack" collapse="false">
+				<item name="Dependencies"
+					href="/java-core/dependencies.html"
+				/>
+				<item name="Module Summary"
+					href="/java-core/project-summary.html"
+				/>
+				<item name="Module Reports"
+					href="/java-core/project-reports.html" collapse="true"
+				>
+					<item name="Cobertura Test Coverage"
+						href="/java-core/cobertura/index.html"
+					/>
+					<item name="CPD Report"
+						href="/java-core/cpd.html"
+					/>
+					<item name="JavaDoc"
+						href="/java-core/apidocs/index.html"
+					/>
+					<item name="Maven Surefire Report"
+						href="/java-core/surefire-report.html"
+					/>
+					<item name="PMD Report"
+						href="/java-core/pmd.html"
+					/>
+					<item name="Source Xref"
+						href="/java-core/xref/index.html"
+					/>
+					<item name="Taglibdoc documentation"
+						href="/java-core/tlddoc/index.html"
+					/>
+					<item name="Tag library validation"
+						href="/java-core/taglibvalidation.html"
+					/>
+					<item name="Tag List"
+						href="/java-core/taglist.html"
+					/>
+					<!--<item name="Tag reference" href="/java-core/tagreference.html" />-->
+					<item name="Test JavaDocs"
+						href="/java-core/testapidocs/index.html"
+					/>
+					<item name="Test Source Xref"
+						href="/java-core/xref-test/index.html"
+					/>
+				</item>
+			</item>
+			<item name="Integration Demo" collapse="false">
+				<item name="Dependencies"
+					href="/java-demo/dependencies.html"
+				/>
+				<item name="Module Summary"
+					href="/java-demo/project-summary.html"
+				/>
+			</item>
+		</menu>
+	</body>
+
+	<poweredBy>
+		<logo name="Maven" href="http://maven.apache.org/"
+			img="http://maven.apache.org/images/logos/maven-inside.png"
+		/>
+	</poweredBy>
+
+</project>
