Index: src/main/java/org/apache/maven/plugin/announcement/JiraAnnouncementParser.java
===================================================================
--- src/main/java/org/apache/maven/plugin/announcement/JiraAnnouncementParser.java	(revision 480110)
+++ src/main/java/org/apache/maven/plugin/announcement/JiraAnnouncementParser.java	(working copy)
@@ -172,7 +172,7 @@
 
             Action action = new Action();
 
-            action.setIssue( issue.getKey() );
+            action.addIssue( issue.getKey() );
 
             if ( issue.getType().equals( "Bug" ) )
             {
Index: src/main/java/org/apache/maven/plugin/announcement/JiraDownloader.java
===================================================================
--- src/main/java/org/apache/maven/plugin/announcement/JiraDownloader.java	(revision 480110)
+++ src/main/java/org/apache/maven/plugin/announcement/JiraDownloader.java	(working copy)
@@ -27,6 +27,10 @@
  */
 public final class JiraDownloader extends AbstractJiraDownloader
 {
+    /**
+     * Create a JiraDownloader.
+     *
+     */
     public JiraDownloader()
     {
         statusMap.put( "Closed", "6" );
Index: src/main/java/org/apache/maven/plugin/changes/Action.java
===================================================================
--- src/main/java/org/apache/maven/plugin/changes/Action.java	(revision 480110)
+++ src/main/java/org/apache/maven/plugin/changes/Action.java	(working copy)
@@ -16,6 +16,9 @@
  * limitations under the License.
  */
 
+import java.util.LinkedList;
+import java.util.List;
+
 /**
  * An action in a changes.xml file.
  *
@@ -31,8 +34,8 @@
 
     private String dueToEmail;
 
-    private String issue;
-
+    private List issues = new LinkedList();
+    
     private String type;
 
     public Action()
@@ -79,14 +82,14 @@
         return dueToEmail;
     }
 
-    public void setIssue( String issue )
+    public void addIssue( String issue )
     {
-        this.issue = issue;
+        this.issues.add( issue.trim() );
     }
 
-    public String getIssue()
+    public List getIssues()
     {
-        return issue;
+        return issues;
     }
 
     public void setType( String type )
Index: src/main/java/org/apache/maven/plugin/changes/ChangesMojo.java
===================================================================
--- src/main/java/org/apache/maven/plugin/changes/ChangesMojo.java	(revision 480110)
+++ src/main/java/org/apache/maven/plugin/changes/ChangesMojo.java	(working copy)
@@ -85,6 +85,28 @@
     private String issueLinkTemplate;
 
     /**
+     * Template string that is used to discover the URL to use to display patch submition.
+     * There are 2 template tokens you can use. %URL%: this is computed by getting the
+     * &lt;issueManagement&gt;&lt;url&gt; value from the POM, and removing the context path. %PATCH% :
+     * this is the patch number.
+     * 
+     * @parameter expression="%URL%/ViewIssue.jspa?key=%PATCH%"
+     *
+     */
+    private String patchLinkTemplate;
+
+    /**
+     * Template string that is used to discover the URL to use to display a feature request.
+     * There are 2 template tokens you can use. %URL%: this is computed by getting the
+     * &lt;issueManagement&gt;&lt;url&gt; value from the POM, and removing the context path. %FEATURE% :
+     * this is the feature request number.
+     * 
+     * @parameter expression="%URL%/ViewIssue.jspa?key=%FEATURE%"
+     *
+     */
+    private String featureLinkTemplate;
+
+    /**
      * @parameter expression="${project.issueManagement.url}"
      * @readonly
      */
@@ -133,6 +155,8 @@
         }
 
         report.setIssueLink( issueLinkTemplate );
+        report.setPatchLink( patchLinkTemplate );
+        report.setFeatureLink( featureLinkTemplate );
         report.setUrl( url );
         report.doGenerateReport( getBundle( locale ), getSink() );
 
Index: src/main/java/org/apache/maven/plugin/changes/ChangesReportGenerator.java
===================================================================
--- src/main/java/org/apache/maven/plugin/changes/ChangesReportGenerator.java	(revision 480110)
+++ src/main/java/org/apache/maven/plugin/changes/ChangesReportGenerator.java	(working copy)
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+import java.util.Iterator;
 import java.util.List;
 import java.util.ResourceBundle;
 
@@ -33,6 +34,10 @@
 
     private String issueLink;
 
+    private String patchLink;
+
+    private String featureLink;
+
     private String url;
 
     public ChangesReportGenerator()
@@ -54,6 +59,26 @@
         return issueLink;
     }
 
+    public void setPatchLink( String patchLink )
+    {
+        this.patchLink = patchLink;
+    }
+
+    public String getPatchLink()
+    {
+        return patchLink;
+    }
+
+    public void setFeatureLink( String featureLink )
+    {
+        this.featureLink = featureLink;
+    }
+
+    public String getFeatureLink()
+    {
+        return featureLink;
+    }
+
     public void setUrl( String url )
     {
         this.url = url;
@@ -110,29 +135,47 @@
 
             sink.rawText( action.getAction() );
 
-            if ( action.getIssue() != null )
+            if ( ! action.getIssues().isEmpty() )
             {
                 sink.text( " " + bundle.getString( "report.changes.text.fixes" ) + " " );
 
                 if ( this.url == null || this.url.trim().equals( "" ) )
                 {
-                    sink.text( action.getIssue() );
-
+                    for ( Iterator issue = action.getIssues().iterator() ; issue.hasNext() ; )
+                    {
+                        sink.text( (String) issue.next() );
+                        
+                        if ( issue.hasNext() )
+                        {
+                            sink.text( ", " );
+                        }
+                    }
+                    
                 }
                 else
                 {
-                    sink.link( parseIssueLink( action.getIssue() ) );
+                    for ( Iterator issue = action.getIssues().iterator() ; issue.hasNext() ; )
+                    {
+                        String value = (String) issue.next();
+                        
+                        sink.link( parseIssueLink( value ) );
 
-                    sink.text( action.getIssue() );
+                        sink.text( value );
 
-                    sinkFigure( "images/external.png", sink );
+                        sinkFigure( "images/external.png", sink );
 
-                    sink.link_();
+                        sink.link_();
 
+                        if ( issue.hasNext() )
+                        {
+                            sink.text( ", " );
+                        }
+                    }
+
                 }
                 sink.text( "." );
             }
-
+            
             if ( action.getDueTo() != null )
             {
                 sink.text( " " + bundle.getString( "report.changes.text.thanx" ) + " " );
@@ -237,6 +280,32 @@
         return parseLink;
     }
 
+    private String parsePatchLink( String patch )
+    {
+        String parseLink = "";
+
+        String url = this.url.substring( 0, this.url.lastIndexOf( "/" ) );
+
+        parseLink = this.patchLink.replaceFirst( "%PATCH%", patch );
+
+        parseLink = parseLink.replaceFirst( "%URL%", url );
+
+        return parseLink;
+    }
+
+    private String parseFeatureLink( String feature )
+    {
+        String parseLink = "";
+
+        String url = this.url.substring( 0, this.url.lastIndexOf( "/" ) );
+
+        parseLink = this.featureLink.replaceFirst( "%FEATURE%", feature );
+
+        parseLink = parseLink.replaceFirst( "%URL%", url );
+
+        return parseLink;
+    }
+
     private void sinkBeginReport( Sink sink, ResourceBundle bundle )
     {
         sink.head();
Index: src/main/java/org/apache/maven/plugin/changes/ChangesXML.java
===================================================================
--- src/main/java/org/apache/maven/plugin/changes/ChangesXML.java	(revision 480110)
+++ src/main/java/org/apache/maven/plugin/changes/ChangesXML.java	(working copy)
@@ -19,6 +19,7 @@
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.StringTokenizer;
 
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
@@ -188,8 +189,20 @@
             action.setDueToEmail( attrs.getValue( "due-to-email" ) );
 
             action.setType( attrs.getValue( "type" ) );
-
-            action.setIssue( attrs.getValue( "issue" ) );
+            
+            String issues = attrs.getValue( "issue" );
+            
+            if ( issues != null )
+            {
+                StringTokenizer tokIssue = new StringTokenizer( issues, "," );
+                
+                while ( tokIssue.hasMoreTokens() )
+                {                
+                    action.addIssue( tokIssue.nextToken() );    
+                }
+            
+            }
+            
         }
 
         currentName = qName;
Index: src/test/java/org/apache/maven/plugin/changes/ActionTest.java
===================================================================
--- src/test/java/org/apache/maven/plugin/changes/ActionTest.java	(revision 480110)
+++ src/test/java/org/apache/maven/plugin/changes/ActionTest.java	(working copy)
@@ -70,11 +70,22 @@
 
     public void testGetSetIssue()
     {
-        action.setIssue( "issue" );
+        action.addIssue( "issue" );
 
-        assertEquals( "issue", action.getIssue() );
+        assertEquals( "issue", action.getIssues().get( 0 ) );
     }
 
+    public void testGetSetMultipleIssue()
+    {
+        action.addIssue( "issue1" );
+
+        action.addIssue( "issue2" );
+
+        assertEquals( "issue1", action.getIssues().get( 0 ) );
+        
+        assertEquals( "issue2", action.getIssues().get( 1 ) );
+    }
+
     public void testGetSetDueTo()
     {
         action.setDueTo( "due-to" );

