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

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

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

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


                        ${project.name}
                        Version ${version}
                        Release Notes


INTRODUCTION:

This document contains the release notes for the ${version} version of ${project.name}.
Commons JCS is a distributed caching system written in Java. It is intend to speed up 
applications by providing a means to manage cached data of various dynamic natures.

JCS 3.0 and onwards now targets Java 8.0, making use of features that arrived with Java 8.0 
such as lambdas.

For the advice on upgrading from 2.x to 3.x, see the following page: 

    ${project.url}UpgradingFrom2x.html

$introduction.replaceAll("(?<!\015)\012", "
").replaceAll("(?m)^ +","")

## N.B. the available variables are described here:
## http://maven.apache.org/plugins/maven-changes-plugin/examples/using-a-custom-announcement-template.html
##
## Hack to improve layout: replace all pairs of spaces with a single new-line
$release.description.replaceAll("  ", "
")

## set up indent sizes. Only change indent1
#set($props=${project.properties})
#set($jiralen=$props.get("commons.jira.id").length())
## indent1 =   POOL-nnnn:
#set($blanklen=$jiralen+6)## +6 for "-nnnn:"
## must be at least as long as the longest JIRA id
#set($blanks="                                  ")
#set($indent1=$blanks.substring(0,$blanklen))
## indent2 allows for issue wrapper
#set($indent2="$indent1   ")
##
#macro ( processaction )
## Use replaceAll to fix up LF-only line ends on Windows.
#set($action=$actionItem.getAction().replaceAll("\n","
"))
## Fix up indentation for multi-line action descriptions
#set($action=$action.replaceAll("(?m)^  +",$indent2))
#if ($actionItem.getIssue())
#set($issue="$actionItem.getIssue():")
## Pad shorter issue numbers
#if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end
#if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end
#if ($issue.length() < $indent1.length())#set ($issue="$issue ")#end
#else
#set($issue=$indent1)
#end
#if ($actionItem.getDueTo())
#set($dueto=" Thanks to $actionItem.getDueTo().")
#else
#set($dueto="")
#end
o $issue ${action}$dueto
#set($action="")
#set($issue="")
#set($dueto="")
#end
##
#if ($release.getActions().size() == 0)
No changes defined in this version.
#else
Changes in this version include:

#if ($release.getActions('add').size() !=0)
New features:
#foreach($actionItem in $release.getActions('add'))
#processaction()
#end 
#end

#if ($release.getActions('fix').size() !=0)
Fixed Bugs:
#foreach($actionItem in $release.getActions('fix'))
#processaction()
#end
#end

#if ($release.getActions('update').size() !=0)
Changes:
#foreach($actionItem in $release.getActions('update'))
#processaction()
#end
#end

#if ($release.getActions('remove').size() !=0)
Removed:
#foreach($actionItem in $release.getActions('remove'))
#processaction()
#end
#end
## End of main loop
#end

Historical list of changes: ${project.url}changes-report.html

For complete information on ${project.name}, including instructions on how to submit bug reports,
patches, or suggestions for improvement, see the ${project.name} website:

${project.url}