<!--
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->
$Id$


                          Commons Chain Package
                                Version 2.0
                               Release Notes


INTRODUCTION
============

This is an update release with new features. New projects are encouraged to
use this release of Chain. There is no urgency for existing projects to
upgrade; Chain 1.2 has proven to be a stable release.

IMPORTANT NOTES
================

BREAKING CHANGES:

 * The minimum JDK version required is 1.5;

 * APIs are NOT backward compatible;

 * Classes have been split in submodules (core, XML configuration and WEB).

DEPENDENCIES
=============

Chain 2.0 users should upgrade to the recommended dependency set below
where possible.

The Recommended Dependency Set for Chain 2.0 is:
   Chain 2.0 + Logging 1.1.1:

The Recommended Dependency Set for Chain Configuration 2.0 is:
   Chain 2.0 + Digester 3.2 (and related transitive dependencies)

The Recommended Dependency Set for Chain Web 2.0 is:
   Chain 2.0 + Chain Configuration 2.0 + Container Provided dependencies

BUG
============

 * [CHAIN-57] - Chain 2.0 does not build on older JDKs
 * [CHAIN-60] - In certain build configurations unit tests fail with the following message: testDefault: Correct command count expected:<17> but was:<19>
 * [CHAIN-61] - Chain 2.0 trunk build is throwing many warnings as a result of generification changes
 * [CHAIN-64] - Context should be Map<String, ? extends Object>
 * [CHAIN-68] - SNAPSHOT tomcat plugin breaks the build

IMPROVEMENT
============

 * [CHAIN-54] - upgrate JUnit dependency to latest released version and adapt tests
 * [CHAIN-55] - split the huge project in submodules
 * [CHAIN-56] - clever Context with generic type "auto-cast" feature
 * [CHAIN-58] - Update Chain Context interface to use K,V generics
 * [CHAIN-63] - Replace Context with Map<String, ? extends Object>
 * [CHAIN-66] - Updated Chain documentation to include new changes to the API
 * [CHAIN-67] - Refactor of explicit Exception throws to a RuntimeException type
 * [CHAIN-69] - Fixed Checkstyle / PMD Warnings

NEW FEATURE
============

 * [CHAIN-70] - Add a small EDSL to simplify Chain setup and execution.

TASK
============

 * [CHAIN-65] - Rename package org.apache.commons.chain to org.apache.commons.chain2 for v2 of chain

OTHER NOTES
============

 * This is the first version of Apache Commons Chain which contains sub-modules
