[maven-release-plugin]  copy for tag log4j-2.0-rc1

git-svn-id: https://svn.apache.org/repos/asf/logging/log4j/log4j2/tags/log4j-2.0-rc1@1566354 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 78fa999..56fa4df 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -33,6 +33,9 @@
 o LOG4J2-402:  Configure RandomAccessFileAppender buffer size. 
 
 Fixed Bugs:
+o LOG4J2-500:  (JMX - ObjectNames changed!) Unloading one web application unloads JMX MBeans for all web applications. 
+o LOG4J2-531:  Fixed bugs where rolled log files were overwritten by RollingFile appender with 
+        composite time and size based policies. Thanks to Geoff Ballinger. 
 o LOG4J2-475:  Changed the MongoDBConnection to add a MongoDB encoding hook instead of a decoding hook. Thanks to Matt Sicker. 
 o LOG4J2-489:  Fixed the JPAAppender's overuse of transactions by connecting (borrowing from pool) on new write internal or on
         flush. 
@@ -43,7 +46,6 @@
 o LOG4J2-438:  Ensured the JDBCAppender commits transactions after a single write or a flush of multiple writes. 
 o LOG4J2-407:  Fixed inability to recover from lost database connection in database appenders by connecting (borrowing from
         pool) on new write internal or on flush. 
-o LOG4J2-500:  (JMX) Unloading one webapp unloads JMX MBeans for all webapps. 
 o LOG4J2-511:  Stop AsyncLoggerConfig Disruptor thread(s), then AsyncAppender thread(s) first
         before stopping other appenders. Thanks to James Pretorius. 
 o LOG4J2-392:  Stop AsyncLoggerConfig Disruptor thread(s), then AsyncAppender thread(s) first
@@ -102,8 +104,8 @@
         org.apache.logging.log4j.core.appender.db.nosql.mongodb. 
 o Renamed the org.apache.logging.log4j.core.appender.db.nosql.couch package to
         org.apache.logging.log4j.core.appender.db.nosql.couchdb. 
-o LOG4J2-41:  Add support for custom logging levels. Thanks to Nick Williams. 
 o LOG4J2-507:  Space Level numbers by 100 instead of 1. 
+o LOG4J2-41:  Add support for custom logging levels. Thanks to Nick Williams. 
 o LOG4J2-490:  Update EasyMock to version 3.2. Thanks to Matt Sicker. 
 o LOG4J2-453:  Update Flume Appender to use Flume 1.4.0. 
 o LOG4J2-528:  Rename package org.apache.logging.log4j.core.appender.rolling.helper to org.apache.logging.log4j.core.appender.rolling.action. 
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/PropertyConfigurator.java b/log4j-1.2-api/src/main/java/org/apache/log4j/PropertyConfigurator.java
index ee13715..0fe1fe0 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/PropertyConfigurator.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/PropertyConfigurator.java
@@ -63,7 +63,7 @@
      * @param configURL The configuration URL
      * @param hierarchy The hierarchy
      */
-    public void doConfigure(final java.net.URL configURL, final LoggerRepository hierarchy) {
+    public void doConfigure(final URL configURL, final LoggerRepository hierarchy) {
     }
 
     /**
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
index 9fd0efd..04a4555 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/xml/DOMConfigurator.java
@@ -72,7 +72,8 @@
 
     }
 
-    public static Object parseElement(final Element element, final Properties props, @SuppressWarnings("rawtypes") final Class expectedClass)
+    public static Object parseElement(final Element element, final Properties props,
+                                      @SuppressWarnings("rawtypes") final Class expectedClass)
         throws Exception {
         return null;
     }
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/Level.java b/log4j-api/src/main/java/org/apache/logging/log4j/Level.java
index ac094b7..48d1f04 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/Level.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/Level.java
@@ -16,15 +16,14 @@
  */
 package org.apache.logging.log4j;
 
-import org.apache.logging.log4j.spi.StandardLevel;
-
-import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Locale;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.logging.log4j.spi.StandardLevel;
+
 /**
  * Levels used for identifying the severity of an event. Levels are organized from most specific to least:
  * <ul>
@@ -288,7 +287,7 @@
     }
 
     // for deserialization
-    protected Object readResolve() throws ObjectStreamException {
+    protected Object readResolve() {
         return Level.valueOf(this.name);
     }
 }
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
index 12a6308..193700d 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
@@ -23,16 +23,20 @@
  */
 public class StructuredDataId implements Serializable {
 
+    private static final String AT = "@";
+
     /**
      * RFC 5424 Time Quality.
      */
     public static final StructuredDataId TIME_QUALITY = new StructuredDataId("timeQuality", null,
         new String[]{"tzKnown", "isSynced", "syncAccuracy"});
+    
     /**
      * RFC 5424 Origin.
      */
     public static final StructuredDataId ORIGIN = new StructuredDataId("origin", null,
         new String[]{"ip", "enterpriseId", "software", "swVersion"});
+    
     /**
      * RFC 5424 Meta.
      */
@@ -60,7 +64,7 @@
                 throw new IllegalArgumentException(String.format("Length of id %s exceeds maximum of %d characters",
                         name, MAX_LENGTH));
             }
-            index = name.indexOf("@");
+            index = name.indexOf(AT);
         }
 
         if (index > 0) {
@@ -87,15 +91,15 @@
         if (name == null) {
             throw new IllegalArgumentException("No structured id name was supplied");
         }
-        if (name.contains("@")) {
-            throw new IllegalArgumentException("Structured id name cannot contain an '@");
+        if (name.contains(AT)) {
+            throw new IllegalArgumentException("Structured id name cannot contain an '" + AT + "'");
         }
         if (enterpriseNumber <= 0) {
             throw new IllegalArgumentException("No enterprise number was supplied");
         }
         this.name = name;
         this.enterpriseNumber = enterpriseNumber;
-        final String id = enterpriseNumber < 0 ? name : name + "@" + enterpriseNumber;
+        final String id = enterpriseNumber < 0 ? name : name + AT + enterpriseNumber;
         if (id.length() > MAX_LENGTH) {
             throw new IllegalArgumentException("Length of id exceeds maximum of 32 characters: " + id);
         }
@@ -183,6 +187,6 @@
 
     @Override
     public String toString() {
-        return isReserved() ? name : name + "@" + enterpriseNumber;
+        return isReserved() ? name : name + AT + enterpriseNumber;
     }
 }
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 91e91fb..7094ebc 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -167,7 +167,6 @@
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
-      <version>3.2.4.RELEASE</version>
       <scope>test</scope>
     </dependency>
     <dependency>
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogFrame.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogFrame.java
index d3e32cb..c649a9e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogFrame.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/TLSSyslogFrame.java
@@ -16,6 +16,8 @@
 */
 package org.apache.logging.log4j.core.appender;
 
+import java.nio.charset.Charset;
+
 /**
  * Wrapper for messages that are formatted according to RFC 5425.
  */
@@ -44,7 +46,7 @@
 
     public byte[] getBytes() {
         String frame = toString();
-        return frame.getBytes();
+        return frame.getBytes(Charset.defaultCharset());
     }
 
     @Override
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
index 0273ca5..7a37371 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
@@ -179,7 +179,9 @@
 
         final List<FileRenameAction> renames = new ArrayList<FileRenameAction>();
         final StringBuilder buf = new StringBuilder();
-        manager.getPatternProcessor().formatFileName(buf, highIndex);
+        
+        // LOG4J2-531: directory scan & rollover must use same format
+        manager.getPatternProcessor().formatFileName(subst, buf, highIndex);
 
         String highFilename = subst.replace(buf);
 
@@ -208,6 +210,8 @@
 
                 if (toRename.exists()) {
                     if (toRenameBase.exists()) {
+                        LOGGER.debug("DefaultRolloverStrategy.purgeAscending deleting {} base of {}.", //
+                                toRenameBase, toRename);
                         toRenameBase.delete();
                     }
                 } else {
@@ -222,6 +226,8 @@
                 //        attempt to delete last file
                 //        if that fails then abandon purge
                 if (i == lowIndex) {
+                    LOGGER.debug("DefaultRolloverStrategy.purgeAscending deleting {} at low index {}: all slots full.", //
+                            toRename, i);
                     if (!toRename.delete()) {
                         return -1;
                     }
@@ -233,7 +239,8 @@
                 //   if intermediate index
                 //     add a rename action to the list
                 buf.setLength(0);
-                manager.getPatternProcessor().formatFileName(buf, i - 1);
+                // LOG4J2-531: directory scan & rollover must use same format
+                manager.getPatternProcessor().formatFileName(subst, buf, i - 1);
 
                 final String lowFilename = subst.replace(buf);
                 String renameTo = lowFilename;
@@ -246,7 +253,8 @@
                 highFilename = lowFilename;
             } else {
                 buf.setLength(0);
-                manager.getPatternProcessor().formatFileName(buf, i - 1);
+                // LOG4J2-531: directory scan & rollover must use same format
+                manager.getPatternProcessor().formatFileName(subst, buf, i - 1);
 
                 highFilename = subst.replace(buf);
             }
@@ -260,8 +268,9 @@
         //
         for (int i = renames.size() - 1; i >= 0; i--) {
             final Action action = renames.get(i);
-
             try {
+                LOGGER.debug("DefaultRolloverStrategy.purgeAscending executing {} of {}: {}", //
+                        i, renames.size(), action);
                 if (!action.execute()) {
                     return -1;
                 }
@@ -287,7 +296,9 @@
 
         final List<FileRenameAction> renames = new ArrayList<FileRenameAction>();
         final StringBuilder buf = new StringBuilder();
-        manager.getPatternProcessor().formatFileName(buf, lowIndex);
+
+        // LOG4J2-531: directory scan & rollover must use same format
+        manager.getPatternProcessor().formatFileName(subst, buf, lowIndex);
 
         String lowFilename = subst.replace(buf);
 
@@ -307,6 +318,8 @@
 
                 if (toRename.exists()) {
                     if (toRenameBase.exists()) {
+                        LOGGER.debug("DefaultRolloverStrategy.purgeDescending deleting {} base of {}.", //
+                                toRenameBase, toRename);
                         toRenameBase.delete();
                     }
                 } else {
@@ -321,6 +334,8 @@
                 //        attempt to delete last file
                 //        if that fails then abandon purge
                 if (i == highIndex) {
+                    LOGGER.debug("DefaultRolloverStrategy.purgeDescending deleting {} at high index {}: all slots full.", //
+                            toRename, i);
                     if (!toRename.delete()) {
                         return -1;
                     }
@@ -332,7 +347,8 @@
                 //   if intermediate index
                 //     add a rename action to the list
                 buf.setLength(0);
-                manager.getPatternProcessor().formatFileName(buf, i + 1);
+                // LOG4J2-531: directory scan & rollover must use same format
+                manager.getPatternProcessor().formatFileName(subst, buf, i + 1);
 
                 final String highFilename = subst.replace(buf);
                 String renameTo = highFilename;
@@ -353,8 +369,9 @@
         //
         for (int i = renames.size() - 1; i >= 0; i--) {
             final Action action = renames.get(i);
-
             try {
+                LOGGER.debug("DefaultRolloverStrategy.purgeDescending executing {} of {}: {}", //
+                        i, renames.size(), action);
                 if (!action.execute()) {
                     return -1;
                 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
index 82fc0ca..de5822c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java
@@ -16,11 +16,13 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 
+import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.lookup.StrSubstitutor;
@@ -29,12 +31,14 @@
 import org.apache.logging.log4j.core.pattern.FormattingInfo;
 import org.apache.logging.log4j.core.pattern.PatternConverter;
 import org.apache.logging.log4j.core.pattern.PatternParser;
+import org.apache.logging.log4j.status.StatusLogger;
 
 /**
  * Parse the rollover pattern.
  */
 public class PatternProcessor {
 
+    protected static final Logger LOGGER = StatusLogger.getLogger();
     private static final String KEY = "FileConverter";
 
     private static final char YEAR_CHAR = 'y';
@@ -100,7 +104,7 @@
             nextTime = cal.getTimeInMillis();
             cal.add(Calendar.YEAR, -1);
             nextFileTime = cal.getTimeInMillis();
-            return nextTime;
+            return debugGetNextTime(nextTime);
         }
         cal.set(Calendar.MONTH, currentCal.get(Calendar.MONTH));
         if (frequency == RolloverFrequency.MONTHLY) {
@@ -108,7 +112,7 @@
             nextTime = cal.getTimeInMillis();
             cal.add(Calendar.MONTH, -1);
             nextFileTime = cal.getTimeInMillis();
-            return nextTime;
+            return debugGetNextTime(nextTime);
         }
         if (frequency == RolloverFrequency.WEEKLY) {
             cal.set(Calendar.WEEK_OF_YEAR, currentCal.get(Calendar.WEEK_OF_YEAR));
@@ -117,7 +121,7 @@
             nextTime = cal.getTimeInMillis();
             cal.add(Calendar.WEEK_OF_YEAR, -1);
             nextFileTime = cal.getTimeInMillis();
-            return nextTime;
+            return debugGetNextTime(nextTime);
         }
         cal.set(Calendar.DAY_OF_YEAR, currentCal.get(Calendar.DAY_OF_YEAR));
         if (frequency == RolloverFrequency.DAILY) {
@@ -125,7 +129,7 @@
             nextTime = cal.getTimeInMillis();
             cal.add(Calendar.DAY_OF_YEAR, -1);
             nextFileTime = cal.getTimeInMillis();
-            return nextTime;
+            return debugGetNextTime(nextTime);
         }
         cal.set(Calendar.HOUR_OF_DAY, currentCal.get(Calendar.HOUR_OF_DAY));
         if (frequency == RolloverFrequency.HOURLY) {
@@ -133,7 +137,7 @@
             nextTime = cal.getTimeInMillis();
             cal.add(Calendar.HOUR_OF_DAY, -1);
             nextFileTime = cal.getTimeInMillis();
-            return nextTime;
+            return debugGetNextTime(nextTime);
         }
         cal.set(Calendar.MINUTE, currentCal.get(Calendar.MINUTE));
         if (frequency == RolloverFrequency.EVERY_MINUTE) {
@@ -141,7 +145,7 @@
             nextTime = cal.getTimeInMillis();
             cal.add(Calendar.MINUTE, -1);
             nextFileTime = cal.getTimeInMillis();
-            return nextTime;
+            return debugGetNextTime(nextTime);
         }
         cal.set(Calendar.SECOND, currentCal.get(Calendar.SECOND));
         if (frequency == RolloverFrequency.EVERY_SECOND) {
@@ -149,16 +153,28 @@
             nextTime = cal.getTimeInMillis();
             cal.add(Calendar.SECOND, -1);
             nextFileTime = cal.getTimeInMillis();
-            return nextTime;
+            return debugGetNextTime(nextTime);
         }
         cal.set(Calendar.MILLISECOND, currentCal.get(Calendar.MILLISECOND));
         increment(cal, Calendar.MILLISECOND, increment, modulus);
         nextTime = cal.getTimeInMillis();
         cal.add(Calendar.MILLISECOND, -1);
         nextFileTime = cal.getTimeInMillis();
+        return debugGetNextTime(nextTime);
+    }
+
+    private long debugGetNextTime(long nextTime) {
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace("PatternProcessor.getNextTime returning {}, nextFileTime={}, prevFileTime={}, freq={}", //
+                    format(nextTime), format(nextFileTime), format(prevFileTime), frequency);
+        }
         return nextTime;
     }
 
+    private String format(long time) {
+        return new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss.SSS").format(new Date(time));
+    }
+
     private void increment(final Calendar cal, final int type, final int increment, final boolean modulate) {
         final int interval =  modulate ? increment - (cal.get(type) % increment) : increment;
         cal.add(type, interval);
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
index a158625..ac7746a 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java
@@ -161,13 +161,10 @@
 
         try {
             final RolloverDescription descriptor = strategy.rollover(this);
-
             if (descriptor != null) {
-
                 close();
-
                 if (descriptor.getSynchronous() != null) {
-
+                    LOGGER.debug("RollingFileManager executing synchronous {}", descriptor.getSynchronous());
                     try {
                         success = descriptor.getSynchronous().execute();
                     } catch (final Exception ex) {
@@ -176,6 +173,7 @@
                 }
 
                 if (success && descriptor.getAsynchronous() != null) {
+                    LOGGER.debug("RollingFileManager executing async {}", descriptor.getAsynchronous());
                     thread = new Thread(new AsyncAction(descriptor.getAsynchronous(), this));
                     thread.start();
                 }
@@ -302,7 +300,6 @@
                 return null;
             }
             final long size = data.append ? file.length() : 0;
-            final long time = file.lastModified();
 
             OutputStream os;
             try {
@@ -310,6 +307,7 @@
                 if (data.bufferedIO) {
                     os = new BufferedOutputStream(os);
                 }
+                final long time = file.lastModified(); // LOG4J2-531 create file first so time has valid value
                 return new RollingFileManager(name, data.pattern, os, data.append, size, time, data.policy,
                     data.strategy, data.advertiseURI, data.layout);
             } catch (final FileNotFoundException ex) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java
index 0726263..4de9ec4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/TimeBasedTriggeringPolicy.java
@@ -46,6 +46,10 @@
     @Override
     public void initialize(final RollingFileManager manager) {
         this.manager = manager;
+        
+        // LOG4J2-531: call getNextTime twice to force initialization of both prevFileTime and nextFileTime
+        manager.getPatternProcessor().getNextTime(manager.getFileTime(), interval, modulate);
+        
         nextRollover = manager.getPatternProcessor().getNextTime(manager.getFileTime(), interval, modulate);
     }
 
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompositeAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompositeAction.java
index f451c55..9312d2d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompositeAction.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompositeAction.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j.core.appender.rolling.action;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.List;
 
 
@@ -97,4 +98,9 @@
 
         return status;
     }
+    
+    @Override
+    public String toString() {
+        return CompositeAction.class.getSimpleName() + Arrays.toString(actions);
+    }
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java
index c9ea48a..9fed741 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/FileRenameAction.java
@@ -143,4 +143,10 @@
             }
         }
     }
+    
+    @Override
+    public String toString() {
+        return FileRenameAction.class.getSimpleName() + "[" + source + " to " + destination //
+                + ", renameEmptyFiles=" + renameEmptyFiles + "]";
+    }
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/GZCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/GZCompressAction.java
index 84d50e1..dfd968f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/GZCompressAction.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/GZCompressAction.java
@@ -125,5 +125,10 @@
     protected void reportException(final Exception ex) {
         LOGGER.warn("Exception during compression of '" + source.toString() + "'.", ex);
     }
-
+    
+    @Override
+    public String toString() {
+        return GZCompressAction.class.getSimpleName() + "[" + source + " to " + destination //
+                + ", deleteSource=" + deleteSource + "]";
+    }
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ZipCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ZipCompressAction.java
index b4c1163..e11257d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ZipCompressAction.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ZipCompressAction.java
@@ -137,4 +137,10 @@
     protected void reportException(final Exception ex) {
         LOGGER.warn("Exception during compression of '" + source.toString() + "'.", ex);
     }
+    
+    @Override
+    public String toString() {
+        return ZipCompressAction.class.getSimpleName() + "[" + source + " to " + destination //
+                + ", level=" + level + ", deleteSource=" + deleteSource + "]";
+    }
 }
diff --git a/log4j-distribution/pom.xml b/log4j-distribution/pom.xml
index 754fc5c..805b796 100644
--- a/log4j-distribution/pom.xml
+++ b/log4j-distribution/pom.xml
@@ -272,6 +272,15 @@
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-site-plugin</artifactId>
+        <version>3.0</version>
+        <configuration>
+          <skip>true</skip>
+          <skipDeploy>true</skipDeploy>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java
index 3c3ec4b..d41245f 100644
--- a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java
+++ b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeAppender.java
@@ -216,7 +216,7 @@
         final int reqTimeout = Integers.parseInt(requestTimeout, 0);
         final int retries = Integers.parseInt(agentRetries, 0);
         final int lockTimeoutRetryCount = Integers.parseInt(lockTimeoutRetries, DEFAULT_LOCK_TIMEOUT_RETRY_COUNT);
-        final int delay = Integers.parseInt(maxDelay, DEFAULT_MAX_DELAY );
+        final int delay = Integers.parseInt(maxDelay, DEFAULT_MAX_DELAY);
 
         if (layout == null) {
             layout = RFC5424Layout.createLayout(null, null, null, "True", null, mdcPrefix, eventPrefix,
diff --git a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java
index ea5b5e6..62e8812 100644
--- a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java
+++ b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEmbeddedManager.java
@@ -187,7 +187,7 @@
                 throw new ConfigurationException("No Flume configuration provided");
             }
 
-            if ((agents != null && agents.length > 0 && properties != null && properties.length > 0)) {
+            if (agents != null && agents.length > 0 && properties != null && properties.length > 0) {
                 LOGGER.error("Agents and Flume configuration cannot both be specified");
                 throw new ConfigurationException("Agents and Flume configuration cannot both be specified");
             }
@@ -215,7 +215,7 @@
                 final StringBuilder sb = new StringBuilder();
                 String leading = "";
                 int priority = agents.length;
-                for (int i = 0; i < agents.length; ++i) {
+                for (int i = 0; i < priority; ++i) {
                     sb.append(leading).append("agent").append(i);
                     leading = " ";
                     final String prefix = "agent" + i;
diff --git a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumePersistentManager.java b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumePersistentManager.java
index 3955205..a8a8b9b 100644
--- a/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumePersistentManager.java
+++ b/log4j-flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumePersistentManager.java
@@ -35,7 +35,6 @@
 import javax.crypto.Cipher;
 import javax.crypto.SecretKey;
 
-import com.sleepycat.je.LockConflictException;
 import org.apache.flume.Event;
 import org.apache.flume.event.SimpleEvent;
 import org.apache.logging.log4j.LoggingException;
@@ -54,6 +53,7 @@
 import com.sleepycat.je.DatabaseEntry;
 import com.sleepycat.je.Environment;
 import com.sleepycat.je.EnvironmentConfig;
+import com.sleepycat.je.LockConflictException;
 import com.sleepycat.je.LockMode;
 import com.sleepycat.je.OperationStatus;
 import com.sleepycat.je.StatsConfig;
@@ -141,6 +141,7 @@
      * @param connectionTimeout The amount of time to wait to establish a connection.
      * @param requestTimeout The amount of time to wait for a response to a request.
      * @param delay Amount of time to delay before delivering a batch.
+     * @param lockTimeoutRetryCount The number of times to retry after a lock timeout.
      * @param dataDir The location of the Berkeley database.
      * @return A FlumeAvroManager.
      */
@@ -221,7 +222,7 @@
         worker.shutdown();
         try {
             worker.join(SHUTDOWN_WAIT * MILLIS_PER_SECOND);
-        } catch(InterruptedException ie) {
+        } catch (InterruptedException ie) {
             // Ignore the exception and shutdown.
         }
         threadPool.shutdown();
@@ -320,7 +321,7 @@
                             txn.abort();
                             txn = null;
                         } catch (Exception ex) {
-                            // Ignore exception
+                            LOGGER.trace("Ignoring exception while aborting transaction during lock conflict.");
                         }
                     }
 
@@ -519,7 +520,7 @@
                 long now = System.currentTimeMillis();
                 long dbCount = database.count();
                 dbCounter.set(dbCount);
-                if (dbCount >= batchSize || (dbCount > 0 && nextBatch <= now)) {
+                if (dbCount >= batchSize || dbCount > 0 && nextBatch <= now) {
                     nextBatch = now + manager.delay;
                     try {
                         boolean errors = false;
@@ -596,7 +597,7 @@
                                             cursor.close();
                                             cursor = null;
                                         } catch (Exception ex) {
-                                            // Ignore exception
+                                            LOGGER.trace("Ignored exception closing cursor during lock conflict.");
                                         }
                                     }
                                     if (txn != null) {
@@ -604,7 +605,7 @@
                                             txn.abort();
                                             txn = null;
                                         } catch (Exception ex) {
-                                            // Ignore exception
+                                            LOGGER.trace("Ignored exception aborting tx during lock conflict.");
                                         }
                                     }
                                 }
@@ -706,7 +707,7 @@
                                         cursor.close();
                                         cursor = null;
                                     } catch (Exception ex) {
-                                        // Ignore exception
+                                        LOGGER.trace("Ignored exception closing cursor during lock conflict.");
                                     }
                                 }
                                 if (txn != null) {
@@ -714,7 +715,7 @@
                                         txn.abort();
                                         txn = null;
                                     } catch (Exception ex) {
-                                        // Ignore exception
+                                        LOGGER.trace("Ignored exception aborting transaction during lock conflict.");
                                     }
                                 }
                             } catch (final Exception ex) {
@@ -730,7 +731,7 @@
                                     cursor.close();
                                     cursor = null;
                                 } catch (Exception ex) {
-                                    // Ignore exception
+                                    LOGGER.trace("Ignored exception closing cursor during lock conflict.");
                                 }
                             }
                             if (txn != null) {
@@ -738,7 +739,7 @@
                                     txn.abort();
                                     txn = null;
                                 } catch (Exception ex) {
-                                    // Ignore exception
+                                    LOGGER.trace("Ignored exception aborting transaction during lock conflict.");
                                 }
                             }
                         } finally {
@@ -823,7 +824,7 @@
         }
 
         @Override
-	    public Thread newThread(final Runnable r) {
+        public Thread newThread(final Runnable r) {
             final Thread thread = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
             thread.setDaemon(true);
             if (thread.getPriority() != Thread.NORM_PRIORITY) {
@@ -833,6 +834,9 @@
         }
     }
 
+    /**
+     * An internal class.
+     */
     private static class Gate {
 
         private boolean isOpen = false;
diff --git a/log4j-jcl/src/main/java/org/apache/logging/log4j/jcl/Log4jLog.java b/log4j-jcl/src/main/java/org/apache/logging/log4j/jcl/Log4jLog.java
index 000aa11..20a5704 100644
--- a/log4j-jcl/src/main/java/org/apache/logging/log4j/jcl/Log4jLog.java
+++ b/log4j-jcl/src/main/java/org/apache/logging/log4j/jcl/Log4jLog.java
@@ -27,7 +27,7 @@
 
     private static final long serialVersionUID = 1L;
 
-	public Log4jLog(final AbstractLogger logger, final String name) {
+    public Log4jLog(final AbstractLogger logger, final String name) {
         super(logger, name, null);
     }
 }
diff --git a/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/Client.java b/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/Client.java
index eb6c720..5025a20 100644
--- a/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/Client.java
+++ b/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/Client.java
@@ -51,7 +51,7 @@
      *             one of the remote mbeans
      * @throws IOException if the connection failed
      */
-    public Client(final JMXConnector connector) throws JMException, IOException {
+    public Client(final JMXConnector connector) throws MalformedObjectNameException, IOException {
         this.connector = Assert.isNotNull(connector, "JMXConnector");
         this.connector.connect();
         this.connection = connector.getMBeanServerConnection();
@@ -68,12 +68,12 @@
      *             one of the remote mbeans
      * @throws IOException if the connection failed
      */
-    public Client(final MBeanServerConnection mBeanServerConnection) throws JMException, IOException {
+    public Client(final MBeanServerConnection mBeanServerConnection) throws MalformedObjectNameException, IOException {
         this.connection = mBeanServerConnection;
         init();
     }
 
-    private void init() throws JMException, IOException {
+    private void init() throws MalformedObjectNameException, IOException {
     }
 
     private Set<ObjectName> find(String pattern) throws JMException, IOException {
@@ -87,8 +87,8 @@
      * remote {@code LoggerContextAdminMBean}s.
      * 
      * @return a list of proxies to the remote {@code LoggerContextAdminMBean}s
-     * @throws IOException
-     * @throws JMException
+     * @throws IOException If an I/O error occurred
+     * @throws JMException If a management error occurred
      */
     public List<LoggerContextAdminMBean> getLoggerContextAdmins() throws JMException, IOException {
         List<LoggerContextAdminMBean> result = new ArrayList<LoggerContextAdminMBean>();
@@ -134,11 +134,11 @@
      * 
      * @param contextName search key
      * @return StatusLoggerAdminMBean or null
-     * @throws MalformedObjectNameException
-     * @throws IOException
+     * @throws MalformedObjectNameException If an object name is malformed
+     * @throws IOException If an I/O error occurred
      */
-    public StatusLoggerAdminMBean getStatusLoggerAdmin(String contextName) throws MalformedObjectNameException,
-            IOException {
+    public StatusLoggerAdminMBean getStatusLoggerAdmin(String contextName)
+            throws MalformedObjectNameException, IOException {
         final String pattern = StatusLoggerAdminMBean.PATTERN;
         final String mbean = String.format(pattern, Server.escape(contextName));
         final ObjectName search = new ObjectName(mbean);
diff --git a/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/ClientGUI.java b/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/ClientGUI.java
index cca488e..6ba4c29 100644
--- a/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/ClientGUI.java
+++ b/log4j-jmx-gui/src/main/java/org/apache/logging/log4j/jmx/gui/ClientGUI.java
@@ -69,6 +69,7 @@
  */
 public class ClientGUI extends JPanel implements NotificationListener {
     private static final long serialVersionUID = -253621277232291174L;
+    private static final int INITIAL_STRING_WRITER_SIZE = 1024;
     private final Client client;
     private Map<ObjectName, Component> contextObjNameToTabbedPaneMap = new HashMap<ObjectName, Component>();
     private Map<ObjectName, JTextArea> statusLogTextAreaMap = new HashMap<ObjectName, JTextArea>();
@@ -229,7 +230,7 @@
         System.err.println(msg);
         ex.printStackTrace();
 
-        StringWriter sw = new StringWriter(1024);
+        StringWriter sw = new StringWriter(INITIAL_STRING_WRITER_SIZE);
         ex.printStackTrace(new PrintWriter(sw));
         JOptionPane.showMessageDialog(this, sw.toString(), msg, JOptionPane.ERROR_MESSAGE);
     }
diff --git a/log4j-samples/pom.xml b/log4j-samples/pom.xml
index 35c56a7..42de9ad 100644
--- a/log4j-samples/pom.xml
+++ b/log4j-samples/pom.xml
@@ -30,7 +30,6 @@
   <url>http://maven.apache.org</url>
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <spring.version>3.1.2.RELEASE</spring.version>
   </properties>
   <dependencyManagement>
     <dependencies>
@@ -62,7 +61,7 @@
       <dependency>
         <groupId>org.springframework.ws</groupId>
         <artifactId>spring-ws-core</artifactId>
-        <version>2.1.3.RELEASE</version>
+        <version>2.1.4.RELEASE</version>
       </dependency>
       <dependency>
         <groupId>javax.servlet</groupId>
@@ -73,7 +72,7 @@
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
-        <version>4.7</version>
+        <version>4.11</version>
         <scope>test</scope>
       </dependency>
     </dependencies>
@@ -88,7 +87,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-site-plugin</artifactId>
-        <version>3.1</version>
+        <version>3.0</version>
         <configuration>
           <skip>true</skip>
           <skipDeploy>true</skipDeploy>
diff --git a/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/EventDataConverter.java b/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/EventDataConverter.java
index 4e42560..6557fb8 100644
--- a/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/EventDataConverter.java
+++ b/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/EventDataConverter.java
@@ -30,10 +30,10 @@
 
     public Message convertEvent(final String message, final Object[] objects, final Throwable throwable) {
         try {
-            final EventData data = (objects != null && objects[0] instanceof EventData) ? (EventData) objects[0]
-                    : new EventData(message);
-            final StructuredDataMessage msg = new StructuredDataMessage(data.getEventId(), data.getMessage(),
-                    data.getEventType());
+            final EventData data = objects != null && objects[0] instanceof EventData ?
+                    (EventData) objects[0] : new EventData(message);
+            final StructuredDataMessage msg =
+                    new StructuredDataMessage(data.getEventId(), data.getMessage(), data.getEventType());
             for (final Map.Entry<String, Object> entry : data.getEventMap().entrySet()) {
                 final String key = entry.getKey();
                 if (EventData.EVENT_TYPE.equals(key) || EventData.EVENT_ID.equals(key)
diff --git a/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/MarkerWrapper.java b/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/MarkerWrapper.java
index 3647b54..306bb20 100644
--- a/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/MarkerWrapper.java
+++ b/log4j-slf4j-impl/src/main/java/org/slf4j/helpers/MarkerWrapper.java
@@ -41,12 +41,12 @@
     }
 
     @Override
-    public org.apache.logging.log4j.Marker getParent() {
+    public Marker getParent() {
         return this.parent;
     }
 
     @Override
-    public boolean isInstanceOf(final org.apache.logging.log4j.Marker marker) {
+    public boolean isInstanceOf(final Marker marker) {
         if (marker == null) {
             throw new IllegalArgumentException("A marker parameter is required");
         }
diff --git a/log4j-taglib/pom.xml b/log4j-taglib/pom.xml
index 50aea72..9ecefc0 100644
--- a/log4j-taglib/pom.xml
+++ b/log4j-taglib/pom.xml
@@ -31,7 +31,6 @@
     <log4jParentDir>${basedir}/..</log4jParentDir>
     <docLabel>Log4j Tag Library Documentation</docLabel>
     <projectDir>/taglib</projectDir>
-    <spring.version>3.1.2.RELEASE</spring.version>
   </properties>
   <dependencies>
     <dependency>
@@ -69,13 +68,11 @@
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-core</artifactId>
-      <version>${spring.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
-      <version>${spring.version}</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLogger.java b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLogger.java
index af8882a..b51c8d9 100644
--- a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLogger.java
+++ b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLogger.java
@@ -30,7 +30,7 @@
 class Log4jTaglibLogger extends AbstractLoggerWrapper {
     private static final long serialVersionUID = 1L;
 
-	public Log4jTaglibLogger(final AbstractLogger logger, final String name, final MessageFactory messageFactory) {
+    public Log4jTaglibLogger(final AbstractLogger logger, final String name, final MessageFactory messageFactory) {
         super(logger, name, messageFactory);
     }
 
diff --git a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLogger.java b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLogger.java
index f28a2e1..e63a57b 100644
--- a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLogger.java
+++ b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLogger.java
@@ -31,7 +31,7 @@
 public class SLF4JLogger extends AbstractLogger {
 
     private static final long serialVersionUID = 1L;
-	private final org.slf4j.Logger logger;
+    private final org.slf4j.Logger logger;
     private final LocationAwareLogger locationAwareLogger;
 
     public SLF4JLogger(final String name, final org.slf4j.Logger logger) {
diff --git a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContextFactory.java b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContextFactory.java
index cd84cdc..4cae70f 100644
--- a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContextFactory.java
+++ b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContextFactory.java
@@ -20,11 +20,13 @@
 
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.spi.LoggerContextFactory;
+import org.apache.logging.log4j.status.StatusLogger;
 
 /**
  *
  */
 public class SLF4JLoggerContextFactory implements LoggerContextFactory {
+    private static final StatusLogger LOGGER = StatusLogger.getLogger();
     private static LoggerContext context = new SLF4JLoggerContext();
 
     public SLF4JLoggerContextFactory() {
@@ -34,7 +36,7 @@
             Class.forName("org.slf4j.helpers.Log4jLoggerFactory");
             misconfigured = true;
         } catch (final ClassNotFoundException classNotFoundIsGood) {
-            // org.slf4j.helpers.Log4jLoggerFactory is not on classpath. Good!
+            LOGGER.debug("org.slf4j.helpers.Log4jLoggerFactory is not on classpath. Good!");
         }
         if (misconfigured) {
             throw new IllegalStateException("slf4j-impl jar is mutually exclusive with log4j-to-slf4j jar "
diff --git a/pom.xml b/pom.xml
index 7437305..c1868a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -138,6 +138,7 @@
     <Log4jReleaseCount>eleventh</Log4jReleaseCount>
     <jackson1.version>1.9.13</jackson1.version>
     <jackson2.version>2.2.2</jackson2.version>
+    <spring.version>3.2.7.RELEASE</spring.version>
     <flumeVersion>1.4.0</flumeVersion>
     <disruptor.version>3.2.0</disruptor.version>
     <!-- Configuration properties for the OSGi maven-bundle-plugin -->
@@ -461,6 +462,51 @@
         <version>3.2</version>
       </dependency>
       <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-aop</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-beans</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-context</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-core</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-expression</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-oxm</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-test</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-web</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-webmvc</artifactId>
+        <version>${spring.version}</version>
+      </dependency>
+      <dependency>
         <groupId>org.hsqldb</groupId>
         <artifactId>hsqldb</artifactId>
         <version>2.3.0</version>
@@ -623,8 +669,8 @@
           </dependency>
         </dependencies>
         <configuration>
-         <!-- only build English site even on other language OS -->
-         <locales>en</locales>
+          <!-- only build English site even on other language OS -->
+          <locales>en</locales>
           <!-- Exclude the navigation file for Maven 1 sites
                and the changes file used by the changes-plugin,
                as they interfere with the site generation. -->
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index e0c0ffc..71d0958 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -20,7 +20,11 @@
     <title>Changes</title>
   </properties>
   <body>
-    <release version="2.0-rc1" date="2014-02-08" description="Bug fixes and enhancements">
+    <release version="2.0-rc1" date="2014-MM-DD" description="Bug fixes and enhancements">
+      <action dev="nickwilliams" type="delete">
+        Removed the DataSourceConnectionSource and the &lt;DriverManager&gt; plugin for the JDBC Appender. It is not
+        safe to use. Please use the DataSource or factory connection sources backed by a connection pool.
+      </action>
       <action dev="nickwilliams" type="update">
         Renamed the org.apache.logging.log4j.core.appender.db.nosql.mongo package to
         org.apache.logging.log4j.core.appender.db.nosql.mongodb.
@@ -29,6 +33,16 @@
         Renamed the org.apache.logging.log4j.core.appender.db.nosql.couch package to
         org.apache.logging.log4j.core.appender.db.nosql.couchdb.
       </action>
+      <action issue="LOG4J2-500" dev="rpopma" type="fix">
+        (JMX - ObjectNames changed!) Unloading one web application unloads JMX MBeans for all web applications.
+      </action>
+      <action issue="LOG4J2-507" dev="ggregory" type="update">
+        Space Level numbers by 100 instead of 1.
+      </action>
+      <action issue="LOG4J2-531" dev="rpopma" type="fix" due-to="Geoff Ballinger">
+        Fixed bugs where rolled log files were overwritten by RollingFile appender with 
+        composite time and size based policies.
+      </action>
       <action issue="LOG4J2-475" dev="nickwilliams" type="fix" due-to="Matt Sicker">
         Changed the MongoDBConnection to add a MongoDB encoding hook instead of a decoding hook.
       </action>
@@ -51,17 +65,10 @@
         Fixed inability to recover from lost database connection in database appenders by connecting (borrowing from
         pool) on new write internal or on flush.
       </action>
-      <action dev="nickwilliams" type="delete">
-        Removed the DataSourceConnectionSource and the &lt;DriverManager&gt; plugin for the JDBC Appender. It is not
-        safe to use. Please use the DataSource or factory connection sources backed by a connection pool.
-      </action>
       <action issue="LOG4J2-530" dev="rpopma" type="add">
         (JMX) JMX Client GUI should dynamically update when LoggerContext MBeans are registered/unregistered in MBean
         server.
       </action>
-      <action issue="LOG4J2-500" dev="rpopma" type="fix">
-        (JMX) Unloading one webapp unloads JMX MBeans for all webapps.
-      </action>
       <action issue="LOG4J2-511" dev="rpopma" type="fix" due-to="James Pretorius">
         Stop AsyncLoggerConfig Disruptor thread(s), then AsyncAppender thread(s) first
         before stopping other appenders.
@@ -106,9 +113,6 @@
       <action issue="LOG4J2-41" dev="rgoers" type="update" due-to="Nick Williams">
         Add support for custom logging levels.
       </action>
-      <action issue="LOG4J2-507" dev="ggregory" type="update">
-        Space Level numbers by 100 instead of 1.
-      </action>
       <action issue="LOG4J2-406" dev="rpopma" type="fix" due-to="Kerrigan Joseph">
         (JMX) Unregister all log4j JMX MBeans when the LoggerContext is stopped
         to allow web application classes to be GC-ed on undeploy.
diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml
index 103e3dd..3776f2e 100644
--- a/src/site/xdoc/manual/appenders.xml
+++ b/src/site/xdoc/manual/appenders.xml
@@ -2145,7 +2145,7 @@
             A RollingFileAppender requires a <a href="#TriggeringPolicies">TriggeringPolicy</a> and a
             <a href="#RolloverStrategies">RolloverStrategy</a>. The triggering policy determines if a rollover should
             be performed while the RolloverStrategy defines how the rollover should be done. If no RolloverStrategy
-            is configured, RollingFileAppender will use the <a href="DefaultRolloverStrategy">DefaultRolloverStrategy</a>.
+            is configured, RollingFileAppender will use the <a href="#DefaultRolloverStrategy">DefaultRolloverStrategy</a>.
           </p>
           <p>
             File locking is not supported by the RollingFileAppender.