## 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 Apache Commons Statistics.

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

## The available variables are described here:
## https://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}

Download page: ${project.url}download_statistics.cgi

Have fun!
-Apache Commons Team
