Index: jempbox/src/main/java/org/apache/jempbox/impl/DateConverter.java
===================================================================
--- jempbox/src/main/java/org/apache/jempbox/impl/DateConverter.java	(revision 1201254)
+++ jempbox/src/main/java/org/apache/jempbox/impl/DateConverter.java	(working copy)
@@ -17,11 +17,14 @@
 package org.apache.jempbox.impl;
 
 import java.io.IOException;
+import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
+import java.util.List;
 import java.util.SimpleTimeZone;
 
 /**
@@ -38,37 +41,53 @@
     //The Date format is supposed to be the PDF_DATE_FORMAT, but not all PDF documents
     //will use that date, so I have added a couple other potential formats
     //to try if the original one does not work.
-    private static final SimpleDateFormat[] POTENTIAL_FORMATS = new SimpleDateFormat[] { 
-        new SimpleDateFormat("EEEE, dd MMM yyyy hh:mm:ss a"),
-        new SimpleDateFormat("EEEE, MMM dd, yyyy hh:mm:ss a"),
-        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"), 
-        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"),
-        new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"),
-        new SimpleDateFormat("MM/dd/yyyy"),
-        new SimpleDateFormat("EEEE, MMM dd, yyyy"), // Acrobat Distiller 1.0.2 for Macintosh
-        new SimpleDateFormat("EEEE MMM dd, yyyy HH:mm:ss"), // ECMP5
-        new SimpleDateFormat("EEEE MMM dd HH:mm:ss z yyyy"), // GNU Ghostscript 7.0.7
-        new SimpleDateFormat("EEEE, MMM dd, yyyy 'at' hh:mma") // Acrobat Net Distiller 1.0 for Windows
-    };
+    private static final List<DateFormat> POTENTIAL_FORMATS = new ArrayList<DateFormat> ();
+    
+    static
+    { 
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("EEEE, dd MMM yyyy hh:mm:ss a"));
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("EEEE, MMM dd, yyyy hh:mm:ss a"));
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz"));
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("MM/dd/yyyy hh:mm:ss"));
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("MM/dd/yyyy"));
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("EEEE, MMM dd, yyyy")); // Acrobat Distiller 1.0.2 for Macintosh
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("EEEE MMM dd, yyyy HH:mm:ss")); // ECMP5
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("EEEE MMM dd HH:mm:ss z yyyy")); // GNU Ghostscript 7.0.7
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("EEEE, MMM dd, yyyy 'at' hh:mma")); // Acrobat Net Distiller 1.0 for Windows
+        POTENTIAL_FORMATS.add (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSZ"));
+    }
     
     private DateConverter()
     {
         //utility class should not be constructed.
     }
+    
+    /**
+     * Register an additional potential date format, that is used to convert the string representation of a date to a native date value.
+     * This method does not check for duplicate date formats.
+     * 
+     * @param dateFormat The new simple date format to be used for parsing. It is only added if it is not <code>null</code>.
+     */
+    public static void registerPotentialDateFormat( final DateFormat dateFormat )
+    {
+      if( dateFormat != null )
+        POTENTIAL_FORMATS.add( dateFormat );
+    }
 
     /**
      * This will convert a string to a calendar.
      *
-     * @param date The string representation of the calendar.
+     * @param pdate The string representation of the calendar.
      *
      * @return The calendar that this string represents.
      *
      * @throws IOException If the date string is not in the correct format.
      */
-    public static Calendar toCalendar( String date ) throws IOException
+    public static Calendar toCalendar( final String pdate ) throws IOException
     {
         Calendar retval = null;
-        if( date != null && date.trim().length() > 0 )
+        if( pdate != null && pdate.trim().length() > 0 )
         {
             //these are the default values
             int year = 0;
@@ -81,11 +100,12 @@
             try
             {
                 SimpleTimeZone zone = null;
+                String date = pdate;
                 if( date.startsWith( "D:" ) )
                 {
                     date = date.substring( 2, date.length() );
                 }
-                date = date.replaceAll("[-:T]", "");
+                date = date.replaceAll("[-:T.]", "");
                 
                 if( date.length() < 4 )
                 {
@@ -163,11 +183,11 @@
                 retval.clear();
                 retval.set( year, month-1, day, hour, minute, second );
             }
-            catch( NumberFormatException e )
+            catch( final NumberFormatException e )
             {
-                
                 // remove the arbitrary : in the timezone. SimpleDateFormat
-                // can't handle it           
+                // can't handle it
+                String date = pdate;
                 if (date.substring(date.length()-3,date.length()-2).equals(":") &&
                         (date.substring(date.length()-6,date.length()-5).equals("+") ||
                                 date.substring(date.length()-6,date.length()-5).equals("-"))) 
@@ -176,15 +196,15 @@
                     date = date.substring(0,date.length()-3) + 
                            date.substring(date.length()-2);
                 }
-                for( int i=0; retval == null && i<POTENTIAL_FORMATS.length; i++ )
+                for( DateFormat potentialFormat : POTENTIAL_FORMATS)
                 {
                     try
                     {
-                        Date utilDate = POTENTIAL_FORMATS[i].parse( date ); 
+                        Date utilDate = potentialFormat.parse( date ); 
                         retval = new GregorianCalendar();
                         retval.setTime( utilDate );
                     }
-                    catch( ParseException pe )
+                    catch( final ParseException pe )
                     {
                         //ignore and move to next potential format
                     }
@@ -192,18 +212,18 @@
                 if( retval == null )
                 {
                     //we didn't find a valid date format so throw an exception
-                    throw new IOException( "Error converting date:" + date );
+                    throw new IOException( "Error converting date:" + pdate );
                 }
             }
         }
         return retval;
     }
     
-    private static final void zeroAppend( StringBuffer out, int number )
+    private static final void zeroAppend( final StringBuilder out, final int number )
     {
         if( number < 10 )
         {
-            out.append( "0" );
+            out.append( '0' );
         }
         out.append( number );
     }
@@ -214,46 +234,38 @@
      * @param cal The date to convert.
      * @return The date represented as an ISO 8601 string.
      */
-    public static String toISO8601( Calendar cal )
+    public static String toISO8601( final Calendar cal )
     {
-        StringBuffer retval = new StringBuffer();
+        StringBuilder retval = new StringBuilder();
         
         retval.append( cal.get( Calendar.YEAR ) );
-        retval.append( "-" );
+        retval.append( '-' );
         zeroAppend( retval, cal.get( Calendar.MONTH )+1 );
-        retval.append( "-" );
+        retval.append( '-' );
         zeroAppend( retval, cal.get( Calendar.DAY_OF_MONTH ) );
-        retval.append( "T" );
+        retval.append( 'T' );
         zeroAppend( retval, cal.get( Calendar.HOUR_OF_DAY ));
-        retval.append( ":" );
+        retval.append( ':' );
         zeroAppend( retval, cal.get( Calendar.MINUTE ));
-        retval.append( ":" );
+        retval.append( ':' );
         zeroAppend( retval, cal.get( Calendar.SECOND ));
         
         int timeZone = cal.get( Calendar.ZONE_OFFSET ) + cal.get(Calendar.DST_OFFSET );
         if( timeZone < 0 )
         {
-            retval.append( "-" );
+            retval.append( '-' );
         }
         else
         {
-            retval.append( "+" );
+            retval.append( '+' );
         }
         timeZone = Math.abs( timeZone );
         //milliseconds/1000 = seconds = seconds / 60 = minutes = minutes/60 = hours
         int hours = timeZone/1000/60/60;
         int minutes = (timeZone - (hours*1000*60*60))/1000/1000;
-        if( hours < 10 )
-        {
-            retval.append( "0" );
-        }
-        retval.append( Integer.toString( hours ) );
-        retval.append( ":" );
-        if( minutes < 10 )
-        {
-            retval.append( "0" );
-        }
-        retval.append( Integer.toString( minutes ) );
+        zeroAppend( retval, hours );
+        retval.append( ':' );
+        zeroAppend( retval, minutes );
         
         return retval.toString();
     }
