From 263d085885df024dca9250cc03c807912b0a7662 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 24 Apr 2012 22:33:21 +0000
Subject: [PATCH] Reformat to comply with new Checkstyle rules.

---
 opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java | 4221 ++++++++++++++++++++++++++++-------------------------------
 1 files changed, 2,016 insertions(+), 2,205 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
index 6edb99e..d892bf3 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
@@ -6,17 +6,16 @@
  * (the "License").  You may not use this file except in compliance
  * with the License.
  *
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
  * or http://forgerock.org/license/CDDLv1.0.html.
  * See the License for the specific language governing permissions
  * and limitations under the License.
  *
  * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
- * add the following below this CDDL HEADER, with the fields enclosed
- * by brackets "[]" replaced with your own identifying information:
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
  *      Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
@@ -28,8 +27,6 @@
 
 package com.forgerock.opendj.util;
 
-
-
 import static org.forgerock.opendj.ldap.CoreMessages.ERR_HEX_DECODE_INVALID_CHARACTER;
 import static org.forgerock.opendj.ldap.CoreMessages.ERR_HEX_DECODE_INVALID_LENGTH;
 
@@ -38,7 +35,14 @@
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.text.ParseException;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.TimeZone;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ThreadFactory;
@@ -55,2280 +59,2087 @@
 import org.forgerock.opendj.ldap.ByteSequence;
 import org.forgerock.opendj.ldap.ByteStringBuilder;
 
-
-
 /**
  * Common utility methods.
  */
-public final class StaticUtils
-{
-  /**
-   * The debug logger which should be used by the SDK.
-   */
-  public static final Logger DEBUG_LOG = Logger.getLogger("org.forgerock.opendj.ldap");
+public final class StaticUtils {
+    /**
+     * The debug logger which should be used by the SDK.
+     */
+    public static final Logger DEBUG_LOG = Logger.getLogger("org.forgerock.opendj.ldap");
 
-  /**
-   * The end-of-line character for this platform.
-   */
-  public static final String EOL = System.getProperty("line.separator");
+    /**
+     * The end-of-line character for this platform.
+     */
+    public static final String EOL = System.getProperty("line.separator");
 
-  /**
-   * A zero-length byte array.
-   */
-  public static final byte[] EMPTY_BYTES = new byte[0];
+    /**
+     * A zero-length byte array.
+     */
+    public static final byte[] EMPTY_BYTES = new byte[0];
 
-  // The name of the time zone for universal coordinated time (UTC).
-  private static final String TIME_ZONE_UTC = "UTC";
+    // The name of the time zone for universal coordinated time (UTC).
+    private static final String TIME_ZONE_UTC = "UTC";
 
-  // UTC TimeZone is assumed to never change over JVM lifetime
-  private static final TimeZone TIME_ZONE_UTC_OBJ = TimeZone
-      .getTimeZone(TIME_ZONE_UTC);
+    // UTC TimeZone is assumed to never change over JVM lifetime
+    private static final TimeZone TIME_ZONE_UTC_OBJ = TimeZone.getTimeZone(TIME_ZONE_UTC);
 
-  private static ScheduledExecutorService defaultScheduler = null;
+    private static ScheduledExecutorService defaultScheduler = null;
 
-  private static final Object DEFAULT_SCHEDULER_LOCK = new Object();
+    private static final Object DEFAULT_SCHEDULER_LOCK = new Object();
 
-
-
-  /**
-   * Retrieves a string representation of the provided byte in hexadecimal.
-   *
-   * @param b
-   *          The byte for which to retrieve the hexadecimal string
-   *          representation.
-   * @return The string representation of the provided byte in hexadecimal.
-   */
-  public static String byteToHex(final byte b)
-  {
-    switch (b & 0xFF)
-    {
-    case 0x00:
-      return "00";
-    case 0x01:
-      return "01";
-    case 0x02:
-      return "02";
-    case 0x03:
-      return "03";
-    case 0x04:
-      return "04";
-    case 0x05:
-      return "05";
-    case 0x06:
-      return "06";
-    case 0x07:
-      return "07";
-    case 0x08:
-      return "08";
-    case 0x09:
-      return "09";
-    case 0x0A:
-      return "0A";
-    case 0x0B:
-      return "0B";
-    case 0x0C:
-      return "0C";
-    case 0x0D:
-      return "0D";
-    case 0x0E:
-      return "0E";
-    case 0x0F:
-      return "0F";
-    case 0x10:
-      return "10";
-    case 0x11:
-      return "11";
-    case 0x12:
-      return "12";
-    case 0x13:
-      return "13";
-    case 0x14:
-      return "14";
-    case 0x15:
-      return "15";
-    case 0x16:
-      return "16";
-    case 0x17:
-      return "17";
-    case 0x18:
-      return "18";
-    case 0x19:
-      return "19";
-    case 0x1A:
-      return "1A";
-    case 0x1B:
-      return "1B";
-    case 0x1C:
-      return "1C";
-    case 0x1D:
-      return "1D";
-    case 0x1E:
-      return "1E";
-    case 0x1F:
-      return "1F";
-    case 0x20:
-      return "20";
-    case 0x21:
-      return "21";
-    case 0x22:
-      return "22";
-    case 0x23:
-      return "23";
-    case 0x24:
-      return "24";
-    case 0x25:
-      return "25";
-    case 0x26:
-      return "26";
-    case 0x27:
-      return "27";
-    case 0x28:
-      return "28";
-    case 0x29:
-      return "29";
-    case 0x2A:
-      return "2A";
-    case 0x2B:
-      return "2B";
-    case 0x2C:
-      return "2C";
-    case 0x2D:
-      return "2D";
-    case 0x2E:
-      return "2E";
-    case 0x2F:
-      return "2F";
-    case 0x30:
-      return "30";
-    case 0x31:
-      return "31";
-    case 0x32:
-      return "32";
-    case 0x33:
-      return "33";
-    case 0x34:
-      return "34";
-    case 0x35:
-      return "35";
-    case 0x36:
-      return "36";
-    case 0x37:
-      return "37";
-    case 0x38:
-      return "38";
-    case 0x39:
-      return "39";
-    case 0x3A:
-      return "3A";
-    case 0x3B:
-      return "3B";
-    case 0x3C:
-      return "3C";
-    case 0x3D:
-      return "3D";
-    case 0x3E:
-      return "3E";
-    case 0x3F:
-      return "3F";
-    case 0x40:
-      return "40";
-    case 0x41:
-      return "41";
-    case 0x42:
-      return "42";
-    case 0x43:
-      return "43";
-    case 0x44:
-      return "44";
-    case 0x45:
-      return "45";
-    case 0x46:
-      return "46";
-    case 0x47:
-      return "47";
-    case 0x48:
-      return "48";
-    case 0x49:
-      return "49";
-    case 0x4A:
-      return "4A";
-    case 0x4B:
-      return "4B";
-    case 0x4C:
-      return "4C";
-    case 0x4D:
-      return "4D";
-    case 0x4E:
-      return "4E";
-    case 0x4F:
-      return "4F";
-    case 0x50:
-      return "50";
-    case 0x51:
-      return "51";
-    case 0x52:
-      return "52";
-    case 0x53:
-      return "53";
-    case 0x54:
-      return "54";
-    case 0x55:
-      return "55";
-    case 0x56:
-      return "56";
-    case 0x57:
-      return "57";
-    case 0x58:
-      return "58";
-    case 0x59:
-      return "59";
-    case 0x5A:
-      return "5A";
-    case 0x5B:
-      return "5B";
-    case 0x5C:
-      return "5C";
-    case 0x5D:
-      return "5D";
-    case 0x5E:
-      return "5E";
-    case 0x5F:
-      return "5F";
-    case 0x60:
-      return "60";
-    case 0x61:
-      return "61";
-    case 0x62:
-      return "62";
-    case 0x63:
-      return "63";
-    case 0x64:
-      return "64";
-    case 0x65:
-      return "65";
-    case 0x66:
-      return "66";
-    case 0x67:
-      return "67";
-    case 0x68:
-      return "68";
-    case 0x69:
-      return "69";
-    case 0x6A:
-      return "6A";
-    case 0x6B:
-      return "6B";
-    case 0x6C:
-      return "6C";
-    case 0x6D:
-      return "6D";
-    case 0x6E:
-      return "6E";
-    case 0x6F:
-      return "6F";
-    case 0x70:
-      return "70";
-    case 0x71:
-      return "71";
-    case 0x72:
-      return "72";
-    case 0x73:
-      return "73";
-    case 0x74:
-      return "74";
-    case 0x75:
-      return "75";
-    case 0x76:
-      return "76";
-    case 0x77:
-      return "77";
-    case 0x78:
-      return "78";
-    case 0x79:
-      return "79";
-    case 0x7A:
-      return "7A";
-    case 0x7B:
-      return "7B";
-    case 0x7C:
-      return "7C";
-    case 0x7D:
-      return "7D";
-    case 0x7E:
-      return "7E";
-    case 0x7F:
-      return "7F";
-    case 0x80:
-      return "80";
-    case 0x81:
-      return "81";
-    case 0x82:
-      return "82";
-    case 0x83:
-      return "83";
-    case 0x84:
-      return "84";
-    case 0x85:
-      return "85";
-    case 0x86:
-      return "86";
-    case 0x87:
-      return "87";
-    case 0x88:
-      return "88";
-    case 0x89:
-      return "89";
-    case 0x8A:
-      return "8A";
-    case 0x8B:
-      return "8B";
-    case 0x8C:
-      return "8C";
-    case 0x8D:
-      return "8D";
-    case 0x8E:
-      return "8E";
-    case 0x8F:
-      return "8F";
-    case 0x90:
-      return "90";
-    case 0x91:
-      return "91";
-    case 0x92:
-      return "92";
-    case 0x93:
-      return "93";
-    case 0x94:
-      return "94";
-    case 0x95:
-      return "95";
-    case 0x96:
-      return "96";
-    case 0x97:
-      return "97";
-    case 0x98:
-      return "98";
-    case 0x99:
-      return "99";
-    case 0x9A:
-      return "9A";
-    case 0x9B:
-      return "9B";
-    case 0x9C:
-      return "9C";
-    case 0x9D:
-      return "9D";
-    case 0x9E:
-      return "9E";
-    case 0x9F:
-      return "9F";
-    case 0xA0:
-      return "A0";
-    case 0xA1:
-      return "A1";
-    case 0xA2:
-      return "A2";
-    case 0xA3:
-      return "A3";
-    case 0xA4:
-      return "A4";
-    case 0xA5:
-      return "A5";
-    case 0xA6:
-      return "A6";
-    case 0xA7:
-      return "A7";
-    case 0xA8:
-      return "A8";
-    case 0xA9:
-      return "A9";
-    case 0xAA:
-      return "AA";
-    case 0xAB:
-      return "AB";
-    case 0xAC:
-      return "AC";
-    case 0xAD:
-      return "AD";
-    case 0xAE:
-      return "AE";
-    case 0xAF:
-      return "AF";
-    case 0xB0:
-      return "B0";
-    case 0xB1:
-      return "B1";
-    case 0xB2:
-      return "B2";
-    case 0xB3:
-      return "B3";
-    case 0xB4:
-      return "B4";
-    case 0xB5:
-      return "B5";
-    case 0xB6:
-      return "B6";
-    case 0xB7:
-      return "B7";
-    case 0xB8:
-      return "B8";
-    case 0xB9:
-      return "B9";
-    case 0xBA:
-      return "BA";
-    case 0xBB:
-      return "BB";
-    case 0xBC:
-      return "BC";
-    case 0xBD:
-      return "BD";
-    case 0xBE:
-      return "BE";
-    case 0xBF:
-      return "BF";
-    case 0xC0:
-      return "C0";
-    case 0xC1:
-      return "C1";
-    case 0xC2:
-      return "C2";
-    case 0xC3:
-      return "C3";
-    case 0xC4:
-      return "C4";
-    case 0xC5:
-      return "C5";
-    case 0xC6:
-      return "C6";
-    case 0xC7:
-      return "C7";
-    case 0xC8:
-      return "C8";
-    case 0xC9:
-      return "C9";
-    case 0xCA:
-      return "CA";
-    case 0xCB:
-      return "CB";
-    case 0xCC:
-      return "CC";
-    case 0xCD:
-      return "CD";
-    case 0xCE:
-      return "CE";
-    case 0xCF:
-      return "CF";
-    case 0xD0:
-      return "D0";
-    case 0xD1:
-      return "D1";
-    case 0xD2:
-      return "D2";
-    case 0xD3:
-      return "D3";
-    case 0xD4:
-      return "D4";
-    case 0xD5:
-      return "D5";
-    case 0xD6:
-      return "D6";
-    case 0xD7:
-      return "D7";
-    case 0xD8:
-      return "D8";
-    case 0xD9:
-      return "D9";
-    case 0xDA:
-      return "DA";
-    case 0xDB:
-      return "DB";
-    case 0xDC:
-      return "DC";
-    case 0xDD:
-      return "DD";
-    case 0xDE:
-      return "DE";
-    case 0xDF:
-      return "DF";
-    case 0xE0:
-      return "E0";
-    case 0xE1:
-      return "E1";
-    case 0xE2:
-      return "E2";
-    case 0xE3:
-      return "E3";
-    case 0xE4:
-      return "E4";
-    case 0xE5:
-      return "E5";
-    case 0xE6:
-      return "E6";
-    case 0xE7:
-      return "E7";
-    case 0xE8:
-      return "E8";
-    case 0xE9:
-      return "E9";
-    case 0xEA:
-      return "EA";
-    case 0xEB:
-      return "EB";
-    case 0xEC:
-      return "EC";
-    case 0xED:
-      return "ED";
-    case 0xEE:
-      return "EE";
-    case 0xEF:
-      return "EF";
-    case 0xF0:
-      return "F0";
-    case 0xF1:
-      return "F1";
-    case 0xF2:
-      return "F2";
-    case 0xF3:
-      return "F3";
-    case 0xF4:
-      return "F4";
-    case 0xF5:
-      return "F5";
-    case 0xF6:
-      return "F6";
-    case 0xF7:
-      return "F7";
-    case 0xF8:
-      return "F8";
-    case 0xF9:
-      return "F9";
-    case 0xFA:
-      return "FA";
-    case 0xFB:
-      return "FB";
-    case 0xFC:
-      return "FC";
-    case 0xFD:
-      return "FD";
-    case 0xFE:
-      return "FE";
-    case 0xFF:
-      return "FF";
-    default:
-      return "??";
-    }
-  }
-
-
-
-  /**
-   * Retrieves a string representation of the provided byte in hexadecimal.
-   *
-   * @param b
-   *          The byte for which to retrieve the hexadecimal string
-   *          representation.
-   * @return The string representation of the provided byte in hexadecimal using
-   *         lowercase characters.
-   */
-  public static String byteToLowerHex(final byte b)
-  {
-    switch (b & 0xFF)
-    {
-    case 0x00:
-      return "00";
-    case 0x01:
-      return "01";
-    case 0x02:
-      return "02";
-    case 0x03:
-      return "03";
-    case 0x04:
-      return "04";
-    case 0x05:
-      return "05";
-    case 0x06:
-      return "06";
-    case 0x07:
-      return "07";
-    case 0x08:
-      return "08";
-    case 0x09:
-      return "09";
-    case 0x0A:
-      return "0a";
-    case 0x0B:
-      return "0b";
-    case 0x0C:
-      return "0c";
-    case 0x0D:
-      return "0d";
-    case 0x0E:
-      return "0e";
-    case 0x0F:
-      return "0f";
-    case 0x10:
-      return "10";
-    case 0x11:
-      return "11";
-    case 0x12:
-      return "12";
-    case 0x13:
-      return "13";
-    case 0x14:
-      return "14";
-    case 0x15:
-      return "15";
-    case 0x16:
-      return "16";
-    case 0x17:
-      return "17";
-    case 0x18:
-      return "18";
-    case 0x19:
-      return "19";
-    case 0x1A:
-      return "1a";
-    case 0x1B:
-      return "1b";
-    case 0x1C:
-      return "1c";
-    case 0x1D:
-      return "1d";
-    case 0x1E:
-      return "1e";
-    case 0x1F:
-      return "1f";
-    case 0x20:
-      return "20";
-    case 0x21:
-      return "21";
-    case 0x22:
-      return "22";
-    case 0x23:
-      return "23";
-    case 0x24:
-      return "24";
-    case 0x25:
-      return "25";
-    case 0x26:
-      return "26";
-    case 0x27:
-      return "27";
-    case 0x28:
-      return "28";
-    case 0x29:
-      return "29";
-    case 0x2A:
-      return "2a";
-    case 0x2B:
-      return "2b";
-    case 0x2C:
-      return "2c";
-    case 0x2D:
-      return "2d";
-    case 0x2E:
-      return "2e";
-    case 0x2F:
-      return "2f";
-    case 0x30:
-      return "30";
-    case 0x31:
-      return "31";
-    case 0x32:
-      return "32";
-    case 0x33:
-      return "33";
-    case 0x34:
-      return "34";
-    case 0x35:
-      return "35";
-    case 0x36:
-      return "36";
-    case 0x37:
-      return "37";
-    case 0x38:
-      return "38";
-    case 0x39:
-      return "39";
-    case 0x3A:
-      return "3a";
-    case 0x3B:
-      return "3b";
-    case 0x3C:
-      return "3c";
-    case 0x3D:
-      return "3d";
-    case 0x3E:
-      return "3e";
-    case 0x3F:
-      return "3f";
-    case 0x40:
-      return "40";
-    case 0x41:
-      return "41";
-    case 0x42:
-      return "42";
-    case 0x43:
-      return "43";
-    case 0x44:
-      return "44";
-    case 0x45:
-      return "45";
-    case 0x46:
-      return "46";
-    case 0x47:
-      return "47";
-    case 0x48:
-      return "48";
-    case 0x49:
-      return "49";
-    case 0x4A:
-      return "4a";
-    case 0x4B:
-      return "4b";
-    case 0x4C:
-      return "4c";
-    case 0x4D:
-      return "4d";
-    case 0x4E:
-      return "4e";
-    case 0x4F:
-      return "4f";
-    case 0x50:
-      return "50";
-    case 0x51:
-      return "51";
-    case 0x52:
-      return "52";
-    case 0x53:
-      return "53";
-    case 0x54:
-      return "54";
-    case 0x55:
-      return "55";
-    case 0x56:
-      return "56";
-    case 0x57:
-      return "57";
-    case 0x58:
-      return "58";
-    case 0x59:
-      return "59";
-    case 0x5A:
-      return "5a";
-    case 0x5B:
-      return "5b";
-    case 0x5C:
-      return "5c";
-    case 0x5D:
-      return "5d";
-    case 0x5E:
-      return "5e";
-    case 0x5F:
-      return "5f";
-    case 0x60:
-      return "60";
-    case 0x61:
-      return "61";
-    case 0x62:
-      return "62";
-    case 0x63:
-      return "63";
-    case 0x64:
-      return "64";
-    case 0x65:
-      return "65";
-    case 0x66:
-      return "66";
-    case 0x67:
-      return "67";
-    case 0x68:
-      return "68";
-    case 0x69:
-      return "69";
-    case 0x6A:
-      return "6a";
-    case 0x6B:
-      return "6b";
-    case 0x6C:
-      return "6c";
-    case 0x6D:
-      return "6d";
-    case 0x6E:
-      return "6e";
-    case 0x6F:
-      return "6f";
-    case 0x70:
-      return "70";
-    case 0x71:
-      return "71";
-    case 0x72:
-      return "72";
-    case 0x73:
-      return "73";
-    case 0x74:
-      return "74";
-    case 0x75:
-      return "75";
-    case 0x76:
-      return "76";
-    case 0x77:
-      return "77";
-    case 0x78:
-      return "78";
-    case 0x79:
-      return "79";
-    case 0x7A:
-      return "7a";
-    case 0x7B:
-      return "7b";
-    case 0x7C:
-      return "7c";
-    case 0x7D:
-      return "7d";
-    case 0x7E:
-      return "7e";
-    case 0x7F:
-      return "7f";
-    case 0x80:
-      return "80";
-    case 0x81:
-      return "81";
-    case 0x82:
-      return "82";
-    case 0x83:
-      return "83";
-    case 0x84:
-      return "84";
-    case 0x85:
-      return "85";
-    case 0x86:
-      return "86";
-    case 0x87:
-      return "87";
-    case 0x88:
-      return "88";
-    case 0x89:
-      return "89";
-    case 0x8A:
-      return "8a";
-    case 0x8B:
-      return "8b";
-    case 0x8C:
-      return "8c";
-    case 0x8D:
-      return "8d";
-    case 0x8E:
-      return "8e";
-    case 0x8F:
-      return "8f";
-    case 0x90:
-      return "90";
-    case 0x91:
-      return "91";
-    case 0x92:
-      return "92";
-    case 0x93:
-      return "93";
-    case 0x94:
-      return "94";
-    case 0x95:
-      return "95";
-    case 0x96:
-      return "96";
-    case 0x97:
-      return "97";
-    case 0x98:
-      return "98";
-    case 0x99:
-      return "99";
-    case 0x9A:
-      return "9a";
-    case 0x9B:
-      return "9b";
-    case 0x9C:
-      return "9c";
-    case 0x9D:
-      return "9d";
-    case 0x9E:
-      return "9e";
-    case 0x9F:
-      return "9f";
-    case 0xA0:
-      return "a0";
-    case 0xA1:
-      return "a1";
-    case 0xA2:
-      return "a2";
-    case 0xA3:
-      return "a3";
-    case 0xA4:
-      return "a4";
-    case 0xA5:
-      return "a5";
-    case 0xA6:
-      return "a6";
-    case 0xA7:
-      return "a7";
-    case 0xA8:
-      return "a8";
-    case 0xA9:
-      return "a9";
-    case 0xAA:
-      return "aa";
-    case 0xAB:
-      return "ab";
-    case 0xAC:
-      return "ac";
-    case 0xAD:
-      return "ad";
-    case 0xAE:
-      return "ae";
-    case 0xAF:
-      return "af";
-    case 0xB0:
-      return "b0";
-    case 0xB1:
-      return "b1";
-    case 0xB2:
-      return "b2";
-    case 0xB3:
-      return "b3";
-    case 0xB4:
-      return "b4";
-    case 0xB5:
-      return "b5";
-    case 0xB6:
-      return "b6";
-    case 0xB7:
-      return "b7";
-    case 0xB8:
-      return "b8";
-    case 0xB9:
-      return "b9";
-    case 0xBA:
-      return "ba";
-    case 0xBB:
-      return "bb";
-    case 0xBC:
-      return "bc";
-    case 0xBD:
-      return "bd";
-    case 0xBE:
-      return "be";
-    case 0xBF:
-      return "bf";
-    case 0xC0:
-      return "c0";
-    case 0xC1:
-      return "c1";
-    case 0xC2:
-      return "c2";
-    case 0xC3:
-      return "c3";
-    case 0xC4:
-      return "c4";
-    case 0xC5:
-      return "c5";
-    case 0xC6:
-      return "c6";
-    case 0xC7:
-      return "c7";
-    case 0xC8:
-      return "c8";
-    case 0xC9:
-      return "c9";
-    case 0xCA:
-      return "ca";
-    case 0xCB:
-      return "cb";
-    case 0xCC:
-      return "cc";
-    case 0xCD:
-      return "cd";
-    case 0xCE:
-      return "ce";
-    case 0xCF:
-      return "cf";
-    case 0xD0:
-      return "d0";
-    case 0xD1:
-      return "d1";
-    case 0xD2:
-      return "d2";
-    case 0xD3:
-      return "d3";
-    case 0xD4:
-      return "d4";
-    case 0xD5:
-      return "d5";
-    case 0xD6:
-      return "d6";
-    case 0xD7:
-      return "d7";
-    case 0xD8:
-      return "d8";
-    case 0xD9:
-      return "d9";
-    case 0xDA:
-      return "da";
-    case 0xDB:
-      return "db";
-    case 0xDC:
-      return "dc";
-    case 0xDD:
-      return "dd";
-    case 0xDE:
-      return "de";
-    case 0xDF:
-      return "df";
-    case 0xE0:
-      return "e0";
-    case 0xE1:
-      return "e1";
-    case 0xE2:
-      return "e2";
-    case 0xE3:
-      return "e3";
-    case 0xE4:
-      return "e4";
-    case 0xE5:
-      return "e5";
-    case 0xE6:
-      return "e6";
-    case 0xE7:
-      return "e7";
-    case 0xE8:
-      return "e8";
-    case 0xE9:
-      return "e9";
-    case 0xEA:
-      return "ea";
-    case 0xEB:
-      return "eb";
-    case 0xEC:
-      return "ec";
-    case 0xED:
-      return "ed";
-    case 0xEE:
-      return "ee";
-    case 0xEF:
-      return "ef";
-    case 0xF0:
-      return "f0";
-    case 0xF1:
-      return "f1";
-    case 0xF2:
-      return "f2";
-    case 0xF3:
-      return "f3";
-    case 0xF4:
-      return "f4";
-    case 0xF5:
-      return "f5";
-    case 0xF6:
-      return "f6";
-    case 0xF7:
-      return "f7";
-    case 0xF8:
-      return "f8";
-    case 0xF9:
-      return "f9";
-    case 0xFA:
-      return "fa";
-    case 0xFB:
-      return "fb";
-    case 0xFC:
-      return "fc";
-    case 0xFD:
-      return "fd";
-    case 0xFE:
-      return "fe";
-    case 0xFF:
-      return "ff";
-    default:
-      return "??";
-    }
-  }
-
-
-
-  /**
-   * Attempts to compress the data in the provided source array into the given
-   * destination array. If the compressed data will fit into the destination
-   * array, then this method will return the number of bytes of compressed data
-   * in the array. Otherwise, it will return -1 to indicate that the compression
-   * was not successful. Note that if -1 is returned, then the data in the
-   * destination array should be considered invalid.
-   *
-   * @param src
-   *          The array containing the raw data to compress.
-   * @param srcOff
-   *          The start offset of the source data.
-   * @param srcLen
-   *          The maximum number of source data bytes to compress.
-   * @param dst
-   *          The array into which the compressed data should be written.
-   * @param dstOff
-   *          The start offset of the compressed data.
-   * @param dstLen
-   *          The maximum number of bytes of compressed data.
-   * @return The number of bytes of compressed data, or -1 if it was not
-   *         possible to actually compress the data.
-   */
-  public static int compress(final byte[] src, final int srcOff,
-      final int srcLen, final byte[] dst, final int dstOff, final int dstLen)
-  {
-    final Deflater deflater = new Deflater();
-    try
-    {
-      deflater.setInput(src, srcOff, srcLen);
-      deflater.finish();
-
-      final int compressedLength = deflater.deflate(dst, dstOff, dstLen);
-      if (deflater.finished())
-      {
-        return compressedLength;
-      }
-      else
-      {
-        return -1;
-      }
-    }
-    finally
-    {
-      deflater.end();
-    }
-  }
-
-
-
-  /**
-   * Attempts to compress the data in the provided byte sequence into the
-   * provided byte string builder. Note that if compression was not successful,
-   * then the byte string builder will be left unchanged.
-   *
-   * @param input
-   *          The source data to be compressed.
-   * @param output
-   *          The destination buffer to which the compressed data will be
-   *          appended.
-   * @return <code>true</code> if compression was successful or
-   *         <code>false</code> otherwise.
-   */
-  public static boolean compress(final ByteSequence input,
-      final ByteStringBuilder output)
-  {
-    final byte[] inputBytes = input.toByteArray();
-    final byte[] outputBytes = new byte[inputBytes.length];
-
-    final int compressedSize = compress(inputBytes, 0, inputBytes.length,
-        outputBytes, 0, outputBytes.length);
-
-    if (compressedSize != -1)
-    {
-      if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE))
-      {
-        StaticUtils.DEBUG_LOG.fine(String.format("Compression %d/%d%n",
-            compressedSize, inputBytes.length));
-      }
-
-      output.append(outputBytes, 0, compressedSize);
-      return true;
-    }
-
-    return false;
-  }
-
-
-
-  /**
-   * Returns a string containing provided date formatted using the generalized
-   * time syntax.
-   *
-   * @param date
-   *          The date to be formated.
-   * @return The string containing provided date formatted using the generalized
-   *         time syntax.
-   * @throws NullPointerException
-   *           If {@code date} was {@code null}.
-   */
-  public static String formatAsGeneralizedTime(final Date date)
-  {
-    return formatAsGeneralizedTime(date.getTime());
-  }
-
-
-
-  /**
-   * Returns a string containing provided date formatted using the generalized
-   * time syntax.
-   *
-   * @param date
-   *          The date to be formated.
-   * @return The string containing provided date formatted using the generalized
-   *         time syntax.
-   * @throws IllegalArgumentException
-   *           If {@code date} was invalid.
-   */
-  public static String formatAsGeneralizedTime(final long date)
-  {
-    // Generalized time has the format yyyyMMddHHmmss.SSS'Z'
-
-    // Do this in a thread-safe non-synchronized fashion.
-    // (Simple)DateFormat is neither fast nor thread-safe.
-
-    final StringBuilder sb = new StringBuilder(19);
-
-    final GregorianCalendar calendar = new GregorianCalendar(TIME_ZONE_UTC_OBJ);
-    calendar.setLenient(false);
-    calendar.setTimeInMillis(date);
-
-    // Format the year yyyy.
-    int n = calendar.get(Calendar.YEAR);
-    if (n < 0)
-    {
-      final IllegalArgumentException e = new IllegalArgumentException(
-          "Year cannot be < 0:" + n);
-      StaticUtils.DEBUG_LOG.throwing("GeneralizedTimeSyntax", "format", e);
-      throw e;
-    }
-    else if (n < 10)
-    {
-      sb.append("000");
-    }
-    else if (n < 100)
-    {
-      sb.append("00");
-    }
-    else if (n < 1000)
-    {
-      sb.append("0");
-    }
-    sb.append(n);
-
-    // Format the month MM.
-    n = calendar.get(Calendar.MONTH) + 1;
-    if (n < 10)
-    {
-      sb.append("0");
-    }
-    sb.append(n);
-
-    // Format the day dd.
-    n = calendar.get(Calendar.DAY_OF_MONTH);
-    if (n < 10)
-    {
-      sb.append("0");
-    }
-    sb.append(n);
-
-    // Format the hour HH.
-    n = calendar.get(Calendar.HOUR_OF_DAY);
-    if (n < 10)
-    {
-      sb.append("0");
-    }
-    sb.append(n);
-
-    // Format the minute mm.
-    n = calendar.get(Calendar.MINUTE);
-    if (n < 10)
-    {
-      sb.append("0");
-    }
-    sb.append(n);
-
-    // Format the seconds ss.
-    n = calendar.get(Calendar.SECOND);
-    if (n < 10)
-    {
-      sb.append("0");
-    }
-    sb.append(n);
-
-    // Format the milli-seconds.
-    sb.append('.');
-    n = calendar.get(Calendar.MILLISECOND);
-    if (n < 10)
-    {
-      sb.append("00");
-    }
-    else if (n < 100)
-    {
-      sb.append("0");
-    }
-    sb.append(n);
-
-    // Format the timezone (always Z).
-    sb.append('Z');
-
-    return sb.toString();
-  }
-
-
-
-  /**
-   * Construct a byte array containing the UTF-8 encoding of the provided
-   * character array.
-   *
-   * @param chars
-   *          The character array to convert to a UTF-8 byte array.
-   * @return A byte array containing the UTF-8 encoding of the provided
-   *         character array.
-   */
-  public static byte[] getBytes(final char[] chars)
-  {
-    final Charset utf8 = Charset.forName("UTF-8");
-    final ByteBuffer buffer = utf8.encode(CharBuffer.wrap(chars));
-    final byte[] bytes = new byte[buffer.remaining()];
-    buffer.get(bytes);
-    return bytes;
-  }
-
-
-
-  /**
-   * Construct a byte array containing the UTF-8 encoding of the provided
-   * string. This is significantly faster than calling
-   * {@link String#getBytes(String)} for ASCII strings.
-   *
-   * @param s
-   *          The string to convert to a UTF-8 byte array.
-   * @return Returns a byte array containing the UTF-8 encoding of the provided
-   *         string.
-   */
-  public static byte[] getBytes(final String s)
-  {
-    if (s == null)
-    {
-      return null;
-    }
-
-    try
-    {
-      char c;
-      final int length = s.length();
-      final byte[] returnArray = new byte[length];
-      for (int i = 0; i < length; i++)
-      {
-        c = s.charAt(i);
-        returnArray[i] = (byte) (c & 0x0000007F);
-        if (c != returnArray[i])
-        {
-          return s.getBytes("UTF-8");
+    /**
+     * Retrieves a string representation of the provided byte in hexadecimal.
+     *
+     * @param b
+     *            The byte for which to retrieve the hexadecimal string
+     *            representation.
+     * @return The string representation of the provided byte in hexadecimal.
+     */
+    public static String byteToHex(final byte b) {
+        switch (b & 0xFF) {
+        case 0x00:
+            return "00";
+        case 0x01:
+            return "01";
+        case 0x02:
+            return "02";
+        case 0x03:
+            return "03";
+        case 0x04:
+            return "04";
+        case 0x05:
+            return "05";
+        case 0x06:
+            return "06";
+        case 0x07:
+            return "07";
+        case 0x08:
+            return "08";
+        case 0x09:
+            return "09";
+        case 0x0A:
+            return "0A";
+        case 0x0B:
+            return "0B";
+        case 0x0C:
+            return "0C";
+        case 0x0D:
+            return "0D";
+        case 0x0E:
+            return "0E";
+        case 0x0F:
+            return "0F";
+        case 0x10:
+            return "10";
+        case 0x11:
+            return "11";
+        case 0x12:
+            return "12";
+        case 0x13:
+            return "13";
+        case 0x14:
+            return "14";
+        case 0x15:
+            return "15";
+        case 0x16:
+            return "16";
+        case 0x17:
+            return "17";
+        case 0x18:
+            return "18";
+        case 0x19:
+            return "19";
+        case 0x1A:
+            return "1A";
+        case 0x1B:
+            return "1B";
+        case 0x1C:
+            return "1C";
+        case 0x1D:
+            return "1D";
+        case 0x1E:
+            return "1E";
+        case 0x1F:
+            return "1F";
+        case 0x20:
+            return "20";
+        case 0x21:
+            return "21";
+        case 0x22:
+            return "22";
+        case 0x23:
+            return "23";
+        case 0x24:
+            return "24";
+        case 0x25:
+            return "25";
+        case 0x26:
+            return "26";
+        case 0x27:
+            return "27";
+        case 0x28:
+            return "28";
+        case 0x29:
+            return "29";
+        case 0x2A:
+            return "2A";
+        case 0x2B:
+            return "2B";
+        case 0x2C:
+            return "2C";
+        case 0x2D:
+            return "2D";
+        case 0x2E:
+            return "2E";
+        case 0x2F:
+            return "2F";
+        case 0x30:
+            return "30";
+        case 0x31:
+            return "31";
+        case 0x32:
+            return "32";
+        case 0x33:
+            return "33";
+        case 0x34:
+            return "34";
+        case 0x35:
+            return "35";
+        case 0x36:
+            return "36";
+        case 0x37:
+            return "37";
+        case 0x38:
+            return "38";
+        case 0x39:
+            return "39";
+        case 0x3A:
+            return "3A";
+        case 0x3B:
+            return "3B";
+        case 0x3C:
+            return "3C";
+        case 0x3D:
+            return "3D";
+        case 0x3E:
+            return "3E";
+        case 0x3F:
+            return "3F";
+        case 0x40:
+            return "40";
+        case 0x41:
+            return "41";
+        case 0x42:
+            return "42";
+        case 0x43:
+            return "43";
+        case 0x44:
+            return "44";
+        case 0x45:
+            return "45";
+        case 0x46:
+            return "46";
+        case 0x47:
+            return "47";
+        case 0x48:
+            return "48";
+        case 0x49:
+            return "49";
+        case 0x4A:
+            return "4A";
+        case 0x4B:
+            return "4B";
+        case 0x4C:
+            return "4C";
+        case 0x4D:
+            return "4D";
+        case 0x4E:
+            return "4E";
+        case 0x4F:
+            return "4F";
+        case 0x50:
+            return "50";
+        case 0x51:
+            return "51";
+        case 0x52:
+            return "52";
+        case 0x53:
+            return "53";
+        case 0x54:
+            return "54";
+        case 0x55:
+            return "55";
+        case 0x56:
+            return "56";
+        case 0x57:
+            return "57";
+        case 0x58:
+            return "58";
+        case 0x59:
+            return "59";
+        case 0x5A:
+            return "5A";
+        case 0x5B:
+            return "5B";
+        case 0x5C:
+            return "5C";
+        case 0x5D:
+            return "5D";
+        case 0x5E:
+            return "5E";
+        case 0x5F:
+            return "5F";
+        case 0x60:
+            return "60";
+        case 0x61:
+            return "61";
+        case 0x62:
+            return "62";
+        case 0x63:
+            return "63";
+        case 0x64:
+            return "64";
+        case 0x65:
+            return "65";
+        case 0x66:
+            return "66";
+        case 0x67:
+            return "67";
+        case 0x68:
+            return "68";
+        case 0x69:
+            return "69";
+        case 0x6A:
+            return "6A";
+        case 0x6B:
+            return "6B";
+        case 0x6C:
+            return "6C";
+        case 0x6D:
+            return "6D";
+        case 0x6E:
+            return "6E";
+        case 0x6F:
+            return "6F";
+        case 0x70:
+            return "70";
+        case 0x71:
+            return "71";
+        case 0x72:
+            return "72";
+        case 0x73:
+            return "73";
+        case 0x74:
+            return "74";
+        case 0x75:
+            return "75";
+        case 0x76:
+            return "76";
+        case 0x77:
+            return "77";
+        case 0x78:
+            return "78";
+        case 0x79:
+            return "79";
+        case 0x7A:
+            return "7A";
+        case 0x7B:
+            return "7B";
+        case 0x7C:
+            return "7C";
+        case 0x7D:
+            return "7D";
+        case 0x7E:
+            return "7E";
+        case 0x7F:
+            return "7F";
+        case 0x80:
+            return "80";
+        case 0x81:
+            return "81";
+        case 0x82:
+            return "82";
+        case 0x83:
+            return "83";
+        case 0x84:
+            return "84";
+        case 0x85:
+            return "85";
+        case 0x86:
+            return "86";
+        case 0x87:
+            return "87";
+        case 0x88:
+            return "88";
+        case 0x89:
+            return "89";
+        case 0x8A:
+            return "8A";
+        case 0x8B:
+            return "8B";
+        case 0x8C:
+            return "8C";
+        case 0x8D:
+            return "8D";
+        case 0x8E:
+            return "8E";
+        case 0x8F:
+            return "8F";
+        case 0x90:
+            return "90";
+        case 0x91:
+            return "91";
+        case 0x92:
+            return "92";
+        case 0x93:
+            return "93";
+        case 0x94:
+            return "94";
+        case 0x95:
+            return "95";
+        case 0x96:
+            return "96";
+        case 0x97:
+            return "97";
+        case 0x98:
+            return "98";
+        case 0x99:
+            return "99";
+        case 0x9A:
+            return "9A";
+        case 0x9B:
+            return "9B";
+        case 0x9C:
+            return "9C";
+        case 0x9D:
+            return "9D";
+        case 0x9E:
+            return "9E";
+        case 0x9F:
+            return "9F";
+        case 0xA0:
+            return "A0";
+        case 0xA1:
+            return "A1";
+        case 0xA2:
+            return "A2";
+        case 0xA3:
+            return "A3";
+        case 0xA4:
+            return "A4";
+        case 0xA5:
+            return "A5";
+        case 0xA6:
+            return "A6";
+        case 0xA7:
+            return "A7";
+        case 0xA8:
+            return "A8";
+        case 0xA9:
+            return "A9";
+        case 0xAA:
+            return "AA";
+        case 0xAB:
+            return "AB";
+        case 0xAC:
+            return "AC";
+        case 0xAD:
+            return "AD";
+        case 0xAE:
+            return "AE";
+        case 0xAF:
+            return "AF";
+        case 0xB0:
+            return "B0";
+        case 0xB1:
+            return "B1";
+        case 0xB2:
+            return "B2";
+        case 0xB3:
+            return "B3";
+        case 0xB4:
+            return "B4";
+        case 0xB5:
+            return "B5";
+        case 0xB6:
+            return "B6";
+        case 0xB7:
+            return "B7";
+        case 0xB8:
+            return "B8";
+        case 0xB9:
+            return "B9";
+        case 0xBA:
+            return "BA";
+        case 0xBB:
+            return "BB";
+        case 0xBC:
+            return "BC";
+        case 0xBD:
+            return "BD";
+        case 0xBE:
+            return "BE";
+        case 0xBF:
+            return "BF";
+        case 0xC0:
+            return "C0";
+        case 0xC1:
+            return "C1";
+        case 0xC2:
+            return "C2";
+        case 0xC3:
+            return "C3";
+        case 0xC4:
+            return "C4";
+        case 0xC5:
+            return "C5";
+        case 0xC6:
+            return "C6";
+        case 0xC7:
+            return "C7";
+        case 0xC8:
+            return "C8";
+        case 0xC9:
+            return "C9";
+        case 0xCA:
+            return "CA";
+        case 0xCB:
+            return "CB";
+        case 0xCC:
+            return "CC";
+        case 0xCD:
+            return "CD";
+        case 0xCE:
+            return "CE";
+        case 0xCF:
+            return "CF";
+        case 0xD0:
+            return "D0";
+        case 0xD1:
+            return "D1";
+        case 0xD2:
+            return "D2";
+        case 0xD3:
+            return "D3";
+        case 0xD4:
+            return "D4";
+        case 0xD5:
+            return "D5";
+        case 0xD6:
+            return "D6";
+        case 0xD7:
+            return "D7";
+        case 0xD8:
+            return "D8";
+        case 0xD9:
+            return "D9";
+        case 0xDA:
+            return "DA";
+        case 0xDB:
+            return "DB";
+        case 0xDC:
+            return "DC";
+        case 0xDD:
+            return "DD";
+        case 0xDE:
+            return "DE";
+        case 0xDF:
+            return "DF";
+        case 0xE0:
+            return "E0";
+        case 0xE1:
+            return "E1";
+        case 0xE2:
+            return "E2";
+        case 0xE3:
+            return "E3";
+        case 0xE4:
+            return "E4";
+        case 0xE5:
+            return "E5";
+        case 0xE6:
+            return "E6";
+        case 0xE7:
+            return "E7";
+        case 0xE8:
+            return "E8";
+        case 0xE9:
+            return "E9";
+        case 0xEA:
+            return "EA";
+        case 0xEB:
+            return "EB";
+        case 0xEC:
+            return "EC";
+        case 0xED:
+            return "ED";
+        case 0xEE:
+            return "EE";
+        case 0xEF:
+            return "EF";
+        case 0xF0:
+            return "F0";
+        case 0xF1:
+            return "F1";
+        case 0xF2:
+            return "F2";
+        case 0xF3:
+            return "F3";
+        case 0xF4:
+            return "F4";
+        case 0xF5:
+            return "F5";
+        case 0xF6:
+            return "F6";
+        case 0xF7:
+            return "F7";
+        case 0xF8:
+            return "F8";
+        case 0xF9:
+            return "F9";
+        case 0xFA:
+            return "FA";
+        case 0xFB:
+            return "FB";
+        case 0xFC:
+            return "FC";
+        case 0xFD:
+            return "FD";
+        case 0xFE:
+            return "FE";
+        case 0xFF:
+            return "FF";
+        default:
+            return "??";
         }
-      }
-
-      return returnArray;
     }
-    catch (final Exception e)
-    {
-      DEBUG_LOG.warning("Unable to encode UTF-8 string " + s);
 
-      return s.getBytes();
+    /**
+     * Retrieves a string representation of the provided byte in hexadecimal.
+     *
+     * @param b
+     *            The byte for which to retrieve the hexadecimal string
+     *            representation.
+     * @return The string representation of the provided byte in hexadecimal
+     *         using lowercase characters.
+     */
+    public static String byteToLowerHex(final byte b) {
+        switch (b & 0xFF) {
+        case 0x00:
+            return "00";
+        case 0x01:
+            return "01";
+        case 0x02:
+            return "02";
+        case 0x03:
+            return "03";
+        case 0x04:
+            return "04";
+        case 0x05:
+            return "05";
+        case 0x06:
+            return "06";
+        case 0x07:
+            return "07";
+        case 0x08:
+            return "08";
+        case 0x09:
+            return "09";
+        case 0x0A:
+            return "0a";
+        case 0x0B:
+            return "0b";
+        case 0x0C:
+            return "0c";
+        case 0x0D:
+            return "0d";
+        case 0x0E:
+            return "0e";
+        case 0x0F:
+            return "0f";
+        case 0x10:
+            return "10";
+        case 0x11:
+            return "11";
+        case 0x12:
+            return "12";
+        case 0x13:
+            return "13";
+        case 0x14:
+            return "14";
+        case 0x15:
+            return "15";
+        case 0x16:
+            return "16";
+        case 0x17:
+            return "17";
+        case 0x18:
+            return "18";
+        case 0x19:
+            return "19";
+        case 0x1A:
+            return "1a";
+        case 0x1B:
+            return "1b";
+        case 0x1C:
+            return "1c";
+        case 0x1D:
+            return "1d";
+        case 0x1E:
+            return "1e";
+        case 0x1F:
+            return "1f";
+        case 0x20:
+            return "20";
+        case 0x21:
+            return "21";
+        case 0x22:
+            return "22";
+        case 0x23:
+            return "23";
+        case 0x24:
+            return "24";
+        case 0x25:
+            return "25";
+        case 0x26:
+            return "26";
+        case 0x27:
+            return "27";
+        case 0x28:
+            return "28";
+        case 0x29:
+            return "29";
+        case 0x2A:
+            return "2a";
+        case 0x2B:
+            return "2b";
+        case 0x2C:
+            return "2c";
+        case 0x2D:
+            return "2d";
+        case 0x2E:
+            return "2e";
+        case 0x2F:
+            return "2f";
+        case 0x30:
+            return "30";
+        case 0x31:
+            return "31";
+        case 0x32:
+            return "32";
+        case 0x33:
+            return "33";
+        case 0x34:
+            return "34";
+        case 0x35:
+            return "35";
+        case 0x36:
+            return "36";
+        case 0x37:
+            return "37";
+        case 0x38:
+            return "38";
+        case 0x39:
+            return "39";
+        case 0x3A:
+            return "3a";
+        case 0x3B:
+            return "3b";
+        case 0x3C:
+            return "3c";
+        case 0x3D:
+            return "3d";
+        case 0x3E:
+            return "3e";
+        case 0x3F:
+            return "3f";
+        case 0x40:
+            return "40";
+        case 0x41:
+            return "41";
+        case 0x42:
+            return "42";
+        case 0x43:
+            return "43";
+        case 0x44:
+            return "44";
+        case 0x45:
+            return "45";
+        case 0x46:
+            return "46";
+        case 0x47:
+            return "47";
+        case 0x48:
+            return "48";
+        case 0x49:
+            return "49";
+        case 0x4A:
+            return "4a";
+        case 0x4B:
+            return "4b";
+        case 0x4C:
+            return "4c";
+        case 0x4D:
+            return "4d";
+        case 0x4E:
+            return "4e";
+        case 0x4F:
+            return "4f";
+        case 0x50:
+            return "50";
+        case 0x51:
+            return "51";
+        case 0x52:
+            return "52";
+        case 0x53:
+            return "53";
+        case 0x54:
+            return "54";
+        case 0x55:
+            return "55";
+        case 0x56:
+            return "56";
+        case 0x57:
+            return "57";
+        case 0x58:
+            return "58";
+        case 0x59:
+            return "59";
+        case 0x5A:
+            return "5a";
+        case 0x5B:
+            return "5b";
+        case 0x5C:
+            return "5c";
+        case 0x5D:
+            return "5d";
+        case 0x5E:
+            return "5e";
+        case 0x5F:
+            return "5f";
+        case 0x60:
+            return "60";
+        case 0x61:
+            return "61";
+        case 0x62:
+            return "62";
+        case 0x63:
+            return "63";
+        case 0x64:
+            return "64";
+        case 0x65:
+            return "65";
+        case 0x66:
+            return "66";
+        case 0x67:
+            return "67";
+        case 0x68:
+            return "68";
+        case 0x69:
+            return "69";
+        case 0x6A:
+            return "6a";
+        case 0x6B:
+            return "6b";
+        case 0x6C:
+            return "6c";
+        case 0x6D:
+            return "6d";
+        case 0x6E:
+            return "6e";
+        case 0x6F:
+            return "6f";
+        case 0x70:
+            return "70";
+        case 0x71:
+            return "71";
+        case 0x72:
+            return "72";
+        case 0x73:
+            return "73";
+        case 0x74:
+            return "74";
+        case 0x75:
+            return "75";
+        case 0x76:
+            return "76";
+        case 0x77:
+            return "77";
+        case 0x78:
+            return "78";
+        case 0x79:
+            return "79";
+        case 0x7A:
+            return "7a";
+        case 0x7B:
+            return "7b";
+        case 0x7C:
+            return "7c";
+        case 0x7D:
+            return "7d";
+        case 0x7E:
+            return "7e";
+        case 0x7F:
+            return "7f";
+        case 0x80:
+            return "80";
+        case 0x81:
+            return "81";
+        case 0x82:
+            return "82";
+        case 0x83:
+            return "83";
+        case 0x84:
+            return "84";
+        case 0x85:
+            return "85";
+        case 0x86:
+            return "86";
+        case 0x87:
+            return "87";
+        case 0x88:
+            return "88";
+        case 0x89:
+            return "89";
+        case 0x8A:
+            return "8a";
+        case 0x8B:
+            return "8b";
+        case 0x8C:
+            return "8c";
+        case 0x8D:
+            return "8d";
+        case 0x8E:
+            return "8e";
+        case 0x8F:
+            return "8f";
+        case 0x90:
+            return "90";
+        case 0x91:
+            return "91";
+        case 0x92:
+            return "92";
+        case 0x93:
+            return "93";
+        case 0x94:
+            return "94";
+        case 0x95:
+            return "95";
+        case 0x96:
+            return "96";
+        case 0x97:
+            return "97";
+        case 0x98:
+            return "98";
+        case 0x99:
+            return "99";
+        case 0x9A:
+            return "9a";
+        case 0x9B:
+            return "9b";
+        case 0x9C:
+            return "9c";
+        case 0x9D:
+            return "9d";
+        case 0x9E:
+            return "9e";
+        case 0x9F:
+            return "9f";
+        case 0xA0:
+            return "a0";
+        case 0xA1:
+            return "a1";
+        case 0xA2:
+            return "a2";
+        case 0xA3:
+            return "a3";
+        case 0xA4:
+            return "a4";
+        case 0xA5:
+            return "a5";
+        case 0xA6:
+            return "a6";
+        case 0xA7:
+            return "a7";
+        case 0xA8:
+            return "a8";
+        case 0xA9:
+            return "a9";
+        case 0xAA:
+            return "aa";
+        case 0xAB:
+            return "ab";
+        case 0xAC:
+            return "ac";
+        case 0xAD:
+            return "ad";
+        case 0xAE:
+            return "ae";
+        case 0xAF:
+            return "af";
+        case 0xB0:
+            return "b0";
+        case 0xB1:
+            return "b1";
+        case 0xB2:
+            return "b2";
+        case 0xB3:
+            return "b3";
+        case 0xB4:
+            return "b4";
+        case 0xB5:
+            return "b5";
+        case 0xB6:
+            return "b6";
+        case 0xB7:
+            return "b7";
+        case 0xB8:
+            return "b8";
+        case 0xB9:
+            return "b9";
+        case 0xBA:
+            return "ba";
+        case 0xBB:
+            return "bb";
+        case 0xBC:
+            return "bc";
+        case 0xBD:
+            return "bd";
+        case 0xBE:
+            return "be";
+        case 0xBF:
+            return "bf";
+        case 0xC0:
+            return "c0";
+        case 0xC1:
+            return "c1";
+        case 0xC2:
+            return "c2";
+        case 0xC3:
+            return "c3";
+        case 0xC4:
+            return "c4";
+        case 0xC5:
+            return "c5";
+        case 0xC6:
+            return "c6";
+        case 0xC7:
+            return "c7";
+        case 0xC8:
+            return "c8";
+        case 0xC9:
+            return "c9";
+        case 0xCA:
+            return "ca";
+        case 0xCB:
+            return "cb";
+        case 0xCC:
+            return "cc";
+        case 0xCD:
+            return "cd";
+        case 0xCE:
+            return "ce";
+        case 0xCF:
+            return "cf";
+        case 0xD0:
+            return "d0";
+        case 0xD1:
+            return "d1";
+        case 0xD2:
+            return "d2";
+        case 0xD3:
+            return "d3";
+        case 0xD4:
+            return "d4";
+        case 0xD5:
+            return "d5";
+        case 0xD6:
+            return "d6";
+        case 0xD7:
+            return "d7";
+        case 0xD8:
+            return "d8";
+        case 0xD9:
+            return "d9";
+        case 0xDA:
+            return "da";
+        case 0xDB:
+            return "db";
+        case 0xDC:
+            return "dc";
+        case 0xDD:
+            return "dd";
+        case 0xDE:
+            return "de";
+        case 0xDF:
+            return "df";
+        case 0xE0:
+            return "e0";
+        case 0xE1:
+            return "e1";
+        case 0xE2:
+            return "e2";
+        case 0xE3:
+            return "e3";
+        case 0xE4:
+            return "e4";
+        case 0xE5:
+            return "e5";
+        case 0xE6:
+            return "e6";
+        case 0xE7:
+            return "e7";
+        case 0xE8:
+            return "e8";
+        case 0xE9:
+            return "e9";
+        case 0xEA:
+            return "ea";
+        case 0xEB:
+            return "eb";
+        case 0xEC:
+            return "ec";
+        case 0xED:
+            return "ed";
+        case 0xEE:
+            return "ee";
+        case 0xEF:
+            return "ef";
+        case 0xF0:
+            return "f0";
+        case 0xF1:
+            return "f1";
+        case 0xF2:
+            return "f2";
+        case 0xF3:
+            return "f3";
+        case 0xF4:
+            return "f4";
+        case 0xF5:
+            return "f5";
+        case 0xF6:
+            return "f6";
+        case 0xF7:
+            return "f7";
+        case 0xF8:
+            return "f8";
+        case 0xF9:
+            return "f9";
+        case 0xFA:
+            return "fa";
+        case 0xFB:
+            return "fb";
+        case 0xFC:
+            return "fc";
+        case 0xFD:
+            return "fd";
+        case 0xFE:
+            return "fe";
+        case 0xFF:
+            return "ff";
+        default:
+            return "??";
+        }
     }
-  }
 
+    /**
+     * Attempts to compress the data in the provided source array into the given
+     * destination array. If the compressed data will fit into the destination
+     * array, then this method will return the number of bytes of compressed
+     * data in the array. Otherwise, it will return -1 to indicate that the
+     * compression was not successful. Note that if -1 is returned, then the
+     * data in the destination array should be considered invalid.
+     *
+     * @param src
+     *            The array containing the raw data to compress.
+     * @param srcOff
+     *            The start offset of the source data.
+     * @param srcLen
+     *            The maximum number of source data bytes to compress.
+     * @param dst
+     *            The array into which the compressed data should be written.
+     * @param dstOff
+     *            The start offset of the compressed data.
+     * @param dstLen
+     *            The maximum number of bytes of compressed data.
+     * @return The number of bytes of compressed data, or -1 if it was not
+     *         possible to actually compress the data.
+     */
+    public static int compress(final byte[] src, final int srcOff, final int srcLen,
+            final byte[] dst, final int dstOff, final int dstLen) {
+        final Deflater deflater = new Deflater();
+        try {
+            deflater.setInput(src, srcOff, srcLen);
+            deflater.finish();
 
-
-  /**
-   * Returns the default scheduler which should be used by the SDK.
-   *
-   * @return The default scheduler.
-   */
-  public static ScheduledExecutorService getDefaultScheduler()
-  {
-    synchronized (DEFAULT_SCHEDULER_LOCK)
-    {
-      if (defaultScheduler == null)
-      {
-        final ThreadFactory factory = newThreadFactory(null,
-            "OpenDJ SDK Default Scheduler", true);
-        defaultScheduler = Executors.newSingleThreadScheduledExecutor(factory);
-      }
+            final int compressedLength = deflater.deflate(dst, dstOff, dstLen);
+            if (deflater.finished()) {
+                return compressedLength;
+            } else {
+                return -1;
+            }
+        } finally {
+            deflater.end();
+        }
     }
-    return defaultScheduler;
-  }
 
+    /**
+     * Attempts to compress the data in the provided byte sequence into the
+     * provided byte string builder. Note that if compression was not
+     * successful, then the byte string builder will be left unchanged.
+     *
+     * @param input
+     *            The source data to be compressed.
+     * @param output
+     *            The destination buffer to which the compressed data will be
+     *            appended.
+     * @return <code>true</code> if compression was successful or
+     *         <code>false</code> otherwise.
+     */
+    public static boolean compress(final ByteSequence input, final ByteStringBuilder output) {
+        final byte[] inputBytes = input.toByteArray();
+        final byte[] outputBytes = new byte[inputBytes.length];
 
+        final int compressedSize =
+                compress(inputBytes, 0, inputBytes.length, outputBytes, 0, outputBytes.length);
 
-  /**
-   * Retrieves the best human-readable message for the provided exception. For
-   * exceptions defined in the OpenDJ project, it will attempt to use the
-   * message (combining it with the message ID if available). For some
-   * exceptions that use encapsulation (e.g., InvocationTargetException), it
-   * will be unwrapped and the cause will be treated. For all others, the
-   *
-   * @param t
-   *          The {@code Throwable} object for which to retrieve the message.
-   * @return The human-readable message generated for the provided exception.
-   */
-  public static LocalizableMessage getExceptionMessage(final Throwable t)
-  {
-    if (t instanceof LocalizableException)
-    {
-      final LocalizableException ie = (LocalizableException) t;
-      return ie.getMessageObject();
+        if (compressedSize != -1) {
+            if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE)) {
+                StaticUtils.DEBUG_LOG.fine(String.format("Compression %d/%d%n", compressedSize,
+                        inputBytes.length));
+            }
+
+            output.append(outputBytes, 0, compressedSize);
+            return true;
+        }
+
+        return false;
     }
-    else if (t instanceof NullPointerException)
-    {
-      final StackTraceElement[] stackElements = t.getStackTrace();
 
-      final LocalizableMessageBuilder message = new LocalizableMessageBuilder();
-      message.append("NullPointerException(");
-      message.append(stackElements[0].getFileName());
-      message.append(":");
-      message.append(stackElements[0].getLineNumber());
-      message.append(")");
-      return message.toMessage();
+    /**
+     * Returns a string containing provided date formatted using the generalized
+     * time syntax.
+     *
+     * @param date
+     *            The date to be formated.
+     * @return The string containing provided date formatted using the
+     *         generalized time syntax.
+     * @throws NullPointerException
+     *             If {@code date} was {@code null}.
+     */
+    public static String formatAsGeneralizedTime(final Date date) {
+        return formatAsGeneralizedTime(date.getTime());
     }
-    else if (t instanceof InvocationTargetException && t.getCause() != null)
-    {
-      return getExceptionMessage(t.getCause());
+
+    /**
+     * Returns a string containing provided date formatted using the generalized
+     * time syntax.
+     *
+     * @param date
+     *            The date to be formated.
+     * @return The string containing provided date formatted using the
+     *         generalized time syntax.
+     * @throws IllegalArgumentException
+     *             If {@code date} was invalid.
+     */
+    public static String formatAsGeneralizedTime(final long date) {
+        // Generalized time has the format yyyyMMddHHmmss.SSS'Z'
+
+        // Do this in a thread-safe non-synchronized fashion.
+        // (Simple)DateFormat is neither fast nor thread-safe.
+
+        final StringBuilder sb = new StringBuilder(19);
+
+        final GregorianCalendar calendar = new GregorianCalendar(TIME_ZONE_UTC_OBJ);
+        calendar.setLenient(false);
+        calendar.setTimeInMillis(date);
+
+        // Format the year yyyy.
+        int n = calendar.get(Calendar.YEAR);
+        if (n < 0) {
+            final IllegalArgumentException e =
+                    new IllegalArgumentException("Year cannot be < 0:" + n);
+            StaticUtils.DEBUG_LOG.throwing("GeneralizedTimeSyntax", "format", e);
+            throw e;
+        } else if (n < 10) {
+            sb.append("000");
+        } else if (n < 100) {
+            sb.append("00");
+        } else if (n < 1000) {
+            sb.append("0");
+        }
+        sb.append(n);
+
+        // Format the month MM.
+        n = calendar.get(Calendar.MONTH) + 1;
+        if (n < 10) {
+            sb.append("0");
+        }
+        sb.append(n);
+
+        // Format the day dd.
+        n = calendar.get(Calendar.DAY_OF_MONTH);
+        if (n < 10) {
+            sb.append("0");
+        }
+        sb.append(n);
+
+        // Format the hour HH.
+        n = calendar.get(Calendar.HOUR_OF_DAY);
+        if (n < 10) {
+            sb.append("0");
+        }
+        sb.append(n);
+
+        // Format the minute mm.
+        n = calendar.get(Calendar.MINUTE);
+        if (n < 10) {
+            sb.append("0");
+        }
+        sb.append(n);
+
+        // Format the seconds ss.
+        n = calendar.get(Calendar.SECOND);
+        if (n < 10) {
+            sb.append("0");
+        }
+        sb.append(n);
+
+        // Format the milli-seconds.
+        sb.append('.');
+        n = calendar.get(Calendar.MILLISECOND);
+        if (n < 10) {
+            sb.append("00");
+        } else if (n < 100) {
+            sb.append("0");
+        }
+        sb.append(n);
+
+        // Format the timezone (always Z).
+        sb.append('Z');
+
+        return sb.toString();
     }
-    else
-    {
-      final StringBuilder message = new StringBuilder();
 
-      final String className = t.getClass().getName();
-      final int periodPos = className.lastIndexOf('.');
-      if (periodPos > 0)
-      {
-        message.append(className.substring(periodPos + 1));
-      }
-      else
-      {
-        message.append(className);
-      }
+    /**
+     * Construct a byte array containing the UTF-8 encoding of the provided
+     * character array.
+     *
+     * @param chars
+     *            The character array to convert to a UTF-8 byte array.
+     * @return A byte array containing the UTF-8 encoding of the provided
+     *         character array.
+     */
+    public static byte[] getBytes(final char[] chars) {
+        final Charset utf8 = Charset.forName("UTF-8");
+        final ByteBuffer buffer = utf8.encode(CharBuffer.wrap(chars));
+        final byte[] bytes = new byte[buffer.remaining()];
+        buffer.get(bytes);
+        return bytes;
+    }
 
-      message.append("(");
-      if (t.getMessage() == null)
-      {
-        final StackTraceElement[] stackElements = t.getStackTrace();
-        message.append(stackElements[0].getFileName());
-        message.append(":");
-        message.append(stackElements[0].getLineNumber());
+    /**
+     * Construct a byte array containing the UTF-8 encoding of the provided
+     * string. This is significantly faster than calling
+     * {@link String#getBytes(String)} for ASCII strings.
+     *
+     * @param s
+     *            The string to convert to a UTF-8 byte array.
+     * @return Returns a byte array containing the UTF-8 encoding of the
+     *         provided string.
+     */
+    public static byte[] getBytes(final String s) {
+        if (s == null) {
+            return null;
+        }
 
-        // FIXME Temporary to debug issue 2256.
-        if (t instanceof IllegalStateException)
-        {
-          for (int i = 1; i < stackElements.length; i++)
-          {
-            message.append(' ');
-            message.append(stackElements[i].getFileName());
+        try {
+            char c;
+            final int length = s.length();
+            final byte[] returnArray = new byte[length];
+            for (int i = 0; i < length; i++) {
+                c = s.charAt(i);
+                returnArray[i] = (byte) (c & 0x0000007F);
+                if (c != returnArray[i]) {
+                    return s.getBytes("UTF-8");
+                }
+            }
+
+            return returnArray;
+        } catch (final Exception e) {
+            DEBUG_LOG.warning("Unable to encode UTF-8 string " + s);
+
+            return s.getBytes();
+        }
+    }
+
+    /**
+     * Returns the default scheduler which should be used by the SDK.
+     *
+     * @return The default scheduler.
+     */
+    public static ScheduledExecutorService getDefaultScheduler() {
+        synchronized (DEFAULT_SCHEDULER_LOCK) {
+            if (defaultScheduler == null) {
+                final ThreadFactory factory =
+                        newThreadFactory(null, "OpenDJ SDK Default Scheduler", true);
+                defaultScheduler = Executors.newSingleThreadScheduledExecutor(factory);
+            }
+        }
+        return defaultScheduler;
+    }
+
+    /**
+     * Retrieves the best human-readable message for the provided exception. For
+     * exceptions defined in the OpenDJ project, it will attempt to use the
+     * message (combining it with the message ID if available). For some
+     * exceptions that use encapsulation (e.g., InvocationTargetException), it
+     * will be unwrapped and the cause will be treated. For all others, the
+     *
+     * @param t
+     *            The {@code Throwable} object for which to retrieve the
+     *            message.
+     * @return The human-readable message generated for the provided exception.
+     */
+    public static LocalizableMessage getExceptionMessage(final Throwable t) {
+        if (t instanceof LocalizableException) {
+            final LocalizableException ie = (LocalizableException) t;
+            return ie.getMessageObject();
+        } else if (t instanceof NullPointerException) {
+            final StackTraceElement[] stackElements = t.getStackTrace();
+
+            final LocalizableMessageBuilder message = new LocalizableMessageBuilder();
+            message.append("NullPointerException(");
+            message.append(stackElements[0].getFileName());
             message.append(":");
-            message.append(stackElements[i].getLineNumber());
-          }
+            message.append(stackElements[0].getLineNumber());
+            message.append(")");
+            return message.toMessage();
+        } else if (t instanceof InvocationTargetException && t.getCause() != null) {
+            return getExceptionMessage(t.getCause());
+        } else {
+            final StringBuilder message = new StringBuilder();
+
+            final String className = t.getClass().getName();
+            final int periodPos = className.lastIndexOf('.');
+            if (periodPos > 0) {
+                message.append(className.substring(periodPos + 1));
+            } else {
+                message.append(className);
+            }
+
+            message.append("(");
+            if (t.getMessage() == null) {
+                final StackTraceElement[] stackElements = t.getStackTrace();
+                message.append(stackElements[0].getFileName());
+                message.append(":");
+                message.append(stackElements[0].getLineNumber());
+
+                // FIXME Temporary to debug issue 2256.
+                if (t instanceof IllegalStateException) {
+                    for (int i = 1; i < stackElements.length; i++) {
+                        message.append(' ');
+                        message.append(stackElements[i].getFileName());
+                        message.append(":");
+                        message.append(stackElements[i].getLineNumber());
+                    }
+                }
+            } else {
+                message.append(t.getMessage());
+            }
+
+            message.append(")");
+
+            return LocalizableMessage.raw(message.toString());
         }
-      }
-      else
-      {
-        message.append(t.getMessage());
-      }
-
-      message.append(")");
-
-      return LocalizableMessage.raw(message.toString());
-    }
-  }
-
-
-
-  /**
-   * Converts the provided hexadecimal string to a byte array.
-   *
-   * @param hexString
-   *          The hexadecimal string to convert to a byte array.
-   * @return The byte array containing the binary representation of the provided
-   *         hex string.
-   * @throws java.text.ParseException
-   *           If the provided string contains invalid hexadecimal digits or
-   *           does not contain an even number of digits.
-   */
-  public static byte[] hexStringToByteArray(final String hexString)
-      throws ParseException
-  {
-    int length;
-    if (hexString == null || (length = hexString.length()) == 0)
-    {
-      return new byte[0];
     }
 
-    if (length % 2 != 0)
-    {
-      final LocalizableMessage message = ERR_HEX_DECODE_INVALID_LENGTH
-          .get(hexString);
-      throw new ParseException(message.toString(), 0);
-    }
-
-    final int arrayLength = length / 2;
-    final byte[] returnArray = new byte[arrayLength];
-    for (int i = 0; i < arrayLength; i++)
-    {
-      returnArray[i] = hexToByte(hexString.charAt(i * 2), hexString
-          .charAt(i * 2 + 1));
-    }
-
-    return returnArray;
-  }
-
-
-
-  /**
-   * Converts the provided pair of characters to a byte.
-   *
-   * @param c1
-   *          The first hexadecimal character.
-   * @param c2
-   *          The second hexadecimal character.
-   * @return The byte containing the binary representation of the provided hex
-   *         characters.
-   * @throws ParseException
-   *           If the provided string contains invalid hexadecimal digits or
-   *           does not contain an even number of digits.
-   */
-  public static byte hexToByte(final char c1, final char c2)
-      throws ParseException
-  {
-    byte b;
-    switch (c1)
-    {
-    case '0':
-      b = 0x00;
-      break;
-    case '1':
-      b = 0x10;
-      break;
-    case '2':
-      b = 0x20;
-      break;
-    case '3':
-      b = 0x30;
-      break;
-    case '4':
-      b = 0x40;
-      break;
-    case '5':
-      b = 0x50;
-      break;
-    case '6':
-      b = 0x60;
-      break;
-    case '7':
-      b = 0x70;
-      break;
-    case '8':
-      b = (byte) 0x80;
-      break;
-    case '9':
-      b = (byte) 0x90;
-      break;
-    case 'A':
-    case 'a':
-      b = (byte) 0xA0;
-      break;
-    case 'B':
-    case 'b':
-      b = (byte) 0xB0;
-      break;
-    case 'C':
-    case 'c':
-      b = (byte) 0xC0;
-      break;
-    case 'D':
-    case 'd':
-      b = (byte) 0xD0;
-      break;
-    case 'E':
-    case 'e':
-      b = (byte) 0xE0;
-      break;
-    case 'F':
-    case 'f':
-      b = (byte) 0xF0;
-      break;
-    default:
-      final LocalizableMessage message = ERR_HEX_DECODE_INVALID_CHARACTER.get(
-          new String(new char[] { c1, c2 }), c1);
-      throw new ParseException(message.toString(), 0);
-    }
-
-    switch (c2)
-    {
-    case '0':
-      // No action required.
-      break;
-    case '1':
-      b |= 0x01;
-      break;
-    case '2':
-      b |= 0x02;
-      break;
-    case '3':
-      b |= 0x03;
-      break;
-    case '4':
-      b |= 0x04;
-      break;
-    case '5':
-      b |= 0x05;
-      break;
-    case '6':
-      b |= 0x06;
-      break;
-    case '7':
-      b |= 0x07;
-      break;
-    case '8':
-      b |= 0x08;
-      break;
-    case '9':
-      b |= 0x09;
-      break;
-    case 'A':
-    case 'a':
-      b |= 0x0A;
-      break;
-    case 'B':
-    case 'b':
-      b |= 0x0B;
-      break;
-    case 'C':
-    case 'c':
-      b |= 0x0C;
-      break;
-    case 'D':
-    case 'd':
-      b |= 0x0D;
-      break;
-    case 'E':
-    case 'e':
-      b |= 0x0E;
-      break;
-    case 'F':
-    case 'f':
-      b |= 0x0F;
-      break;
-    default:
-      final LocalizableMessage message = ERR_HEX_DECODE_INVALID_CHARACTER.get(
-          new String(new char[] { c1, c2 }), c1);
-      throw new ParseException(message.toString(), 0);
-    }
-
-    return b;
-  }
-
-
-
-  /**
-   * Indicates whether the provided character is an ASCII alphabetic character.
-   *
-   * @param c
-   *          The character for which to make the determination.
-   * @return <CODE>true</CODE> if the provided value is an uppercase or
-   *         lowercase ASCII alphabetic character, or <CODE>false</CODE> if it
-   *         is not.
-   */
-  public static boolean isAlpha(final char c)
-  {
-    final ASCIICharProp cp = ASCIICharProp.valueOf(c);
-    return cp != null ? cp.isLetter() : false;
-  }
-
-
-
-  /**
-   * Indicates whether the provided character is a numeric digit.
-   *
-   * @param c
-   *          The character for which to make the determination.
-   * @return <CODE>true</CODE> if the provided character represents a numeric
-   *         digit, or <CODE>false</CODE> if not.
-   */
-  public static boolean isDigit(final char c)
-  {
-    final ASCIICharProp cp = ASCIICharProp.valueOf(c);
-    return cp != null ? cp.isDigit() : false;
-  }
-
-
-
-  /**
-   * Indicates whether the provided character is a hexadecimal digit.
-   *
-   * @param c
-   *          The character for which to make the determination.
-   * @return <CODE>true</CODE> if the provided character represents a
-   *         hexadecimal digit, or <CODE>false</CODE> if not.
-   */
-  public static boolean isHexDigit(final char c)
-  {
-    final ASCIICharProp cp = ASCIICharProp.valueOf(c);
-    return cp != null ? cp.isHexDigit() : false;
-  }
-
-
-
-  /**
-   * Indicates whether the provided character is a keychar.
-   *
-   * @param c
-   *          The character for which to make the determination.
-   * @param allowCompatChars
-   *          {@code true} if certain illegal characters should be allowed for
-   *          compatibility reasons.
-   * @return <CODE>true</CODE> if the provided character represents a
-   *         keychar, or <CODE>false</CODE> if not.
-   */
-  public static boolean isKeyChar(final char c, final boolean allowCompatChars)
-  {
-    final ASCIICharProp cp = ASCIICharProp.valueOf(c);
-    return cp != null ? cp.isKeyChar(allowCompatChars) : false;
-  }
-
-
-
-  /**
-   * Returns a string whose content is the string representation of the objects
-   * contained in the provided collection concatenated together using the
-   * provided separator.
-   *
-   * @param c
-   *          The collection whose elements are to be joined.
-   * @param separator
-   *          The separator string.
-   * @return A string whose content is the string representation of the objects
-   *         contained in the provided collection concatenated together using
-   *         the provided separator.
-   * @throws NullPointerException
-   *           If {@code c} or {@code separator} were {@code null}.
-   */
-  public static String joinCollection(Collection<?> c, String separator)
-  {
-    Validator.ensureNotNull(c, separator);
-
-    switch (c.size())
-    {
-    case 0:
-      return "";
-    case 1:
-      return String.valueOf(c.iterator().next());
-    default:
-      StringBuilder builder = new StringBuilder();
-      Iterator<?> i = c.iterator();
-      builder.append(i.next());
-      while (i.hasNext())
-      {
-        builder.append(separator);
-        builder.append(i.next());
-      }
-      String s = builder.toString();
-      return s;
-    }
-  }
-
-
-
-
-  /**
-   * Creates a new thread factory which will create threads using the specified
-   * thread group, naming template, and daemon status.
-   *
-   * @param group
-   *          The thread group, which may be {@code null}.
-   * @param nameTemplate
-   *          The thread name format string which may contain a "%d" format
-   *          option which will be substituted with the thread count.
-   * @param isDaemon
-   *          Indicates whether or not threads should be daemon threads.
-   * @return The new thread factory.
-   */
-  public static ThreadFactory newThreadFactory(final ThreadGroup group,
-      final String nameTemplate, final boolean isDaemon)
-  {
-    return new ThreadFactory()
-    {
-      private final AtomicInteger count = new AtomicInteger();
-
-
-
-      public Thread newThread(Runnable r)
-      {
-        final String name = String
-            .format(nameTemplate, count.getAndIncrement());
-        final Thread t = new Thread(group, r, name);
-        t.setDaemon(isDaemon);
-        return t;
-      }
-    };
-  }
-
-
-  /**
-   * Returns a string representation of the contents of the provided byte
-   * sequence using hexadecimal characters and a space between each byte.
-   *
-   * @param bytes
-   *          The byte sequence.
-   * @return A string representation of the contents of the provided byte
-   *         sequence using hexadecimal characters.
-   */
-  public static String toHex(final ByteSequence bytes)
-  {
-    return toHex(bytes, new StringBuilder((bytes.length() - 1) * 3 + 2))
-        .toString();
-  }
-
-
-
-  /**
-   * Appends the string representation of the contents of the provided byte
-   * sequence to a string builder using hexadecimal characters and a space
-   * between each byte.
-   *
-   * @param bytes
-   *          The byte sequence.
-   * @param builder
-   *          The string builder to which the hexadecimal representation of
-   *          {@code bytes} should be appended.
-   * @return The string builder.
-   */
-  public static StringBuilder toHex(final ByteSequence bytes,
-      final StringBuilder builder)
-  {
-    final int length = bytes.length();
-    builder.ensureCapacity(builder.length() + (length - 1) * 3 + 2);
-    builder.append(StaticUtils.byteToHex(bytes.byteAt(0)));
-    for (int i = 1; i < length; i++)
-    {
-      builder.append(" ");
-      builder.append(StaticUtils.byteToHex(bytes.byteAt(i)));
-    }
-    return builder;
-  }
-
-
-
-  /**
-   * Appends a string representation of the data in the provided byte sequence
-   * to the given string builder using the specified indent.
-   * <p>
-   * The data will be formatted with sixteen hex bytes in a row followed by the
-   * ASCII representation, then wrapping to a new line as necessary. The state
-   * of the byte buffer is not changed.
-   *
-   * @param bytes
-   *          The byte sequence.
-   * @param builder
-   *          The string builder to which the information is to be appended.
-   * @param indent
-   *          The number of spaces to indent the output.
-   * @return The string builder.
-   */
-  public static StringBuilder toHexPlusAscii(final ByteSequence bytes,
-      final StringBuilder builder, final int indent)
-  {
-    final StringBuilder indentBuf = new StringBuilder(indent);
-    for (int i = 0; i < indent; i++)
-    {
-      indentBuf.append(' ');
-    }
-
-    final int length = bytes.length();
-    int pos = 0;
-    while (length - pos >= 16)
-    {
-      final StringBuilder asciiBuf = new StringBuilder(17);
-
-      byte currentByte = bytes.byteAt(pos);
-      builder.append(indentBuf);
-      builder.append(StaticUtils.byteToHex(currentByte));
-      asciiBuf.append(byteToASCII(currentByte));
-      pos++;
-
-      for (int i = 1; i < 16; i++, pos++)
-      {
-        currentByte = bytes.byteAt(pos);
-        builder.append(' ');
-        builder.append(StaticUtils.byteToHex(currentByte));
-        asciiBuf.append(byteToASCII(currentByte));
-
-        if (i == 7)
-        {
-          builder.append("  ");
-          asciiBuf.append(' ');
-        }
-      }
-
-      builder.append("  ");
-      builder.append(asciiBuf);
-      builder.append(EOL);
-    }
-
-    final int remaining = length - pos;
-    if (remaining > 0)
-    {
-      final StringBuilder asciiBuf = new StringBuilder(remaining + 1);
-
-      byte currentByte = bytes.byteAt(pos);
-      builder.append(indentBuf);
-      builder.append(StaticUtils.byteToHex(currentByte));
-      asciiBuf.append(byteToASCII(currentByte));
-      pos++;
-
-      for (int i = 1; i < 16; i++, pos++)
-      {
-        builder.append(' ');
-
-        if (i < remaining)
-        {
-          currentByte = bytes.byteAt(pos);
-          builder.append(StaticUtils.byteToHex(currentByte));
-          asciiBuf.append(byteToASCII(currentByte));
-        }
-        else
-        {
-          builder.append("  ");
+    /**
+     * Converts the provided hexadecimal string to a byte array.
+     *
+     * @param hexString
+     *            The hexadecimal string to convert to a byte array.
+     * @return The byte array containing the binary representation of the
+     *         provided hex string.
+     * @throws java.text.ParseException
+     *             If the provided string contains invalid hexadecimal digits or
+     *             does not contain an even number of digits.
+     */
+    public static byte[] hexStringToByteArray(final String hexString) throws ParseException {
+        int length;
+        if (hexString == null || (length = hexString.length()) == 0) {
+            return new byte[0];
         }
 
-        if (i == 7)
-        {
-          builder.append("  ");
-
-          if (i < remaining)
-          {
-            asciiBuf.append(' ');
-          }
+        if (length % 2 != 0) {
+            final LocalizableMessage message = ERR_HEX_DECODE_INVALID_LENGTH.get(hexString);
+            throw new ParseException(message.toString(), 0);
         }
-      }
 
-      builder.append("  ");
-      builder.append(asciiBuf);
-      builder.append(EOL);
+        final int arrayLength = length / 2;
+        final byte[] returnArray = new byte[arrayLength];
+        for (int i = 0; i < arrayLength; i++) {
+            returnArray[i] = hexToByte(hexString.charAt(i * 2), hexString.charAt(i * 2 + 1));
+        }
+
+        return returnArray;
     }
 
-    return builder;
-  }
+    /**
+     * Converts the provided pair of characters to a byte.
+     *
+     * @param c1
+     *            The first hexadecimal character.
+     * @param c2
+     *            The second hexadecimal character.
+     * @return The byte containing the binary representation of the provided hex
+     *         characters.
+     * @throws ParseException
+     *             If the provided string contains invalid hexadecimal digits or
+     *             does not contain an even number of digits.
+     */
+    public static byte hexToByte(final char c1, final char c2) throws ParseException {
+        byte b;
+        switch (c1) {
+        case '0':
+            b = 0x00;
+            break;
+        case '1':
+            b = 0x10;
+            break;
+        case '2':
+            b = 0x20;
+            break;
+        case '3':
+            b = 0x30;
+            break;
+        case '4':
+            b = 0x40;
+            break;
+        case '5':
+            b = 0x50;
+            break;
+        case '6':
+            b = 0x60;
+            break;
+        case '7':
+            b = 0x70;
+            break;
+        case '8':
+            b = (byte) 0x80;
+            break;
+        case '9':
+            b = (byte) 0x90;
+            break;
+        case 'A':
+        case 'a':
+            b = (byte) 0xA0;
+            break;
+        case 'B':
+        case 'b':
+            b = (byte) 0xB0;
+            break;
+        case 'C':
+        case 'c':
+            b = (byte) 0xC0;
+            break;
+        case 'D':
+        case 'd':
+            b = (byte) 0xD0;
+            break;
+        case 'E':
+        case 'e':
+            b = (byte) 0xE0;
+            break;
+        case 'F':
+        case 'f':
+            b = (byte) 0xF0;
+            break;
+        default:
+            final LocalizableMessage message =
+                    ERR_HEX_DECODE_INVALID_CHARACTER.get(new String(new char[] { c1, c2 }), c1);
+            throw new ParseException(message.toString(), 0);
+        }
 
+        switch (c2) {
+        case '0':
+            // No action required.
+            break;
+        case '1':
+            b |= 0x01;
+            break;
+        case '2':
+            b |= 0x02;
+            break;
+        case '3':
+            b |= 0x03;
+            break;
+        case '4':
+            b |= 0x04;
+            break;
+        case '5':
+            b |= 0x05;
+            break;
+        case '6':
+            b |= 0x06;
+            break;
+        case '7':
+            b |= 0x07;
+            break;
+        case '8':
+            b |= 0x08;
+            break;
+        case '9':
+            b |= 0x09;
+            break;
+        case 'A':
+        case 'a':
+            b |= 0x0A;
+            break;
+        case 'B':
+        case 'b':
+            b |= 0x0B;
+            break;
+        case 'C':
+        case 'c':
+            b |= 0x0C;
+            break;
+        case 'D':
+        case 'd':
+            b |= 0x0D;
+            break;
+        case 'E':
+        case 'e':
+            b |= 0x0E;
+            break;
+        case 'F':
+        case 'f':
+            b |= 0x0F;
+            break;
+        default:
+            final LocalizableMessage message =
+                    ERR_HEX_DECODE_INVALID_CHARACTER.get(new String(new char[] { c1, c2 }), c1);
+            throw new ParseException(message.toString(), 0);
+        }
 
+        return b;
+    }
 
-  /**
-   * Appends a lowercase string representation of the contents of the given byte
-   * array to the provided buffer. This implementation presumes that the
-   * provided string will contain only ASCII characters and is optimized for
-   * that case. However, if a non-ASCII character is encountered it will fall
-   * back on a more expensive algorithm that will work properly for non-ASCII
-   * characters.
-   *
-   * @param b
-   *          The byte array for which to obtain the lowercase string
-   *          representation.
-   * @param builder
-   *          The buffer to which the lowercase form of the string should be
-   *          appended.
-   * @return The updated {@code StringBuilder}.
-   */
-  public static StringBuilder toLowerCase(final ByteSequence b,
-      final StringBuilder builder)
-  {
-    Validator.ensureNotNull(b, builder);
+    /**
+     * Indicates whether the provided character is an ASCII alphabetic
+     * character.
+     *
+     * @param c
+     *            The character for which to make the determination.
+     * @return <CODE>true</CODE> if the provided value is an uppercase or
+     *         lowercase ASCII alphabetic character, or <CODE>false</CODE> if it
+     *         is not.
+     */
+    public static boolean isAlpha(final char c) {
+        final ASCIICharProp cp = ASCIICharProp.valueOf(c);
+        return cp != null ? cp.isLetter() : false;
+    }
 
-    // FIXME: What locale should we use for non-ASCII characters? I
-    // think we should use default to the Unicode StringPrep.
+    /**
+     * Indicates whether the provided character is a numeric digit.
+     *
+     * @param c
+     *            The character for which to make the determination.
+     * @return <CODE>true</CODE> if the provided character represents a numeric
+     *         digit, or <CODE>false</CODE> if not.
+     */
+    public static boolean isDigit(final char c) {
+        final ASCIICharProp cp = ASCIICharProp.valueOf(c);
+        return cp != null ? cp.isDigit() : false;
+    }
 
-    final int origBufferLen = builder.length();
-    final int length = b.length();
+    /**
+     * Indicates whether the provided character is a hexadecimal digit.
+     *
+     * @param c
+     *            The character for which to make the determination.
+     * @return <CODE>true</CODE> if the provided character represents a
+     *         hexadecimal digit, or <CODE>false</CODE> if not.
+     */
+    public static boolean isHexDigit(final char c) {
+        final ASCIICharProp cp = ASCIICharProp.valueOf(c);
+        return cp != null ? cp.isHexDigit() : false;
+    }
 
-    for (int i = 0; i < length; i++)
-    {
-      final int c = b.byteAt(i);
+    /**
+     * Indicates whether the provided character is a keychar.
+     *
+     * @param c
+     *            The character for which to make the determination.
+     * @param allowCompatChars
+     *            {@code true} if certain illegal characters should be allowed
+     *            for compatibility reasons.
+     * @return <CODE>true</CODE> if the provided character represents a keychar,
+     *         or <CODE>false</CODE> if not.
+     */
+    public static boolean isKeyChar(final char c, final boolean allowCompatChars) {
+        final ASCIICharProp cp = ASCIICharProp.valueOf(c);
+        return cp != null ? cp.isKeyChar(allowCompatChars) : false;
+    }
 
-      if (c < 0)
-      {
-        builder.replace(origBufferLen, builder.length(), b.toString()
-            .toLowerCase(Locale.ENGLISH));
+    /**
+     * Returns a string whose content is the string representation of the
+     * objects contained in the provided collection concatenated together using
+     * the provided separator.
+     *
+     * @param c
+     *            The collection whose elements are to be joined.
+     * @param separator
+     *            The separator string.
+     * @return A string whose content is the string representation of the
+     *         objects contained in the provided collection concatenated
+     *         together using the provided separator.
+     * @throws NullPointerException
+     *             If {@code c} or {@code separator} were {@code null}.
+     */
+    public static String joinCollection(Collection<?> c, String separator) {
+        Validator.ensureNotNull(c, separator);
+
+        switch (c.size()) {
+        case 0:
+            return "";
+        case 1:
+            return String.valueOf(c.iterator().next());
+        default:
+            StringBuilder builder = new StringBuilder();
+            Iterator<?> i = c.iterator();
+            builder.append(i.next());
+            while (i.hasNext()) {
+                builder.append(separator);
+                builder.append(i.next());
+            }
+            String s = builder.toString();
+            return s;
+        }
+    }
+
+    /**
+     * Creates a new thread factory which will create threads using the
+     * specified thread group, naming template, and daemon status.
+     *
+     * @param group
+     *            The thread group, which may be {@code null}.
+     * @param nameTemplate
+     *            The thread name format string which may contain a "%d" format
+     *            option which will be substituted with the thread count.
+     * @param isDaemon
+     *            Indicates whether or not threads should be daemon threads.
+     * @return The new thread factory.
+     */
+    public static ThreadFactory newThreadFactory(final ThreadGroup group,
+            final String nameTemplate, final boolean isDaemon) {
+        return new ThreadFactory() {
+            private final AtomicInteger count = new AtomicInteger();
+
+            public Thread newThread(Runnable r) {
+                final String name = String.format(nameTemplate, count.getAndIncrement());
+                final Thread t = new Thread(group, r, name);
+                t.setDaemon(isDaemon);
+                return t;
+            }
+        };
+    }
+
+    /**
+     * Returns a string representation of the contents of the provided byte
+     * sequence using hexadecimal characters and a space between each byte.
+     *
+     * @param bytes
+     *            The byte sequence.
+     * @return A string representation of the contents of the provided byte
+     *         sequence using hexadecimal characters.
+     */
+    public static String toHex(final ByteSequence bytes) {
+        return toHex(bytes, new StringBuilder((bytes.length() - 1) * 3 + 2)).toString();
+    }
+
+    /**
+     * Appends the string representation of the contents of the provided byte
+     * sequence to a string builder using hexadecimal characters and a space
+     * between each byte.
+     *
+     * @param bytes
+     *            The byte sequence.
+     * @param builder
+     *            The string builder to which the hexadecimal representation of
+     *            {@code bytes} should be appended.
+     * @return The string builder.
+     */
+    public static StringBuilder toHex(final ByteSequence bytes, final StringBuilder builder) {
+        final int length = bytes.length();
+        builder.ensureCapacity(builder.length() + (length - 1) * 3 + 2);
+        builder.append(StaticUtils.byteToHex(bytes.byteAt(0)));
+        for (int i = 1; i < length; i++) {
+            builder.append(" ");
+            builder.append(StaticUtils.byteToHex(bytes.byteAt(i)));
+        }
         return builder;
-      }
-
-      // At this point 0 <= 'c' <= 128.
-      final ASCIICharProp cp = ASCIICharProp.valueOf(c);
-      builder.append(cp.toLowerCase());
     }
 
-    return builder;
-  }
-
-
-
-  /**
-   * Retrieves a lower-case representation of the given string. This
-   * implementation presumes that the provided string will contain only ASCII
-   * characters and is optimized for that case. However, if a non-ASCII
-   * character is encountered it will fall back on a more expensive algorithm
-   * that will work properly for non-ASCII characters.
-   *
-   * @param s
-   *          The string for which to obtain the lower-case representation.
-   * @return The lower-case representation of the given string.
-   */
-  public static String toLowerCase(final String s)
-  {
-    Validator.ensureNotNull(s);
-
-    // FIXME: What locale should we use for non-ASCII characters? I
-    // think we should use default to the Unicode StringPrep.
-
-    // This code is optimized for the case where the input string 's'
-    // has already been converted to lowercase.
-    final int length = s.length();
-    int i = 0;
-    ASCIICharProp cp = null;
-
-    // Scan for non lowercase ASCII.
-    while (i < length)
-    {
-      cp = ASCIICharProp.valueOf(s.charAt(i));
-      if (cp == null || cp.isUpperCase())
-      {
-        break;
-      }
-      i++;
-    }
-
-    if (i == length)
-    {
-      // String was already lowercase ASCII.
-      return s;
-    }
-
-    // Found non lowercase ASCII.
-    final StringBuilder builder = new StringBuilder(length);
-    builder.append(s, 0, i);
-
-    if (cp != null)
-    {
-      // Upper-case ASCII.
-      builder.append(cp.toLowerCase());
-      i++;
-      while (i < length)
-      {
-        cp = ASCIICharProp.valueOf(s.charAt(i));
-        if (cp == null)
-        {
-          break;
+    /**
+     * Appends a string representation of the data in the provided byte sequence
+     * to the given string builder using the specified indent.
+     * <p>
+     * The data will be formatted with sixteen hex bytes in a row followed by
+     * the ASCII representation, then wrapping to a new line as necessary. The
+     * state of the byte buffer is not changed.
+     *
+     * @param bytes
+     *            The byte sequence.
+     * @param builder
+     *            The string builder to which the information is to be appended.
+     * @param indent
+     *            The number of spaces to indent the output.
+     * @return The string builder.
+     */
+    public static StringBuilder toHexPlusAscii(final ByteSequence bytes,
+            final StringBuilder builder, final int indent) {
+        final StringBuilder indentBuf = new StringBuilder(indent);
+        for (int i = 0; i < indent; i++) {
+            indentBuf.append(' ');
         }
-        builder.append(cp.toLowerCase());
-        i++;
-      }
-    }
 
-    if (i < length)
-    {
-      builder.append(s.substring(i).toLowerCase(Locale.ENGLISH));
-    }
+        final int length = bytes.length();
+        int pos = 0;
+        while (length - pos >= 16) {
+            final StringBuilder asciiBuf = new StringBuilder(17);
 
-    return builder.toString();
-  }
+            byte currentByte = bytes.byteAt(pos);
+            builder.append(indentBuf);
+            builder.append(StaticUtils.byteToHex(currentByte));
+            asciiBuf.append(byteToASCII(currentByte));
+            pos++;
 
+            for (int i = 1; i < 16; i++, pos++) {
+                currentByte = bytes.byteAt(pos);
+                builder.append(' ');
+                builder.append(StaticUtils.byteToHex(currentByte));
+                asciiBuf.append(byteToASCII(currentByte));
 
+                if (i == 7) {
+                    builder.append("  ");
+                    asciiBuf.append(' ');
+                }
+            }
 
-  /**
-   * Appends a lower-case representation of the given string to the provided
-   * buffer. This implementation presumes that the provided string will contain
-   * only ASCII characters and is optimized for that case. However, if a
-   * non-ASCII character is encountered it will fall back on a more expensive
-   * algorithm that will work properly for non-ASCII characters.
-   *
-   * @param s
-   *          The string for which to obtain the lower-case representation.
-   * @param builder
-   *          The {@code StringBuilder} to which the lower-case form of the
-   *          string should be appended.
-   * @return The updated {@code StringBuilder}.
-   */
-  public static StringBuilder toLowerCase(final String s,
-      final StringBuilder builder)
-  {
-    Validator.ensureNotNull(s, builder);
+            builder.append("  ");
+            builder.append(asciiBuf);
+            builder.append(EOL);
+        }
 
-    // FIXME: What locale should we use for non-ASCII characters? I
-    // think we should use default to the Unicode StringPrep.
+        final int remaining = length - pos;
+        if (remaining > 0) {
+            final StringBuilder asciiBuf = new StringBuilder(remaining + 1);
 
-    final int length = s.length();
-    builder.ensureCapacity(builder.length() + length);
+            byte currentByte = bytes.byteAt(pos);
+            builder.append(indentBuf);
+            builder.append(StaticUtils.byteToHex(currentByte));
+            asciiBuf.append(byteToASCII(currentByte));
+            pos++;
 
-    for (int i = 0; i < length; i++)
-    {
-      final ASCIICharProp cp = ASCIICharProp.valueOf(s.charAt(i));
-      if (cp != null)
-      {
-        builder.append(cp.toLowerCase());
-      }
-      else
-      {
-        // Non-ASCII.
-        builder.append(s.substring(i).toLowerCase(Locale.ENGLISH));
+            for (int i = 1; i < 16; i++, pos++) {
+                builder.append(' ');
+
+                if (i < remaining) {
+                    currentByte = bytes.byteAt(pos);
+                    builder.append(StaticUtils.byteToHex(currentByte));
+                    asciiBuf.append(byteToASCII(currentByte));
+                } else {
+                    builder.append("  ");
+                }
+
+                if (i == 7) {
+                    builder.append("  ");
+
+                    if (i < remaining) {
+                        asciiBuf.append(' ');
+                    }
+                }
+            }
+
+            builder.append("  ");
+            builder.append(asciiBuf);
+            builder.append(EOL);
+        }
+
         return builder;
-      }
     }
 
-    return builder;
-  }
+    /**
+     * Appends a lowercase string representation of the contents of the given
+     * byte array to the provided buffer. This implementation presumes that the
+     * provided string will contain only ASCII characters and is optimized for
+     * that case. However, if a non-ASCII character is encountered it will fall
+     * back on a more expensive algorithm that will work properly for non-ASCII
+     * characters.
+     *
+     * @param b
+     *            The byte array for which to obtain the lowercase string
+     *            representation.
+     * @param builder
+     *            The buffer to which the lowercase form of the string should be
+     *            appended.
+     * @return The updated {@code StringBuilder}.
+     */
+    public static StringBuilder toLowerCase(final ByteSequence b, final StringBuilder builder) {
+        Validator.ensureNotNull(b, builder);
 
+        // FIXME: What locale should we use for non-ASCII characters? I
+        // think we should use default to the Unicode StringPrep.
 
+        final int origBufferLen = builder.length();
+        final int length = b.length();
 
-  /**
-   * Attempts to uncompress the data in the provided source array into the given
-   * destination array. If the uncompressed data will fit into the given
-   * destination array, then this method will return the number of bytes of
-   * uncompressed data written into the destination buffer. Otherwise, it will
-   * return a negative value to indicate that the destination buffer was not
-   * large enough. The absolute value of that negative return value will
-   * indicate the buffer size required to fully decompress the data. Note that
-   * if a negative value is returned, then the data in the destination array
-   * should be considered invalid.
-   *
-   * @param src
-   *          The array containing the raw data to compress.
-   * @param srcOff
-   *          The start offset of the source data.
-   * @param srcLen
-   *          The maximum number of source data bytes to compress.
-   * @param dst
-   *          The array into which the compressed data should be written.
-   * @param dstOff
-   *          The start offset of the compressed data.
-   * @param dstLen
-   *          The maximum number of bytes of compressed data.
-   * @return A positive value containing the number of bytes of uncompressed
-   *         data written into the destination buffer, or a negative value whose
-   *         absolute value is the size of the destination buffer required to
-   *         fully decompress the provided data.
-   * @throws java.util.zip.DataFormatException
-   *           If a problem occurs while attempting to uncompress the data.
-   */
-  public static int uncompress(final byte[] src, final int srcOff,
-      final int srcLen, final byte[] dst, final int dstOff, final int dstLen)
-      throws DataFormatException
-  {
-    final Inflater inflater = new Inflater();
-    try
-    {
-      inflater.setInput(src, srcOff, srcLen);
+        for (int i = 0; i < length; i++) {
+            final int c = b.byteAt(i);
 
-      final int decompressedLength = inflater.inflate(dst, dstOff, dstLen);
-      if (inflater.finished())
-      {
-        return decompressedLength;
-      }
-      else
-      {
-        int totalLength = decompressedLength;
+            if (c < 0) {
+                builder.replace(origBufferLen, builder.length(), b.toString().toLowerCase(
+                        Locale.ENGLISH));
+                return builder;
+            }
 
-        while (!inflater.finished())
-        {
-          totalLength += inflater.inflate(dst, dstOff, dstLen);
+            // At this point 0 <= 'c' <= 128.
+            final ASCIICharProp cp = ASCIICharProp.valueOf(c);
+            builder.append(cp.toLowerCase());
         }
 
-        return -totalLength;
-      }
-    }
-    finally
-    {
-      inflater.end();
-    }
-  }
-
-
-
-  /**
-   * Attempts to uncompress the data in the provided byte sequence into the
-   * provided byte string builder. Note that if uncompression was not
-   * successful, then the data in the destination buffer should be considered
-   * invalid.
-   *
-   * @param input
-   *          The source data to be uncompressed.
-   * @param output
-   *          The destination buffer to which the uncompressed data will be
-   *          appended.
-   * @param uncompressedSize
-   *          The uncompressed size of the data if known or 0 otherwise.
-   * @return <code>true</code> if decompression was successful or
-   *         <code>false</code> otherwise.
-   * @throws java.util.zip.DataFormatException
-   *           If a problem occurs while attempting to uncompress the data.
-   */
-  public static boolean uncompress(final ByteSequence input,
-      final ByteStringBuilder output, final int uncompressedSize)
-      throws DataFormatException
-  {
-    final byte[] inputBytes = input.toByteArray();
-    byte[] outputBytes = new byte[uncompressedSize > 0 ? uncompressedSize : 0];
-
-    int decompressResult = uncompress(inputBytes, 0, inputBytes.length,
-        outputBytes, 0, outputBytes.length);
-
-    if (decompressResult < 0)
-    {
-      // The destination buffer wasn't big enough. Resize and retry.
-      outputBytes = new byte[-decompressResult];
-      decompressResult = uncompress(inputBytes, 0, inputBytes.length,
-          outputBytes, 0, outputBytes.length);
+        return builder;
     }
 
-    if (decompressResult >= 0)
-    {
-      // It was successful.
-      output.append(outputBytes, 0, decompressResult);
-      return true;
+    /**
+     * Retrieves a lower-case representation of the given string. This
+     * implementation presumes that the provided string will contain only ASCII
+     * characters and is optimized for that case. However, if a non-ASCII
+     * character is encountered it will fall back on a more expensive algorithm
+     * that will work properly for non-ASCII characters.
+     *
+     * @param s
+     *            The string for which to obtain the lower-case representation.
+     * @return The lower-case representation of the given string.
+     */
+    public static String toLowerCase(final String s) {
+        Validator.ensureNotNull(s);
+
+        // FIXME: What locale should we use for non-ASCII characters? I
+        // think we should use default to the Unicode StringPrep.
+
+        // This code is optimized for the case where the input string 's'
+        // has already been converted to lowercase.
+        final int length = s.length();
+        int i = 0;
+        ASCIICharProp cp = null;
+
+        // Scan for non lowercase ASCII.
+        while (i < length) {
+            cp = ASCIICharProp.valueOf(s.charAt(i));
+            if (cp == null || cp.isUpperCase()) {
+                break;
+            }
+            i++;
+        }
+
+        if (i == length) {
+            // String was already lowercase ASCII.
+            return s;
+        }
+
+        // Found non lowercase ASCII.
+        final StringBuilder builder = new StringBuilder(length);
+        builder.append(s, 0, i);
+
+        if (cp != null) {
+            // Upper-case ASCII.
+            builder.append(cp.toLowerCase());
+            i++;
+            while (i < length) {
+                cp = ASCIICharProp.valueOf(s.charAt(i));
+                if (cp == null) {
+                    break;
+                }
+                builder.append(cp.toLowerCase());
+                i++;
+            }
+        }
+
+        if (i < length) {
+            builder.append(s.substring(i).toLowerCase(Locale.ENGLISH));
+        }
+
+        return builder.toString();
     }
 
-    // Still unsuccessful. Give up.
-    return false;
-  }
+    /**
+     * Appends a lower-case representation of the given string to the provided
+     * buffer. This implementation presumes that the provided string will
+     * contain only ASCII characters and is optimized for that case. However, if
+     * a non-ASCII character is encountered it will fall back on a more
+     * expensive algorithm that will work properly for non-ASCII characters.
+     *
+     * @param s
+     *            The string for which to obtain the lower-case representation.
+     * @param builder
+     *            The {@code StringBuilder} to which the lower-case form of the
+     *            string should be appended.
+     * @return The updated {@code StringBuilder}.
+     */
+    public static StringBuilder toLowerCase(final String s, final StringBuilder builder) {
+        Validator.ensureNotNull(s, builder);
 
+        // FIXME: What locale should we use for non-ASCII characters? I
+        // think we should use default to the Unicode StringPrep.
 
+        final int length = s.length();
+        builder.ensureCapacity(builder.length() + length);
 
-  /**
-   * Returns a copy of the provided byte array.
-   *
-   * @param bytes
-   *          The byte array to be copied.
-   * @return A copy of the provided byte array.
-   */
-  public static byte[] copyOfBytes(final byte[] bytes)
-  {
-    return Arrays.copyOf(bytes, bytes.length);
-  }
+        for (int i = 0; i < length; i++) {
+            final ASCIICharProp cp = ASCIICharProp.valueOf(s.charAt(i));
+            if (cp != null) {
+                builder.append(cp.toLowerCase());
+            } else {
+                // Non-ASCII.
+                builder.append(s.substring(i).toLowerCase(Locale.ENGLISH));
+                return builder;
+            }
+        }
 
-
-
-  /**
-   * Retrieves the printable ASCII representation of the provided byte.
-   *
-   * @param b
-   *          The byte for which to retrieve the printable ASCII representation.
-   * @return The printable ASCII representation of the provided byte, or a space
-   *         if the provided byte does not have printable ASCII representation.
-   */
-  private static char byteToASCII(final byte b)
-  {
-    if (b >= 32 && b <= 126)
-    {
-      return (char) b;
+        return builder;
     }
 
-    return ' ';
-  }
+    /**
+     * Attempts to uncompress the data in the provided source array into the
+     * given destination array. If the uncompressed data will fit into the given
+     * destination array, then this method will return the number of bytes of
+     * uncompressed data written into the destination buffer. Otherwise, it will
+     * return a negative value to indicate that the destination buffer was not
+     * large enough. The absolute value of that negative return value will
+     * indicate the buffer size required to fully decompress the data. Note that
+     * if a negative value is returned, then the data in the destination array
+     * should be considered invalid.
+     *
+     * @param src
+     *            The array containing the raw data to compress.
+     * @param srcOff
+     *            The start offset of the source data.
+     * @param srcLen
+     *            The maximum number of source data bytes to compress.
+     * @param dst
+     *            The array into which the compressed data should be written.
+     * @param dstOff
+     *            The start offset of the compressed data.
+     * @param dstLen
+     *            The maximum number of bytes of compressed data.
+     * @return A positive value containing the number of bytes of uncompressed
+     *         data written into the destination buffer, or a negative value
+     *         whose absolute value is the size of the destination buffer
+     *         required to fully decompress the provided data.
+     * @throws java.util.zip.DataFormatException
+     *             If a problem occurs while attempting to uncompress the data.
+     */
+    public static int uncompress(final byte[] src, final int srcOff, final int srcLen,
+            final byte[] dst, final int dstOff, final int dstLen) throws DataFormatException {
+        final Inflater inflater = new Inflater();
+        try {
+            inflater.setInput(src, srcOff, srcLen);
 
+            final int decompressedLength = inflater.inflate(dst, dstOff, dstLen);
+            if (inflater.finished()) {
+                return decompressedLength;
+            } else {
+                int totalLength = decompressedLength;
 
+                while (!inflater.finished()) {
+                    totalLength += inflater.inflate(dst, dstOff, dstLen);
+                }
 
-  // Prevent instantiation.
-  private StaticUtils()
-  {
-    // No implementation required.
-  }
+                return -totalLength;
+            }
+        } finally {
+            inflater.end();
+        }
+    }
+
+    /**
+     * Attempts to uncompress the data in the provided byte sequence into the
+     * provided byte string builder. Note that if uncompression was not
+     * successful, then the data in the destination buffer should be considered
+     * invalid.
+     *
+     * @param input
+     *            The source data to be uncompressed.
+     * @param output
+     *            The destination buffer to which the uncompressed data will be
+     *            appended.
+     * @param uncompressedSize
+     *            The uncompressed size of the data if known or 0 otherwise.
+     * @return <code>true</code> if decompression was successful or
+     *         <code>false</code> otherwise.
+     * @throws java.util.zip.DataFormatException
+     *             If a problem occurs while attempting to uncompress the data.
+     */
+    public static boolean uncompress(final ByteSequence input, final ByteStringBuilder output,
+            final int uncompressedSize) throws DataFormatException {
+        final byte[] inputBytes = input.toByteArray();
+        byte[] outputBytes = new byte[uncompressedSize > 0 ? uncompressedSize : 0];
+
+        int decompressResult =
+                uncompress(inputBytes, 0, inputBytes.length, outputBytes, 0, outputBytes.length);
+
+        if (decompressResult < 0) {
+            // The destination buffer wasn't big enough. Resize and retry.
+            outputBytes = new byte[-decompressResult];
+            decompressResult =
+                    uncompress(inputBytes, 0, inputBytes.length, outputBytes, 0, outputBytes.length);
+        }
+
+        if (decompressResult >= 0) {
+            // It was successful.
+            output.append(outputBytes, 0, decompressResult);
+            return true;
+        }
+
+        // Still unsuccessful. Give up.
+        return false;
+    }
+
+    /**
+     * Returns a copy of the provided byte array.
+     *
+     * @param bytes
+     *            The byte array to be copied.
+     * @return A copy of the provided byte array.
+     */
+    public static byte[] copyOfBytes(final byte[] bytes) {
+        return Arrays.copyOf(bytes, bytes.length);
+    }
+
+    /**
+     * Retrieves the printable ASCII representation of the provided byte.
+     *
+     * @param b
+     *            The byte for which to retrieve the printable ASCII
+     *            representation.
+     * @return The printable ASCII representation of the provided byte, or a
+     *         space if the provided byte does not have printable ASCII
+     *         representation.
+     */
+    private static char byteToASCII(final byte b) {
+        if (b >= 32 && b <= 126) {
+            return (char) b;
+        }
+
+        return ' ';
+    }
+
+    // Prevent instantiation.
+    private StaticUtils() {
+        // No implementation required.
+    }
 
 }

--
Gitblit v1.10.0