mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Fabio Pistolesi
12.52.2015 7e6e243cf513bec3486001a2ad2789d1bf2a8eee
Refactor StaticUtils in server code by calling SDK's basic methods.
Remove unused methods (getBytes(char[]) and byteToBinary()) and inline some of the less used (byteToASCII() and one of the toLowerCase()).
6 files modified
774 ■■■■ changed files
opendj-core/src/test/java/com/forgerock/opendj/util/StaticUtilsTestCase.java 73 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/api/CompressedSchema.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/plugins/AttributeCleanupPlugin.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/types/RDN.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java 615 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/util/TestStaticUtils.java 80 ●●●●● patch | view | raw | blame | history
opendj-core/src/test/java/com/forgerock/opendj/util/StaticUtilsTestCase.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2009 Sun Microsystems, Inc.
 *      Portions copyright 2014 ForgeRock AS
 *      Portions copyright 2014-2015 ForgeRock AS
 */
package com.forgerock.opendj.util;
@@ -30,6 +30,8 @@
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;
import java.util.TimeZone;
import org.testng.Assert;
@@ -111,7 +113,7 @@
    }
    /**
     * Tests {@link GeneralizedTimeSyntax#format(java.util.Date)}.
     * Tests {@link StaticUtils#formatAsGeneralizedTime(java.util.Date)}.
     *
     * @param yyyy
     *            The year.
@@ -227,6 +229,20 @@
        }
    }
    @Test(dataProvider = "getBytesTestData")
    public void testCharsToBytes(String inputString) throws Exception {
        Assert.assertEquals(StaticUtils.getBytes(inputString.toCharArray()), inputString.getBytes("UTF-8"));
    }
    @Test(dataProvider = "byteToHexTestData")
    public void testByteToASCII(byte b) throws Exception {
        if (b < 32 || b > 126) {
            Assert.assertEquals(byteToASCII(b), ' ');
        } else {
            Assert.assertEquals(byteToASCII(b), (char) b);
        }
    }
    @DataProvider
    public Object[][] stackTraceToSingleLineFullStackStackProvider() {
        return new Object[][] {
@@ -270,4 +286,57 @@
        assertThat(trace).contains(expectedContains);
        assertThat(trace).doesNotContain("...)");
    }
    @DataProvider(name = "byteToHexTestData")
    public Object[][] createByteToHexTestData() {
        Object[][] data = new Object[256][];
        for (int i = 0; i < 256; i++) {
            data[i] = new Object[] { new Byte((byte) i) };
        }
        return data;
    }
    @DataProvider(name = "getBytesTestData")
    public Object[][] createGetBytesTestData() {
        List<String> strings = new LinkedList<>();
        // Some simple strings.
        strings.add("");
        strings.add(" ");
        strings.add("an ascii string");
        // A string containing just UTF-8 1 byte sequences.
        StringBuilder builder = new StringBuilder();
        for (char c = '\u0000'; c < '\u0080'; c++) {
            builder.append(c);
        }
        strings.add(builder.toString());
        // A string containing UTF-8 1 and 2 byte sequences.
        builder = new StringBuilder();
        for (char c = '\u0000'; c < '\u0100'; c++) {
            builder.append(c);
        }
        strings.add(builder.toString());
        // A string containing UTF-8 1 and 6 byte sequences.
        builder = new StringBuilder();
        for (char c = '\u0000'; c < '\u0080'; c++) {
            builder.append(c);
        }
        for (char c = '\uff00'; c != '\u0000'; c++) {
            builder.append(c);
        }
        strings.add(builder.toString());
        // Construct the array.
        Object[][] data = new Object[strings.size()][];
        for (int i = 0; i < strings.size(); i++) {
            data[i] = new Object[] { strings.get(i) };
        }
        return data;
    }
}
opendj-server-legacy/src/main/java/org/opends/server/api/CompressedSchema.java
@@ -27,7 +27,7 @@
package org.opends.server.api;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.util.StaticUtils.toLowerCase;
import static com.forgerock.opendj.util.StaticUtils.toLowerCase;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Collection;
opendj-server-legacy/src/main/java/org/opends/server/plugins/AttributeCleanupPlugin.java
@@ -27,7 +27,7 @@
package org.opends.server.plugins;
import static org.opends.messages.PluginMessages.*;
import static org.opends.server.util.StaticUtils.toLowerCase;
import static com.forgerock.opendj.util.StaticUtils.toLowerCase;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
opendj-server-legacy/src/main/java/org/opends/server/types/RDN.java
@@ -45,7 +45,7 @@
import org.opends.server.core.DirectoryServer;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.util.StaticUtils.*;
import static com.forgerock.opendj.util.StaticUtils.*;
/**
 * This class defines a data structure for storing and interacting
opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java
@@ -30,7 +30,6 @@
import static org.opends.server.util.ServerConstants.*;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
@@ -102,29 +101,11 @@
   */
  public static final int MB = KB * KB;
  private static final String[][] BYTE_HEX_STRINGS = new String[2][256];
  private static final String[] BYTE_BIN_STRINGS = new String[256];
  private static final int UPPER_CASE = 0;
  private static final int LOWER_CASE = 1;
  /** Private constructor to prevent instantiation. */
  private StaticUtils() {
    // No implementation required.
  }
  static {
    String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
    for (int i = 0; i < 256; i++) {
      BYTE_HEX_STRINGS[UPPER_CASE][i] = hexDigits[i >>> 4] + hexDigits[i & 0xF];
      BYTE_HEX_STRINGS[LOWER_CASE][i] = BYTE_HEX_STRINGS[UPPER_CASE][i].toLowerCase();
      StringBuilder sb = new StringBuilder();
      for (int j = 7; j >= 0; j--) {
        sb.append((i & (1 << j)) == 0 ? "0" : "1");
      }
      BYTE_BIN_STRINGS[i] = sb.toString();
    }
  }
  /**
   * Construct a byte array containing the UTF-8 encoding of the
   * provided string. This is significantly faster
@@ -137,46 +118,9 @@
   */
  public static byte[] getBytes(String s)
  {
    if (s == null)
    {
      return null;
    return com.forgerock.opendj.util.StaticUtils.getBytes(s);
    }
    try
    {
      char c;
      int length = s.length();
      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 (Exception e)
    {
      logger.traceException(e);
      try
      {
        return s.getBytes("UTF-8");
      }
      catch (Exception e2)
      {
        logger.traceException(e2);
        return s.getBytes();
      }
    }
  }
  /**
   * Returns the provided byte array decoded as a UTF-8 string without throwing
@@ -234,73 +178,31 @@
  /**
   * Construct a byte array containing the UTF-8 encoding of the
   * provided <code>char</code> array.
   *
   * @param chars
   *          The character array to convert to a UTF-8 byte array.
   * @return Returns a byte array containing the UTF-8 encoding of the
   *         provided <code>char</code> array.
   */
  public static byte[] getBytes(char[] chars)
  {
    return getBytes(new String(chars));
  }
  /**
   * Retrieves a string representation of the provided byte in hexadecimal.
   *
   * @param  b  The byte for which to retrieve the hexadecimal string
   * @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(byte b)
  public static String byteToHex(final byte b)
  {
    return BYTE_HEX_STRINGS[UPPER_CASE][b & 0xFF];
    return com.forgerock.opendj.util.StaticUtils.byteToHex(b);
  }
  /**
   * 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(byte b)
  public static String byteToLowerHex(final byte b)
  {
    return BYTE_HEX_STRINGS[LOWER_CASE][b & 0xFF];
    return com.forgerock.opendj.util.StaticUtils.byteToLowerHex(b);
  }
  /**
   * 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.
   */
  public static char byteToASCII(byte b)
  {
    if (32 <= b && b <= 126)
    {
      return (char) b;
    }
    return ' ';
  }
  /**
   * Retrieves a string representation of the contents of the provided byte
   * array using hexadecimal characters with no space between each byte.
@@ -554,7 +456,10 @@
    }
  }
  private static char byteToASCII(byte b)
  {
    return com.forgerock.opendj.util.StaticUtils.byteToASCII(b);
  }
  /**
   * Appends a string representation of the remaining unread data in the
@@ -660,21 +565,6 @@
  /**
   * Retrieves a binary representation of the provided byte.  It will always be
   * a sequence of eight zeros and/or ones.
   *
   * @param  b  The byte for which to retrieve the binary representation.
   *
   * @return  The binary representation for the provided byte.
   */
  public static String byteToBinary(byte b)
  {
    return BYTE_BIN_STRINGS[b & 0xFF];
  }
  /**
   * Compare two byte arrays for order. Returns a negative integer,
   * zero, or a positive integer as the first argument is less than,
   * equal to, or greater than the second.
@@ -809,73 +699,9 @@
      message.append(")");
      return LocalizableMessage.raw(message.toString());
    }
    else if (t instanceof NullPointerException)
    {
      LocalizableMessageBuilder message = new LocalizableMessageBuilder();
      message.append("NullPointerException(");
      StackTraceElement[] stackElements = t.getStackTrace();
      if (stackElements.length > 0)
      {
        message.append(stackElements[0].getFileName());
        message.append(":");
        message.append(stackElements[0].getLineNumber());
      }
      message.append(")");
      return message.toMessage();
    }
    else if (t instanceof InvocationTargetException && t.getCause() != null)
    {
      return getExceptionMessage(t.getCause());
    }
    else
    {
      StringBuilder message = new StringBuilder();
      String className = t.getClass().getName();
      int periodPos = className.lastIndexOf('.');
      if (periodPos > 0)
      {
        message.append(className.substring(periodPos+1));
      }
      else
      {
        message.append(className);
      }
      message.append("(");
      if (t.getMessage() == null)
      {
        StackTraceElement[] stackElements = t.getStackTrace();
        if (stackElements.length > 0)
        {
          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());
      return com.forgerock.opendj.util.StaticUtils.getExceptionMessage(t);
    }
  }
@@ -891,8 +717,7 @@
   */
  public static String stackTraceToSingleLineString(Throwable t)
  {
    return com.forgerock.opendj.util.StaticUtils.stackTraceToSingleLineString(
        t, DynamicConstants.DEBUG_BUILD);
    return com.forgerock.opendj.util.StaticUtils.stackTraceToSingleLineString(t, DynamicConstants.DEBUG_BUILD);
  }
@@ -907,8 +732,7 @@
  public static void stackTraceToSingleLineString(StringBuilder buffer,
                                                  Throwable t)
  {
    com.forgerock.opendj.util.StaticUtils.stackTraceToSingleLineString(
        buffer, t, DynamicConstants.DEBUG_BUILD);
    com.forgerock.opendj.util.StaticUtils.stackTraceToSingleLineString(buffer, t, DynamicConstants.DEBUG_BUILD);
  }
@@ -1091,24 +915,8 @@
   * @return  <CODE>true</CODE> if the provided character represents a numeric
   *          digit, or <CODE>false</CODE> if not.
   */
  public static boolean isDigit(char c)
  {
    switch (c)
    {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        return true;
      default:
        return false;
    }
  public static boolean isDigit(final char c) {
    return com.forgerock.opendj.util.StaticUtils.isDigit(c);
  }
@@ -1122,81 +930,9 @@
   *          lowercase ASCII alphabetic character, or <CODE>false</CODE> if it
   *          is not.
   */
  public static boolean isAlpha(char c)
  {
    switch (c)
    {
      case 'A':
      case 'B':
      case 'C':
      case 'D':
      case 'E':
      case 'F':
      case 'G':
      case 'H':
      case 'I':
      case 'J':
      case 'K':
      case 'L':
      case 'M':
      case 'N':
      case 'O':
      case 'P':
      case 'Q':
      case 'R':
      case 'S':
      case 'T':
      case 'U':
      case 'V':
      case 'W':
      case 'X':
      case 'Y':
      case 'Z':
        return true;
      case '[':
      case '\\':
      case ']':
      case '^':
      case '_':
      case '`':
        // Making sure all possible cases are present in one contiguous range
        // can result in a performance improvement.
        return false;
      case 'a':
      case 'b':
      case 'c':
      case 'd':
      case 'e':
      case 'f':
      case 'g':
      case 'h':
      case 'i':
      case 'j':
      case 'k':
      case 'l':
      case 'm':
      case 'n':
      case 'o':
      case 'p':
      case 'q':
      case 'r':
      case 's':
      case 't':
      case 'u':
      case 'v':
      case 'w':
      case 'x':
      case 'y':
      case 'z':
        return true;
      default:
        return false;
  public static boolean isAlpha(final char c) {
    return com.forgerock.opendj.util.StaticUtils.isAlpha(c);
    }
  }
  /**
   * Indicates whether the provided character is a hexadecimal digit.
@@ -1206,39 +942,9 @@
   * @return  <CODE>true</CODE> if the provided character represents a
   *          hexadecimal digit, or <CODE>false</CODE> if not.
   */
  public static boolean isHexDigit(char c)
  {
    switch (c)
    {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
      case 'A':
      case 'B':
      case 'C':
      case 'D':
      case 'E':
      case 'F':
      case 'a':
      case 'b':
      case 'c':
      case 'd':
      case 'e':
      case 'f':
        return true;
      default:
        return false;
  public static boolean isHexDigit(final char c) {
    return com.forgerock.opendj.util.StaticUtils.isHexDigit(c);
    }
  }
  /**
   * Indicates whether the provided byte represents a hexadecimal digit.
@@ -1915,155 +1621,21 @@
  /**
   * Retrieves a lowercase 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.
   * Returns a lower-case string representation of a given string, verifying for null input string.
   * {@see com.forgerock.opendj.util.StaticUtils#toLowerCase(String s)}
   *
   * @param  s  The string for which to obtain the lowercase representation.
   *
   * @return  The lowercase representation of the given string.
   * @param s the mixed case string
   * @return a lower-case string
   */
  public static String toLowerCase(String s)
  {
    if (s == null)
    {
      return null;
    return (s == null ? null : com.forgerock.opendj.util.StaticUtils.toLowerCase(s));
    }
    StringBuilder buffer = new StringBuilder(s.length());
    toLowerCase(s, buffer);
    return buffer.toString();
  }
  /**
   * Appends a lowercase 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 lowercase
   *                 representation.
   * @param  buffer  The buffer to which the lowercase form of the string should
   *                 be appended.
   */
  public static void toLowerCase(String s, StringBuilder buffer)
  {
    if (s == null)
    {
      return;
    }
    int length = s.length();
    for (int i=0; i < length; i++)
    {
      char c = s.charAt(i);
      if ((c & 0x7F) != c)
      {
        buffer.append(s.substring(i).toLowerCase());
        return;
      }
      switch (c)
      {
        case 'A':
          buffer.append('a');
          break;
        case 'B':
          buffer.append('b');
          break;
        case 'C':
          buffer.append('c');
          break;
        case 'D':
          buffer.append('d');
          break;
        case 'E':
          buffer.append('e');
          break;
        case 'F':
          buffer.append('f');
          break;
        case 'G':
          buffer.append('g');
          break;
        case 'H':
          buffer.append('h');
          break;
        case 'I':
          buffer.append('i');
          break;
        case 'J':
          buffer.append('j');
          break;
        case 'K':
          buffer.append('k');
          break;
        case 'L':
          buffer.append('l');
          break;
        case 'M':
          buffer.append('m');
          break;
        case 'N':
          buffer.append('n');
          break;
        case 'O':
          buffer.append('o');
          break;
        case 'P':
          buffer.append('p');
          break;
        case 'Q':
          buffer.append('q');
          break;
        case 'R':
          buffer.append('r');
          break;
        case 'S':
          buffer.append('s');
          break;
        case 'T':
          buffer.append('t');
          break;
        case 'U':
          buffer.append('u');
          break;
        case 'V':
          buffer.append('v');
          break;
        case 'W':
          buffer.append('w');
          break;
        case 'X':
          buffer.append('x');
          break;
        case 'Y':
          buffer.append('y');
          break;
        case 'Z':
          buffer.append('z');
          break;
        default:
          buffer.append(c);
      }
    }
  }
  /**
   * Appends a lowercase string representation of the contents of the given byte
   * array to the provided buffer, optionally trimming leading and trailing
   * spaces.  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.
   * Appends a lower-case string representation of a given ByteSequence to a StringBuilder,
   * verifying for null input.
   * {@see com.forgerock.opendj.util.StaticUtils#toLowerCase(ByteSequence s, StringBuilder string)}
   *
   * @param  b       The byte array for which to obtain the lowercase string
   *                 representation.
@@ -2072,138 +1644,41 @@
   * @param  trim    Indicates whether leading and trailing spaces should be
   *                 omitted from the string representation.
   */
  public static void toLowerCase(ByteSequence b, StringBuilder buffer,
                                 boolean trim)
  public static void toLowerCase(ByteSequence b, StringBuilder buffer, boolean trim)
  {
    if (b == null)
    {
      return;
    }
    int origBufferLen = buffer.length();
    int length = b.length();
    for (int i=0; i < length; i++)
    {
      if ((b.byteAt(i) & 0x7F) != b.byteAt(i))
      {
        buffer.replace(origBufferLen, buffer.length(),
            b.toString().toLowerCase());
        break;
      }
      int bufferLength = buffer.length();
      switch (b.byteAt(i))
      {
        case ' ':
          // If we don't care about trimming, then we can always append the
          // space.  Otherwise, only do so if there are other characters in the value.
          if (trim && bufferLength == 0)
          {
            break;
          }
          buffer.append(' ');
          break;
        case 'A':
          buffer.append('a');
          break;
        case 'B':
          buffer.append('b');
          break;
        case 'C':
          buffer.append('c');
          break;
        case 'D':
          buffer.append('d');
          break;
        case 'E':
          buffer.append('e');
          break;
        case 'F':
          buffer.append('f');
          break;
        case 'G':
          buffer.append('g');
          break;
        case 'H':
          buffer.append('h');
          break;
        case 'I':
          buffer.append('i');
          break;
        case 'J':
          buffer.append('j');
          break;
        case 'K':
          buffer.append('k');
          break;
        case 'L':
          buffer.append('l');
          break;
        case 'M':
          buffer.append('m');
          break;
        case 'N':
          buffer.append('n');
          break;
        case 'O':
          buffer.append('o');
          break;
        case 'P':
          buffer.append('p');
          break;
        case 'Q':
          buffer.append('q');
          break;
        case 'R':
          buffer.append('r');
          break;
        case 'S':
          buffer.append('s');
          break;
        case 'T':
          buffer.append('t');
          break;
        case 'U':
          buffer.append('u');
          break;
        case 'V':
          buffer.append('v');
          break;
        case 'W':
          buffer.append('w');
          break;
        case 'X':
          buffer.append('x');
          break;
        case 'Y':
          buffer.append('y');
          break;
        case 'Z':
          buffer.append('z');
          break;
        default:
          buffer.append((char) b.byteAt(i));
      }
    }
    if (trim)
    {
      // Strip off any trailing spaces.
      for (int i=buffer.length()-1; i > 0; i--)
      int begin = 0;
      int end = b.length() - 1;
      while (begin <= end)
      {
        if (buffer.charAt(i) == ' ')
        if (b.byteAt(begin) == ' ')
        {
          buffer.delete(i, i+1);
          begin++;
        }
        else if (b.byteAt(end) == ' ')
        {
          end--;
        }
        else
        {
          break;
        }
      }
      if (begin > 0 || end < b.length() - 1)
      {
        b = b.subSequence(begin, end + 1);
    }
  }
    com.forgerock.opendj.util.StaticUtils.toLowerCase(b, buffer);
  }
  /**
opendj-server-legacy/src/test/java/org/opends/server/util/TestStaticUtils.java
@@ -169,20 +169,6 @@
  }
  /**
   * Tests the {@link StaticUtils#getBytes(char[])} method.
   *
   * @param inputString
   *          The input string.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "getBytesTestData")
  public void testCharsToBytes(String inputString) throws Exception {
    Assert.assertEquals(StaticUtils.getBytes(inputString.toCharArray()),
        inputString.getBytes("UTF-8"));
  }
  /**
   * Create test strings for the {@link StaticUtils#byteToHex(byte)}.
   *
   * @return Returns an array of test strings.
@@ -235,23 +221,6 @@
  }
  /**
   * Tests the {@link StaticUtils#byteToASCII(byte)} method.
   *
   * @param b
   *          The input byte.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "byteToHexTestData")
  public void testByteToASCII(byte b) throws Exception {
    if (b < 32 || b > 126) {
      Assert.assertEquals(StaticUtils.byteToASCII(b), ' ');
    } else {
      Assert.assertEquals(StaticUtils.byteToASCII(b), (char) b);
    }
  }
  /**
   * Create test strings for the {@link StaticUtils#bytesToHex(byte[])}.
   *
   * @return Returns an array of test data.
@@ -302,19 +271,6 @@
  }
  /**
   * Tests the {@link StaticUtils#byteToBinary(byte)} method.
   *
   * @param b
   *          The input byte.
   * @throws Exception
   *           If the test failed unexpectedly.
   */
  @Test(dataProvider = "byteToHexTestData")
  public void testByteToBinary(byte b) throws Exception {
    Assert.assertEquals(StaticUtils.byteToBinary(b), BIT_STRINGS[b & 0xff]);
  }
  /**
   * Create test data for {@link StaticUtils#compare(byte[], byte[])}.
   *
   * @return Returns an array of test data.
@@ -1101,11 +1057,45 @@
  }
  /**
   * Create test strings for the {@link StaticUtils#toLowerCase(ByteSequence, StringBuilder, boolean)} method
   * with trimming enabled.
   *
   * @return Returns an array of test data.
   */
  @DataProvider(name = "stringCaseConversionTestDataWithTrim")
  public Object[][] createStringCaseConversionTestDataWithTrim()
  {
    return new Object[][] {
        {" aBc", "abc"},
        {"abC", "abc"},
        {"   A bC  ", "a bc"},
        {"fgh ", "fgh"},
        {"    ", ""},
        {"  D ", "d"}
    };
  }
  /**
   * Tests to lower case strings with space trimming.
   * @param input the test string
   * @param lower test string in lower case
   * @throws Exception if tests fails
   */
  @Test(dataProvider = "stringCaseConversionTestDataWithTrim")
  public void testToLowerCaseWithTrim(String input, String lower) throws Exception
  {
    StringBuilder sb = new StringBuilder();
    ByteString bytes = input != null ? ByteString.valueOf(input) : null;
    StaticUtils.toLowerCase(bytes, sb, true);
    Assert.assertEquals(sb.toString(), lower);
  }
  /**
   * Create test strings for the
   * {@link StaticUtils#toRFC3641StringValue(StringBuilder, String)}
   * method.
   *
   * @return Returns an array of test data.
   * @return an array of test data.
   */
  @DataProvider(name = "toRFC3641StringValueTestData")
  public Object[][] createToRFC3641StringValueTestData() {