commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject cvs commit: jakarta-commons/lang/src/test/org/apache/commons/lang/exception ExceptionTestSuite.java NestableDelegateTestCase.java NestableExceptionTestCase.java NestableRuntimeExceptionTestCase.java
Date Fri, 19 Jul 2002 03:35:56 GMT
bayard      2002/07/18 20:35:56

  Added:       lang     LICENSE PROPOSAL.html RELEASE-NOTES.txt STATUS.html
                        build.xml default.properties
               lang/src/conf MANIFEST.MF
               lang/src/java/org/apache/commons/lang CharRange.java
                        CharSet.java CharSetUtils.java NumberRange.java
                        NumberUtils.java ObjectUtils.java
                        RandomStringUtils.java SerializationException.java
                        SerializationUtils.java StringUtils.java
               lang/src/java/org/apache/commons/lang/exception
                        Nestable.java NestableDelegate.java
                        NestableException.java
                        NestableRuntimeException.java
               lang/src/test/org/apache/commons/lang CharSetUtilsTest.java
                        LangTestSuite.java NumberRangeTest.java
                        NumberUtilsTest.java ObjectUtilsTest.java
                        RandomStringUtilsTest.java
                        SerializationUtilsTest.java
                        StringUtilsEqualsIndexOfTest.java
                        StringUtilsIsTest.java
                        StringUtilsSubstringTest.java StringUtilsTest.java
                        StringUtilsTrimEmptyTest.java
               lang/src/test/org/apache/commons/lang/exception
                        ExceptionTestSuite.java
                        NestableDelegateTestCase.java
                        NestableExceptionTestCase.java
                        NestableRuntimeExceptionTestCase.java
  Log:
  Initial copy from jakarta-commons-sandbox
  
  Revision  Changes    Path
  1.1                  jakarta-commons/lang/LICENSE
  
  Index: LICENSE
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
  
  1.1                  jakarta-commons/lang/PROPOSAL.html
  
  Index: PROPOSAL.html
  ===================================================================
  <html>
  <head>
  <title>Proposal for Lang Package</title>
  </head>
  <body bgcolor="white">
  
  <div align="center">
  <h1>Proposal for <em>Lang</em> Package</h1>
  </div>
  
  <h3>(0) Rationale</h3>
  
  <p>The standard Java libraries fail to provide enough methods for 
  manipulation of its main components. The <em>Lang</em> Package provides 
  these extra methods. There are other classes which might justifiably 
  be included in java.lang someday, this package also provides for them.</p>
  
  
  <h3>(1) Scope of the Package</h3>
  
  <p>This proposal is to create a package of Java utility classes for the
  classes that are in java.lang's hierarchy, or are considered to be so 
  standard as to justify existence in java.lang. The <em>Lang</em> Package 
  also applies to primitives and arrays.</p>
  
  
  <h3>(1.5) Interaction With Other Packages</h3>
  
  <p><em>Lang</em> relies only on standard JDK 1.2 (or later) APIs for
  production deployment.  It utilizes the JUnit unit testing framework for
  developing and executing unit tests, but this is of interest only to
  developers of the component.  Lang will be a dependency for
  several existing components in the open source world.</p>
  
  <p>No external configuration files are utilized.</p>
  
  
  <h3>(2) Initial Source of the Package</h3>
  
  <p>The initial classes came from the Commons.Util subproject.</p>
  
  <p>The proposed package name for the new component is
  <code>org.apache.commons.lang</code>.</p>
  
  
  <h3>(3)  Required Jakarta-Commons Resources</h3>
  
  <ul>
  <li>CVS Repository - New directory <code>lang</code> in the
      <code>jakarta-commons</code> CVS repository.</li>
  <li>Mailing List - Discussions will take place on the general
      <em>commons-dev@jakarta.apache.org</em> mailing list.  To help
      list subscribers identify messages of interest, it is suggested that
      the message subject of messages about this component be prefixed with
      [lang].</li>
  <li>Bugzilla - New component "Lang" under the "Commons" product
      category, with appropriate version identifiers as needed.</li>
  <li>Jyve FAQ - New category "commons-lang" (when available).</li>
  </ul>
  
  
  <h3>(4) Initial Committers</h3>
  
  <p>The initial committers on the Lang component shall be as follows:
  <ul>
  <li>Henri Yandell (bayard)</li>
  <li>Daniel Rall (dlr)</li>
  <li>Stephen Colebourne (scolebourne)</li>
  <!-- Add your real name and user name here -->
  </ul>
  </p>
  
  </body>
  </html>
  
  
  
  1.1                  jakarta-commons/lang/RELEASE-NOTES.txt
  
  Index: RELEASE-NOTES.txt
  ===================================================================
  $Id: RELEASE-NOTES.txt,v 1.1 2002/07/19 03:35:53 bayard Exp $
  
  			Commons Lang Package
  			   Version 1.0-dev
  			    Release Notes
  
  
  INTRODUCTION:
  
  This document contains the release notes for this version of the Commons
  Lang package, and highlights changes since the previous version.  The
  current release adds new features and bug fixes, and is being done now to
  follow the release early/release often mentality.
  
  
  NEW FEATURES:
  
  BUG FIXES:
  
  
  
  
  
  1.1                  jakarta-commons/lang/STATUS.html
  
  Index: STATUS.html
  ===================================================================
  <html>
  <head>
  <title>Status File for Jakarta Commons "Lang" Component</title>
  </head>
  <body bgcolor="white">
  
  
  <div align="center">
  <h1>The Jakarta Commons <em>Lang</em> Component</h1>
  $Id: STATUS.html,v 1.1 2002/07/19 03:35:53 bayard Exp $<br />
  <a href="#Introduction">[Introduction]</a>
  <a href="#Dependencies">[Dependencies]</a>
  <a href="#Release Info">[Release Info]</a>
  <a href="#Committers">[Committers]</a>
  <a href="#Action Items">[Action Items]</a>
  <br /><br />
  </div>
  
  
  <a name="Introduction"></a>
  <h3>1.  INTRODUCTION</h3>
  
  <p>The <em>Lang</em> Component contains a set of Java classes that provide
  helper methods for standard Java classes, especially those found in the 
  java.lang package in the Sun JDK.
  The following classes are included:</p>
  <ul>
  <li><strong>Strings</strong> - Helper for java.lang.String.</li>
  <li><strong>Numbers</strong> - Helper for java.lang.Number and its subclasses.</li>
  <li><strong>Objects</strong> - Helper for creating any Object.</li>
  <li><strong>Classes</strong> - Helper for working with java.lang.Class.</li>
  <li><strong>NestedException package</strong> - A sub-package for creation of nested exceptions.</li>
  </ul>
  
  
  <a name="Dependencies"></a>
  <h3>2.  DEPENDENCIES</h3>
  
  <p>The <em>Lang</em> component is dependent upon the following external
  components for development and use:</p>
  <ul>
  <li><a href="http://java.sun.com/j2se">Java Development Kit</a>
      (Version 1.2 or later)</li>
  <li><a href="http://www.junit.org">JUnit Testing Framework</a>
      (Version 3.7 or later) - for unit tests only, not required
      for deployment</li>
  </ul>
  
  
  <a name="Release Info"></a>
  <h3>3.  RELEASE INFO</h3>
  
  <p>Current Release: Lang is yet to be released.</p>
  
  <p>Planned Next Release:  The components are relatively mature and from 
  commons.util, however time will be given for the Lang package to achieve 
  some stability, and unit-tests to arrive.</p>
  
  
  <a name="Committers"></a>
  <h3>4.  COMMITTERS</h3>
  
  <p>The following individuals are the primary developers and maintainers of this
  component.  Developers who plan to use <em>Lang</em> in their own
  projects are encouraged to collaborate on the future development of this
  component to ensure that it continues to meet a variety of needs.</p>
  <ul>
  <li><a href="mailto:bayard@apache.org">Henri Yandell</a></li>
  <li><a href="mailto:scolebourne@joda.org">Stephen Colebourne</a></li>
  </ul>
  
  </body>
  </html>
  
  
  
  1.1                  jakarta-commons/lang/build.xml
  
  Index: build.xml
  ===================================================================
  <project name="Lang" default="compile" basedir=".">
  
  
  <!--
          "Lang" component of the Jakarta Commons Subproject
          $Id: build.xml,v 1.1 2002/07/19 03:35:53 bayard Exp $
  -->
  
  
  <!-- ========== Initialize Properties ===================================== -->
  
    <property file="${user.home}/${component.name}.build.properties" /> 
    <property file="${user.home}/build.properties" />
    <property file="${basedir}/build.properties" />
    <property file="${basedir}/default.properties" />
  
  <!-- ========== Construct compile classpath =============================== -->
  
    <path id="compile.classpath">
      <pathelement location="${build.home}/classes"/>
    </path>
  
  <!-- ========== Construct unit test classpath ============================= -->
  
    <path id="test.classpath">
      <pathelement location="${build.home}/classes"/>
      <pathelement location="${build.home}/tests"/>
      <pathelement location="${junit.jar}"/>
    </path>
  
  <!-- ========== Executable Targets ======================================== -->
  
    <target name="init"
     description="Initialize and evaluate conditionals">
      <echo message="-------- ${component.name} ${component.version} --------"/>
      <filter  token="name"                  value="${component.name}"/>
      <filter  token="package"               value="${component.package}"/>
      <filter  token="version"               value="${component.version}"/>
    </target>
  
  
    <target name="prepare" depends="init"
     description="Prepare build directory">
      <mkdir dir="${build.home}"/>
      <mkdir dir="${build.home}/classes"/>
      <mkdir dir="${build.home}/conf"/>
      <mkdir dir="${build.home}/tests"/>
    </target>
  
  
    <target name="static" depends="prepare"
     description="Copy static files to build directory">
      <tstamp/>
      <copy  todir="${build.home}/conf" filtering="on">
        <fileset dir="${conf.home}" includes="*.MF"/>
      </copy>
    </target>
  
  
    <target name="compile" depends="static"
     description="Compile shareable components">
      <javac  srcdir="${source.home}"
             destdir="${build.home}/classes"
               debug="${compile.debug}"
         deprecation="${compile.deprecation}"
            optimize="${compile.optimize}">
        <classpath refid="compile.classpath"/>
      </javac>
      <copy    todir="${build.home}/classes" filtering="on">
        <fileset dir="${source.home}" excludes="**/*.java"/>
      </copy>
    </target>
  
  
    <target name="compile.tests" depends="compile"
     description="Compile unit test cases">
      <javac  srcdir="${test.home}"
             destdir="${build.home}/tests"
               debug="${compile.debug}"
         deprecation="${compile.deprecation}"
            optimize="${compile.optimize}">
        <classpath refid="test.classpath"/>
      </javac>
      <copy    todir="${build.home}/tests" filtering="on">
        <fileset dir="${test.home}" excludes="**/*.java"/>
      </copy>
    </target>
  
  
    <target name="clean"
     description="Clean build and distribution directories">
      <delete    dir="${build.home}"/>
      <delete    dir="${dist.home}"/>
    </target>
  
  
    <target name="all" depends="clean,compile"
     description="Clean and compile all components"/>
  
  
    <target name="javadoc" depends="compile"
     description="Create component Javadoc documentation">
      <mkdir      dir="${dist.home}"/>
      <mkdir      dir="${dist.home}/docs"/>
      <mkdir      dir="${dist.home}/docs/api"/>
      <javadoc sourcepath="${source.home}"
                  destdir="${dist.home}/docs/api"
             packagenames="org.apache.commons.*"
                   author="true"
                  private="true"
                  version="true"
                 doctitle="&lt;h1&gt;${component.title}&lt;/h1&gt;"
              windowtitle="${component.title} (Version ${component.version})"
                   bottom="Copyright (c) 2001-2002 - Apache Software Foundation">
        <classpath refid="compile.classpath"/>
      </javadoc>
    </target>
  
  
    <target name="dist" depends="compile,javadoc"
     description="Create binary distribution">
      <mkdir      dir="${dist.home}"/>
      <copy      file="../LICENSE"
                todir="${dist.home}"/>
      <copy      file="RELEASE-NOTES.txt"
                todir="${dist.home}"/>
      <antcall target="jar"/>
    </target>
  
  
    <target name="jar" depends="compile"
     description="Create jar">
      <mkdir      dir="${dist.home}"/>
      <mkdir      dir="${build.home}/classes/META-INF"/>
      <copy      file="../LICENSE"
               tofile="${build.home}/classes/META-INF/LICENSE.txt"/>
      <jar    jarfile="${dist.home}/${final.name}.jar"
              basedir="${build.home}/classes"
             manifest="${build.home}/conf/MANIFEST.MF"/>
    </target>
  
  
    <target name="install-jar" depends="jar"
     description="--> Installs jar file in ${lib.repo}">
      <copy todir="${lib.repo}" filtering="no">
        <fileset dir="${dist.home}">
          <include name="${final.name}.jar"/>
        </fileset>
      </copy>
    </target>
  
  
  <!-- ========== Unit Test Targets ========================================= -->
  
  
    <target name="test"  depends="compile.tests, test.exception"
     description="Run all unit test cases">
      <echo message="Running tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.LangTestSuite"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
  
    <target name="test.strings" depends="compile.tests">
      <echo message="Running Strings tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.StringsTest"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
    <target name="test.objects" depends="compile.tests">
      <echo message="Running Objects tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.ObjectsTest"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
    <target name="test.numberRange" depends="compile.tests">
      <echo message="Running NumberRange tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.NumberRangeTest"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
    <target name="test.randomStrings" depends="compile.tests">
      <echo message="Running RandomStrings tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.RandomStringsTest"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
    <target name="test.serialization" depends="compile.tests">
      <echo message="Running Serialization tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.SerializationTest"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
    <target name="test.charset" depends="compile.tests">
      <echo message="Running CharSet tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.CharSetTest"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
    <target name="test.exception" depends="compile.tests">
      <echo message="Running exception package tests ..."/>
      <java classname="${test.runner}" fork="yes"
          failonerror="${test.failonerror}">
        <arg value="org.apache.commons.lang.exception.ExceptionTestSuite"/>
        <classpath refid="test.classpath"/>
      </java>
    </target>
  
  </project>
  
  
  
  1.1                  jakarta-commons/lang/default.properties
  
  Index: default.properties
  ===================================================================
  # The pathname of the "junit.jar" JAR file
  #junit.jar = ${junit.home}/junit-3.7.jar
  junit.jar = /usr/local/javalib/junit.jar
  
  # The name of this component
  component.name = commons-lang
  
  # The primary package name of this component
  component.package = org.apache.commons.lang
  
  # The title of this component
  component.title = Core Language Utilities
  
  # The current version number of this component
  component.version = 1.0-dev
  
  # The name that is used to create the jar file
  final.name = ${component.name}-${component.version}
  
  # The base directory for compilation targets
  build.home = target
  
  # The base directory for component configuration files
  conf.home = src/conf
  
  # The base directory for distribution targets
  dist.home = dist
  
  # The base directory for component sources
  source.home = src/java
  
  # The base directory for unit test sources
  test.home = src/test
  
  # Should Java compilations set the 'debug' compiler option?
  compile.debug = true
  
  # Should Java compilations set the 'deprecation' compiler option?
  compile.deprecation = true
  
  # Should Java compilations set the 'optimize' compiler option?
  compile.optimize = true
  
  # Should all tests fail if one does?
  test.failonerror = true
  
  # The test runner to execute
  test.runner = junit.textui.TestRunner
  
  
  
  1.1                  jakarta-commons/lang/src/conf/MANIFEST.MF
  
  Index: MANIFEST.MF
  ===================================================================
  Extension-Name: @name@
  Specification-Vendor: Apache Software Foundation
  Specification-Version: 1.0
  Implementation-Vendor: Apache Software Foundation
  Implementation-Title: commons-lang
  Implementation-Version: @version@
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/CharRange.java
  
  Index: CharRange.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * A range of characters. Able to understand the idea of a contiguous 
   * sublist of an alphabet, a negated concept, and a set of characters.
   * Used by CharSet to handle sets of characters.
   *
   * @author <a href="bayard@generationjava.com">Henri Yandell</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: CharRange.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  class CharRange {
  
      /**
       * Used internally to represent null in a char.
       */
      private static char UNSET;
  
      private char start;
      private char close;
      private boolean negated;
  
      /**
       * Construct a CharRange over a single character.
       *
       * @param start char over which this range is placed
       */
      public CharRange(char start) {
          this.start = start;
      }
  
      /**
       * Construct a CharRange over a set of characters.
       *
       * @param start  char start character in this range. inclusive
       * @param close  char close character in this range. inclusive
       */
      public CharRange(char start, char close) {
          this.start = start;
          this.close = close;
      }
  
      /**
       * Construct a CharRange over a set of characters.
       *
       * @param start  String start first character is in this range (inclusive).
       * @param close  String first character is close character in this
       * range (inclusive).
       */
      public CharRange(String start, String close) {
          this.start = start.charAt(0);
          this.close = close.charAt(0);
      }
  
      /**
       * Get the start character for this character range
       * 
       * @return start char (inclusive)
       */
      public char getStart() {
          return this.start;
      }
  
      /**
       * Get the end character for this character range
       * 
       * @return end char (inclusive)
       */
      public char getEnd() {
          return this.close;
      }
  
      /**
       * Set the start character for this character range
       * 
       * @param ch  start char (inclusive)
       */
      public void setStart(char ch) {
          this.start = ch;
      }
  
      /**
       * Set the end character for this character range
       * 
       * @param ch  start char (inclusive)
       */
      public void setEnd(char ch) {
          this.close = ch;
      }
  
      /**
       * Is this CharRange over many characters
       *
       * @return boolean true is many characters
       */
      public boolean isRange() {
          return this.close != UNSET;
      }
  
      /**
       * Is the passed in character inside this range
       *
       * @return boolean true is in range
       */
      public boolean inRange(char ch) {
          if(isRange()) {
              return ((ch >= start) && (ch <= close) );
          } else {
              return start == ch;
          }
      }
  
      /**
       * Checks if this CharRange is negated.
       *
       * @return boolean true is negated
       */
      public boolean isNegated() {
          return negated;
      }
  
      /**
       * Sets this character range to be negated or not. 
       * This implies that this CharRange is over all characters except 
       * the ones in this range.
       * 
       * @param negated  true to negate the range
       */
      public void setNegated(boolean negated) {
          this.negated = negated;
      }
  
      /**
       * Output a string representation of the character range
       * 
       * @return string representation
       */
      public String toString() {
          String str = "";
          if(isNegated()) {
              str += "^";
          }
          str += start;
          if(isRange()) {
              str += "-";
              str += close;
          }
          return str;
      }
      
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/CharSet.java
  
  Index: CharSet.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.Iterator;
  import java.util.List;
  import java.util.LinkedList;
  /**
   * A set of characters. You can iterate over the characters in the 
   * set. 
   *
   * @author <a href="bayard@generationjava.com">Henri Yandell</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: CharSet.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class CharSet {
  
      private LinkedList set = new LinkedList();
  
      /**
       * Restricted consructor. Use the factory method evaluateSet().
       */
      protected CharSet(String[] set) {
          int sz = set.length;
          for (int i = 0; i < sz; i++) {
              add(set[i]);
          }
      }
  
      /**
       * Does the set contain the character specified
       * 
       * @param ch  the character to check for
       * @return true if it does contain it
       */
      public boolean contains(char ch) {
          Iterator iterator = set.iterator();
          boolean bool = false;
          while (iterator.hasNext()) {
              CharRange range = (CharRange) iterator.next();
              if (range.isNegated()) {
                  if (!range.inRange(ch)) {
                      bool = true;
                  }
              } else {
                  if (range.inRange(ch)) {
                      bool = true;
                  }
              }
          }
          return bool;
      }
  
      /**
       * Add a set definition string to the set
       * 
       * @param str  set definition string
       */
      protected void add(String str) {
          int sz = str.length();
          CharRange range = null;
  
          if("-".equals(str)) {
              range = new CharRange('_');
              set.add(range);
              return;
          } 
  
          boolean end = false;
          boolean negated = false;
          for(int i=0; i<sz; i++) {
              char ch = str.charAt(i);
              if(ch == '-') {
                  end = true;
                  continue;
              }
              if(end) {
                  range.setEnd(ch);
                  continue;
              }
              if(ch == '^') {
                  negated = true;
                  continue;
              }
              range = new CharRange(ch);
              range.setNegated(negated);
              set.add(range);
          }
      }
  
      /**
       * Returns a string representation of the set
       * 
       * @return string representation
       */
      public String toString() {
          return set.toString();
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/CharSetUtils.java
  
  Index: CharSetUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.Iterator;
  import java.util.List;
  import java.util.LinkedList;
  
  /**
   * Numerous routines to manipulate a character set.
   *
   * @author <a href="bayard@generationjava.com">Henri Yandell</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: CharSetUtils.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class CharSetUtils {
  
      /**
       * Creates a CharSetUtils object which allows a certain amount of 
       * set logic to be performed upon the following syntax:
       *
       * "aeio" which implies 'a','e',..
       * "^e" implies not e. However it only negates, it's not 
       * a set in itself due to the size of that set in unicode.
       * "ej-m" implies e,j->m. e,j,k,l,m.
       */
      public static CharSet evaluateSet(String[] set) {
          return new CharSet(set); 
      }
  
      /**
       * Squeezes any repititions of a character that is mentioned in the 
       * supplied set. An example is:
       *    squeeze("hello", "el")  => "helo"
       * See evaluateSet for set-syntax.
       * 
       * @param str  the string to work from
       * @param set  the character set to use for manipulation
       */
      public static String squeeze(String str, String set) {
          String[] strs = new String[1];
          strs[0] = set;
          return squeeze(str, strs);
      }
  
      /**
       * Squeezes any repititions of a character that is mentioned in the 
       * supplied set. An example is:
       *    squeeze("hello", {"el"})  => "helo"
       * See evaluateSet for set-syntax.
       * 
       * @param str  the string to work from
       * @param set  the character set to use for manipulation
       */
      public static String squeeze(String str, String[] set) {
          CharSet chars = evaluateSet(set);
          StringBuffer buffer = new StringBuffer(str.length());
          char[] chrs = str.toCharArray();
          int sz = chrs.length;
          char lastChar = ' ';
          char ch = ' ';
          for (int i = 0; i < sz; i++) {
              ch = chrs[i];
              if (chars.contains(ch)) {
                  if ((ch == lastChar) && (i != 0)) {
                      continue;
                  }
              }
              buffer.append(ch);
              lastChar = ch;
          }
          return buffer.toString();
      }
  
      /**
       * Takes an argument in set-syntax, see evaluateSet,
       * and returns the number of characters present in the specified string.
       * An example would be:   count("hello", {"c-f","o"}) returns 2.
       *
       * @param str  String target to count characters in
       * @param set  String set of characters to count
       */
      public static int count(String str, String set) {
          String[] strs = new String[1];
          strs[0] = set;
          return count(str, strs);
      }
      
      /**
       * Takes an argument in set-syntax, see evaluateSet,
       * and returns the number of characters present in the specified string.
       * An example would be:   count("hello", {"c-f","o"}) returns 2.
       *
       * @param str  String target to count characters in
       * @param set  String[] set of characters to count
       */
      public static int count(String str, String[] set) {
          CharSet chars = evaluateSet(set);
          int count = 0;
          char[] chrs = str.toCharArray();
          int sz = chrs.length;
          for(int i=0; i<sz; i++) {
              if(chars.contains(chrs[i])) {
                  count++;
              }
          }
          return count;
      }
  
      /**
       * Takes an argument in set-syntax, see evaluateSet,
       * and deletes any of characters present in the specified string.
       * An example would be:   delete("hello", {"c-f","o"}) returns "hll"
       *
       * @param str  String target to delete characters from
       * @param set  String set of characters to delete
       */
      public static String delete(String str, String set) {
          String[] strs = new String[1];
          strs[0] = set;
          return delete(str, strs);
      }
      
      /**
       * Takes an argument in set-syntax, see evaluateSet,
       * and deletes any of characters present in the specified string.
       * An example would be:   delete("hello", {"c-f","o"}) returns "hll"
       *
       * @param str  String target to delete characters from
       * @param set  String[] set of characters to delete
       */
      public static String delete(String str, String[] set) {
          CharSet chars = evaluateSet(set);
          StringBuffer buffer = new StringBuffer(str.length());
          char[] chrs = str.toCharArray();
          int sz = chrs.length;
          for(int i=0; i<sz; i++) {
              if(!chars.contains(chrs[i])) {
                  buffer.append(chrs[i]);
              }
          }
          return buffer.toString();
      }
  
      /**
       * NEEDS TO TAKE A CHAR-SET.
       * Translate characters in a String.
       * An example is:  translate("hello", "ho", "jy") => jelly
       * If the length of characters to search for is greater than the 
       * length of characters to replace, then the last character is 
       * used.
       *
       * @param target String to replace characters  in
       * @param repl String to find that will be replaced
       * @param with String to put into the target String
       */
      public static String translate(String target, String repl, String with) {
          StringBuffer buffer = new StringBuffer(target.length());
          char[] chrs = target.toCharArray();
          char[] withChrs = with.toCharArray();
          int sz = chrs.length;
          int withMax = with.length() - 1;
          for(int i=0; i<sz; i++) {
              int idx = repl.indexOf(chrs[i]);
              if(idx != -1) {
                  if(idx > withMax) {
                      idx = withMax;
                  }
                  buffer.append(withChrs[idx]);
              } else {
                  buffer.append(chrs[i]);
              }
          }
          return buffer.toString();
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/NumberRange.java
  
  Index: NumberRange.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * Represents a range of {@link Number} objects.
   *
   * @author <a href="mailto:chrise@esha.com">Christopher Elkins</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/19 03:35:54 $
   */
  public final class NumberRange {
  
  
      /* The minimum number in this range. */
      private final Number min;
  
      /* The maximum number in this range. */
      private final Number max;
  
  
      /**
       * Constructs a new instance using the specified number as both the
       * minimum and maximum in theis range.
       *
       * @param num the number to use for this range
       * @throws NullPointerException if the number is <code>null</code>
       */
      public NumberRange(Number num) {
          if (num == null) {
              throw new NullPointerException("num cannot be null");
          }
  
          this.min = num;
          this.max = num;
      }
  
      /**
       * Constructs a new instance with the specified minimum and maximum
       * numbers.
       *
       * @param min the minimum number in this range
       * @param max the maximum number in this range
       * @throws NullPointerException if either the minimum or maximum number is
       *         <code>null</code>
       */
      public NumberRange(Number min, Number max) {
          if (min == null) {
              throw new NullPointerException("min cannot be null");
          } else if (max == null) {
              throw new NullPointerException("max cannot be null");
          }
  
          if (max.doubleValue() < min.doubleValue()) {
              this.min = this.max = min;
          } else {
              this.min = min;
              this.max = max;
          }
      }
  
      /**
       * Returns the minimum number in this range.
       *
       * @return the minimum number in this range
       */
      public Number getMinimum() {
          return min;
      }
  
      /**
       * Returns the maximum number in this range.
       *
       * @return the maximum number in this range
       */
      public Number getMaximum() {
          return min;
      }
  
      /**
       * Tests whether the specified number occurs within this range.
       *
       * @param number the number to test
       * @return <code>true</code> if the specified number occurs within this
       *         range; otherwise, <code>false</code>
       */
      public boolean includesNumber(Number number) {
          if (number == null) {
              return false;
          } else {
              return !(min.doubleValue() > number.doubleValue()) &&
                  !(max.doubleValue() < number.doubleValue());
          }
      }
  
      /**
       * Tests whether the specified range occurs entirely within this range.
       *
       * @param range the range to test
       * @return <code>true</code> if the specified range occurs entirely within
       *         this range; otherwise, <code>false</code>
       */
      public boolean includesRange(NumberRange range) {
          if (range == null) {
              return false;
          } else {
              return includesNumber(range.min) && includesNumber(range.max);
          }
      }
  
      /**
       * Tests whether the specified range overlaps with this range.
       *
       * @param range the range to test
       * @return <code>true</code> if the specified range overlaps with this
       *         range; otherwise, <code>false</code>
       */
      public boolean overlaps(NumberRange range) {
          if (range == null) {
              return false;
          } else {
              return range.includesNumber(min) || range.includesNumber(max) || 
                  includesRange(range);
          }
      }
  
      /**
       * Indicates whether some other object is "equal" to this one.
       *
       * @param obj the reference object with which to compare
       * @return <code>true</code> if this object is the same as the obj
       *         argument; <code>false</code> otherwise
       */
      public boolean equals(Object obj) {
          if (obj == this) {
              return true;
          } else if (!(obj instanceof NumberRange)) {
              return false;
          } else {
              NumberRange range = (NumberRange)obj;
              return min.equals(range.min) && max.equals(range.max);
          }
      }
  
      /**
       * Returns a hash code value for this object.
       *
       * @return a hash code value for this object
       */
      public int hashCode() {
          int result = 17;
          result = 37 * result + min.hashCode();
          result = 37 * result + max.hashCode();
          return result;
      }
  
      /**
       * Returns the string representation of this range. This string is the
       * string representation of the minimum and maximum numbers in the range,
       * separated by a hyphen. If a number is negative, then it is enclosed
       * in parentheses.
       *
       * @return the string representation of this range
       */
      public String toString() {
          StringBuffer sb = new StringBuffer();
  
          if (min.intValue() < 0) {
              sb.append('(')
                  .append(min)
                  .append(')');
          } else {
              sb.append(min);
          }
  
          sb.append('-');
  
          if (max.intValue() < 0) {
              sb.append('(')
                  .append(max)
                  .append(')');
          } else {
              sb.append(max);
          }
  
          return sb.toString();
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/NumberUtils.java
  
  Index: NumberUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.math.BigInteger;
  import java.math.BigDecimal;
  /**
   * Provides extra functionality for java Number classes.
   *
   * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
   * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: NumberUtils.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public final class NumberUtils {
  
      /**
       * Convert a String to an int, returning zero if the conversion fails
       * 
       * @param str  the string to convert
       * @return the int represented by the string, or zero if conversion fails
       */
      public static int stringToInt(String str) {
          return stringToInt(str, 0);
      }
  
      /**
       * Convert a String to an int, returning a default value if the 
       * conversion fails.
       * 
       * @param str  the string to convert
       * @param defaultValue  the default value
       * @return the int represented by the string, or the default if conversion fails
       */
      public static int stringToInt(String str, int defaultValue) {
          try {
              return Integer.parseInt(str);
          } catch (NumberFormatException nfe) {
              return defaultValue;
          }
      }
  
      // must handle Long, Float, Integer, Float, Short,
      //                  BigDecimal, BigInteger and Byte
      // useful methods:
      // Byte.decode(String)
      // Byte.valueOf(String,int radix)
      // Byte.valueOf(String)
      // Double.valueOf(String)
      // Float.valueOf(String)
      // new Float(String)
      // Integer.valueOf(String,int radix)
      // Integer.valueOf(String)
      // Integer.decode(String)
      // Integer.getInteger(String)
      // Integer.getInteger(String,int val)
      // Integer.getInteger(String,Integer val)
      // new Integer(String)
      // new Double(String)
      // new Byte(String)
      // new Long(String)
      // Long.getLong(String)
      // Long.getLong(String,int)
      // Long.getLong(String,Integer)
      // Long.valueOf(String,int)
      // Long.valueOf(String)
      // new Short(String)
      // Short.decode(String)
      // Short.valueOf(String,int)
      // Short.valueOf(String)
      // new BigDecimal(String)
      // new BigInteger(String)
      // new BigInteger(String,int radix)
      // Possible inputs:
      // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd
      // plus minus everything. Prolly more. A lot are not separable.
  
      /**
       * <p>
       * Turns a string value into a java.lang.Number.
       * First, the value is examined for a type qualifier on the end 
       * (<code>'f','F','d','D','l','L'</code>).  If it is found, it starts 
       * trying to create succissively larger types from the type specified
       * until one is found that can hold the value.
       * </p>
       * <p>
       * If a type specifier is not found, it will check for a decimal point
       * and then try successively larger types from Integer to BigInteger 
       * and from Float to BigDecimal.
       * </p>
       * <p>
       * If the string starts with "0x" or "-0x", it will be interpreted as a 
       * hexadecimal integer.  Values with leading 0's will not be interpreted 
       * as octal.
       * </p>
       * 
       * @param val String containing a number
       * @return Number created from the string
       * @throws NumberFormatException if the value cannot be converted
       */
      public static Number createNumber(String val) throws NumberFormatException {
          if (val == null) {
              return null;
          }
          if (val.length() == 0) {
              throw new NumberFormatException("\"\" is not a valid number.");
          }
          if (val.startsWith("--")) {
              // this is protection for poorness in java.lang.BigDecimal.
              // it accepts this as a legal value, but it does not appear 
              // to be in specification of class. OS X Java parses it to 
              // a wrong value.
              return null;
          }
          if (val.startsWith("0x") || val.startsWith("-0x")) {
              return createInteger(val);
          }   
          char lastChar = val.charAt(val.length() - 1);
          String mant;
          String dec;
          String exp;
          int decPos = val.indexOf('.');
          int expPos = val.indexOf('e') + val.indexOf('E') + 1;
  
          if (decPos > -1) {
  
              if (expPos > -1) {
                  if (expPos < decPos) {
                      throw new NumberFormatException(val + " is not a valid number.");
                  }
                  dec = val.substring(decPos + 1, expPos);
              } else {
                  dec = val.substring(decPos + 1);
              }
              mant = val.substring(0, decPos);
          } else {
              if (expPos > -1) {
                  mant = val.substring(0, expPos);
              } else {
                  mant = val;
              }
              dec = null;
          }
          if (!Character.isDigit(lastChar)) {
              if (expPos > -1 && expPos < val.length() - 1) {
                  exp = val.substring(expPos + 1, val.length() - 1);
              } else {
                  exp = null;
              }
              //Requesting a specific type..
              String numeric = val.substring(0, val.length() - 1);
              boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
              switch (lastChar) {
                  case 'l' :
                  case 'L' :
                      if (dec == null
                          && exp == null
                          && isDigits(numeric.substring(1))
                          && (numeric.charAt(0) == '-' || Character.isDigit(numeric.charAt(0)))) {
                          try {
                              return createLong(numeric);
                          } catch (NumberFormatException nfe) {
                              //Too big for a long
                          }
                          return createBigInteger(numeric);
  
                      }
                      throw new NumberFormatException(val + " is not a valid number.");
                  case 'f' :
                  case 'F' :
                      try {
                          Float f = NumberUtils.createFloat(numeric);
                          if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
                              //If it's too big for a float or the float value = 0 and the string
                              //has non-zeros in it, then float doens't have the presision we want
                              return f;
                          }
  
                      } catch (NumberFormatException nfe) {
                      }
                      //Fall through
                  case 'd' :
                  case 'D' :
                      try {
                          Double d = NumberUtils.createDouble(numeric);
                          if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) {
                              return d;
                          }
                      } catch (NumberFormatException nfe) {
                      }
                      try {
                          return createBigDecimal(numeric);
                      } catch (NumberFormatException e) {
                      }
                      //Fall through
                  default :
                      throw new NumberFormatException(val + " is not a valid number.");
  
              }
          } else {
              //User doesn't have a preference on the return type, so let's start
              //small and go from there...
              if (expPos > -1 && expPos < val.length() - 1) {
                  exp = val.substring(expPos + 1, val.length());
              } else {
                  exp = null;
              }
              if (dec == null && exp == null) {
                  //Must be an int,long,bigint
                  try {
                      return createInteger(val);
                  } catch (NumberFormatException nfe) {
                  }
                  try {
                      return createLong(val);
                  } catch (NumberFormatException nfe) {
                  }
                  return createBigInteger(val);
  
              } else {
                  //Must be a float,double,BigDec
                  boolean allZeros = isAllZeros(mant) && isAllZeros(exp);
                  try {
                      Float f = createFloat(val);
                      if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) {
                          return f;
                      }
                  } catch (NumberFormatException nfe) {
                  }
                  try {
                      Double d = createDouble(val);
                      if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) {
                          return d;
                      }
                  } catch (NumberFormatException nfe) {
                  }
  
                  return createBigDecimal(val);
  
              }
  
          }
      }
  
      /**
       * Utility method for createNumber.  Returns true if s is null
       * 
       * @param s the String to check
       * @return if it is all zeros or null
       */
      private static boolean isAllZeros(String s) {
          if (s == null) {
              return true;
          }
          for (int i = s.length() - 1; i >= 0; i--) {
              if (s.charAt(i) != '0') {
                  return false;
              }
          }
          return s.length() > 0;
      }
  
      /**
       * Convert a String to a Float
       * 
       * @param val  a String to convert
       * @return converted Float
       * @throws NumberFormatException if the value cannot be converted
       */
      public static Float createFloat(String val) {
          return Float.valueOf(val);
      }
  
      /**
       * Convert a String to a Double
       * 
       * @param val  a String to convert
       * @return converted Double
       * @throws NumberFormatException if the value cannot be converted
       */
      public static Double createDouble(String val) {
          return Double.valueOf(val);
      }
  
      /**
       * Convert a String to a Integer, handling hex and
       * octal notations.
       * 
       * @param val  a String to convert
       * @return converted Integer
       * @throws NumberFormatException if the value cannot be converted
       */
      public static Integer createInteger(String val) {
          // decode() handles 0xAABD and 0777 (hex and octal) as well.
          return Integer.decode(val);
      }
  
      /**
       * Convert a String to a Long
       * 
       * @param val  a String to convert
       * @return converted Long
       * @throws NumberFormatException if the value cannot be converted
       */
      public static Long createLong(String val) {
          return Long.valueOf(val);
      }
  
      /**
       * Convert a String to a BigInteger
       * 
       * @param val  a String to convert
       * @return converted BigInteger
       * @throws NumberFormatException if the value cannot be converted
       */
      public static BigInteger createBigInteger(String val) {
          BigInteger bi = new BigInteger(val);
          return bi;
      }
  
      /**
       * Convert a String to a BigDecimal
       * 
       * @param val  a String to convert
       * @return converted BigDecimal
       * @throws NumberFormatException if the value cannot be converted
       */
      public static BigDecimal createBigDecimal(String val) {
          BigDecimal bd = new BigDecimal(val);
          return bd;
      }
  
      /**
       * Get the minimum of three values.
       */
      public static int minimum(int a, int b, int c) {
          if (b < a) {
              a = b;
          }
          if (c < a) {
              a = c;
          }
          return a;
      }
  
      /**
       * Get the maximum of three values.
       */
      public static int maximum(int a, int b, int c) {
          if (b > a) {
              a = b;
          }
          if (c > a) {
              a = c;
          }
          return a;
      }
  
      /**
       * Checks whether the String contains only digit characters.
       * Null and blank string will return false.
       *
       * @param str  the string to check
       * @return boolean contains only unicode numeric
       */
      public static boolean isDigits(String str) {
          if ((str == null) || (str.length() == 0)) {
              return false;
          }
          for (int i = 0; i < str.length(); i++) {
              if (!Character.isDigit(str.charAt(i))) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * <p>
       * Checks whether the String a valid Java number.
       * Valid numbers include hexadecimal marked with the "0x" qualifier,
       * scientific notation and numbers marked with a type qualifier (e.g. 123L).
       * </p>
       * <p>
       * Null and blank string will return false.
       * </p>
       * 
       * @param str  the string to check
       * @return true if the string is a correctly formatted number
       */
      public static boolean isNumber(String str) {
          if ((str == null) || (str.length() == 0)) {
              return false;
          }
          char[] chars = str.toCharArray();
          int sz = chars.length;
          boolean hasExp = false;
          boolean hasDecPoint = false;
          boolean allowSigns = false;
          boolean foundDigit = false;
          //Deal with any possible sign up front
          int start = (chars[0] == '-') ? 1 : 0;
          if (sz > start + 1) {
              if (chars[start] == '0' && chars[start + 1] == 'x') {
                  int i = start + 2;
                  if (i == sz) {
                      return false; // str == "0x"
                  }
                  //Checking hex (it can't be anything else)
                  for (; i < chars.length; i++) {
                      if ((chars[i] < '0' || chars[i] > '9')
                          && (chars[i] < 'a' || chars[i] > 'f')
                          && (chars[i] < 'A' || chars[i] > 'F')) {
                          return false;
                      }
                  }
                  return true;
              }
          }
          sz--; //Don't want to loop to the last char, check it afterwords
                //for type qualifiers
          int i = start;
          //Loop to the next to last char or to the last char if we need another digit to
          //make a valid number (e.g. chars[0..5] = "1234E")
          while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
              if (chars[i] >= '0' && chars[i] <= '9') {
                  foundDigit = true;
                  allowSigns = false;
  
              } else if (chars[i] == '.') {
                  if (hasDecPoint || hasExp) {
                      //Two decimal points or dec in exponent   
                      return false;
                  }
                  hasDecPoint = true;
              } else if (chars[i] == 'e' || chars[i] == 'E') {
                  //We've already taken care of hex.
                  if (hasExp) {
                      //Two E's
                      return false;
                  }
                  if (!foundDigit) {
                      return false;
                  }
                  hasExp = true;
                  allowSigns = true;
              } else if (chars[i] == '+' || chars[i] == '-') {
                  if (!allowSigns) {
                      return false;
                  }
                  allowSigns = false;
                  foundDigit = false; //We need a digit after the E
              } else {
                  return false;
              }
              i++;
          }
          if (i < chars.length) {
              if (chars[i] >= '0' && chars[i] <= '9') {
                  //No type qualifier, OK
                  return true;
              }
              if (chars[i] == 'e' || chars[i] == 'E') {
                  //Can't have an E at the last byte
                  return false;
              }
              if (!allowSigns
                  && (chars[i] == 'd'
                      || chars[i] == 'D'
                      || chars[i] == 'f'
                      || chars[i] == 'F')) {
                  return foundDigit;
              }
              if (chars[i] == 'l'
                  || chars[i] == 'L') {
                  //Not allowing L with an exponoent
                  return foundDigit && !hasExp;
              }
          }
          //allowSigns is true iff the val ends in 'E'
          //Found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
          return !allowSigns && foundDigit;
      }
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/ObjectUtils.java
  
  Index: ObjectUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /**
   * Common <code>Object</code> manipulation routines.
   *
   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
   * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: ObjectUtils.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class ObjectUtils {
      
      /**
       * Prevent construction of ObjectUtils instances
       */
      private ObjectUtils() {
      }
  
      /**
       * Returns a default value if the object passed is null.
       *
       * @param object  the object to test.
       * @param defaultValue  the default value to return.
       * @return object if it is not null, defaultValue otherwise.
       */
      public static Object defaultIfNull(Object object, Object defaultValue) {
          return (object != null ? object : defaultValue);
      }
  
      /**
       * Compares two objects for equality, where either one or both
       * objects may be <code>null</code>.
       *
       * @param object1  the first object.
       * @param object2  the second object.
       * @return True if the values of both objects are the same.
       */
      public static boolean equals(Object object1, Object object2) {
          if (object1 == null) {
              return (object2 == null);
          } else if (object2 == null) {
              // object1 is not null
              return false;
          } else {
              return object1.equals(object2);
          }
      }
      
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/RandomStringUtils.java
  
  Index: RandomStringUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.Random;
  /**
   * <p>Common random <code>String</code> manipulation routines.</p>
   *
   * <p>Originally from 
   *  <a href="http://jakarta.apache.org/turbine/">Turbine</a> and the
   * GenerationJavaCore library.</p>
   *
   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
   * @author <a href="mailto:bayard@generationjava.com">Bayard</a>
   * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: RandomStringUtils.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class RandomStringUtils {
  
      /**
       * Random object used by random method. This has to be not local 
       * to the random method so as to not return the same value in the 
       * same millisecond. 
       */
      private static final Random RANDOM = new Random();
  
      /**
       * Prevent construction of RandomStringUtils instances
       */
      private RandomStringUtils() {
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of all characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String random(int count) {
          return random(count, false, false);
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of characters whose
       * ASCII value is between 32 and 127 .
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomAscii(int count) {
          return random(count, 32, 127, false, false);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alphabetic
       * characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomAlphabetic(int count) {
          return random(count, true, false);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alpha-numeric
       * characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomAlphanumeric(int count) {
          return random(count, true, true);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of numeric
       * characters.
       *
       * @param count length of random string to create
       * @return the random string
       */
      public static String randomNumeric(int count) {
          return random(count, false, true);
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alpha-numeric
       * characters as indicated by the arguments.
       *
       * @param count length of random string to create
       * @param letters if <code>true</code>, generated string will include
       * alphabetic characters
       * @param numbers if <code>true</code>, generatd string will include
       * numeric characters
       * @return the random string
       */
      public static String random(int count, boolean letters, boolean numbers) {
          return random(count, 0, 0, letters, numbers);
      }
      
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of alpha-numeric
       * characters as indicated by the arguments.
       *
       * @param count length of random string to create
       * @param start int position in set of chars to start at
       * @param end int position in set of chars to end before
       * @param letters if <code>true</code>, generated string will include
       * alphabetic characters
       * @param numbers if <code>true</code>, generatd string will include
       * numeric characters
       * @return the random string
       */
      public static String random(int count, int start, int end, boolean letters, boolean numbers) {
          return random(count, start, end, letters, numbers, null);
      }
      
      /**
       * Creates a random string based on a variety of options.
       *
       * @param count int length of random string to create
       * @param start int position in set of chars to start at
       * @param end int position in set of chars to end before
       * @param letters boolean only allow letters?
       * @param numbers boolean only allow numbers?
       * @param set char[] set of chars to choose randoms from.
       *        If null, then it will use the set of all chars.
       * @return the random string
       */
      public static String random(int count, int start, int end, boolean letters, boolean numbers, char[] set) {
          if( (start == 0) && (end == 0) ) {
              end = (int)'z';
              start = (int)' ';
              if(!letters && !numbers) {
                  start = 0;
                  end = Integer.MAX_VALUE;
              }
          }
  
          StringBuffer buffer = new StringBuffer();
          int gap = end - start;
  
          while(count-- != 0) {
              char ch;
              if(set == null) {
                  ch = (char)(RANDOM.nextInt(gap) + start);
              } else {
                  ch = set[RANDOM.nextInt(gap) + start];
              }
              if( (letters && numbers && Character.isLetterOrDigit(ch)) ||
                  (letters && Character.isLetter(ch)) ||
                  (numbers && Character.isDigit(ch)) ||
                  (!letters && !numbers)
                ) 
              {
                  buffer.append( ch );
              } else {
                  count++;
              }
          }
          return buffer.toString();
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of characters
       * specified.
       *
       * @param count int length of random string to create
       * @param set String containing the set of characters to use
       * @return the random string
       */
      public static String random(int count, String set) {
          return random(count, set.toCharArray());
      }
  
      /**
       * Creates a random string whose length is the number of characters
       * specified. Characters will be chosen from the set of characters
       * specified.
       *
       * @param count int length of random string to create
       * @param set character array containing the set of characters to use
       * @return the random string
       */
      public static String random(int count, char[] set) {
          return random(count, 0, set.length - 1, false, false, set);
      }
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/SerializationException.java
  
  Index: SerializationException.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.apache.commons.lang.exception.NestableRuntimeException;
  
  /**
   * Exception thrown when the Serialization process fails. The original
   * error is wrapped within this one.
   *
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: SerializationException.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class SerializationException extends NestableRuntimeException {
  
      /**
       * Constructs a new <code>SerializationException</code> without specified
       * detail message.
       */
      public SerializationException() {
          super();
      }
  
      /**
       * Constructs a new <code>SerializationException</code> with specified
       * detail message.
       *
       * @param msg The error message.
       */
      public SerializationException(String msg) {
          super(msg);
      }
  
      /**
       * Constructs a new <code>SerializationException</code> with specified
       * nested <code>Throwable</code>.
       *
       * @param nested The exception or error that caused this exception
       *               to be thrown.
       */
      public SerializationException(Throwable cause) {
          super(cause);
      }
  
      /**
       * Constructs a new <code>SerializationException</code> with specified
       * detail message and nested <code>Throwable</code>.
       *
       * @param msg    The error message.
       * @param nested The exception or error that caused this exception
       *               to be thrown.
       */
      public SerializationException(String msg, Throwable cause) {
          super(msg, cause);
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/SerializationUtils.java
  
  Index: SerializationUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.OutputStream;
  import java.io.Serializable;
  
  /**
   * Methods that assist with the serialization process, or perform
   * additional functionality based on serialization.
   * <ul>
   * <li>Deep clone using serialization
   * <li>Serialize managing finally and IOException
   * <li>Deserialize managing finally and IOException
   * </ul>
   *
   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
   * @author <a href="mailto:janekdb@yahoo.co.uk">Janek Bogucki</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: SerializationUtils.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class SerializationUtils {
      
      /**
       * Constructor for SerializationUtils is private
       */
      private SerializationUtils() {
          super();
      }
  
      /**
       * Deep clone an object using serialization.
       * <p>
       * This is many times slower than writing clone methods by hand
       * on all objects in your object graph. However, for complex object
       * graphs, or for those that don't support deep cloning this can
       * be a simple alternative implementation. Of course all the objects
       * must be <code>Serializable</code>.
       * 
       * @param object  the <code>Serializable</code> object to clone
       * @return the cloned object
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static Object clone(Serializable object) {
          return deserialize( serialize(object) );
      }
      
      /**
       * Serializes an object to the specified stream. The stream will
       * be closed once the object is written. This avoids the need for
       * a finally clause, and maybe also exception handling, in the
       * application code.
       *
       * @param obj  the object to serialize to bytes
       * @param outputStream  the stream to write to
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static void serialize(Serializable obj, OutputStream outputStream) {
          ObjectOutputStream out = null;
          try {
              // stream closed in the finally
              out = new ObjectOutputStream(outputStream);
              out.writeObject(obj);
              
          } catch (IOException ex) {
              throw new SerializationException(ex);
          } finally {
              try {
                  if (out != null) {
                      out.close();
                  }
              } catch (IOException ex) {
                  // ignore;
              }
          }
      }
  
      /**
       * Serializes an object to a byte array for storage/serialization.
       *
       * @param obj  the object to serialize to bytes
       * @return a byte[] with the converted Serializable.
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static byte[] serialize(Serializable obj) {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          serialize(obj, baos);
          return baos.toByteArray();
      }
  
      /**
       * Deserializes an object from the specified stream. The stream will
       * be closed once the object is written. This avoids the need for
       * a finally clause, and maybe also exception handling, in the
       * application code.
       *
       * @param objectData  the serialized object.
       * @return the deserialized object
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static Object deserialize(InputStream inputStream) {
          ObjectInputStream in = null;
          try {
              // stream closed in the finally
              in = new ObjectInputStream(inputStream);
              return in.readObject();
              
          } catch (ClassNotFoundException ex) {
              throw new SerializationException(ex);
          } catch (IOException ex) {
              throw new SerializationException(ex);
          } finally {
              try {
                  if (in != null) {
                      in.close();
                  }
              } catch (IOException ex) {
                  // ignore
              }
          }
      }
  
      /**
       * Deserializes a single object from an array of bytes.
       *
       * @param objectData  the serialized object.
       * @return the deserialized object
       * @throws SerializationException (runtime) if the serialization fails
       */
      public static Object deserialize(byte[] objectData) {
          ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
          return deserialize(bais);
      }
      
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/StringUtils.java
  
  Index: StringUtils.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.io.OutputStream;
  import java.io.PrintWriter;
  import java.io.IOException;
  import java.util.NoSuchElementException;
  import java.util.StringTokenizer;
  
  import java.util.Iterator;
  
  /**
   * <p>Common <code>String</code> manipulation routines.</p>
   *
   * <p>Originally from 
   * <a href="http://jakarta.apache.org/turbine/">Turbine</a> and the
   * GenerationJavaCore library.</p>
   *
   * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
   * @author <a href="mailto:bayard@generationjava.com">Bayard</a>
   * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
   * @author <a href="mailto:rand_mcneely@yahoo.com>Rand McNeely</a>
   * @author <a href="mailto:scolebourne@joda.org>Stephen Colebourne</a>
   * @version $Id: StringUtils.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class StringUtils {
  
      /**
       * The size of the buffer to use when working with I/O (4 kB).
       */
      public static int CHAR_BUFFER_SIZE = 4 * 1024;
      
      /**
       * Prevent construction of StringUtils instances
       */
      private StringUtils() {
      }
  
      // Empty
      //--------------------------------------------------------------------------
  
      /**
       * Removes white space from both ends of this string, handling null
       * by returning an empty string.
       *
       * @see java.lang.String#trim()
       * @param str  the string to check
       * @return the trimmed text (never <code>null</code>)
       */
      public static String clean(String str) {
          return (str == null ? "" : str.trim());
      }
  
      /**
       * Removes white space from both ends of this string, handling null
       * by returning null.
       *
       * @see java.lang.String#trim()
       * @param str  the string to check
       * @return the trimmed text (or <code>null</code>)
       */
      public static String trim(String str) {
          return (str == null ? null : str.trim());
      }
  
      /**
       * Checks if a String is non null and is not empty (length > 0).
       *
       * @param str  the string to check
       * @return true if the String is non-null, and not length zero
       */
      public static boolean isNotEmpty(String str) {
          return (str != null && str.length() > 0);
      }
  
      /**
       * Checks if a (trimmed) String is null or empty.
       *
       * @param str  the string to check
       * @return true if the String is null, or length zero once trimmed
       */
      public static boolean isEmpty(String str) {
          return (str == null || str.trim().length() == 0);
      }
  
      // Equals and IndexOf
      //--------------------------------------------------------------------------
  
      /**
       * Compares two Strings, returning true if they are equal.
       * Nulls are handled without exceptions. Two <code>null</code>
       * references are considered equal. Comparison is case sensitive.
       *
       * @param str1  the first string
       * @param str2  the second string
       * @return true if the Strings are equal, case sensitive, or both null
       */
      public static boolean equals(String str1, String str2) {
          return (str1 == null ? str2 == null : str1.equals(str2));
      }
  
      /**
       * Compares two Strings, returning true if they are equal ignoring case.
       * Nulls are handled without exceptions. Two <code>null</code>
       * references are considered equal. Comparison is case insensitive.
       *
       * @param str1  the first string
       * @param str2  the second string
       * @return true if the Strings are equal, case insensitive, or both null
       */
      public static boolean equalsIgnoreCase(String str1, String str2) {
          return (str1 == null ? str2 == null : str1.equalsIgnoreCase(str2));
      }
  
      /**
       * Find the earliest index of any of a set of potential substrings.
       * Null string will return -1.
       * 
       * @param str  the string to check
       * @param searchStrs  the strings to search for
       * @return the earliest index of any of the strings
       */
      public static int indexOfAny(String str, String[] searchStrs) {
          if ((str == null) || (searchStrs == null)) {
              return -1;
          }
          int sz = searchStrs.length;
  
          // String's can't have a MAX_VALUEth index.
          int ret = Integer.MAX_VALUE;
  
          int tmp = 0;
          for (int i = 0; i < sz; i++) {
              tmp = str.indexOf(searchStrs[i]);
              if (tmp == -1) {
                  continue;
              }
  
              if (tmp < ret) {
                  ret = tmp;
              }
          }
  
          return (ret == Integer.MAX_VALUE) ? -1 : ret;
      }
  
      /**
       * Find the latest index of any of a set of potential substrings.
       * Null string will return -1.
       * 
       * @param str  the string to check
       * @param searchStrs  the strings to search for
       * @return the last index of any of the strings
       */
      public static int lastIndexOfAny(String str, String[] searchStrs) {
          if ((str == null) || (searchStrs == null)) {
              return -1;
          }
          int sz = searchStrs.length;
          int ret = -1;
          int tmp = 0;
          for (int i = 0; i < sz; i++) {
              tmp = str.lastIndexOf(searchStrs[i]);
              if (tmp > ret) {
                  ret = tmp;
              }
          }
          return ret;
      }
  
      // Substring
      //--------------------------------------------------------------------------
      
      /**
       * Gets a substring of the specified string avoiding exceptions.
       * A negative start position can be used to start n characters from
       * the end of the string.
       * 
       * @param str  the string to get the substring from
       * @param start  the position to start from,  negative means 
       * count back from the end of the string by this many characters
       * @return substring from start position
       */
      public static String substring(String str, int start) {
          if (str == null) {
              return null;
          }
  
          // handle negatives, which means last n characters
          if (start < 0) {
              start = str.length() + start; // remember start is negative
          }
  
          if (start < 0) {
              start = 0;
          }
          if (start > str.length()) {
              return "";
          }
  
          return str.substring(start);
      }
      
      /**
       * Gets a substring of the specified string avoiding exceptions.
       * A negative start position can be used to start/end n characters
       * from the end of the string.
       * 
       * @param str  the string to get the substring from
       * @param start  the position to start from, negative means 
       * count back from the end of the string by this many characters
       * @param end  the position to end at (exclusive),  negative means 
       * count back from the end of the string by this many characters
       * @return substring from start position to end positon
       */
      public static String substring(String str, int start, int end) {
          if (str == null) {
              return null;
          }
  
          // handle negatives
          if (end < 0) {
              end = str.length() + end; // remember end is negative
          }
          if (start < 0) {
              start = str.length() + start; // remember start is negative
          }
  
          // check length next
          if (end > str.length()) {
              // check this works.
              end = str.length();
          }
  
          // if start is greater than end, return ""
          if (start > end) {
              return "";
          }
  
          if (start < 0) {
              start = 0;
          }
          if (end < 0) {
              end = 0;
          }
  
          return str.substring(start, end);
      }
  
      /**
       * Gets the leftmost n characters of a string. If n characters are not 
       * available, or the string is null, the string will be returned 
       * without an exception.
       *
       * @param str  the string to get the leftmost characters from
       * @param len  the length of the required string
       * @return the leftmost characters
       * @throws IllegalArgumentException if len is less than zero
       */
      public static String left(String str, int len) {
          if (len < 0) {
              throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
          }
          if ((str == null) || (str.length() <= len)) {
              return str;
          } else {
              return str.substring(0, len);
          }
      }
  
      /**
       * Gets the rightmost n characters of a string. If n characters are not 
       * available, or the string is null, the string will be returned 
       * without an exception.
       *
       * @param str  the string to get the rightmost characters from
       * @param len  the length of the required string
       * @return the leftmost characters
       * @throws IllegalArgumentException if len is less than zero
       */
      public static String right(String str, int len) {
          if (len < 0) {
              throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
          }
          if ((str == null) || (str.length() <= len)) {
              return str;
          } else {
              return str.substring(str.length() - len);
          }
      }
  
      /**
       * Gets n characters from the middle of a string. If n characters are 
       * not available, the remainder of the string will be returned 
       * without an exception. If the string is null, null will be returned.
       *
       * @param str  the string to get the characters from
       * @param pos  the position to start from
       * @param len  the length of the required string
       * @return the leftmost characters
       * @throws IndexOutOfBoundsException if pos is out of bounds
       * @throws IllegalArgumentException if len is less than zero
       */
      public static String mid(String str, int pos, int len) {
          if ((pos < 0) ||
              (str != null && pos > str.length())) {
              throw new StringIndexOutOfBoundsException("String index " + pos + " is out of bounds");
          }
          if (len < 0) {
              throw new IllegalArgumentException("Requested String length " + len + " is less than zero");
          }
          if (str == null) {
              return null;
          }
          if (str.length() <= (pos + len)) {
              return str.substring(pos);
          } else {
              return str.substring(pos, pos + len);
          }
      }
  
      // Splitting
      //--------------------------------------------------------------------------
      
      /**
       * Splits the provided text into a list, using whitespace as the separator.
       * The separator is not included in the returned String array.
       *
       * @param str  the string to parse
       * @return an array of parsed Strings 
       */
      public static String[] split(String text) {
          return split(text, null, -1);
      }
  
      /**
       * Splits the provided text into a list, based on a given separator.
       * The separator is not included in the returned String array.
       * A null separator will cause parsing to be on whitespace.
       *
       * @param str  the string to parse
       * @param separator  The separator character. If <code>null</code>, splits
       *  on whitespace.
       * @return an array of parsed Strings 
       */
      public static String[] split(String text, String separator) {
          return split(text, separator, -1);
      }
  
      /**
       * Splits the provided text into a list, based on a given separator.
       * The separator is not included in the returned String array.
       * The maximum number of splits to perfom can be controlled.
       * A null separator will cause parsing to be on whitespace.
       *
       * @param str  the string to parse
       * @param separator  The separator character. If <code>null</code>, splits
       *  on whitespace.
       * @param max  The maximum number of elements to include in the
       *  list.  A zero or negative value implies no limit.
       * @return an array of parsed Strings 
       */
      public static String[] split(String text, String separator, int max) {
          StringTokenizer tok = null;
          if (separator == null) {
              // Null separator means we're using StringTokenizer's default
              // delimiter, which comprises all whitespace characters.
              tok = new StringTokenizer(text);
          } else {
              tok = new StringTokenizer(text, separator);
          }
  
          int listSize = tok.countTokens();
          if (max > 0 && listSize > max) {
              listSize = max;
          }
  
          String[] list = new String[listSize];
          int i = 0;
          while (tok.hasMoreTokens()) {
              if (max > 0 && i == listSize - 1) {
                  // In the situation where we hit the max yet have
                  // tokens left over in our input, the last list
                  // element gets all remaining text.
                  StringBuffer buf = new StringBuffer((int) 1.2 * text.length() * (listSize - i) / listSize);
                  while (tok.hasMoreTokens()) {
                      buf.append(tok.nextToken());
                      if (tok.hasMoreTokens()) {
                          buf.append(separator);
                      }
                  }
                  list[i] = buf.toString();
                  break;
              } else {
                  list[i] = tok.nextToken();
              }
              i++;
          }
          return list;
      }
  
      // Joining
      //--------------------------------------------------------------------------
      
      /**
       * Joins the elements of the provided array into a single string
       * containing the provided list of elements. 
       * No delimiter is added before or after the list.
       * A null separator is the same as a blank String.
       *
       * @param array  the array of values to join together
       * @param separator  the separator character to use
       * @return the joined String
       */
      public static String join(Object[] array, String separator) {
          if (separator == null) {
              separator = "";
          }
          int arraySize = array.length;
          int bufSize = (arraySize == 0 ? 0 : (array[0].toString().length() +
                                   separator.length()) * arraySize);
          StringBuffer buf = new StringBuffer(bufSize);
  
          for (int i = 0; i < arraySize; i++) {
              if (i > 0) {
                  buf.append(separator);
              }
              buf.append(array[i]);
          }
          return buf.toString();
      }
  
      /**
       * Joins the elements of the provided iterator into a single string
       * containing the provided elements.
       * No delimiter is added before or after the list.
       * A null separator is the same as a blank String.
       *
       * @param iterator  the iterator of values to join together
       * @param separator  the separator character to use
       * @return the joined String
       */
      public static String join(Iterator iterator, String separator) {
          if (separator == null) {
              separator = "";
          }
          StringBuffer buf = new StringBuffer(256);  // Java default is 16, probably too small
          while (iterator.hasNext()) {
              buf.append(iterator.next());
              if (iterator.hasNext()) {
                  buf.append(separator);
              }
          }
          return buf.toString();
      }
  
  
  
      // Replacing
      //--------------------------------------------------------------------------
      
      /**
       * Replace a string with another string inside a larger string, once.
       *
       * @see #replace(String text, String repl, String with, int max)
       * @param text  text to search and replace in
       * @param repl  String to search for
       * @param with  String to replace with
       * @return the text with any replacements processed
       */
      public static String replaceOnce(String text, String repl, String with) {
          return replace(text, repl, with, 1);
      }
  
      /**
       * Replace all occurances of a string within another string.
       *
       * @see #replace(String text, String repl, String with, int max)
       * @param text  text to search and replace in
       * @param repl  String to search for
       * @param with  String to replace with
       * @return the text with any replacements processed
       */
      public static String replace(String text, String repl, String with) {
          return replace(text, repl, with, -1);
      }
  
      /**
       * Replace a string with another string inside a larger string,
       * for the first <code>max</code> values of the search string.  A
       * <code>null</code> reference is passed to this method is a
       * no-op.
       *
       * @param text  text to search and replace in
       * @param repl  String to search for
       * @param with  String to replace with
       * @param max  maximum number of values to replace, or
       * <code>-1</code> if no maximum
       * @return the text with any replacements processed
       */
      public static String replace(String text, String repl, String with,
                                   int max) {
          if (text == null) {
              return null;
          }
  
          StringBuffer buf = new StringBuffer(text.length());
          int start = 0, end = 0;
          while ( (end = text.indexOf(repl, start)) != -1 ) {
              buf.append(text.substring(start, end)).append(with);
              start = end + repl.length();
  
              if (--max == 0) {
                  break;
              }
          }
          buf.append(text.substring(start));
          return buf.toString();
      }
  
      /**
       * Overlay a part of a string with another string.
       *
       * @param text String to do overlaying in
       * @param overlay String to overlay
       * @param start int to start overlaying at
       * @param end   int to stop overlaying before
       * @return String with overlayed text
       */
      public static String overlayString(String text, String overlay, int start, int end) {
          return new StringBuffer(start + overlay.length() + text.length() - end + 1)
  			.append(text.substring(0, start))
  			.append(overlay)
  			.append(text.substring(end))
  			.toString();
      }
  
      // Centering
      //--------------------------------------------------------------------------
      
      /**
       * Center a string in a larger string of size n.
       * Uses spaces as the value to buffer the string with..
       *
       * @param str  String to center
       * @param size  int size of new String
       * @return String containing centered String
       */
      public static String center(String str, int size) {
          return center(str, size, " ");
      }
  
      /**
       * Center a string in a larger string of size n.
       * Uses a supplied String as the value to buffer the string with..
       *
       * @param str  String to center
       * @param size  int size of new String
       * @param delim  String to buffer the new String with
       * @return String containing centered String
       */
      public static String center(String str, int size, String delim) {
          int sz = str.length();
          int p = size - sz;
          if (p < 1) {
              return str;
          }
          str = leftPad(str, sz + p / 2, delim);
          str = rightPad(str, size, delim);
          return str;
      }
  
      // Chomping
      //--------------------------------------------------------------------------
      
      /** 
       * Remove the last newline, and everything after it from a String.
       *
       * @param str  String to chomp the newline from
       * @return String without chomped newline
       */
      public static String chomp(String str) {
          return chomp(str, "\n");
      }
      
      /** 
       * Remove the last value of a supplied String, and everything after it 
       * from a String.
       *
       * @param str  String to chomp from
       * @param sep  String to chomp
       * @return String without chomped ending
       */
      public static String chomp(String str, String sep) {
          int idx = str.lastIndexOf(sep);
          if (idx != -1) {
              return str.substring(0,idx);
          } else {
              return str;
          }
      }
      
      /**
       * Remove a newline if and only if it is at the end 
       * of the supplied string.
       * 
       * @param str  String to chomp from
       * @return String without chomped ending
       */
      public static String chompLast(String str) {
          return chompLast(str, "\n");
      }
      
      /**
       * Remove a value if and only if the string ends with that value.
       * 
       * @param str  String to chomp from
       * @param sep  String to chomp
       * @return String without chomped ending
       */
      public static String chompLast(String str, String sep) {
          if (str.length() == 0) {
              return str;
          }
          String sub = str.substring(str.length() - sep.length());
          if (sep.equals(sub)) {
              return str.substring(0, str.length() - sep.length());
          } else {
              return str;
          }
      }
  
      /** 
       * Remove everything and return the last value of a supplied String, and 
       * everything after it from a String.
       *
       * @param str String to chomp from
       * @param sep String to chomp
       * @return String chomped
       */
      public static String getChomp(String str, String sep) {
          int idx = str.lastIndexOf(sep);
          if (idx == str.length() - sep.length()) {
              return sep;
          } else if (idx != -1) {
              return str.substring(idx);
          } else {
              return "";
          }
      }
  
      /** 
       * Remove the first value of a supplied String, and everything before it 
       * from a String.
       *
       * @param str String to chomp from
       * @param sep String to chomp
       * @return String without chomped beginning
       */
      public static String prechomp(String str, String sep) {
          int idx = str.indexOf(sep);
          if (idx != -1) {
              return str.substring(idx + sep.length());
          } else {
              return str;
          }
      }
  
      /** 
       * Remove and return everything before the first value of a 
       * supplied String from another String.
       *
       * @param str String to chomp from
       * @param sep String to chomp
       * @return String prechomped
       */
      public static String getPrechomp(String str, String sep) {
          int idx = str.indexOf(sep);
          if (idx != -1) {
              return str.substring(0, idx + sep.length());
          } else {
              return "";
          }
      }
  
      // Chopping
      //--------------------------------------------------------------------------
      
      /**
       * Remove the last character from a String. If the String 
       * ends in \r\n, then remove both of them.
       *
       * @param str String to chop last character from
       * @return String without last character
       */
      public static String chop(String str) {
          if ("".equals(str)) {
              return "";
          }
          if (str.length() == 1) {
              return "";
          }
          int lastIdx = str.length() - 1;
          String ret = str.substring(0, lastIdx);
          char last = str.charAt(lastIdx);
          if (last == '\n') {
              if (ret.charAt(lastIdx - 1) == '\r') {
                  return ret.substring(0, lastIdx - 1);
              }
          }
          return ret;
      }
  
      /**
       * Remove \n from end of a String if it's there.
       * If a \r precedes it, then remove that too.
       *
       * @param str String to chop a newline from
       * @param String without newline on end
       * @return String without newline
       */
      public static String chopNewline(String str) {
          int lastIdx = str.length()-1;
          char last = str.charAt(lastIdx);
          if(last == '\n') {
              if(str.charAt(lastIdx-1) == '\r') {
                  lastIdx --;
              }
          } else {
              lastIdx++;
          }
          return str.substring(0,lastIdx);
      }
  
  
      // Conversion
      //--------------------------------------------------------------------------
      
      // spec 3.10.6
      /**
       * Escapes any values it finds into their String form.
       * So a tab becomes the characters '\\' and 't'.
       *
       * @param str String to escape values in
       *
       * @return String with escaped values
       */
      // improved with code from  cybertiger@cyberiantiger.org
      // unicode from him, and defaul for < 32's.
      public static String escape(String str) {
          int sz = str.length();
          StringBuffer buffer = new StringBuffer(2*sz);
          for(int i=0; i<sz; i++) {
              char ch = str.charAt(i);
  
              // handle unicode
              if(ch > 0xfff) {
                  buffer.append("\\u"+Integer.toHexString(ch));
              } else 
              if(ch > 0xff) {
                  buffer.append("\\u0"+Integer.toHexString(ch));
              } else 
              if(ch > 0x7f) {
                  buffer.append("\\u00"+Integer.toHexString(ch));
              } else 
              if(ch < 32) {
                  switch(ch) {
                      case '\b' : 
                          buffer.append('\\');
                          buffer.append('b');
                          break;
                      case '\n' : 
                          buffer.append('\\');
                          buffer.append('n');
                          break;
                      case '\t' : 
                          buffer.append('\\');
                          buffer.append('t');
                          break;
                      case '\f' : 
                          buffer.append('\\');
                          buffer.append('f');
                          break;
                      case '\r' : 
                          buffer.append('\\');
                          buffer.append('r');
                          break;
                      default :
                          if( ch > 0xf ) {
                              buffer.append("\\u00"+Integer.toHexString(ch));
                          } else {
                              buffer.append("\\u000"+Integer.toHexString(ch));
                          }
                          break;
                  }
              } else {
                  switch(ch) {
                      case '\'' : 
                          buffer.append('\\');
                          buffer.append('\'');
                          break;
                      case '"' : 
                          buffer.append('\\');
                          buffer.append('"');
                          break;
                      case '\\' : 
                          buffer.append('\\');
                          buffer.append('\\');
                          break;
                      default :
                          buffer.append(ch);
                          break;
                  }
              }
          }
          return buffer.toString();
      }
  
      // Padding
      //--------------------------------------------------------------------------
      
      /**
       * Repeat a string n times to form a new string.
       *
       * @param str  String to repeat
       * @param repeat  int number of times to repeat
       * @return String with repeated string
       */
      public static String repeat(String str, int repeat) {
          StringBuffer buffer = new StringBuffer(repeat * str.length());
          for (int i = 0; i < repeat; i++) {
              buffer.append(str);
          }
          return buffer.toString();
      }
  
      /**
       * Right pad a String with spaces. Pad to a size of n.
       * 
       * @param str  String to repeat
       * @param size  int number of times to repeat
       * @return String with repeated string
       */
      public static String rightPad(String str, int size) {
          return rightPad(str, size, " ");
      }
      
      /**
       * Right pad a String with a specified string. Pad to a size of n.
       *
       * @param str  String to pad out
       * @param size  int size to pad to
       * @param delim  String to pad with
       */
      public static String rightPad(String str, int size, String delim) {
          size = (size - str.length()) / delim.length();
          if (size > 0) {
              str += repeat(delim, size);
          }
          return str;
      }
  
      /**
       * Left pad a String with spaces. Pad to a size of n.
       *
       * @param str  String to pad out
       * @param size  int size to pad to
       */
      public static String leftPad(String str, int size) {
          return leftPad(str, size, " ");
      }
      /**
       * Left pad a String with a specified string. Pad to a size of n.
       *
       * @param str  String to pad out
       * @param size  int size to pad to
       * @param delim  String to pad with
       */
      public static String leftPad(String str, int size, String delim) {
          size = (size - str.length()) / delim.length();
          if (size > 0) {
              str = repeat(delim, size) + str;
          }
          return str;
      }
  
      // Stripping
      //--------------------------------------------------------------------------
      
      /**
       * Remove whitespace from the front and back of a String.
       * 
       * @param str  the string to remove whitespace from
       * @return the stripped string
       */
      public static String strip(String str) {
          return strip(str, null);
      }
      /**
       * Remove a specified String from the front and back of a 
       * String. If Whitespace is wanted to be removed, used the 
       * strip(String) method.
       * 
       * @param str  the string to remove a string from
       * @param delim  the string to remove at start and end
       * @return the stripped string
       */
      public static String strip(String str, String delim) {
          str = stripStart(str, delim);
          return stripEnd(str, delim);
      }
  
      /**
       * Strip whitespace from the front and back of every string
       * in the array.
       * 
       * @param strs  the strings to remove whitespace from
       * @return the stripped strings
       */
      public static String[] stripAll(String[] strs) {
          return stripAll(strs, null);
      }
   
      /**
       * Strip the specified delimiter from the front and back of
       * every String in the array.
       * 
       * @param strs  the strings to remove a string from
       * @param delim  the string to remove at start and end
       * @return the stripped strings
       */
      public static String[] stripAll(String[] strs, String delimiter) {
          if ((strs == null) || (strs.length == 0)) {
              return strs;
          }
          int sz = strs.length;
          String[] newArr = new String[sz];
          for (int i = 0; i < sz; i++) {
              newArr[i] = strip(strs[i], delimiter);
          }
          return newArr;
      }   
  
      /**
       * Strip any of a supplied string (first letter) from the end of a String..
       * If the strip string is null, whitespace is stripped.
       * 
       * @param str  the string to remove characters from
       * @param strip  the string to remove
       * @return the stripped string
       */
      public static String stripEnd(String str, String strip) {
          if (str == null) {
              return null;
          }
          int end = str.length();
   
          if (strip == null) {
              while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
                  end--;
              }
          } else {
              char chr = strip.charAt(0);
              while ((end != 0) && (str.charAt(end - 1) == chr)) {
                  end--;
              }
          }
          return str.substring(0, end);
      }
  
      /**
       * Strip any of a supplied string (first letter) from the start of a String.
       * If the strip string is null, whitespace is stripped.
       * 
       * @param str  the string to remove characters from
       * @param strip  the string to remove
       * @return the stripped string
       */
      public static String stripStart(String str, String strip) {
          if (str == null) {
              return null;
          }
   
          int start = 0;
   
          int sz = str.length();
   
          if (strip == null) {
              while ((start != sz) && Character.isWhitespace(str.charAt(start))) {
                  start++;
              }
          } else {
              char chr = strip.charAt(0);
              while ((start != sz) && (str.charAt(start) == chr)) {
                  start++;
              }
          }
          return str.substring(start);
      }
  
      // Case conversion
      //--------------------------------------------------------------------------
      
      /**
       * Convert a String to upper case, null string returns null.
       * 
       * @param str  the string to uppercase
       * @return the upper cased string
       */
      public static String upperCase(String str) {
          if (str == null) {
              return null;
          }
          return str.toUpperCase();
      }
  
      /**
       * Convert a String to lower case, null string returns null.
       * 
       * @param str  the string to lowercase
       * @return the lower cased string
       */
      public static String lowerCase(String str) {
          if (str == null) {
              return null;
          }
          return str.toLowerCase();
      }
  
      /**
       * Uncapitalise a string. That is, convert the first character into 
       * lower-case. Null is returned as null.
       *
       * @param str  the string to uncapitalise
       * @return uncapitalised string
       */
      public static String uncapitalise(String str) {
          if (str == null) {
              return null;
          }
          if (str.length() == 0) {
              return "";
          }
          return new StringBuffer(str.length())
              .append(Character.toLowerCase(str.charAt(0)))
              .append(str.substring(1))
              .toString();
      }
  
      /**
       * Capitalise a string. That is, convert the first character into 
       * title-case. Null is returned as null.
       *
       * @param str  the string to capitalise
       * @return capitalised string
       */
      public static String capitalise(String str) {
          if (str == null) {
              return null;
          }
          if (str.length() == 0) {
              return "";
          }
          return new StringBuffer(str.length())
              .append(Character.toTitleCase(str.charAt(0)))
              .append(str.substring(1))
              .toString();
      }
  
      /**
       * Swaps the case of String. Properly looks after 
       * making sure the start of words are Titlecase and not 
       * Uppercase. Null is returned as null.
       * 
       * @param str  the string to swap the case of
       * @return the modified string
       */
      public static String swapCase(String str) {
          if (str == null) {
              return null;
          }
          int sz = str.length();
          StringBuffer buffer = new StringBuffer(sz);
  
          boolean whitespace = false;
          char ch = 0;
          char tmp = 0;
  
          for(int i=0; i<sz; i++) {
              ch = str.charAt(i);
              if(Character.isUpperCase(ch)) {
                  tmp = Character.toLowerCase(ch);
              } else
              if(Character.isTitleCase(ch)) {
                  tmp = Character.toLowerCase(ch);
              } else
              if(Character.isLowerCase(ch)) {
                  if(whitespace) {
                      tmp = Character.toTitleCase(ch);
                  } else {
                      tmp = Character.toUpperCase(ch);
                  }
              } else {
                  tmp = ch;
              }
              buffer.append(tmp);
              whitespace = Character.isWhitespace(ch);
          }
          return buffer.toString();
      }
  
  
      /**
       * Capitalise all the words in a string. Uses Character.isWhitespace 
       * as a separator between words. Null will return null.
       *
       * @param str  the string to capitalise
       * @return capitalised string
       */
      public static String capitaliseAllWords(String str) {
          if (str == null) {
              return null;
          }
          int sz = str.length();
          StringBuffer buffer = new StringBuffer(sz);
          boolean space = true;
          for(int i=0; i<sz; i++) {
              char ch = str.charAt(i);
              if(Character.isWhitespace(ch)) {
                  buffer.append(ch);
                  space = true;
              } else
              if(space) {
                  buffer.append(Character.toTitleCase(ch));
                  space = false;
              } else {
                  buffer.append(ch);
              }
          }
          return buffer.toString();
      }
  
      // Nested extraction
      //--------------------------------------------------------------------------
      
      /**
       * Get the String that is nested in between two instances of the 
       * same String.
       *
       * @param str  the string containing nested-string
       * @param tag  the string before and after nested-string
       * @return the string that was nested, or null
       */
      public static String getNestedString(String str, String tag) {
          return getNestedString(str, tag, tag);
      }
      
      /**
       * Get the string that is nested in between two strings.
       *
       * @param str  the string containing nested-string
       * @param open  the string before nested-string
       * @param close  the string after nested-string
       * @return the string that was nested, or null
       */
      public static String getNestedString(String str, String open, String close) {
          if (str == null) {
              return null;
          }
          int start = str.indexOf(open);
          if (start != -1) {
              int end = str.indexOf(close, start + open.length());
              if (end != -1) {
                  return str.substring(start + open.length(), end);
              }
          }
          return null;
      }
  
      /**
       * How many times is the substring in the larger string.
       * Null returns 0.
       * 
       * @param str  the string to check
       * @return the number of occurances, 0 if the string is null
       */
      public static int countMatches(String str, String sub) {
          if (str == null) {
              return 0;
          }
          int count = 0;
          int idx = 0;
          while ((idx = str.indexOf(sub, idx)) != -1) {
              count++;
              idx += sub.length();
          }
          return count;
      }
  
      // Character Tests
      //--------------------------------------------------------------------------
      
      /**
       * Checks if the string contains only unicode letters.
       * Null will return null.
       * 
       * @param str  the string to check
       * @return true if only contains letters, and is non-null
       */
      public static boolean isAlpha(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          for (int i = 0; i < sz; i++) {
              if (Character.isLetter(str.charAt(i)) == false) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * Checks if the string contains only unicode letters and space (' ').
       * Null will return null.
       * 
       * @param str  the string to check
       * @return true if only contains letters and space, and is non-null
       */
      public static boolean isAlphaSpace(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          for (int i = 0; i < sz; i++) {
              if ((Character.isLetter(str.charAt(i)) == false) &&
                  (str.charAt(i) != ' ')) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * Checks if the string contains only unicode letters or digits.
       * Null will return null.
       * 
       * @param str  the string to check
       * @return true if only contains letters or digits, and is non-null
       */
      public static boolean isAlphanumeric(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          for (int i = 0; i < sz; i++) {
              if (Character.isLetterOrDigit(str.charAt(i)) == false) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * Checks if the string contains only unicode letters, digits or space (' ').
       * Null will return null.
       * 
       * @param str  the string to check
       * @return true if only contains letters, digits or space, and is non-null
       */
      public static boolean isAlphanumericSpace(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          for (int i = 0; i < sz; i++) {
              if ((Character.isLetterOrDigit(str.charAt(i)) == false) &&
                  (str.charAt(i) != ' ')) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * Checks if the string contains only unicode digits.
       * Null will return null.
       * 
       * @param str  the string to check
       * @return true if only contains digits, and is non-null
       */
      public static boolean isNumeric(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          for (int i = 0; i < sz; i++) {
              if (Character.isDigit(str.charAt(i)) == false) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * Checks if the string contains only unicode digits or space (' ').
       * Null will return null.
       * 
       * @param str  the string to check
       * @return true if only contains digits or space, and is non-null
       */
      public static boolean isNumericSpace(String str) {
          if (str == null) {
              return false;
          }
          int sz = str.length();
          for (int i = 0; i < sz; i++) {
              if ((Character.isDigit(str.charAt(i)) == false) &&
                  (str.charAt(i) != ' ')) {
                  return false;
              }
          }
          return true;
      }
  
      // Defaults
      //--------------------------------------------------------------------------
      
      /**
       * Return either the passed in String, or if it is null, 
       * then an empty String.
       * 
       * @param str  the string to check
       * @return the passed in string, or blank if it was null
       */
      public static String defaultString(String str) {
          return defaultString(str, "");
      }
  
      /**
       * Return either the passed in String, or if it is null, 
       * then a passed in default String.
       * 
       * @param str  the string to check
       * @param defaultString  the default string to return is str is null
       * @return the passed in string, or the default if it was null
       */
      public static String defaultString(String str, String defaultString) {
          return (str == null) ? defaultString : str;
      }
  
      // Reversing
      //--------------------------------------------------------------------------
  
      /**
       * Reverse a String, null string returns null.
       * 
       * @param str  the string to reverse
       * @return the reversed string
       */
      public static String reverse(String str) {
          if (str == null) {
              return null;
          }
          return new StringBuffer(str).reverse().toString();
      }
  
      /**
       * Reverses a string that is delimited by a specific character.
       * The strings between the delimiters are not reversed.
       * Thus java.lang.String becomes String.lang.java (if the delimiter is '.').
       * 
       * @param str  the string to reverse
       * @param delimiter  the delimiter to use
       * @return the reversed string
       */
      public static String reverseDelimitedString(String str, String delimiter) {
          // could implement manually, but simple way is to reuse other, 
          // probably slower, methods.
          String[] strs = split(str, delimiter);
          reverseArray(strs);
          return join(strs, delimiter);
      }
  
      /**
       * Reverses an array. 
       * TAKEN FROM CollectionsUtils.
       */
      private static void reverseArray(Object[] array) {
          int i = 0;
          int j = array.length - 1;
          Object tmp;
  
          while (j > i) {
              tmp = array[j];
              array[j] = array[i];
              array[i] = tmp;
              j--;
              i++;
          }
      }
  
  
      // Misc
      //--------------------------------------------------------------------------
      
      /**
       * Get the stack trace from a Throwable as a String.
       * <p>
       * This method uses printStackTrace() internally to obtain the stack trace.
       *
       * @see java.lang.Throwable#printStackTrace()
       * @param throwable  the throwable to extract a stack trace from
       * @return the extracted stack trace, or null if an error occurs
       */
      public static String stackTrace(Throwable throwable) {
          String trace = null;
          try {
              // And show the Error Screen.
              ByteArrayOutputStream buf = new ByteArrayOutputStream();
              throwable.printStackTrace( new PrintWriter(buf, true) );
              trace = buf.toString();
              
          } catch (Exception ex) {
              // ignore
          }
          return trace;
      }
  
      /**
       * Find the Levenshtein distance between two strings.
       * This is the number of changes needed to change one string into 
       * another. Where each change is a single character modification.
       *
       * This implemmentation of the levenshtein distance algorithm 
       * is from http://www.merriampark.com/ld.htm
       */
      public static int getLevenshteinDistance(String s, String t) {
          int d[][]; // matrix
          int n; // length of s
          int m; // length of t
          int i; // iterates through s
          int j; // iterates through t
          char s_i; // ith character of s
          char t_j; // jth character of t
          int cost; // cost
  
          // Step 1
          n = s.length ();
          m = t.length ();
          if (n == 0) {
              return m;
          }
          if (m == 0) {
              return n;
          }
          d = new int[n+1][m+1];
  
          // Step 2
          for (i = 0; i <= n; i++) {
              d[i][0] = i;
          }
  
          for (j = 0; j <= m; j++) {
              d[0][j] = j;
          }
  
          // Step 3
          for (i = 1; i <= n; i++) {
              s_i = s.charAt (i - 1);
  
              // Step 4
              for (j = 1; j <= m; j++) {
                  t_j = t.charAt (j - 1);
  
                  // Step 5
                  if (s_i == t_j) {
                      cost = 0;
                  } else {
                      cost = 1;
                  }
  
                  // Step 6
                  d[i][j] = NumberUtils.minimum(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1] + cost);
              }
          }
  
          // Step 7
          return d[n][m];
      }
  
      /**
       * Convert a string from unicode to bytes in a native encoding.
       * The string must be in unicode (as Java always expects this);
       * {@link #convertNativeToUnicode(String, String)} will convert
       * strings in native encodings into unicode.  This method is
       * generally used to create a <code>String</code> for use as
       * output, and is useful when dealing with I18N.
       *
       * @param source String the unicode string to convert
       * @param charset String the name of the charset into which to
       * convert.
       * @return The string given represented in the native encoding
       * specified.
       * @see #convertNativeToUnicode(String, String)
       */
      public static String convertUnicodeToNative(String source, String charset)
              throws IOException {
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          OutputStreamWriter out = new OutputStreamWriter(baos, charset);
          out.write(source);
          out.close();
          return baos.toString();
      }
  
      /**
       * Convert a string from a native encoding to unicode.  This
       * method is generally used to create a <code>String</code> for
       * use as input, and is useful when dealing with I18N.
       *
       * @param input String the input to convert from native encoding
       * to unicode.
       * @param charset String the charset from which to convert.
       * @return The string given represented in unicode rather than the
       * specified native encoding.
       */
      public static String convertNativeToUnicode(String input, String charset)
              throws IOException {
          InputStreamReader in = new InputStreamReader
              (new ByteArrayInputStream(input.getBytes()), charset);
          StringBuffer output = new StringBuffer();
          char[] buf = new char[CHAR_BUFFER_SIZE];
          int count = 0;
          while ((count = in.read(buf, 0, CHAR_BUFFER_SIZE)) > 0)
          {
              output.append(buf, 0, count);
          }
          in.close();
          return output.toString();
      }
      
  // these are not really of use in the Java world. Only if you're a C afficionado
  //    public static String sprintf(String format, Object[] list);
  //    public static Object[] sscanf(String str, String format);
  //    public static String pack(String[] strs, String format);
  //    public static String[] unpack(String str, String format);
  
  }
  
  
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/exception/Nestable.java
  
  Index: Nestable.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.PrintWriter;
  
  /**
   * An interface to be implemented by {@link java.lang.Throwable}
   * extensions which would like to be able to nest root exceptions
   * inside themselves.
   *
   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
   * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @version $Id: Nestable.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public interface Nestable
  {
      /**
       * Returns the reference to the exception or error that caused the
       * exception implementing the <code>Nestable</code> to be thrown.
       */
      public Throwable getCause();
  
      /**
       * Returns the number of nested <code>Throwable</code>s represented by
       * this <code>Nestable</code>, including this <code>Nestable</code>.
       */
      public int getLength();
      
      /**
       * Returns the error message of this and any nested
       * <code>Throwable</code>.
       *
       * @return The error message.
       */
      public String getMessage();
  
      /**
       * Returns the error message of the <code>Throwable</code> in the chain
       * of <code>Throwable</code>s at the specified index, numbererd from 0.
       * If <code>index</code> is negative, the effect is the same as if it
       * were 0. If <code>index</code> is greater than or equal to the length
       * of the chain, the message of the last <code>Throwable</code> in the
       * chain is returned.
       *
       * @param index the index of the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s
       * @return the error message
       */
      public String getMessage(int index);
  
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       *
       * @return the error messages
       */
      public String[] getMessages();
  
      /**
       * Returns the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s at the specified index, numbererd from 0. If
       * <code>index</code> is negative, the effect is the same as if it
       * were 0. If <code>index</code> is greater than or equal to the length
       * of the chain, the last <code>Throwable</code> in the chain is returned.
       *
       * @param index the index of the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s
       * @return the <code>Throwable</code>
       */
      public Throwable getThrowable(int index);
  
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       *
       * @return the <code>Throwable</code>s
       */
      public Throwable[] getThrowables();
  
      /**
       * Returns the index, numbered from 0, of the first occurrence of the
       * specified type in the chain of <code>Throwable</code>s, or -1 if the
       * specified type is not found in the chain. If <code>pos</code> is
       * negative, the effect is the same as if it were 0. If <code>pos</code>
       * is greater than or equal to the length of the chain, the effect is the
       * same as if it were the index of the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(Class type);
  
      /**
       * Returns the index, numbered from 0, of the first <code>Throwable</code>
       * that matches the specified type in the chain of <code>Throwable</code>s
       * with an index greater than or equal to the specified position, or -1 if
       * the type is not found. If <code>pos</code> is negative, the effect is the
       * same as if it were 0. If <code>pos</code> is greater than or equal to the
       * length of the chain, the effect is the same as if it were the index of
       * the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @param pos index, numbered from 0, of the starting position in the chain
       * to be searched
       * 
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type);
      
      /**
       * Prints the stack trace of this exception to the specified print
       * writer.  Includes inforamation from the exception--if
       * any--which caused this exception.
       *
       * @param out <code>PrintWriter</code> to use for output.
       */
      public void printStackTrace(PrintWriter out);
  
      /**
       * Prints the stack trace for this exception only--root cause not
       * included--using the provided writer.  Used by {@link
       * org.apache.commons.lang.exception.NestableDelegate} to write
       * individual stack traces to a buffer.  The implementation of
       * this method should call
       * <code>super.printStackTrace(out);</code> in most cases.
       *
       * @param out The writer to use.
       */
      public void printPartialStackTrace(PrintWriter out);
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/exception/NestableDelegate.java
  
  Index: NestableDelegate.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.OutputStream;
  import java.io.PrintStream;
  import java.io.PrintWriter;
  import java.io.StringWriter;
  import java.io.Writer;
  import java.util.LinkedList;
  import java.util.StringTokenizer;
  
  /**
   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
   * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @version $Id: NestableDelegate.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class NestableDelegate
  {
      /**
       * Constructor error message.
       */
      private static final String MUST_BE_THROWABLE =
          "The Nestable implementation passed to the NestableDelegate(Nestable) "
          + "constructor must extend java.lang.Throwable";
  
      /**
       * Holds the reference to the exception or error that caused
       * this exception to be thrown.
       */
      private Nestable cause = null;
  
      /**
       * @param cause The Nestable implementation to get a stack trace for
       * (<i>must</i> extend {@link java.lang.Throwable}).
       */
      NestableDelegate(Nestable cause) // package
      {
          if (cause instanceof Throwable)
          {
              this.cause = cause;
          }
          else
          {
              throw new IllegalArgumentException(MUST_BE_THROWABLE);
          }
      }
  
      /**
       * Returns the number of <code>Throwable</code>s contained in the
       * <code>Nestable</code> contained by this delegate.
       */
      int getLength() // package
      {
          // Count the number of throwables
          int count = 1;
          String msg = null;
          if(this.cause.getCause() == null)
          {
              return count;
          }
          Throwable t = this.cause.getCause();
          while(t != null)
          {
              ++count;
              if(Nestable.class.isInstance(t))
              {
                  t = ((Nestable) t).getCause();
              }
              else
              {
                  t = null;
              }
          }
          return count;
      }
      
      /**
       * @param baseMsg The base message to use when creating the full
       * message.  Should be generally be called via
       * <code>nestableHelper.getMessage(super.getMessage())</code>,
       * where <code>super</code> is an instance of {@link
       * java.lang.Throwable}.
       * @return The concatenated message for this and all nested
       * exceptions.
       */
      String getMessage(String baseMsg) // package
      {
          StringBuffer msg = new StringBuffer();
          if (baseMsg != null)
          {
              msg.append(baseMsg);
          }
  
          Throwable nestedCause = cause.getCause();
          if (nestedCause != null)
          {
              String causeMsg = nestedCause.getMessage();
              if (causeMsg != null)
              {
                  if (baseMsg != null)
                  {
                      msg.append(": ");
                  }
                  msg.append(causeMsg);
              }
  
          }
          return (msg.length() > 0 ? msg.toString() : null);
      }
  
      String getMessage(int index)
      {
          Throwable t = this.getThrowable(index);
          if(Nestable.class.isInstance(t))
          {
              return ((Nestable) t).getMessage(0);
          }
          else
          {
              return t.getMessage();
          }
      }
      
      Throwable getThrowable(int index)
      {
          Throwable[] throwables = this.getThrowables();
          if(index < 0)
          {
              index = 0;
          }
          if(index == 0)
          {
              return (Throwable) this.cause;
          }
          if(index >= throwables.length)
          {
              index = throwables.length - 1;
          }
          return throwables[index];
      }
      
      Throwable[] getThrowables() // package
      {
          int count = this.getLength();
          // Allocate an array to hold the messages
          Throwable[] throwables = new Throwable[count];
          count = 0;
          if(cause != null)
          {
              throwables[count++] = (Throwable) this.cause;
              Throwable t = this.cause.getCause();
              while(t != null)
              {
                  throwables[count++] = t;
                  if(Nestable.class.isInstance(t))
                  {
                      t = ((Nestable) t).getCause();
                  }
                  else
                  {
                      t = null;
                  }
              }
          }
          return throwables;
      }
  
      String[] getMessages() // package
      {
          Throwable throwables[] = this.getThrowables();
          String[] msgs = new String[throwables.length];
          for(int i = 0; i < throwables.length; i++)
          {
              msgs[i] = (Nestable.class.isInstance(throwables[i]) ? ((Nestable) throwables[i]).getMessage(0) : throwables[i].getMessage());
          }
          return msgs;
      }
  
      int indexOfThrowable(int pos, Class type) // package
      {
          pos = (pos < 0) ? 0 : pos;
          Throwable throwables[] = this.getThrowables();
          pos = (pos >= throwables.length) ? throwables.length - 1 : pos;
          for(int i = pos; i < throwables.length; i++)
          {
              if(throwables[i].getClass().equals(type))
              {
                  return i;
              }
          }
          return -1;
      }
      
      /**
       * Prints the stack trace of this exception the the standar error
       * stream.
       */
      public void printStackTrace()
      {
          synchronized (System.err)
          {
              printStackTrace(System.err);
          }
      }
  
      /**
       * Prints the stack trace of this exception to the specified print stream.
       *
       * @param out <code>PrintStream</code> to use for output.
       */
      public void printStackTrace(PrintStream out)
      {
          synchronized (out)
          {
              PrintWriter pw = new PrintWriter(out, false);
              printStackTrace(pw);
              // Flush the PrintWriter before it's GC'ed.
              pw.flush();
          }
      }
  
      /**
       * Prints the stack trace of this exception to the specified print writer.
       *
       * @param out <code>PrintWriter</code> to use for output.
       */
      public void printStackTrace(PrintWriter out)
      {
          synchronized (out)
          {
              String[] st = decompose((Throwable) cause);
              Throwable nestedCause = cause.getCause();
              if (nestedCause != null)
              {
                  if (nestedCause instanceof Nestable)
                  {
                      // Recurse until a non-Nestable is encountered.
                      ((Nestable) nestedCause).printStackTrace(out);
                  }
                  else
                  {
                      String[] nst = decompose(nestedCause);
                      for (int i = 0; i < nst.length; i++)
                      {
                          out.println(nst[i]);
                      }
                  }
                  out.print("rethrown as ");
              }
  
              // Output desired frames from stack trace.
              for (int i = 0; i < st.length; i++)
              {
                  out.println(st[i]);
              }
          }
      }
  
      /**
       * Captures the stack trace associated with a <code>Throwable</code>
       * object, decomposing it into a list of stack frames.
       *
       * @param t The <code>Throwable</code>.
       * @return  An array of strings describing each stack frame.
       */
      private String[] decompose(Throwable t)
      {
          StringWriter sw = new StringWriter();
          PrintWriter pw = new PrintWriter(sw, true);
  
          // Avoid infinite loop between decompose() and printStackTrace().
          if (t instanceof Nestable)
          {
              ((Nestable) t).printPartialStackTrace(pw);
          }
          else
          {
              t.printStackTrace(pw);
          }
  
          String linebreak = System.getProperty("line.separator");
          StringTokenizer st = new StringTokenizer(sw.getBuffer().toString(),
                                                   linebreak);
          LinkedList list = new LinkedList();
          while (st.hasMoreTokens())
          {
              list.add(st.nextToken());
          }
          return (String []) list.toArray(new String[] {});
      }
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/exception/NestableException.java
  
  Index: NestableException.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.OutputStream;
  import java.io.PrintStream;
  import java.io.PrintWriter;
  import java.io.StringWriter;
  import java.io.Writer;
  import java.util.LinkedList;
  import java.util.StringTokenizer;
  
  /**
   * The base class of all exceptions which can contain other exceptions.
   *
   * It is intended to ease the debugging by carrying on the information
   * about the exception which was caught and provoked throwing the
   * current exception. Catching and rethrowing may occur multiple
   * times, and provided that all exceptions except the first one
   * are descendands of <code>NestedException</code>, when the
   * exception is finally printed out using any of the <code>
   * printStackTrace()</code> methods, the stacktrace will contain
   * the information about all exceptions thrown and caught on
   * the way.
   * <p> Running the following program
   * <p><blockquote><pre>
   *  1 import org.apache.commons.NestedException;
   *  2
   *  3 public class Test {
   *  4     public static void main( String[] args ) {
   *  5         try {
   *  6             a();
   *  7         } catch(Exception e) {
   *  8             e.printStackTrace();
   *  9         }
   * 10      }
   * 11
   * 12      public static void a() throws Exception {
   * 13          try {
   * 14              b();
   * 15          } catch(Exception e) {
   * 16              throw new NestedException("foo", e);
   * 17          }
   * 18      }
   * 19
   * 20      public static void b() throws Exception {
   * 21          try {
   * 22              c();
   * 23          } catch(Exception e) {
   * 24              throw new NestedException("bar", e);
   * 25          }
   * 26      }
   * 27
   * 28      public static void c() throws Exception {
   * 29          throw new Exception("baz");
   * 30      }
   * 31 }
   * </pre></blockquote>
   * <p>Yields the following stacktrace:
   * <p><blockquote><pre>
   * java.lang.Exception: baz: bar: foo
   *    at Test.c(Test.java:29)
   *    at Test.b(Test.java:22)
   * rethrown as NestedException: bar
   *    at Test.b(Test.java:24)
   *    at Test.a(Test.java:14)
   * rethrown as NestedException: foo
   *    at Test.a(Test.java:16)
   *    at Test.main(Test.java:6)
   * </pre></blockquote><br>
   *
   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
   * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @version $Id: NestableException.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class NestableException extends Exception implements Nestable
  {
      /**
       * The helper instance which contains much of the code which we
       * delegate to.
       */
      protected NestableDelegate delegate = new NestableDelegate(this);
  
      /**
       * Holds the reference to the exception or error that caused
       * this exception to be thrown.
       */
      private Throwable cause = null;
  
      /**
       * Constructs a new <code>NestableException</code> without specified
       * detail message.
       */
      public NestableException()
      {
          super();
      }
  
      /**
       * Constructs a new <code>NestableException</code> with specified
       * detail message.
       *
       * @param msg The error message.
       */
      public NestableException(String msg)
      {
          super(msg);
      }
  
      /**
       * Constructs a new <code>NestableException</code> with specified
       * nested <code>Throwable</code>.
       *
       * @param nested The exception or error that caused this exception
       *               to be thrown.
       */
      public NestableException(Throwable cause)
      {
          super();
          this.cause = cause;
      }
  
      /**
       * Constructs a new <code>NestableException</code> with specified
       * detail message and nested <code>Throwable</code>.
       *
       * @param msg    The error message.
       * @param nested The exception or error that caused this exception
       *               to be thrown.
       */
      public NestableException(String msg, Throwable cause)
      {
          super(msg);
          this.cause = cause;
      }
  
      /**
       * @see org.apache.commons.lang.exception.Nestable#getCause()
       */
      public Throwable getCause()
      {
          return cause;
      }
  
      /**
       * Returns the number of nested <code>Throwable</code>s represented by
       * this <code>Nestable</code>, including this <code>Nestable</code>.
       */
      public int getLength()
      {
          return delegate.getLength();
      }
      
      /**
       * @see org.apache.commons.lang.exception.Nestable#getMessage()
       */
      public String getMessage()
      {
          StringBuffer msg = new StringBuffer();
          String ourMsg = super.getMessage();
          if (ourMsg != null)
          {
              msg.append(ourMsg);
          }
          if (cause != null)
          {
              String causeMsg = cause.getMessage();
              if (causeMsg != null)
              {
                  if (ourMsg != null)
                  {
                      msg.append(": ");
                  }
                  msg.append(causeMsg);
              }
  
          }
          return (msg.length() > 0 ? msg.toString() : null);
      }
  
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       */
      public String[] getMessages()
      {
          return delegate.getMessages();
      }
      
      public Throwable getThrowable(int index)
      {
          return delegate.getThrowable(index);
      }
      
      public Throwable[] getThrowables()
      {
          return delegate.getThrowables();
      }
      
      public String getMessage(int index)
      {
          if(index == 0)
          {
              return super.getMessage();
          }
          else
          {
              return delegate.getMessage(index);
          }
      }
      
      /**
       * Returns the index, numbered from 0, of the first occurrence of the
       * specified type in the chain of <code>Throwable</code>s, or -1 if the
       * specified type is not found in the chain. If <code>pos</code> is
       * negative, the effect is the same as if it were 0. If <code>pos</code>
       * is greater than or equal to the length of the chain, the effect is the
       * same as if it were the index of the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(Class type)
      {
          return delegate.indexOfThrowable(0, type);
      }
  
      /**
       * Returns the index, numbered from 0, of the first <code>Throwable</code>
       * that matches the specified type in the chain of <code>Throwable</code>s
       * with an index greater than or equal to the specified position, or -1 if
       * the type is not found. If <code>pos</code> is negative, the effect is the
       * same as if it were 0. If <code>pos</code> is greater than or equal to the
       * length of the chain, the effect is the same as if it were the index of
       * the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @param pos index, numbered from 0, of the starting position in the chain
       * to be searched
       * 
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type)
      {
          return delegate.indexOfThrowable(pos, type);
      }
      
      /**
       * Prints the stack trace of this exception the the standar error
       * stream.
       */
      public void printStackTrace()
      {
          delegate.printStackTrace();
      }
  
      /**
       * Prints the stack trace of this exception to the specified print stream.
       *
       * @param out <code>PrintStream</code> to use for output.
       */
      public void printStackTrace(PrintStream out)
      {
          delegate.printStackTrace(out);
      }
  
      /**
       * @see org.apache.commons.lang.exception.Nestable#printStackTrace(PrintWriter out)
       */
      public void printStackTrace(PrintWriter out)
      {
          delegate.printStackTrace(out);
      }
  
      /**
       * @see org.apache.commons.lang.exception.Nestable#printPartialStackTrace(PrintWriter out)
       */
      public final void printPartialStackTrace(PrintWriter out)
      {
          super.printStackTrace(out);
      }
      
  }
  
  
  
  1.1                  jakarta-commons/lang/src/java/org/apache/commons/lang/exception/NestableRuntimeException.java
  
  Index: NestableRuntimeException.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.OutputStream;
  import java.io.PrintStream;
  import java.io.PrintWriter;
  import java.io.StringWriter;
  import java.io.Writer;
  import java.util.LinkedList;
  import java.util.StringTokenizer;
  
  /**
   * The base class of all runtime exceptions which can contain other
   * exceptions.
   *
   * @see org.apache.commons.lang.exception.NestableException
   * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
   * @author <a href="mailto:knielsen@apache.org">Kasper Nielsen</a>
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @version $Id: NestableRuntimeException.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class NestableRuntimeException extends RuntimeException
      implements Nestable
  {
      /**
       * The helper instance which contains much of the code which we
       * delegate to.
       */
      protected NestableDelegate delegate = new NestableDelegate(this);
  
      /**
       * Holds the reference to the exception or error that caused
       * this exception to be thrown.
       */
      private Throwable cause = null;
  
      /**
       * Constructs a new <code>NestableRuntimeException</code> without specified
       * detail message.
       */
      public NestableRuntimeException()
      {
          super();
      }
  
      /**
       * Constructs a new <code>NestableRuntimeException</code> with specified
       * detail message.
       *
       * @param msg The error message.
       */
      public NestableRuntimeException(String msg)
      {
          super(msg);
      }
  
      /**
       * Constructs a new <code>NestableRuntimeException</code> with specified
       * nested <code>Throwable</code>.
       *
       * @param nested The exception or error that caused this exception
       *               to be thrown.
       */
      public NestableRuntimeException(Throwable cause)
      {
          super();
          this.cause = cause;
      }
  
      /**
       * Constructs a new <code>NestableRuntimeException</code> with specified
       * detail message and nested <code>Throwable</code>.
       *
       * @param msg    The error message.
       * @param nested The exception or error that caused this exception
       *               to be thrown.
       */
      public NestableRuntimeException(String msg, Throwable cause)
      {
          super(msg);
          this.cause = cause;
      }
  
      /**
       * @see org.apache.commons.lang.exception.Nestable#getCause()
       */
      public Throwable getCause()
      {
          return cause;
      }
  
      /**
       * Returns the number of nested <code>Throwable</code>s represented by
       * this <code>Nestable</code>, including this <code>Nestable</code>.
       */
      public int getLength()
      {
          return delegate.getLength();
      }
      
      /**
       * @see org.apache.commons.lang.exception.Nestable#getMessage()
       */
      public String getMessage()
      {
          StringBuffer msg = new StringBuffer();
          String ourMsg = super.getMessage();
          if (ourMsg != null)
          {
              msg.append(ourMsg);
          }
          if (cause != null)
          {
              String causeMsg = cause.getMessage();
              if (causeMsg != null)
              {
                  if (ourMsg != null)
                  {
                      msg.append(": ");
                  }
                  msg.append(causeMsg);
              }
  
          }
          return (msg.length() > 0 ? msg.toString() : null);
      }
  
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       */
      public String[] getMessages()
      {
          return delegate.getMessages();
      }
      
      public Throwable getThrowable(int index)
      {
          return delegate.getThrowable(index);
      }
      
      public Throwable[] getThrowables()
      {
          return delegate.getThrowables();
      }
      
      public String getMessage(int index)
      {
          if(index == 0)
          {
              return super.getMessage();
          }
          else
          {
              return delegate.getMessage(index);
          }
      }
      
      /**
       * Returns the index, numbered from 0, of the first occurrence of the
       * specified type in the chain of <code>Throwable</code>s, or -1 if the
       * specified type is not found in the chain. If <code>pos</code> is
       * negative, the effect is the same as if it were 0. If <code>pos</code>
       * is greater than or equal to the length of the chain, the effect is the
       * same as if it were the index of the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(Class type)
      {
          return delegate.indexOfThrowable(0, type);
      }
  
      /**
       * Returns the index, numbered from 0, of the first <code>Throwable</code>
       * that matches the specified type in the chain of <code>Throwable</code>s
       * with an index greater than or equal to the specified position, or -1 if
       * the type is not found. If <code>pos</code> is negative, the effect is the
       * same as if it were 0. If <code>pos</code> is greater than or equal to the
       * length of the chain, the effect is the same as if it were the index of
       * the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @param pos index, numbered from 0, of the starting position in the chain
       * to be searched
       * 
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type)
      {
          return delegate.indexOfThrowable(pos, type);
      }
      
      /**
       * Prints the stack trace of this exception the the standar error
       * stream.
       */
      public void printStackTrace()
      {
          delegate.printStackTrace();
      }
  
      /**
       * Prints the stack trace of this exception to the specified print stream.
       *
       * @param out <code>PrintStream</code> to use for output.
       */
      public void printStackTrace(PrintStream out)
      {
          delegate.printStackTrace(out);
      }
  
      /**
       * @see org.apache.commons.lang.exception.Nestable#printStackTrace(PrintWriter out)
       */
      public void printStackTrace(PrintWriter out)
      {
          delegate.printStackTrace(out);
      }
  
      /**
       * @see org.apache.commons.lang.exception.Nestable#printPartialStackTrace(PrintWriter out)
       */
      public final void printPartialStackTrace(PrintWriter out)
      {
          super.printStackTrace(out);
      }
      
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/CharSetUtilsTest.java
  
  Index: CharSetUtilsTest.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.Arrays;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  /**
   * Unit tests {@link org.apache.commons.lang.CharSetUtils}.
   *
   * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: CharSetUtilsTest.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class CharSetUtilsTest extends TestCase
  {
      public CharSetUtilsTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(CharSetUtilsTest.class);
      	suite.setName("CharSetUtils Tests");
          return suite;
      }
  
      protected void setUp() throws Exception {
          super.setUp();
      }
  
      protected void tearDown() throws Exception {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
  
      public void testSqueeze()
      {
          assertEquals("squeeze(String,String[]) failed",
                       "helo", CharSetUtils.squeeze("hello", new String[] {"el"}));
          assertEquals("squeeze(String,String[]) failed",
                       "", CharSetUtils.squeeze("", new String[] {"el"}));
          assertEquals("squeeze(String,String[]) failed",
                       "hello", CharSetUtils.squeeze("hello", new String[] {"e"}));
          assertEquals("squeeze(String,String[]) failed",
                       "fofof", CharSetUtils.squeeze("fooffooff", new String[] {"of"}));
          assertEquals("squeeze(String,String[]) failed",
                       "fof", CharSetUtils.squeeze("fooooff", new String[] {"fo"}));
      }
  
      public void testCount()
      {
          assertEquals("count(String,String[]) failed",
                       3, CharSetUtils.count("hello", new String[] {"el"}));
          assertEquals("count(String,String[]) failed",
                       0, CharSetUtils.count("", new String[] {"el"}));
          assertEquals("count(String,String[]) failed",
                       0, CharSetUtils.count("hello", new String[] {"x"}));
          assertEquals("count(String,String[]) failed",
                       2, CharSetUtils.count("hello", new String[] {"e-i"}));
          assertEquals("count(String,String[]) failed",
                       5, CharSetUtils.count("hello", new String[] {"a-z"}));
          assertEquals("count(String,String[]) failed",
                       0, CharSetUtils.count("hello", new String[] {""}));
      }
  
      public void testDelete()
      {
          assertEquals("delete(String,String[]) failed",
                       "ho", CharSetUtils.delete("hello", new String[] {"el"}));
          assertEquals("delete(String,String[]) failed",
                       "", CharSetUtils.delete("hello", new String[] {"elho"}));
          assertEquals("delete(String,String[]) failed",
                       "hello", CharSetUtils.delete("hello", new String[] {""}));
          assertEquals("delete(String,String[]) failed",
                       "", CharSetUtils.delete("hello", new String[] {"a-z"}));
          assertEquals("delete(String,String[]) failed",
                       "heo", CharSetUtils.delete("hello", new String[] {"l"}));
      }
  }
  
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/LangTestSuite.java
  
  Index: LangTestSuite.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  /**
   * Test suite for the Lang package.
   *
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: LangTestSuite.java,v 1.1 2002/07/19 03:35:54 bayard Exp $
   */
  public class LangTestSuite extends TestCase {
      
      /**
       * Construct a new instance.
       */
      public LangTestSuite(String name) {
          super(name);
      }
  
      /**
       * Command-line interface.
       */
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      /**
       * Get the suite of tests
       */
      public static Test suite() {
          TestSuite suite = new TestSuite();
          suite.setName("Commons-Lang Tests");
          suite.addTest(CharSetUtilsTest.suite());
          suite.addTest(NumberRangeTest.suite());
          suite.addTest(NumberUtilsTest.suite());
          suite.addTest(ObjectUtilsTest.suite());
          suite.addTest(RandomStringUtilsTest.suite());
          suite.addTest(SerializationUtilsTest.suite());
          suite.addTest(StringUtilsTest.suite());
          suite.addTest(StringUtilsTrimEmptyTest.suite());
          suite.addTest(StringUtilsSubstringTest.suite());
          suite.addTest(StringUtilsEqualsIndexOfTest.suite());
          suite.addTest(StringUtilsIsTest.suite());
          return suite;
      }
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/NumberRangeTest.java
  
  Index: NumberRangeTest.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  
  
  /**
   * Test cases for the {@link NumberRange} class.
   *
   * @author <a href="mailto:chrise@esha.com">Christopher Elkins</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/19 03:35:55 $
   */
  
  public final class NumberRangeTest extends TestCase {
  
  
      private NumberRange tenToTwenty;
      private Number five;
      private Number ten;
      private Number fifteen;
      private Number twenty;
      private Number twentyFive;
  
  
      public NumberRangeTest(String name) {
          super(name);
      }
  
  
      public void setUp() {
          five       = new Integer(5);
          ten        = new Integer(10);
          fifteen    = new Integer(15);
          twenty     = new Integer(20);
          twentyFive = new Integer(25);
  
          tenToTwenty = new NumberRange(ten, twenty);
      }
  
  
      public static Test suite() {
          TestSuite suite = new TestSuite(NumberRangeTest.class);
          suite.setName("NumberRange Tests");
          return suite;
      }
  
  
      public void testEquals() {
          boolean expected = false;
          boolean result = tenToTwenty.equals(new NumberRange(five, ten));
          assertEquals(expected, result);
  
          expected = true;
          result = tenToTwenty.equals(new NumberRange(ten, twenty));
          assertEquals(expected, result);
  
          expected = false;
          result = tenToTwenty.equals(new NumberRange(ten, fifteen));
          assertEquals(expected, result);
  
          expected = false;
          result = tenToTwenty.equals(new NumberRange(fifteen, twenty));
          assertEquals(expected, result);
      }
  
  
      public void testIncludesNumber() {
          boolean expected = false;
          boolean result = tenToTwenty.includesNumber(five);
          assertEquals(expected, result);
  
          expected = true;
          result = tenToTwenty.includesNumber(ten);
          assertEquals(expected, result);
  
          expected = true;
          result = tenToTwenty.includesNumber(fifteen);
          assertEquals(expected, result);
  
          expected = true;
          result = tenToTwenty.includesNumber(twenty);
          assertEquals(expected, result);
  
          expected = false;
          result = tenToTwenty.includesNumber(twentyFive);
          assertEquals(expected, result);
      }
  
  
      public void testIncludesRange() {
          boolean expected = false;
          boolean result = tenToTwenty.includesRange(new NumberRange(five, ten));
          assertEquals(expected, result);
  
          expected = false;
          result = tenToTwenty.includesRange(new NumberRange(five, fifteen));
          assertEquals(expected, result);
  
          expected = true;
          result = tenToTwenty.includesRange(new NumberRange(ten, fifteen));
          assertEquals(expected, result);
  
          expected = true;
          result = tenToTwenty.includesRange(new NumberRange(ten, twenty));
          assertEquals(expected, result);
  
          expected = true;
          result = tenToTwenty.includesRange(new NumberRange(fifteen, twenty));
          assertEquals(expected, result);
  
          expected = false;
          result = 
              tenToTwenty.includesRange(new NumberRange(fifteen, twentyFive));
          assertEquals(expected, result);
  
          expected = false;
          result = 
              tenToTwenty.includesRange(new NumberRange(twenty, twentyFive));
          assertEquals(expected, result);
      }
  
  
      public void testToString() {
          String expected = "10-20";
          String result = tenToTwenty.toString();
          assertEquals(expected, result);
      }
  
  
  }
  
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/NumberUtilsTest.java
  
  Index: NumberUtilsTest.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.lang.reflect.Method;
  import java.math.BigDecimal;
  import java.math.BigInteger;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  /**
   * Unit tests {@link org.apache.commons.lang.NumberUtils}.
   *
   * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: NumberUtilsTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class NumberUtilsTest extends TestCase {
  
      public NumberUtilsTest(String name) {
          super(name);
      }
  
      public static Test suite() {
          TestSuite suite = new TestSuite(NumberUtilsTest.class);
          suite.setName("NumberUtils Tests");
          return suite;
      }
  
      //---------------------------------------------------------------------
  
      /**
       * Test for int stringToInt(String)
       */
      public void testStringToIntString() {
          assertTrue("stringToInt(String) 1 failed", NumberUtils.stringToInt("12345") == 12345);
          assertTrue("stringToInt(String) 2 failed", NumberUtils.stringToInt("abc") == 0);
      }
  
      /**
       * Test for int stringToInt(String, int)
       */
      public void testStringToIntStringI() {
          assertTrue("stringToInt(String,int) 1 failed", NumberUtils.stringToInt("12345", 5) == 12345);
          assertTrue("stringToInt(String,int) 2 failed", NumberUtils.stringToInt("1234.5", 5) == 5);
      }
  
      public void testCreateNumber() {
          //a lot of things can go wrong
          assertEquals("createNumber(String) 1 failed", new Float("1234.5"), NumberUtils.createNumber("1234.5"));
          assertEquals("createNumber(String) 2 failed", new Integer("12345"), NumberUtils.createNumber("12345"));
          assertEquals("createNumber(String) 3 failed", new Double("1234.5"), NumberUtils.createNumber("1234.5D"));
          assertEquals("createNumber(String) 4 failed", new Float("1234.5"), NumberUtils.createNumber("1234.5F"));
          assertEquals("createNumber(String) 5 failed", new Long(Integer.MAX_VALUE + 1L), NumberUtils.createNumber("" + (Integer.MAX_VALUE + 1L)));
          assertEquals("createNumber(String) 6 failed", new Long(12345), NumberUtils.createNumber("12345L"));
          assertEquals("createNumber(String) 7 failed", new Float("-1234.5"), NumberUtils.createNumber("-1234.5"));
          assertEquals("createNumber(String) 8 failed", new Integer("-12345"), NumberUtils.createNumber("-12345"));
          assertTrue("createNumber(String) 9 failed", 0xFADE == NumberUtils.createNumber("0xFADE").intValue());
          assertTrue("createNumber(String) 10 failed", -0xFADE == NumberUtils.createNumber("-0xFADE").intValue());
          assertEquals("createNumber(String) 11 failed", new Double("1.1E200"), NumberUtils.createNumber("1.1E200"));
          assertEquals("createNumber(String) 12 failed", new Float("1.1E20"), NumberUtils.createNumber("1.1E20"));
          assertEquals("createNumber(String) 13 failed", new Double("-1.1E200"), NumberUtils.createNumber("-1.1E200"));
          assertEquals("createNumber(String) 14 failed", new Double("1.1E-200"), NumberUtils.createNumber("1.1E-200"));
          assertEquals("createNumber(String) 15 failed", new BigDecimal("1.1E-700"), NumberUtils.createNumber("1.1E-700F"));
          assertEquals(
              "createNumber(String) 16 failed",
              new Long("10" + Integer.MAX_VALUE),
              NumberUtils.createNumber("10" + Integer.MAX_VALUE + "L"));
          assertEquals(
              "createNumber(String) 17 failed",
              new Long("10" + Integer.MAX_VALUE),
              NumberUtils.createNumber("10" + Integer.MAX_VALUE));
          assertEquals(
              "createNumber(String) 18 failed",
              new BigInteger("10" + Long.MAX_VALUE),
              NumberUtils.createNumber("10" + Long.MAX_VALUE));
  
      }
  
      public void testCreateFloat() {
          assertEquals("createFloat(String) failed", new Float("1234.5"), NumberUtils.createFloat("1234.5"));
      }
  
      public void testCreateDouble() {
          assertEquals("createDouble(String) failed", new Double("1234.5"), NumberUtils.createDouble("1234.5"));
      }
  
      public void testCreateInteger() {
          assertEquals("createInteger(String) failed", new Integer("12345"), NumberUtils.createInteger("12345"));
      }
  
      public void testCreateLong() {
          assertEquals("createInteger(String) failed", new Long("12345"), NumberUtils.createLong("12345"));
      }
  
      public void testCreateBigInteger() {
          assertEquals("createBigInteger(String) failed", new BigInteger("12345"), NumberUtils.createBigInteger("12345"));
      }
  
      public void testCreateBigDecimal() {
          assertEquals("createBigDecimal(String) failed", new BigDecimal("1234.5"), NumberUtils.createBigDecimal("1234.5"));
      }
  
      public void testMinimum() {
          assertEquals("minimum(int,int,int) 1 failed", 12345, NumberUtils.minimum(12345, 12345 + 1, 12345 + 2));
          assertEquals("minimum(int,int,int) 2 failed", 12345, NumberUtils.minimum(12345 + 1, 12345, 12345 + 2));
          assertEquals("minimum(int,int,int) 3 failed", 12345, NumberUtils.minimum(12345 + 1, 12345 + 2, 12345));
          assertEquals("minimum(int,int,int) 4 failed", 12345, NumberUtils.minimum(12345 + 1, 12345, 12345));
          assertEquals("minimum(int,int,int) 5 failed", 12345, NumberUtils.minimum(12345, 12345, 12345));
  
      }
  
      public void testMaximum() {
          assertEquals("maximum(int,int,int) 1 failed", 12345, NumberUtils.maximum(12345, 12345 - 1, 12345 - 2));
          assertEquals("maximum(int,int,int) 2 failed", 12345, NumberUtils.maximum(12345 - 1, 12345, 12345 - 2));
          assertEquals("maximum(int,int,int) 3 failed", 12345, NumberUtils.maximum(12345 - 1, 12345 - 2, 12345));
          assertEquals("maximum(int,int,int) 4 failed", 12345, NumberUtils.maximum(12345 - 1, 12345, 12345));
          assertEquals("maximum(int,int,int) 5 failed", 12345, NumberUtils.maximum(12345, 12345, 12345));
  
      }
  
      public void testIsDigits() {
          assertEquals("isDigits(null) failed", false, NumberUtils.isDigits(null));
          assertEquals("isDigits('') failed", false, NumberUtils.isDigits(""));
          assertEquals("isDigits(String) failed", true, NumberUtils.isDigits("12345"));
          assertEquals("isDigits(String) neg 1 failed", false, NumberUtils.isDigits("1234.5"));
          assertEquals("isDigits(String) neg 3 failed", false, NumberUtils.isDigits("1ab"));
          assertEquals("isDigits(String) neg 4 failed", false, NumberUtils.isDigits("abc"));
      }
      
      /**
       * Tests isNumber(String) and tests that createNumber(String) returns
       * a valid number iff isNumber(String) returns false.
       */
      public void testIsNumber() {
          String val = "12345";
          assertTrue("isNumber(String) 1 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 1 failed", checkCreateNumber(val));
          val = "1234.5";
          assertTrue("isNumber(String) 2 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 2 failed", checkCreateNumber(val));
          val = ".12345";
          assertTrue("isNumber(String) 3 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 3 failed", checkCreateNumber(val));
          val = "1234E5";
          assertTrue("isNumber(String) 4 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 4 failed", checkCreateNumber(val));
          val = "1234E+5";
          assertTrue("isNumber(String) 5 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 5 failed", checkCreateNumber(val));
          val = "1234E-5";
          assertTrue("isNumber(String) 6 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 6 failed", checkCreateNumber(val));
          val = "123.4E5";
          assertTrue("isNumber(String) 7 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 7 failed", checkCreateNumber(val));
          val = "-1234";
          assertTrue("isNumber(String) 8 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 8 failed", checkCreateNumber(val));
          val = "-1234.5";
          assertTrue("isNumber(String) 9 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 9 failed", checkCreateNumber(val));
          val = "-.12345";
          assertTrue("isNumber(String) 10 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 10 failed", checkCreateNumber(val));
          val = "-1234E5";
          assertTrue("isNumber(String) 11 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 11 failed", checkCreateNumber(val));
          val = "0";
          assertTrue("isNumber(String) 12 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 12 failed", checkCreateNumber(val));
          val = "-0";
          assertTrue("isNumber(String) 13 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 13 failed", checkCreateNumber(val));
          val = "01234";
          assertTrue("isNumber(String) 14 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 14 failed", checkCreateNumber(val));
          val = "-01234";
          assertTrue("isNumber(String) 15 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 15 failed", checkCreateNumber(val));
          val = "0xABC123";
          assertTrue("isNumber(String) 16 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 16 failed", checkCreateNumber(val));
          val = "0x0";
          assertTrue("isNumber(String) 17 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 17 failed", checkCreateNumber(val));
          val = "123.4E21D";
          assertTrue("isNumber(String) 19 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 19 failed", checkCreateNumber(val));
          val = "-221.23F";
          assertTrue("isNumber(String) 20 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 20 failed", checkCreateNumber(val));
          val = "22338L";
          assertTrue("isNumber(String) 21 failed", NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 21 failed", checkCreateNumber(val));
          val = null;
          assertTrue("isNumber(String) 1 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 1 Neg failed", !checkCreateNumber(val));
          val = "";
          assertTrue("isNumber(String) 2 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 2 Neg failed", !checkCreateNumber(val));
          val = "--2.3";
          assertTrue("isNumber(String) 3 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 3 Neg failed", !checkCreateNumber(val));
          val = ".12.3";
          assertTrue("isNumber(String) 4 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 4 Neg failed", !checkCreateNumber(val));
          val = "-123E";
          assertTrue("isNumber(String) 5 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 5 Neg failed", !checkCreateNumber(val));
          val = "-123E+-212";
          assertTrue("isNumber(String) 6 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 6 Neg failed", !checkCreateNumber(val));
          val = "-123E2.12";
          assertTrue("isNumber(String) 7 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 7 Neg failed", !checkCreateNumber(val));
          val = "0xGF";
          assertTrue("isNumber(String) 8 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 8 Neg failed", !checkCreateNumber(val));
          val = "0xFAE-1";
          assertTrue("isNumber(String) 9 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 9 Neg failed", !checkCreateNumber(val));
          val = ".";
          assertTrue("isNumber(String) 10 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 10 Neg failed", !checkCreateNumber(val));
          val = "-0ABC123";
          assertTrue("isNumber(String) 11 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 11 Neg failed", !checkCreateNumber(val));
          val = "123.4E-D";
          assertTrue("isNumber(String) 12 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 12 Neg failed", !checkCreateNumber(val));
          val = "123.4ED";
          assertTrue("isNumber(String) 13 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 13 Neg failed", !checkCreateNumber(val));
          val = "1234E5l";
          assertTrue("isNumber(String) 14 Neg failed", !NumberUtils.isNumber(val));
          assertTrue("isNumber(String)/createNumber(String) 14 Neg failed", !checkCreateNumber(val));
  
      }
  
      private boolean checkCreateNumber(String val) {
          try {
              Object obj = NumberUtils.createNumber(val);
              if(obj == null) {
                  return false;
              }
              return true;
          } catch (NumberFormatException e) {
              return false;
          } catch (NullPointerException e) {
              return false;
          }
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/ObjectUtilsTest.java
  
  Index: ObjectUtilsTest.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  /**
   * Unit tests {@link org.apache.commons.lang.ObjectUtils}.
   *
   * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: ObjectUtilsTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class ObjectUtilsTest extends TestCase
  {
      private static final String FOO = "foo";
      private static final String BAR = "bar";
  
      public ObjectUtilsTest(String name)
      {
          super(name);
      }
      
      public static void main(String[] args) 
      {
          TestRunner.run(suite());
      }
  
      public static Test suite() 
      {
      	TestSuite suite = new TestSuite(ObjectUtilsTest.class);
      	suite.setName("ObjectUtils Tests");
          return suite;
      }
  
      protected void setUp() throws Exception 
      {
          super.setUp();
      }
  
      protected void tearDown() throws Exception
      {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
      
      public void testIsNull()
      {
          Object o = FOO;
          Object dflt = BAR;
          assertSame("dflt was not returned when o was null", dflt,
                       ObjectUtils.defaultIfNull(null, dflt));
          assertSame("dflt was returned when o was not null", o,
                       ObjectUtils.defaultIfNull(o, dflt));
      }
          
      public void testEquals()
      {
          assertTrue("ObjectUtils.equals(null, null) returned false", 
                     ObjectUtils.equals(null, null));
          assertTrue("ObjectUtils.equals(\"foo\", null) returned true", 
                     !ObjectUtils.equals(FOO, null));
          assertTrue("ObjectUtils.equals(null, \"bar\") returned true", 
                     !ObjectUtils.equals(null, BAR));
          assertTrue("ObjectUtils.equals(\"foo\", \"bar\") returned true", 
                     !ObjectUtils.equals(FOO, BAR));
          assertTrue("ObjectUtils.equals(\"foo\", \"foo\") returned false", 
                     ObjectUtils.equals(FOO, FOO));
      }        
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/RandomStringUtilsTest.java
  
  Index: RandomStringUtilsTest.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import junit.framework.*;
  import junit.textui.TestRunner;
  /**
   * Unit tests {@link org.apache.commons.lang.RandomStringUtils}.
   *
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: RandomStringUtilsTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class RandomStringUtilsTest extends junit.framework.TestCase {
      /**
       * Construct a new instance of RandomStringUtilsTest with the specified name
       */
      public RandomStringUtilsTest(String name) {
          super(name);
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(RandomStringUtilsTest.class);
      	suite.setName("RandomStringUtils Tests");
          return suite;
      }
      
      /**
       * Set up instance variables required by this test case.
       */
      public void setUp() {
      }
      
      /**
       * Tear down instance variables required by this test case.
       */
      public void tearDown() {
      }
      
      /**
       * Test the implementation
       */
      public void testRandomStringUtils() {
          String r1 = RandomStringUtils.random(50);
          assertEquals("random(5) length", 50, r1.length());
          String r2 = RandomStringUtils.random(50);
          assertEquals("random(5) length", 50, r2.length());
          assertTrue("!r1.equals(r2)", !r1.equals(r2));
          
          r1 = RandomStringUtils.randomAscii(50);
          assertEquals("randomAscii(10) length", 50, r1.length());
          for(int i = 0; i < r1.length(); i++) {
              assertTrue("char between 32 and 127", (int) r1.charAt(i) >= 32 && (int) r1.charAt(i) <= 127);
          }        
          r2 = RandomStringUtils.randomAscii(50);
          assertTrue("!r1.equals(r2)", !r1.equals(r2));
  
          r1 = RandomStringUtils.randomAlphabetic(50);
          assertEquals("randomAlphabetic(50)", 50, r1.length());
          for(int i = 0; i < r1.length(); i++) {
              assertEquals("r1 contains alphabetic", true, Character.isLetter(r1.charAt(i)) && !Character.isDigit(r1.charAt(i)));
          }
          r2 = RandomStringUtils.randomAlphabetic(50);
          assertTrue("!r1.equals(r2)", !r1.equals(r2));
          
          r1 = RandomStringUtils.randomAlphanumeric(50);
          assertEquals("randomAlphanumeric(50)", 50, r1.length());
          for(int i = 0; i < r1.length(); i++) {
              assertEquals("r1 contains alphanumeric", true, Character.isLetterOrDigit(r1.charAt(i)));
          }
          r2 = RandomStringUtils.randomAlphabetic(50);
          assertTrue("!r1.equals(r2)", !r1.equals(r2));
          
          r1 = RandomStringUtils.randomNumeric(50);
          assertEquals("randomNumeric(50)", 50, r1.length());
          for(int i = 0; i < r1.length(); i++) {
              assertEquals("r1 contains numeric", true, Character.isDigit(r1.charAt(i)) && !Character.isLetter(r1.charAt(i)));
          }
          r2 = RandomStringUtils.randomNumeric(50);
          assertTrue("!r1.equals(r2)", !r1.equals(r2));
          
          String set = "abcdefg";
          r1 = RandomStringUtils.random(50, set);
          assertEquals("random(50, \"abcdefg\")", 50, r1.length());
          for(int i = 0; i < r1.length(); i++) {
              assertTrue("random char in set", set.indexOf(r1.charAt(i)) > -1);
          }
          r2 = RandomStringUtils.random(50, set);
          assertTrue("!r1.equals(r2)", !r1.equals(r2));
          
          set = "stuvwxyz";
          r1 = RandomStringUtils.random(50, set.toCharArray());
          assertEquals("random(50, \"stuvwxyz\")", 50, r1.length());
          for(int i = 0; i < r1.length(); i++) {
              assertTrue("random char in set", set.indexOf(r1.charAt(i)) > -1);
          }
          r2 = RandomStringUtils.random(50, set);
          assertTrue("!r1.equals(r2)", !r1.equals(r2));
      }
  
      public static void main(String args[]) {
          TestRunner.run(suite());
      }
  }
  
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/SerializationUtilsTest.java
  
  Index: SerializationUtilsTest.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.InputStream;
  import java.io.ObjectOutputStream;
  import java.util.HashMap;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  
  /**
   * Unit tests {@link org.apache.commons.lang.SerializationUtils}.
   *
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: SerializationUtilsTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class SerializationUtilsTest extends TestCase {
      private String iString;
      private Integer iInteger;
      private HashMap iMap;
  
      public SerializationUtilsTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(SerializationUtilsTest.class);
      	suite.setName("SerializationUtils Tests");
          return suite;
      }
  
      protected void setUp() throws Exception {
          super.setUp();
  
          iString = "foo";
          iInteger = new Integer(7);
          iMap = new HashMap();
          iMap.put("FOO", iString);
          iMap.put("BAR", iInteger);
      }
  
      protected void tearDown() throws Exception {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
  
      public void testSerializeStream() throws Exception {
          ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
          SerializationUtils.serialize(iMap, streamTest);
  
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(iMap);
          oos.flush();
          oos.close();
  
          byte[] testBytes = streamTest.toByteArray();
          byte[] realBytes = streamReal.toByteArray();
          assertEquals(testBytes.length, realBytes.length);
          for (int i = 0; i < realBytes.length; i++) {
              assertEquals(realBytes[i], testBytes[i]);
          }
      }
  
      public void testSerializeStreamUnserializable() throws Exception {
          ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
          try {
              iMap.put(new Object(), new Object());
              SerializationUtils.serialize(iMap, streamTest);
          } catch (SerializationException ex) {
              return;
          }
          fail();
      }
  
      public void testSerializeStreamNullObj() throws Exception {
          ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
          SerializationUtils.serialize(null, streamTest);
  
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(null);
          oos.flush();
          oos.close();
  
          byte[] testBytes = streamTest.toByteArray();
          byte[] realBytes = streamReal.toByteArray();
          assertEquals(testBytes.length, realBytes.length);
          for (int i = 0; i < realBytes.length; i++) {
              assertEquals(realBytes[i], testBytes[i]);
          }
      }
  
      public void testSerializeStreamObjNull() throws Exception {
          ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
          try {
              SerializationUtils.serialize(iMap, null);
          } catch (NullPointerException ex) {
              return;
          }
          fail();
      }
  
      public void testSerializeStreamNullNull() throws Exception {
          ByteArrayOutputStream streamTest = new ByteArrayOutputStream();
          try {
              SerializationUtils.serialize(null, null);
          } catch (NullPointerException ex) {
              return;
          }
          fail();
      }
  
      //-----------------------------------------------------------------------
  
      public void testDeserializeStream() throws Exception {
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(iMap);
          oos.flush();
          oos.close();
  
          ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
          Object test = SerializationUtils.deserialize(inTest);
          assertNotNull(test);
          assertTrue(test instanceof HashMap);
          assertTrue(test != iMap);
          HashMap testMap = (HashMap) test;
          assertEquals(iString, testMap.get("FOO"));
          assertTrue(iString != testMap.get("FOO"));
          assertEquals(iInteger, testMap.get("BAR"));
          assertTrue(iInteger != testMap.get("BAR"));
          assertEquals(iMap, testMap);
      }
  
      public void testDeserializeStreamOfNull() throws Exception {
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(null);
          oos.flush();
          oos.close();
  
          ByteArrayInputStream inTest = new ByteArrayInputStream(streamReal.toByteArray());
          Object test = SerializationUtils.deserialize(inTest);
          assertNull(test);
      }
  
      public void testDeserializeStreamNull() throws Exception {
          try {
              SerializationUtils.deserialize((InputStream) null);
          } catch (NullPointerException ex) {
              return;
          }
          fail();
      }
  
      public void testDeserializeStreamBadStream() throws Exception {
          try {
              SerializationUtils.deserialize(new ByteArrayInputStream(new byte[0]));
          } catch (SerializationException ex) {
              return;
          }
          fail();
      }
  
      //-----------------------------------------------------------------------
  
      public void testSerializeBytes() throws Exception {
          byte[] testBytes = SerializationUtils.serialize(iMap);
  
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(iMap);
          oos.flush();
          oos.close();
  
          byte[] realBytes = streamReal.toByteArray();
          assertEquals(testBytes.length, realBytes.length);
          for (int i = 0; i < realBytes.length; i++) {
              assertEquals(realBytes[i], testBytes[i]);
          }
      }
  
      public void testSerializeBytesUnserializable() throws Exception {
          try {
              iMap.put(new Object(), new Object());
              SerializationUtils.serialize(iMap);
          } catch (SerializationException ex) {
              return;
          }
          fail();
      }
  
      public void testSerializeBytesNull() throws Exception {
          byte[] testBytes = SerializationUtils.serialize(null);
  
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(null);
          oos.flush();
          oos.close();
  
          byte[] realBytes = streamReal.toByteArray();
          assertEquals(testBytes.length, realBytes.length);
          for (int i = 0; i < realBytes.length; i++) {
              assertEquals(realBytes[i], testBytes[i]);
          }
      }
  
      //-----------------------------------------------------------------------
  
      public void testDeserializeBytes() throws Exception {
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(iMap);
          oos.flush();
          oos.close();
  
          Object test = SerializationUtils.deserialize(streamReal.toByteArray());
          assertNotNull(test);
          assertTrue(test instanceof HashMap);
          assertTrue(test != iMap);
          HashMap testMap = (HashMap) test;
          assertEquals(iString, testMap.get("FOO"));
          assertTrue(iString != testMap.get("FOO"));
          assertEquals(iInteger, testMap.get("BAR"));
          assertTrue(iInteger != testMap.get("BAR"));
          assertEquals(iMap, testMap);
      }
  
      public void testDeserializeBytesOfNull() throws Exception {
          ByteArrayOutputStream streamReal = new ByteArrayOutputStream();
          ObjectOutputStream oos = new ObjectOutputStream(streamReal);
          oos.writeObject(null);
          oos.flush();
          oos.close();
  
          Object test = SerializationUtils.deserialize(streamReal.toByteArray());
          assertNull(test);
      }
  
      public void testDeserializeBytesNull() throws Exception {
          try {
              SerializationUtils.deserialize((byte[]) null);
          } catch (NullPointerException ex) {
              return;
          }
          fail();
      }
  
      public void testDeserializeBytesBadStream() throws Exception {
          try {
              SerializationUtils.deserialize(new byte[0]);
          } catch (SerializationException ex) {
              return;
          }
          fail();
      }
  
      //-----------------------------------------------------------------------
  
      public void testClone() throws Exception {
          Object test = SerializationUtils.clone(iMap);
          assertNotNull(test);
          assertTrue(test instanceof HashMap);
          assertTrue(test != iMap);
          HashMap testMap = (HashMap) test;
          assertEquals(iString, testMap.get("FOO"));
          assertTrue(iString != testMap.get("FOO"));
          assertEquals(iInteger, testMap.get("BAR"));
          assertTrue(iInteger != testMap.get("BAR"));
          assertEquals(iMap, testMap);
      }
  
      public void testCloneNull() throws Exception {
          Object test = SerializationUtils.clone(null);
          assertNull(test);
      }
  
      public void testCloneUnserializable() throws Exception {
          try {
              iMap.put(new Object(), new Object());
              SerializationUtils.clone(iMap);
          } catch (SerializationException ex) {
              return;
          }
          fail();
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/StringUtilsEqualsIndexOfTest.java
  
  Index: StringUtilsEqualsIndexOfTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  
  /**
   * Unit tests {@link org.apache.commons.lang.StringUtils} - Substring methods
   *
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: StringUtilsEqualsIndexOfTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class StringUtilsEqualsIndexOfTest extends TestCase {
      private static final String FOO = "foo";
      private static final String BAR = "bar";
      private static final String FOOBAR = "foobar";
      private static final String[] FOOBAR_SUB_ARRAY = new String[] {"ob", "ba"};
  
      public StringUtilsEqualsIndexOfTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(StringUtilsEqualsIndexOfTest.class);
      	suite.setName("StringUtilsEqualsIndexOf Tests");
          return suite;
      }
  
      protected void setUp() throws Exception {
          super.setUp();
      }
  
      protected void tearDown() throws Exception {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
  
      public void testEquals() {
          assertEquals(true, StringUtils.equals(null, null));
          assertEquals(true, StringUtils.equals(FOO, FOO));
          assertEquals(true, StringUtils.equals(FOO, new String(new char[] { 'f', 'o', 'o' })));
          assertEquals(false, StringUtils.equals(FOO, new String(new char[] { 'f', 'O', 'O' })));
          assertEquals(false, StringUtils.equals(FOO, BAR));
          assertEquals(false, StringUtils.equals(FOO, null));
          assertEquals(false, StringUtils.equals(null, FOO));
      }
  
      public void testEqualsIgnoreCase() {
          assertEquals(true, StringUtils.equalsIgnoreCase(null, null));
          assertEquals(true, StringUtils.equalsIgnoreCase(FOO, FOO));
          assertEquals(true, StringUtils.equalsIgnoreCase(FOO, new String(new char[] { 'f', 'o', 'o' })));
          assertEquals(true, StringUtils.equalsIgnoreCase(FOO, new String(new char[] { 'f', 'O', 'O' })));
          assertEquals(false, StringUtils.equalsIgnoreCase(FOO, BAR));
          assertEquals(false, StringUtils.equalsIgnoreCase(FOO, null));
          assertEquals(false, StringUtils.equalsIgnoreCase(null, FOO));
      }
  
      public void testIndexOfAny() {
          assertEquals(-1, StringUtils.indexOfAny(null, null));
          assertEquals(-1, StringUtils.indexOfAny(null, FOOBAR_SUB_ARRAY));
          assertEquals(-1, StringUtils.indexOfAny(FOOBAR, null));
          assertEquals(2, StringUtils.indexOfAny(FOOBAR, FOOBAR_SUB_ARRAY));
          assertEquals(-1, StringUtils.indexOfAny(FOOBAR, new String[0]));
          assertEquals(-1, StringUtils.indexOfAny(FOOBAR, new String[] {"llll"}));
      }
  
      public void testLastIndexOfAny() {
          assertEquals(-1, StringUtils.lastIndexOfAny(null, null));
          assertEquals(-1, StringUtils.lastIndexOfAny(null, FOOBAR_SUB_ARRAY));
          assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, null));
          assertEquals(3, StringUtils.lastIndexOfAny(FOOBAR, FOOBAR_SUB_ARRAY));
          assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, new String[0]));
          assertEquals(-1, StringUtils.lastIndexOfAny(FOOBAR, new String[] {"llll"}));
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/StringUtilsIsTest.java
  
  Index: StringUtilsIsTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  
  /**
   * Unit tests {@link org.apache.commons.lang.StringUtils} - Substring methods
   *
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @version $Id: StringUtilsIsTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class StringUtilsIsTest extends TestCase {
  
      public StringUtilsIsTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(StringUtilsIsTest.class);
      	suite.setName("StringUtilsIsXxx Tests");
          return suite;
      }
  
      protected void setUp() throws Exception {
          super.setUp();
      }
  
      protected void tearDown() throws Exception {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
  
      public void testIsAlpha() {
          assertEquals(false, StringUtils.isAlpha(null));
          assertEquals(true, StringUtils.isAlpha(""));
          assertEquals(false, StringUtils.isAlpha(" "));
          assertEquals(true, StringUtils.isAlpha("a"));
          assertEquals(true, StringUtils.isAlpha("A"));
          assertEquals(true, StringUtils.isAlpha("kgKgKgKgkgkGkjkjlJlOKLgHdGdHgl"));
          assertEquals(false, StringUtils.isAlpha("ham kso"));
          assertEquals(false, StringUtils.isAlpha("1"));
          assertEquals(false, StringUtils.isAlpha("hkHKHik6iUGHKJgU7tUJgKJGI87GIkug"));
          assertEquals(false, StringUtils.isAlpha("_"));
          assertEquals(false, StringUtils.isAlpha("hkHKHik*khbkuh"));
      }
  
      public void testIsAlphanumeric() {
          assertEquals(false, StringUtils.isAlphanumeric(null));
          assertEquals(true, StringUtils.isAlphanumeric(""));
          assertEquals(false, StringUtils.isAlphanumeric(" "));
          assertEquals(true, StringUtils.isAlphanumeric("a"));
          assertEquals(true, StringUtils.isAlphanumeric("A"));
          assertEquals(true, StringUtils.isAlphanumeric("kgKgKgKgkgkGkjkjlJlOKLgHdGdHgl"));
          assertEquals(false, StringUtils.isAlphanumeric("ham kso"));
          assertEquals(true, StringUtils.isAlphanumeric("1"));
          assertEquals(true, StringUtils.isAlphanumeric("hkHKHik6iUGHKJgU7tUJgKJGI87GIkug"));
          assertEquals(false, StringUtils.isAlphanumeric("_"));
          assertEquals(false, StringUtils.isAlphanumeric("hkHKHik*khbkuh"));
      }
  
      public void testIsAlphaspace() {
          assertEquals(false, StringUtils.isAlphaSpace(null));
          assertEquals(true, StringUtils.isAlphaSpace(""));
          assertEquals(true, StringUtils.isAlphaSpace(" "));
          assertEquals(true, StringUtils.isAlphaSpace("a"));
          assertEquals(true, StringUtils.isAlphaSpace("A"));
          assertEquals(true, StringUtils.isAlphaSpace("kgKgKgKgkgkGkjkjlJlOKLgHdGdHgl"));
          assertEquals(true, StringUtils.isAlphaSpace("ham kso"));
          assertEquals(false, StringUtils.isAlphaSpace("1"));
          assertEquals(false, StringUtils.isAlphaSpace("hkHKHik6iUGHKJgU7tUJgKJGI87GIkug"));
          assertEquals(false, StringUtils.isAlphaSpace("_"));
          assertEquals(false, StringUtils.isAlphaSpace("hkHKHik*khbkuh"));
      }
  
      public void testIsAlphanumericSpace() {
          assertEquals(false, StringUtils.isAlphanumericSpace(null));
          assertEquals(true, StringUtils.isAlphanumericSpace(""));
          assertEquals(true, StringUtils.isAlphanumericSpace(" "));
          assertEquals(true, StringUtils.isAlphanumericSpace("a"));
          assertEquals(true, StringUtils.isAlphanumericSpace("A"));
          assertEquals(true, StringUtils.isAlphanumericSpace("kgKgKgKgkgkGkjkjlJlOKLgHdGdHgl"));
          assertEquals(true, StringUtils.isAlphanumericSpace("ham kso"));
          assertEquals(true, StringUtils.isAlphanumericSpace("1"));
          assertEquals(true, StringUtils.isAlphanumericSpace("hkHKHik6iUGHKJgU7tUJgKJGI87GIkug"));
          assertEquals(false, StringUtils.isAlphanumericSpace("_"));
          assertEquals(false, StringUtils.isAlphanumericSpace("hkHKHik*khbkuh"));
      }
  
      public void testIsNumeric() {
          assertEquals(false, StringUtils.isNumeric(null));
          assertEquals(true, StringUtils.isNumeric(""));
          assertEquals(false, StringUtils.isNumeric(" "));
          assertEquals(false, StringUtils.isNumeric("a"));
          assertEquals(false, StringUtils.isNumeric("A"));
          assertEquals(false, StringUtils.isNumeric("kgKgKgKgkgkGkjkjlJlOKLgHdGdHgl"));
          assertEquals(false, StringUtils.isNumeric("ham kso"));
          assertEquals(true, StringUtils.isNumeric("1"));
          assertEquals(true, StringUtils.isNumeric("1000"));
          assertEquals(false, StringUtils.isNumeric("2.3"));
          assertEquals(false, StringUtils.isNumeric("10 00"));
          assertEquals(false, StringUtils.isNumeric("hkHKHik6iUGHKJgU7tUJgKJGI87GIkug"));
          assertEquals(false, StringUtils.isNumeric("_"));
          assertEquals(false, StringUtils.isNumeric("hkHKHik*khbkuh"));
      }
  
      public void testIsNumericSpace() {
          assertEquals(false, StringUtils.isNumericSpace(null));
          assertEquals(true, StringUtils.isNumericSpace(""));
          assertEquals(true, StringUtils.isNumericSpace(" "));
          assertEquals(false, StringUtils.isNumericSpace("a"));
          assertEquals(false, StringUtils.isNumericSpace("A"));
          assertEquals(false, StringUtils.isNumericSpace("kgKgKgKgkgkGkjkjlJlOKLgHdGdHgl"));
          assertEquals(false, StringUtils.isNumericSpace("ham kso"));
          assertEquals(true, StringUtils.isNumericSpace("1"));
          assertEquals(true, StringUtils.isNumericSpace("1000"));
          assertEquals(false, StringUtils.isNumericSpace("2.3"));
          assertEquals(true, StringUtils.isNumericSpace("10 00"));
          assertEquals(false, StringUtils.isNumericSpace("hkHKHik6iUGHKJgU7tUJgKJGI87GIkug"));
          assertEquals(false, StringUtils.isNumericSpace("_"));
          assertEquals(false, StringUtils.isNumericSpace("hkHKHik*khbkuh"));
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/StringUtilsSubstringTest.java
  
  Index: StringUtilsSubstringTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  
  /**
   * Unit tests {@link org.apache.commons.lang.StringUtils} - Substring methods
   *
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: StringUtilsSubstringTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class StringUtilsSubstringTest extends TestCase {
      private static final String FOO = "foo";
      private static final String BAR = "bar";
      private static final String BAZ = "baz";
      private static final String FOOBAR = "foobar";
      private static final String SENTENCE = "foo bar baz";
  
      public StringUtilsSubstringTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(StringUtilsSubstringTest.class);
      	suite.setName("StringUtilsSubstring Tests");
          return suite;
      }
  
      protected void setUp() throws Exception {
          super.setUp();
      }
  
      protected void tearDown() throws Exception {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
  
  
      public void testSubstring2() {
          assertEquals("", StringUtils.substring(SENTENCE, 80));
          assertEquals(BAZ, StringUtils.substring(SENTENCE, 8));
          assertEquals(BAZ, StringUtils.substring(SENTENCE, -3));
          assertEquals(SENTENCE, StringUtils.substring(SENTENCE, 0));
      }
      
      public void testSubstring3() {
          assertEquals("", StringUtils.substring(SENTENCE, 8, 6));
          assertEquals(FOO, StringUtils.substring(SENTENCE, 0, 3));
          assertEquals("o", StringUtils.substring(SENTENCE, -9, 3));
          assertEquals(FOO, StringUtils.substring(SENTENCE, 0, -8));
          assertEquals("o", StringUtils.substring(SENTENCE, -9, -8));
          assertEquals(SENTENCE, StringUtils.substring(SENTENCE, 0, 80));
      }
      
      public void testLeft() {
          assertSame(null, StringUtils.left(null, 0));
          assertSame(null, StringUtils.left(null, 2));
          assertSame("", StringUtils.left("", 0));
          assertSame("", StringUtils.left("", 2));
          assertEquals("", StringUtils.left(FOOBAR, 0));
          assertEquals(FOO, StringUtils.left(FOOBAR, 3));
          assertSame(FOOBAR, StringUtils.left(FOOBAR, 80));
      }
      
      public void testLeftEx() {
          try {
              StringUtils.left(FOOBAR, -1);
          } catch (IllegalArgumentException ex) {
              return;
          }
          fail();
      }
  
      public void testRight() {
          assertSame(null, StringUtils.right(null, 0));
          assertSame(null, StringUtils.right(null, 2));
          assertSame("", StringUtils.right("", 0));
          assertSame("", StringUtils.right("", 2));
          assertEquals("", StringUtils.right(FOOBAR, 0));
          assertEquals(BAR, StringUtils.right(FOOBAR, 3));
          assertSame(FOOBAR, StringUtils.right(FOOBAR, 80));
      }
      
      public void testRightEx() {
          try {
              StringUtils.right(FOOBAR, -1);
          } catch (IllegalArgumentException ex) {
              return;
          }
          fail();
      }
  
      public void testMid() {
          assertSame(null, StringUtils.mid(null, 3, 0));
          assertSame(null, StringUtils.mid(null, 3, 2));
          assertSame("", StringUtils.mid("", 0, 0));
          assertSame("", StringUtils.mid("", 0, 2));
          assertEquals("", StringUtils.mid(FOOBAR, 3, 0));
          assertEquals("b", StringUtils.mid(FOOBAR, 3, 1));
          assertEquals(FOO, StringUtils.mid(FOOBAR, 0, 3));
          assertEquals(BAR, StringUtils.mid(FOOBAR, 3, 3));
          assertEquals(FOOBAR, StringUtils.mid(FOOBAR, 0, 80));
          assertEquals(BAR, StringUtils.mid(FOOBAR, 3, 80));
      }
      
      public void testMidEx1() {
          try {
              StringUtils.mid(FOOBAR, 0, -1);
          } catch (IllegalArgumentException ex) {
              return;
          }
          fail();
      }
  
      public void testMidEx2() {
          try {
              StringUtils.mid(FOOBAR, -1, 3);
          } catch (IndexOutOfBoundsException ex) {
              return;
          }
          fail();
      }
  
      public void testMidEx3() {
          try {
              StringUtils.mid(FOOBAR, 7, 3);
          } catch (IndexOutOfBoundsException ex) {
              return;
          }
          fail();
      }
  
      public void testCountMatches() {
          assertEquals(3, 
               StringUtils.countMatches("one long someone sentence of one", "one"));
          assertEquals(0, 
               StringUtils.countMatches("one long someone sentence of one", "two"));
          assertEquals(4, 
               StringUtils.countMatches("oooooooooooo", "ooo"));
      }
  
      public void testGetNestedString() {
          assertEquals( "", StringUtils.getNestedString("", "") );
          assertEquals( "", StringUtils.getNestedString("    ", " ") );
          assertEquals( "bar", StringUtils.getNestedString("\nbar\n", "\n") );
          assertEquals( "", StringUtils.getNestedString("", "", "") );
          assertEquals( "", StringUtils.getNestedString("    ", " ", "  ") );
          assertEquals( "bar", StringUtils.getNestedString("<foo>bar</foo>", "<foo>", "</foo>") );
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/StringUtilsTest.java
  
  Index: StringUtilsTest.java
  ===================================================================
  package org.apache.commons.lang;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.Arrays;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  /**
   * Unit tests {@link org.apache.commons.lang.StringUtils}.
   *
   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
   * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: StringUtilsTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class StringUtilsTest extends TestCase
  {
      private static final String[] ARRAY_LIST = { "foo", "bar", "baz" };
  
      private static final String SEPARATOR = ",";
  
      private static final String TEXT_LIST = "foo,bar,baz";
  
      private static final String FOO = "foo";
      private static final String BAR = "bar";
      private static final String CAP_FOO = "Foo";
      private static final String UPPER_FOO = "FOO";
  
      private static final String SENTENCE = "foo bar baz";
  
      public StringUtilsTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(StringUtilsTest.class);
      	suite.setName("StringUtilsTest Tests");
          return suite;
      }
  
      protected void setUp() throws Exception {
          super.setUp();
      }
  
      protected void tearDown() throws Exception {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
  
      public void testCaseFunctions()
      {
          assertEquals("capitalise(String) failed",
                       CAP_FOO, StringUtils.capitalise(FOO) );
          assertEquals("capitalise(empty-string) failed",
                       "", StringUtils.capitalise("") );
          assertEquals("capitaliseAllWords(String) failed",
                       "Foo Bar Baz", StringUtils.capitaliseAllWords(SENTENCE) );
          assertEquals("capitaliseAllWords(empty-string) failed",
                       "", StringUtils.capitaliseAllWords("") );
          assertEquals("uncapitalise(String) failed",
                       FOO, StringUtils.uncapitalise(CAP_FOO) );
          assertEquals("uncapitalise(empty-string) failed",
                       "", StringUtils.uncapitalise("") );
  
          assertEquals("upperCase(String) failed",
                       "FOO TEST THING", StringUtils.upperCase("fOo test THING") );
          assertEquals("upperCase(empty-string) failed",
                       "", StringUtils.upperCase("") );
          assertEquals("lowerCase(String) failed",
                       "foo test thing", StringUtils.lowerCase("fOo test THING") );
          assertEquals("lowerCase(empty-string) failed",
                       "", StringUtils.lowerCase("") );
  
          assertEquals("swapCase(empty-string) failed",
                       "", StringUtils.swapCase("") );
          assertEquals("swapCase(String-with-numbers) failed",
                       "a123RgYu", StringUtils.swapCase("A123rGyU") );
          assertEquals("swapCase(String) failed",
                       "Hello aPACHE", StringUtils.swapCase("hELLO Apache") );
      }
  
      public void testJoin()
      {
          assertEquals("join(Object[], String) failed", TEXT_LIST,
                       StringUtils.join(ARRAY_LIST, SEPARATOR));
          assertEquals("join(Iterator, String) failed", TEXT_LIST,
                       StringUtils.join(Arrays.asList(ARRAY_LIST).iterator(),
                                        SEPARATOR));
      }
  
      public void testSplit()
      {
          String[] result = StringUtils.split(TEXT_LIST, SEPARATOR, 2);
          String[] expected = { "foo", "bar,baz" };
          assertEquals("split(Object[], String, int) yielded unexpected length",
                       expected.length, result.length);
          for (int i = 0; i < result.length; i++)
          {
              assertEquals("split(Object[], String, int) failed", expected[i],
                           result[i]);
          }
  
          result = StringUtils.split(TEXT_LIST, SEPARATOR, 0);
          expected = ARRAY_LIST;
          assertEquals("split(Object[], String, int) yielded unexpected length",
                       expected.length, result.length);
          for (int i = 0; i < result.length; i++)
          {
              assertEquals("split(Object[], String, int) failed", expected[i],
                           result[i]);
          }
  
          result = StringUtils.split(TEXT_LIST, SEPARATOR, -1);
          expected = ARRAY_LIST;
          assertEquals("split(Object[], String, int) yielded unexpected length",
                       expected.length, result.length);
          for (int i = 0; i < result.length; i++)
          {
              assertEquals("split(Object[], String, int) failed", expected[i],
                           result[i]);
          }
      }
  
      public void testReplaceFunctions()
      {
          assertEquals("replace(String, String, String, int) failed",
                       FOO, StringUtils.replace("oo" + FOO, "o", "", 2));
          assertEquals("replace(String, String, String) failed",
                       "", StringUtils.replace(FOO + FOO + FOO, FOO, ""));
          assertEquals("replaceOnce(String, String, String) failed",
                       FOO, StringUtils.replaceOnce(FOO + FOO, FOO, ""));
      }
  
      public void testOverlayString()
      {
          assertEquals("overlayString(String, String, int, int) failed",
                       "foo foor baz", StringUtils.overlayString(SENTENCE, FOO, 4, 6) );
      }
  
      public void testRepeat()
      {
          assertEquals("repeat(String, int) failed",
                       FOO + FOO + FOO, StringUtils.repeat(FOO, 3) );
      }
  
      public void testCenter()
      {
          assertEquals("center(String, int) failed",
                       "   "+FOO+"   ", StringUtils.center(FOO, 9) );
      }
  
      public void testChompFunctions()
      {
  
          assertEquals("chomp(String) failed",
                       FOO, StringUtils.chomp(FOO + "\n" + FOO) );
  
          assertEquals("chompLast(String) failed",
                       FOO, StringUtils.chompLast(FOO + "\n") );
  
          assertEquals("getChomp(String, String) failed",
                       "\n" + FOO, StringUtils.getChomp(FOO + "\n" + FOO, "\n") );
  
          assertEquals("prechomp(String, String) failed",
                       FOO, StringUtils.prechomp(FOO + "\n" + FOO, "\n") );
  
          assertEquals("getPrechomp(String, String) failed",
                       FOO + "\n", StringUtils.getPrechomp(FOO + "\n" + FOO, "\n") );
  
          assertEquals("chop(String, String) failed",
                       FOO, StringUtils.chop(FOO + "\r\n") );
  
          assertEquals("chopNewline(String, String) failed",
                       FOO, StringUtils.chopNewline(FOO + "\r\n") );
      }
  
      public void testPadFunctions()
      {
          assertEquals("rightPad(String, int) failed",
                       "1234    ", StringUtils.rightPad ("1234", 8) );
  
          assertEquals("rightPad(String, int, String) failed",
                       "1234-+-+", StringUtils.rightPad ("1234", 8, "-+") );
  
          assertEquals("rightPad(String, int, String) failed",
                       "123456-+~", StringUtils.rightPad ("123456", 9, "-+~") );
  
          assertEquals("leftPad(String, int) failed",
                       "    1234", StringUtils.leftPad("1234", 8) );
  
          assertEquals("leftPad(String, int, String) failed",
                       "-+-+1234", StringUtils.leftPad("1234", 8, "-+") );
  
          assertEquals("leftPad(String, int, String) failed",
                       "-+~123456", StringUtils.leftPad("123456", 9, "-+~") );
      }
  
      public void testUnicodeFunctions() throws java.io.IOException
      {
          /* this test fails on my window box with an Sun english JDK 1.3.1
             I think that the input string is not right
          */
  /* Kept out for the moment.
          String input = "これは日本楔譴離謄好箸任后#";
          String unicode = StringUtils.convertNativeToUnicode(input, "iso-2022-jp");
          String iso = StringUtils.convertUnicodeToNative(unicode, "iso-2022-jp");
          assertEquals("Unicode conversions failed", input, iso);
  */
      }
  
      public void testReverseFunctions() {
          assertEquals("reverse(String) failed",
                       "sdrawkcab", StringUtils.reverse("backwards") );
          assertEquals("reverse(empty-string) failed",
                       "", StringUtils.reverse("") );
          assertEquals("reverseDelimitedString(String,'.') failed",
                       "org.apache.test", 
                         StringUtils.reverseDelimitedString("test.apache.org", ".") );
          assertEquals("reverseDelimitedString(empty-string,'.') failed",
                       "", 
                         StringUtils.reverseDelimitedString("", ".") );
          assertEquals("reverseDelimitedString(String,' ') failed",
                       "once upon a time", 
                         StringUtils.reverseDelimitedString("time a upon once"," ") );
      }
  
      public void testDefaultFunctions() {
          assertEquals("defaultString(empty-string) failed",
                       "", StringUtils.defaultString("") );
          assertEquals("defaultString(String) failed",
                       FOO, StringUtils.defaultString(FOO) );
          assertEquals("defaultString(null) failed",
                       "", StringUtils.defaultString(null) );
          assertEquals("defaultString(empty-string,String) failed",
                       "", StringUtils.defaultString("", BAR) );
          assertEquals("defaultString(String,String) failed",
                       FOO, StringUtils.defaultString(FOO, BAR) );
          assertEquals("defaultString(null,String) failed",
                       BAR, StringUtils.defaultString(null, BAR) );
      }
  
      public void testEscapeFunctions() {
          assertEquals("escape(empty-string) failed",
                       "", StringUtils.escape("") );
          assertEquals("escape(String) failed",
                       FOO, StringUtils.escape(FOO) );
          assertEquals("escape(String) failed",
                       "\\t", StringUtils.escape("\t") );
          assertEquals("escape(String) failed",
                       "\\\\", StringUtils.escape("\\") );
          assertEquals("escape(String) failed",
                       "\\\\\\b\\t\\r", StringUtils.escape("\\\b\t\r") );
          assertEquals("escape(String) failed",
                       "\\u1234", StringUtils.escape("\u1234") );
          assertEquals("escape(String) failed",
                       "\\u0234", StringUtils.escape("\u0234") );
          assertEquals("escape(String) failed",
                       "\\u00fd", StringUtils.escape("\u00fd") );
      }
  
      public void testGetLevenshteinDistance() {
          assertEquals("getLevenshteinDistance(empty-string, empty-string) failed",
                       0, StringUtils.getLevenshteinDistance("", "") );
          assertEquals("getLevenshteinDistance(empty-string, String) failed",
                       1, StringUtils.getLevenshteinDistance("", "a") );
          assertEquals("getLevenshteinDistance(String, empty-string) failed",
                       7, StringUtils.getLevenshteinDistance("aaapppp", "") );
          assertEquals("getLevenshteinDistance(String, String) failed",
                       1, StringUtils.getLevenshteinDistance("frog", "fog") );
          assertEquals("getLevenshteinDistance(String, String) failed",
                       3, StringUtils.getLevenshteinDistance("fly", "ant") );
          assertEquals("getLevenshteinDistance(String, String) failed",
                       7, StringUtils.getLevenshteinDistance("elephant", "hippo") );
          assertEquals("getLevenshteinDistance(String, String) failed",
                       7, StringUtils.getLevenshteinDistance("hippo", "elephant") );
          assertEquals("getLevenshteinDistance(String, String) failed",
                       1, StringUtils.getLevenshteinDistance("hello", "hallo") );
      }
  
  }
  
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/StringUtilsTrimEmptyTest.java
  
  Index: StringUtilsTrimEmptyTest.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.commons.lang;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  
  /**
   * Unit tests {@link org.apache.commons.lang.StringUtils} - Trim/Empty methods
   *
   * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a>
   * @author <a href="mailto:ridesmet@users.sourceforge.net">Ringo De Smet</a>
   * @version $Id: StringUtilsTrimEmptyTest.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class StringUtilsTrimEmptyTest extends TestCase {
      private static final String FOO = "foo";
  
      public StringUtilsTrimEmptyTest(String name) {
          super(name);
      }
  
      public static void main(String[] args) {
          TestRunner.run(suite());
      }
  
      public static Test suite() {
      	TestSuite suite = new TestSuite(StringUtilsTrimEmptyTest.class);
      	suite.setName("StringUtilsTrimEmpty Tests");
          return suite;
      }
  
      protected void setUp() throws Exception {
          super.setUp();
      }
  
      protected void tearDown() throws Exception {
          super.tearDown();
      }
  
      //-----------------------------------------------------------------------
  
      public void testClean() {
          assertEquals(FOO, StringUtils.clean(FOO + "  "));
          assertEquals(FOO, StringUtils.clean(" " + FOO + "  "));
          assertEquals(FOO, StringUtils.clean(" " + FOO));
          assertEquals(FOO, StringUtils.clean(FOO + ""));
          assertEquals("", StringUtils.clean(null));
      }
  
      public void testTrim() {
          assertEquals(FOO, StringUtils.trim(FOO + "  "));
          assertEquals(FOO, StringUtils.trim(" " + FOO + "  "));
          assertEquals(FOO, StringUtils.trim(" " + FOO));
          assertEquals(FOO, StringUtils.trim(FOO + ""));
          assertEquals(null, StringUtils.trim(null));
      }
  
      public void testIsNotEmpty() {
          assertEquals(true, StringUtils.isNotEmpty(FOO));
          assertEquals(true, StringUtils.isNotEmpty(" "));
          assertEquals(false, StringUtils.isNotEmpty(""));
          assertEquals(false, StringUtils.isNotEmpty(null));
      }
  
      public void testIsEmpty() {
          assertEquals(false, StringUtils.isEmpty(FOO));
          assertEquals(true, StringUtils.isEmpty(" "));
          assertEquals(true, StringUtils.isEmpty(""));
          assertEquals(true, StringUtils.isEmpty(null));
      }
  
      public void testStrip() {
          // it's important that foo2Space is fooLeftSpace and fooRightSpace 
          // merged together. So same number of spaces to left as fLS and same 
          // to right as fLS. Same applies for foo2Dots.
          String foo2Space = "    "+FOO+"    ";
          String foo2Dots = "......"+FOO+".........";
          String fooLeftSpace = "    "+FOO;
          String fooLeftDots = "......"+FOO;
          String fooRightSpace = FOO+"    ";
          String fooRightDots = FOO+".........";
  
          assertEquals("", StringUtils.strip(""));
          assertEquals(FOO, StringUtils.strip(foo2Space));
          assertEquals(FOO, StringUtils.strip(foo2Dots, "."));
          assertEquals(FOO, StringUtils.strip(fooRightSpace));
          assertEquals(FOO, StringUtils.strip(fooRightDots, "."));
          assertEquals(FOO, StringUtils.strip(fooLeftSpace));
          assertEquals(FOO, StringUtils.strip(fooLeftDots, "."));
  
          assertEquals("", StringUtils.stripStart("", " "));
          assertEquals(fooRightSpace, StringUtils.stripStart(foo2Space, " "));
          assertEquals(fooRightDots, StringUtils.stripStart(foo2Dots, "."));
          assertEquals(fooRightSpace, StringUtils.stripStart(fooRightSpace, " "));
          assertEquals(fooRightDots, StringUtils.stripStart(fooRightDots, "."));
          assertEquals(FOO, StringUtils.stripStart(fooLeftSpace, " "));
          assertEquals(FOO, StringUtils.stripStart(fooLeftDots, "."));
  
          assertEquals("", StringUtils.stripEnd("", " "));
          assertEquals(fooLeftSpace, StringUtils.stripEnd(foo2Space, " "));
          assertEquals(fooLeftDots, StringUtils.stripEnd(foo2Dots, "."));
          assertEquals(FOO, StringUtils.stripEnd(fooRightSpace, " "));
          assertEquals(FOO, StringUtils.stripEnd(fooRightDots, "."));
          assertEquals(fooLeftSpace, StringUtils.stripEnd(fooLeftSpace, " "));
          assertEquals(fooLeftDots, StringUtils.stripEnd(fooLeftDots, "."));
  
          // test stripAll method, merely an array version of the above strip
          String[] empty = new String[0];
          String[] fooSpace = new String[] { foo2Space, fooLeftSpace, fooRightSpace };
          String[] fooDots = new String[] { foo2Dots, fooLeftDots, fooRightDots };
          String[] foo = new String[] { FOO, FOO, FOO };
  
          assertArrayEquals(empty, StringUtils.stripAll(empty));
          assertArrayEquals(foo, StringUtils.stripAll(fooSpace));
          assertArrayEquals(foo, StringUtils.stripAll(fooDots, "."));
      }
  
      private void assertArrayEquals(Object[] o1, Object[] o2) {
          if(o1 == null) {
              assertEquals(o1,o2);
              return;
          }
          assertEquals("Length not equal. ", o1.length, o2.length);
          int sz = o1.length;
          for(int i=0; i<sz; i++) {
              if(o1[i] instanceof Object[]) {
                  // do an assert equals on type....
                  assertArrayEquals( (Object[]) o1[i], (Object[]) o2[i] );
              } else {
                  assertEquals(o1[i], o2[i]);
              }
          }
      }
  
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/exception/ExceptionTestSuite.java
  
  Index: ExceptionTestSuite.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import junit.textui.TestRunner;
  
  /**
   * Test manager for the org.apache.commons.lang.exception classes.
   *
   * @author <a href="mailto:stevencaswell@yahoo.com">Steven Caswell</a>
   */
  public class ExceptionTestSuite extends TestCase
  {
      /**
       * Construct a new instance.
       */
      public ExceptionTestSuite(String name)
      {
          super(name);
      }
  
      /**
       * Command-line interface.
       */
      public static void main(String[] args)
      {
          TestRunner.run(suite());
      }
      
      public static Test suite()
      {
          TestSuite suite = new TestSuite();
          suite.addTest(NestableDelegateTestCase.suite());
          suite.addTest(NestableExceptionTestCase.suite());
          suite.addTest(NestableRuntimeExceptionTestCase.suite());
          return suite;
      }
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/exception/NestableDelegateTestCase.java
  
  Index: NestableDelegateTestCase.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayOutputStream;
  import java.io.PrintWriter;
  import java.io.PrintStream;
  
  import junit.framework.*;
  import junit.textui.TestRunner;
  /**
   * Tests the org.apache.commons.lang.exception.NestableDelegate class.
   *
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
   * @version $Id: NestableDelegateTestCase.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class NestableDelegateTestCase extends junit.framework.TestCase
  {
      private static final String CONSTRUCTOR_FAILED_MSG = 
      "The Nestable implementation passed to the NestableDelegate(Nestable) constructor must extend java.lang.Throwable";
  
      private static final String PARTIAL_STACK_TRACE =
          "rethrown as ThrowableNestedNestable partial stack trace place-holder";
  
      protected String lineSeparator;
  
      /**
       * Construct a new instance of NestableDelegateTestCase with the specified name
       */
      public NestableDelegateTestCase(String name)
      {
          super(name);
      }
  
      /**
       * Set up instance variables required by this test case.
       */
      public void setUp()
      {
          lineSeparator = System.getProperty("line.separator");
      }
      
      public static Test suite()
      {
          return new TestSuite(NestableDelegateTestCase.class);
      }
      
      /**
       * Tear down instance variables required by this test case.
       */
      public void tearDown()
      {
          lineSeparator = null;
      }
      
      /**
       * Test the implementation
       */
      public void testNestableDelegateConstructor()
      {
          String msg = null;
          boolean constructorFailed = false;
          try
          {
              NestableDelegate nonThrowableCause = new NestableDelegate(new NonThrowableNestable());
          }
          catch(IllegalArgumentException iae)
          {
              constructorFailed = true;
              msg = iae.getMessage();
          }
          assertTrue("nestable delegate constructor with non-throwable cause failed == true", constructorFailed);
          assertTrue("constructor failed exception msg == " + CONSTRUCTOR_FAILED_MSG,
              msg.equals(CONSTRUCTOR_FAILED_MSG));
  
          constructorFailed = false;
          try
          {
              NestableDelegate nd1 = new NestableDelegate(new ThrowableNestable());
          }
          catch(IllegalArgumentException iae)
          {
              constructorFailed = true;
          }
          assertTrue("nestable delegate constructor with throwable cause failed == false", !constructorFailed);
      }
  
      public void testNestableDelegateGetMessage()
      {
          Nestable ne1 = new ThrowableNestable();
          assertTrue("ThrowableNestable ne1 getMessage() == ThrowableNestable exception",
              ne1.getMessage().equals("ThrowableNestable exception"));
          NestableDelegate nd1 = new NestableDelegate(ne1);
          assertTrue("nd1 getMessage() == " + ne1.getCause().getMessage(),
              nd1.getMessage("base").equals("base: " + ne1.getCause().getMessage()));
          
          Nestable ne2 = new ThrowableNestedNestable(new Exception("nested exception 2"));
          NestableDelegate nd2 = new NestableDelegate(ne2);
          assertTrue("nd2 getMessage() == base: " + ne2.getCause().getMessage(),
              nd2.getMessage("base").equals("base: " + ne2.getCause().getMessage()));
      }
  
      public void testNestableDelegateGetLength()
      {
          Nestable n = null;
          NestableDelegate d = null;
          
          n = new NestableDelegateTester1();
          d = new NestableDelegate(n);
          doNestableDelegateGetLength(d, 1);
          
          n = new NestableDelegateTester1("level 1");
          d = new NestableDelegate(n);
          doNestableDelegateGetLength(d, 1);
          
          n = new NestableDelegateTester1(new Exception());
          d = new NestableDelegate(n);
          doNestableDelegateGetLength(d, 2);
          
          n = new NestableDelegateTester1(new Exception("level 2"));
          d = new NestableDelegate(n);
          doNestableDelegateGetLength(d, 2);
          
          n = new NestableDelegateTester1("level 1", new NestableDelegateTester2("level 2", new NestableDelegateTester1(new NestableDelegateTester2("level 4", new Exception("level 5")))));
          d = new NestableDelegate(n);
          doNestableDelegateGetLength(d, 5);
      }
  
      private void doNestableDelegateGetLength(NestableDelegate d, int len)
      {
          // Compare the lengths
          assertEquals("delegate length", len, d.getLength());
      }
      
      public void testNestableDelegateGetMessages()
      {
          Nestable n = null;
          NestableDelegate d = null;
          String msgs[] = null;
          
          msgs = new String[1];
          n = new NestableDelegateTester1();
          d = new NestableDelegate(n);        
          doNestableDelegateGetMessages(d, msgs);
          
          msgs = new String[1];
          msgs[0] = "level 1";
          n = new NestableDelegateTester1(msgs[0]);
          d = new NestableDelegate(n);
          doNestableDelegateGetMessages(d, msgs);
  
          msgs = new String[2];
          n = new NestableDelegateTester1(new Exception());
          d = new NestableDelegate(n);
          doNestableDelegateGetMessages(d, msgs);
  
          msgs = new String[2];
          msgs[0] = null;
          msgs[1] = "level 2";
          n = new NestableDelegateTester1(new Exception(msgs[1]));
          d = new NestableDelegate(n);
          doNestableDelegateGetMessages(d, msgs);
   
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
          d = new NestableDelegate(n);
          doNestableDelegateGetMessages(d, msgs);
      }
  
      private void doNestableDelegateGetMessages(NestableDelegate d, String[] nMsgs)
      {
          // Compare the messages
          String[] dMsgs = d.getMessages();
          assertEquals("messages length", nMsgs.length, dMsgs.length);
          for(int i = 0; i < nMsgs.length; i++)
          {
              assertEquals("message " + i, nMsgs[i], dMsgs[i]);
          }
      }
  
      public void testNestableDelegateGetMessageN()
      {
          Nestable n = null;
          NestableDelegate d = null;
          String[] msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
          d = new NestableDelegate(n);
          for(int i = 0; i < msgs.length; i++)
          {
              assertEquals("message " + i, msgs[i], d.getMessage(i));
          }
          assertEquals("message -1", msgs[0], d.getMessage(-1));
          assertEquals("message -1", msgs[msgs.length - 1], d.getMessage(msgs.length + 100));
      }
  
      public void testNestableDelegateGetThrowable()
      {
          Nestable n = null;
          NestableDelegate d = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[2];
          msgs[0] = null;
          msgs[1] = "level 2";
          throwables = new Class[2];
          throwables[0] = NestableDelegateTester1.class;
          throwables[1] = Exception.class;
          n = new NestableDelegateTester1(new Exception(msgs[1]));
          d = new NestableDelegate(n);
          doNestableDelegateGetThrowable(d, throwables, msgs);
   
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableDelegateTester1.class;
          throwables[1] = NestableDelegateTester2.class;
          throwables[2] = NestableDelegateTester1.class;
          throwables[3] = NestableDelegateTester2.class;
          throwables[4] = Exception.class;        
          n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
          d = new NestableDelegate(n);
          doNestableDelegateGetThrowable(d, throwables, msgs);
      }
  
      private void doNestableDelegateGetThrowable(NestableDelegate d, Class[] classes, String[] msgs)
      {
          Throwable t = null;
          String msg = null;
          
          for(int i = 0; i < classes.length; i++)
          {
              t = d.getThrowable(i);
              assertEquals("throwable class", classes[i], t.getClass());
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("throwable message", msgs[i], msg);
          }
          t = d.getThrowable(-1);
          assertEquals("throwable(-1)", classes[0], t.getClass());
          if(Nestable.class.isInstance(t))
          {
              msg = ((Nestable) t).getMessage(0);
          }
          else
          {
              msg = t.getMessage();
          }
          assertEquals("throwable message", msgs[0], msg);
          t = d.getThrowable(999);
          assertEquals("throwable(999)", classes[classes.length - 1], t.getClass());
          if(Nestable.class.isInstance(t))
          {
              msg = ((Nestable) t).getMessage(0);
          }
          else
          {
              msg = t.getMessage();
          }
          assertEquals("throwable message", msgs[msgs.length - 1], msg);
      }
  
      public void testNestableDelegateGetThrowables()
      {
          Nestable n = null;
          NestableDelegate d = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[2];
          msgs[0] = null;
          msgs[1] = "level 2";
          throwables = new Class[2];
          throwables[0] = NestableDelegateTester1.class;
          throwables[1] = Exception.class;
          n = new NestableDelegateTester1(new Exception(msgs[1]));
          d = new NestableDelegate(n);
          doNestableDelegateGetThrowables(d, throwables, msgs);
   
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableDelegateTester1.class;
          throwables[1] = NestableDelegateTester2.class;
          throwables[2] = NestableDelegateTester1.class;
          throwables[3] = NestableDelegateTester2.class;
          throwables[4] = Exception.class;        
          n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
          d = new NestableDelegate(n);
          doNestableDelegateGetThrowables(d, throwables, msgs);
      }
      
      private void doNestableDelegateGetThrowables(NestableDelegate d, Class[] classes, String[] msgs)
      {
          Throwable[] throwables = null;
          String msg = null;
  
          throwables = d.getThrowables();
          assertEquals("throwables length", classes.length, throwables.length);
          for(int i = 0; i < classes.length; i++)
          {
              assertEquals("throwable class", classes[i], throwables[i].getClass());
              Throwable t = throwables[i];
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("throwable message", msgs[i], msg);
          }
      }
  
      public void testIndexOfThrowable()
      {
          Nestable n = null;
          NestableDelegate d = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableDelegateTester1.class;
          throwables[1] = NestableDelegateTester2.class;
          throwables[2] = NestableDelegateTester1.class;
          throwables[3] = NestableDelegateTester2.class;
          throwables[4] = Exception.class;
          int[] indexes = {0, 1, 0, 1, 4};
          n = new NestableDelegateTester1(msgs[0], new NestableDelegateTester2(msgs[1], new NestableDelegateTester1(new NestableDelegateTester2(msgs[3], new Exception(msgs[4])))));
          d = new NestableDelegate(n);
          for(int i = 0; i < throwables.length; i++)
          {
              doNestableDelegateIndexOfThrowable(d, throwables[i], 0, indexes[i], msgs[indexes[i]]);
          }
          doNestableDelegateIndexOfThrowable(d, NestableDelegateTester2.class, 2, 3, msgs[3]);
          doNestableDelegateIndexOfThrowable(d, NestableDelegateTester1.class, 1, 2, msgs[2]);
          doNestableDelegateIndexOfThrowable(d, java.util.Date.class, 0, -1, null);
      }
  
      private void doNestableDelegateIndexOfThrowable(NestableDelegate d, Class type, int pos, int expectedIndex, String expectedMsg)
      {
          Throwable t = null;
          
          int index = d.indexOfThrowable(pos, type);
          assertEquals("index of throwable " + type.getName(), expectedIndex, index);
          t = d.getThrowable(index);
          if(expectedMsg != null)
          {
              String msg = null;
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("message of indexed throwable", expectedMsg, msg);
          }
      }
      
      public void testNestableDelegetePrintStackTrace()
      {
          int lineSepLen = lineSeparator.length();
          int partialStackTraceLen = PARTIAL_STACK_TRACE.length();
          Nestable ne3 = new ThrowableNestedNestable(new Exception("nested exception 3"));
          NestableDelegate nd3 = new NestableDelegate(ne3);
  
          ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
          PrintStream ps1 = new PrintStream(baos1);
          nd3.printStackTrace(ps1);
          String stack1 = baos1.toString();
          assertTrue("stack trace startsWith == java.lang.Exception: nested exception 3",
              stack1.startsWith("java.lang.Exception: nested exception 3"));
          int start1 = (stack1.length() - lineSepLen) - partialStackTraceLen;
          int end1 = stack1.length() - lineSepLen;
          assertEquals("stack trace substring(" + start1 + "," + end1 + ") == " +
                       PARTIAL_STACK_TRACE,
                       PARTIAL_STACK_TRACE,
                       stack1.substring(start1, end1));
  
          ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
          PrintStream ps2 = new PrintStream(baos2);
          System.setErr(ps2);
          nd3.printStackTrace();
          String stack2 = baos2.toString();
          assertTrue("stack trace startsWith == java.lang.Exception: nested exception 3",
              stack2.startsWith("java.lang.Exception: nested exception 3"));
          int start2 = (stack2.length() - lineSepLen) - partialStackTraceLen;
          int end2 = stack2.length() - lineSepLen;
          assertTrue("stack trace substring(" + start2 + "," + end2 + ") == " + PARTIAL_STACK_TRACE,
              stack2.substring(start2, end2).equals(PARTIAL_STACK_TRACE));
      }
      
      public static void main(String args[])
      {
          TestRunner.run(suite());
      }
  }
  
  class NestableDelegateTester1 extends Exception implements Nestable
  {
      private Throwable cause = null;
  
      public NestableDelegateTester1()
      {
          super();
      }
  
      public NestableDelegateTester1(String reason, Throwable cause)
      {
          super(reason);
          this.cause = cause;
      }
      
      public NestableDelegateTester1(String reason)
      {
          super(reason);
      }
      
      public NestableDelegateTester1(Throwable cause)
      {
          super();
          this.cause = cause;
      }
      
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       *
       * @return the <code>Throwable</code>s
       */
      public Throwable[] getThrowables()
      {
          return new Throwable[0];
      }
      
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       *
       * @return the error messages
       */
      public String[] getMessages()
      {
          return new String[0];
      }
      
      /**
       * Returns the index, numbered from 0, of the first occurrence of the
       * specified type in the chain of <code>Throwable</code>s, or -1 if the
       * specified type is not found in the chain. If <code>pos</code> is
       * negative, the effect is the same as if it were 0. If <code>pos</code>
       * is greater than or equal to the length of the chain, the effect is the
       * same as if it were the index of the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(Class type)
      {
          return -1;
      }
      
      /**
       * Returns the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s at the specified index, numbererd from 0. If
       * <code>index</code> is negative, the effect is the same as if it
       * were 0. If <code>index</code> is greater than or equal to the length
       * of the chain, the last <code>Throwable</code> in the chain is returned.
       *
       * @param index the index of the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s
       * @return the <code>Throwable</code>
       */
      public Throwable getThrowable(int index)
      {
          return null;
      }
      
      /**
       * Returns the number of nested <code>Throwable</code>s represented by
       * this <code>Nestable</code>, including this <code>Nestable</code>.
       */
      public int getLength()
      {
          return 1;
      }
      
      /**
       * Returns the reference to the exception or error that caused the
       * exception implementing the <code>Nestable</code> to be thrown.
       */
      public Throwable getCause()
      {
          return cause;
      }
      
      /**
       * Prints the stack trace for this exception only--root cause not
       * included--using the provided writer.  Used by {@link
       * org.apache.commons.lang.exception.NestableDelegate} to write
       * individual stack traces to a buffer.  The implementation of
       * this method should call
       * <code>super.printStackTrace(out);</code> in most cases.
       *
       * @param out The writer to use.
       */
      public void printPartialStackTrace(PrintWriter out)
      {
      }
      
      /**
       * Returns the error message of the <code>Throwable</code> in the chain
       * of <code>Throwable</code>s at the specified index, numbererd from 0.
       * If <code>index</code> is negative, the effect is the same as if it
       * were 0. If <code>index</code> is greater than or equal to the length
       * of the chain, the message of the last <code>Throwable</code> in the
       * chain is returned.
       *
       * @param index the index of the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s
       * @return the error message
       */
      public String getMessage(int index)
      {
          if(index == 0)
          {
              return super.getMessage();
          }
          else
          {
              return "";
          }
      }
      
      /**
       * Returns the index, numbered from 0, of the first <code>Throwable</code>
       * that matches the specified type in the chain of <code>Throwable</code>s
       * with an index greater than or equal to the specified position, or -1 if
       * the type is not found. If <code>pos</code> is negative, the effect is the
       * same as if it were 0. If <code>pos</code> is greater than or equal to the
       * length of the chain, the effect is the same as if it were the index of
       * the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @param pos index, numbered from 0, of the starting position in the chain
       * to be searched
       *
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type)
      {
          return -1;
      }
      
  }
  
  class NestableDelegateTester2 extends Throwable implements Nestable
  {
      private Throwable cause = null;
  
      public NestableDelegateTester2()
      {
          super();
      }
      
      public NestableDelegateTester2(String reason, Throwable cause)
      {
          super(reason);
          this.cause = cause;
      }
      
      public NestableDelegateTester2(String reason)
      {
          super(reason);
      }
      
      public NestableDelegateTester2(Throwable cause)
      {
          super();
          this.cause = cause;
      }
      
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       *
       * @return the <code>Throwable</code>s
       */
      public Throwable[] getThrowables()
      {
          return new Throwable[0];
      }
      
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       *
       * @return the error messages
       */
      public String[] getMessages()
      {
          return new String[0];
      }
      
      /**
       * Returns the index, numbered from 0, of the first occurrence of the
       * specified type in the chain of <code>Throwable</code>s, or -1 if the
       * specified type is not found in the chain. If <code>pos</code> is
       * negative, the effect is the same as if it were 0. If <code>pos</code>
       * is greater than or equal to the length of the chain, the effect is the
       * same as if it were the index of the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(Class type)
      {
          return -1;
      }
      
      /**
       * Returns the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s at the specified index, numbererd from 0. If
       * <code>index</code> is negative, the effect is the same as if it
       * were 0. If <code>index</code> is greater than or equal to the length
       * of the chain, the last <code>Throwable</code> in the chain is returned.
       *
       * @param index the index of the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s
       * @return the <code>Throwable</code>
       */
      public Throwable getThrowable(int index)
      {
          return null;
      }
      
      /**
       * Returns the number of nested <code>Throwable</code>s represented by
       * this <code>Nestable</code>, including this <code>Nestable</code>.
       */
      public int getLength()
      {
          return 1;
      }
      
      /**
       * Returns the reference to the exception or error that caused the
       * exception implementing the <code>Nestable</code> to be thrown.
       */
      public Throwable getCause()
      {
          return cause;
      }
      
      /**
       * Prints the stack trace for this exception only--root cause not
       * included--using the provided writer.  Used by {@link
       * org.apache.commons.lang.exception.NestableDelegate} to write
       * individual stack traces to a buffer.  The implementation of
       * this method should call
       * <code>super.printStackTrace(out);</code> in most cases.
       *
       * @param out The writer to use.
       */
      public void printPartialStackTrace(PrintWriter out)
      {
      }
      
      /**
       * Returns the error message of the <code>Throwable</code> in the chain
       * of <code>Throwable</code>s at the specified index, numbererd from 0.
       * If <code>index</code> is negative, the effect is the same as if it
       * were 0. If <code>index</code> is greater than or equal to the length
       * of the chain, the message of the last <code>Throwable</code> in the
       * chain is returned.
       *
       * @param index the index of the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s
       * @return the error message
       */
      public String getMessage(int index)
      {
          if(index == 0)
          {
              return super.getMessage();
          }
          else
          {
              return "";
          }
      }
      
      /**
       * Returns the index, numbered from 0, of the first <code>Throwable</code>
       * that matches the specified type in the chain of <code>Throwable</code>s
       * with an index greater than or equal to the specified position, or -1 if
       * the type is not found. If <code>pos</code> is negative, the effect is the
       * same as if it were 0. If <code>pos</code> is greater than or equal to the
       * length of the chain, the effect is the same as if it were the index of
       * the last element in the chain.
       *
       * @param type <code>Class</code> to be found
       * @param pos index, numbered from 0, of the starting position in the chain
       * to be searched
       *
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type)
      {
          return -1;
      }
      
  }
  
  class ThrowableNestable extends Throwable implements Nestable
  {
      private Throwable cause = new Exception("ThrowableNestable cause");
  
      /**
       * Returns the number of nested <code>Throwable</code>s represented by
       * this <code>Nestable</code>, including this <code>Nestable</code>.
       */
      public int getLength()
      {
          return 1;
      }
      
      /**
       * Returns the error message of this and any nested
       * <code>Throwable</code>.
       *
       * @return The error message.
       */
      public String getMessage()
      {
          return "ThrowableNestable exception";
      }
  
      /**
       * Returns the error message of the <code>Throwable</code> in the chain
       * of <code>Throwable</code>s at the specified index, numbererd from 0.
       * If <code>index</code> is negative, the effect is the same as if it
       * were 0. If <code>index</code> is greater than or equal to the length
       * of the chain, the message of the last <code>Throwable</code> in the
       * chain is returned.
       *
       * @param index the index of the <code>Throwable</code> in the chain of
       * <code>Throwable</code>s
       * @return the error message
       */
      public String getMessage(int index)
      {
          return getMessage();
      }
  
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       */
      public String[] getMessages()
      {
          String msgs[] = new String[1];
          msgs[0] = getMessage();
          return msgs;
      }
      
      /**
       * Returns the reference to the exception or error that caused the
       * exception implementing the <code>Nestable</code> to be thrown.
       */
      public Throwable getCause()
      {
          return cause;
      }
  
      /**
       * Prints the stack trace of this exception to the specified print
       * writer.  Includes inforamation from the exception--if
       * any--which caused this exception.
       *
       * @param out <code>PrintWriter</code> to use for output.
       */
      public void printStackTrace(PrintWriter out)
      {
      }
      
      /**
       * Prints the stack trace for this exception only--root cause not
       * included--using the provided writer.  Used by {@link
       * org.apache.commons.lang.exception.NestableDelegate} to write
       * individual stack traces to a buffer.  The implementation of
       * this method should call
       * <code>super.printStackTrace(out);</code> in most cases.
       *
       * @param out The writer to use.
       */
      public void printPartialStackTrace(PrintWriter out)
      {
      }
      
      public Throwable getThrowable(int index)
      {
          return cause;
      }
      
      public Throwable[] getThrowables()
      {
          Throwable throwables[] = new Throwable[1];
          throwables[0] = cause;
          return throwables;
      }
      
      public int indexOfThrowable(Class type)
      {
          if(Exception.class.isInstance(type))
          {
              return 0;
          }
          return -1;
      }
      
      /**
       * Returns the index of the first <code>Throwable</code> that matches the
       * specified type with an index greater than or equal to the specified
       * position, or -1 if the type is not found.
       *
       * @param type <code>Class</code> to be found
       * @param pos
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type)
      {
          return indexOfThrowable(type);
      }
      
  }
  
  class ThrowableNestedNestable extends Throwable implements Nestable
  {
      private Throwable cause = null;
      
      public ThrowableNestedNestable(Throwable cause)
      {
          this.cause = cause;
      }
      
      public int getLength()
      {
          return 1;
      }
      
      /**
       * Returns the error message of this and any nested
       * <code>Throwable</code>.
       *
       * @return The error message.
       */
      public String getMessage()
      {
          return "ThrowableNestedNestable exception (" + cause.getMessage() + ")";
      }
  
      public String getMessage(int index)
      {
          return "ThrowableNestedNestable exception (" + cause.getMessage() + ")";
      }
      
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       */
      public String[] getMessages()
      {
          String[] msgs = new String[1];
          msgs[0] = "ThrowableNestedNestable exception (" + cause.getMessage() + ")";
          return msgs;
      }
      
      /**
       * Returns the reference to the exception or error that caused the
       * exception implementing the <code>Nestable</code> to be thrown.
       */
      public Throwable getCause()
      {
          return cause;
      }
      
      /**
       * Prints the stack trace of this exception to the specified print
       * writer.  Includes inforamation from the exception--if
       * any--which caused this exception.
       *
       * @param out <code>PrintWriter</code> to use for output.
       */
      public void printStackTrace(PrintWriter out)
      {
          out.println("ThrowableNestedNestable stack trace place-holder");
      }
      
      /**
       * Prints the stack trace for this exception only--root cause not
       * included--using the provided writer.  Used by {@link
       * org.apache.commons.lang.exception.NestableDelegate} to write
       * individual stack traces to a buffer.  The implementation of
       * this method should call
       * <code>super.printStackTrace(out);</code> in most cases.
       *
       * @param out The writer to use.
       */
      public void printPartialStackTrace(PrintWriter out)
      {
          out.println("ThrowableNestedNestable partial stack trace place-holder");
      }
      
      public Throwable getThrowable(int index)
      {
          return cause;
      }
      
      public Throwable[] getThrowables()
      {
          Throwable throwables[] = new Throwable[1];
          throwables[0] = cause;
          return throwables;
      }
      
      public int indexOfThrowable(Class type)
      {
          if(Exception.class.isInstance(type))
          {
              return 0;
          }
          return -1;
      }
      
      /**
       * Returns the index of the first <code>Throwable</code> that matches the
       * specified type with an index greater than or equal to the specified
       * position, or -1 if the type is not found.
       *
       * @param type <code>Class</code> to be found
       * @param pos
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type)
      {
          return indexOfThrowable(type);
      }
      
  }
  
  class NonThrowableNestable implements Nestable
  {
      public int getLength()
      {
          return 1;
      }
      
      /**
       * Returns the error message of this and any nested
       * <code>Throwable</code>.
       *
       * @return The error message.
       */
      public String getMessage()
      {
          return "non-throwable";
      }
  
      public String getMessage(int index)
      {
          return "non-throwable";
      }
      
      /**
       * Returns the error message of this and any nested <code>Throwable</code>s
       * in an array of Strings, one element for each message. Any
       * <code>Throwable</code> specified without a message is represented in
       * the array by a null.
       */
      public String[] getMessages()
      {
          String[] msgs = new String[1];
          msgs[0] = "non-throwable";
          return msgs;
      }
      
      /**
       * Returns the reference to the exception or error that caused the
       * exception implementing the <code>Nestable</code> to be thrown.
       */
      public Throwable getCause()
      {
          return null;
      }
      
      /**
       * Prints the stack trace of this exception to the specified print
       * writer.  Includes inforamation from the exception--if
       * any--which caused this exception.
       *
       * @param out <code>PrintWriter</code> to use for output.
       */
      public void printStackTrace(PrintWriter out)
      {
      }
      
      /**
       * Prints the stack trace for this exception only--root cause not
       * included--using the provided writer.  Used by {@link
       * org.apache.commons.lang.exception.NestableDelegate} to write
       * individual stack traces to a buffer.  The implementation of
       * this method should call
       * <code>super.printStackTrace(out);</code> in most cases.
       *
       * @param out The writer to use.
       */
      public void printPartialStackTrace(PrintWriter out)
      {
      }
      
      public Throwable getThrowable(int index)
      {
          return null;
      }
      
      public Throwable[] getThrowables()
      {
          return new Throwable[0];
      }
      
      public int indexOfThrowable(Class type)
      {
          return -1;
      }
      
      /**
       * Returns the index of the first <code>Throwable</code> that matches the
       * specified type with an index greater than or equal to the specified
       * position, or -1 if the type is not found.
       *
       * @param type <code>Class</code> to be found
       * @param pos
       * @return index of the first occurrence of the type in the chain, or -1 if
       * the type is not found
       */
      public int indexOfThrowable(int pos, Class type)
      {
          return -1;
      }
      
  }
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/exception/NestableExceptionTestCase.java
  
  Index: NestableExceptionTestCase.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayOutputStream;
  import java.io.PrintStream;
  import java.io.PrintWriter;
  
  import junit.framework.*;
  import junit.textui.TestRunner;
  /**
   * Tests the org.apache.commons.lang.exception.NestableException class.
   *
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @version $Id: NestableExceptionTestCase.java,v 1.1 2002/07/19 03:35:55 bayard Exp $
   */
  public class NestableExceptionTestCase extends junit.framework.TestCase
  {
      
      /**
       * Construct a new instance of NestableExceptionTestCase with the specified name
       */
      public NestableExceptionTestCase(String name)
      {
          super(name);
      }
  
      /**
       * Set up instance variables required by this test case.
       */
      public void setUp()
      {
      }
      
      public static Test suite()
      {
          return new TestSuite(NestableExceptionTestCase.class);
      }
      
      /**
       * Tear down instance variables required by this test case.
       */
      public void tearDown()
      {
      }
      
      /**
       * Test the implementation
       */
      public void testGetCause()
      {
          NestableException ne1 = new NestableException();
          assertNull("nestable exception() cause is null", ne1.getCause()); 
          
          NestableException ne2 = new NestableException("ne2");
          assertNull("nestable exception(\"ne2\") cause is null", ne2.getCause());
          
          NestableException ne3 = new NestableException(new Exception("ne3 exception"));
          assertNotNull("nestable exception(new Exception(\"ne3 exception\") cause is not null",
              ne3.getCause()); 
          assertTrue("nestable exception(new Exception(\"ne3 exception\") cause message == ne3 exception",
              ne3.getCause().getMessage().equals("ne3 exception")); 
          
          NestableException ne4 = new NestableException("ne4", new Exception("ne4 exception"));
          assertNotNull("nestable exception(\"ne4\", new Exception(\"ne4 exception\") cause is not null", 
              ne4.getCause()); 
          
          NestableException ne5 = new NestableException("ne5", null);
          assertNull("nestable exception(\"ne5\", null) cause is null", 
              ne5.getCause()); 
          
          NestableException ne6 = new NestableException(null, new Exception("ne6 exception"));
          assertNotNull("nestable exception(null, new Exception(\"ne6 exception\") cause is not null", 
              ne6.getCause()); 
      }
  
      public void testGetLength()
      {
          NestableException ne1 = new NestableException();
          assertEquals("ne1 length", 1, ne1.getLength());
  
          NestableException ne2 = new NestableException("ne2");
          assertEquals("ne2 length", 1, ne2.getLength());
          
          NestableException ne3 = new NestableException(new Exception("ne3 exception"));
          assertEquals("ne3 length", 2, ne3.getLength());
          
          NestableException ne4 = new NestableException("ne4", new Exception("ne4 exception"));
          assertEquals("ne4 length", 2, ne4.getLength());
          
          NestableException ne5 = new NestableException("ne5", null);
          assertEquals("ne 5 length", 1, ne5.getLength());
          
          NestableException ne6 = new NestableException(null, new Exception("ne6 exception"));
          assertEquals("ne 6 length", 2, ne6.getLength());
          
          NestableException ne7 = new NestableException("ne7o", new NestableException("ne7i", new Exception("ne7 exception")));
          assertEquals("ne 7 length", 3, ne7.getLength());
  
          NestableException ne8 = new NestableException("level 1", new NestableException("level 2", new NestableException(new NestableException("level 4", new Exception("level 5")))));
          assertEquals("ne 8 length", 5, ne8.getLength());
      }
      
      public void testGetMessage()
      {
          NestableException ne1 = new NestableException();
          assertNull("nestable exception() message is null", ne1.getMessage()); 
  
          NestableException ne2 = new NestableException("ne2");
          assertNotNull("nestable exception(\"ne2\") message is not null", ne2.getMessage());
          assertTrue("nestable exception(\"ne2\") message == ne2", ne2.getMessage().equals("ne2"));
          
          NestableException ne3 = new NestableException(new Exception("ne3 exception"));
          assertNotNull("nestable exception(new Exception(\"ne3 exception\") message is not null",
              ne3.getMessage()); 
          assertTrue("nestable exception(new Exception(\"ne3 exception\") message == cause message",
              ne3.getMessage().equals(ne3.getCause().getMessage())); 
          
          NestableException ne4 = new NestableException("ne4", new Exception("ne4 exception"));
          assertNotNull("nestable exception(\"ne4\", new Exception(\"ne4 exception\") message is not null", 
              ne4.getMessage()); 
          assertTrue("nestable exception(\"ne4\", new Exception(\"ne4 exception\") message == ne4: ne4 exception", 
              ne4.getMessage().equals("ne4: ne4 exception")); 
          
          NestableException ne5 = new NestableException("ne5", null);
          assertNotNull("nestable exception(\"ne5\", new Exception(\"ne5 exception\") message is not null", 
              ne5.getMessage()); 
          assertTrue("nestable exception(\"ne5\", null) message == ne5", 
              ne5.getMessage().equals("ne5")); 
          
          NestableException ne6 = new NestableException(null, new Exception("ne6 exception"));
          assertTrue("nestable exception(null, new Exception(\"ne6 exception\") cause == ne6 exception", 
              ne6.getMessage().equals("ne6 exception")); 
          
          NestableException ne7 = new NestableException("ne7o", new NestableException("ne7i", new Exception("ne7 exception")));
          assertTrue("nextable exception(\"ne7o\", new NestableException(\"ne7i\", new Exception(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
              ne7.getMessage().equals("ne7o: ne7i: ne7 exception"));
  
      }
  
      public void testGetMessageN()
      {
          String[] msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          NestableException ne = new NestableException(msgs[0], new NestableException(msgs[1], new NestableException(new NestableException(msgs[3], new Exception(msgs[4])))));
          for(int i = 0; i < msgs.length; i++)
          {
              assertEquals("message " + i, msgs[i], ne.getMessage(i));
          }
          assertEquals("message -1", msgs[0], ne.getMessage(-1));
          assertEquals("message 999", msgs[4], ne.getMessage(999));
      }
      
      public void testGetMessages()
      {
          String[] msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          NestableException ne = new NestableException(msgs[0], new NestableException(msgs[1], new NestableException(new NestableException(msgs[3], new Exception(msgs[4])))));
          String[] nMsgs = ne.getMessages();
          assertEquals("messages length", msgs.length, nMsgs.length);
          for(int i = 0; i < nMsgs.length; i++)
          {
              assertEquals("message " + i, msgs[i], nMsgs[i]);
          }
      }
  
      public void testGetThrowable()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[2];
          msgs[0] = null;
          msgs[1] = "level 2";
          throwables = new Class[2];
          throwables[0] = NestableExceptionTester1.class;
          throwables[1] = Exception.class;
          n = new NestableExceptionTester1(new Exception(msgs[1]));
          doNestableExceptionGetThrowable(n, throwables, msgs);
   
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableExceptionTester1.class;
          throwables[1] = NestableExceptionTester2.class;
          throwables[2] = NestableExceptionTester1.class;
          throwables[3] = NestableExceptionTester2.class;
          throwables[4] = Exception.class;        
          n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
          doNestableExceptionGetThrowable(n, throwables, msgs);
      }
      
      private void doNestableExceptionGetThrowable(Nestable n, Class[] classes, String[] msgs)
      {
          Throwable t = null;
          String msg = null;
  
          for(int i = 0; i < classes.length; i++)
          {
              t = n.getThrowable(i);
              assertEquals("throwable class", classes[i], t.getClass());
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("throwable message", msgs[i], msg);
          }
          t = n.getThrowable(-1);
          assertEquals("throwable(-1)", classes[0], t.getClass());
          if(Nestable.class.isInstance(t))
          {
              msg = ((Nestable) t).getMessage(0);
          }
          else
          {
              msg = t.getMessage();
          }
          assertEquals("throwable message", msgs[0], msg);
          t = n.getThrowable(999);
          assertEquals("throwable(999)", classes[classes.length - 1], t.getClass());
          if(Nestable.class.isInstance(t))
          {
              msg = ((Nestable) t).getMessage(0);
          }
          else
          {
              msg = t.getMessage();
          }
          assertEquals("throwable message", msgs[msgs.length - 1], msg);
      }
      
      public void testGetThrowables()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[2];
          msgs[0] = null;
          msgs[1] = "level 2";
          throwables = new Class[2];
          throwables[0] = NestableExceptionTester1.class;
          throwables[1] = Exception.class;
          n = new NestableExceptionTester1(new Exception(msgs[1]));
          doNestableExceptionGetThrowables(n, throwables, msgs);
   
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableExceptionTester1.class;
          throwables[1] = NestableExceptionTester2.class;
          throwables[2] = NestableExceptionTester1.class;
          throwables[3] = NestableExceptionTester2.class;
          throwables[4] = Exception.class;        
          n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
          doNestableExceptionGetThrowables(n, throwables, msgs);
      }
      
      private void doNestableExceptionGetThrowables(Nestable n, Class[] classes, String[] msgs)
      {
          String msg = null;
  
          Throwable throwables[] = n.getThrowables();
          assertEquals("throwables length", classes.length, throwables.length);
          for(int i = 0; i < classes.length; i++)
          {
              assertEquals("throwable class", classes[i], throwables[i].getClass());
              Throwable t = throwables[i];
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("throwable message", msgs[i], msg);
          }
      }
      
      public void testIndexOfThrowable()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableExceptionTester1.class;
          throwables[1] = NestableExceptionTester2.class;
          throwables[2] = NestableExceptionTester1.class;
          throwables[3] = NestableExceptionTester2.class;
          throwables[4] = Exception.class;
          int[] indexes = {0, 1, 0, 1, 4};
          n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
          for(int i = 0; i < throwables.length; i++)
          {
              doNestableExceptionIndexOfThrowable(n, throwables[i], indexes[i], msgs[indexes[i]]);
          }
          doNestableExceptionIndexOfThrowable(n, java.util.Date.class, -1, null);
      }
      
      private void doNestableExceptionIndexOfThrowable(Nestable n, Class type, int expectedIndex, String expectedMsg)
      {
          Throwable t = null;
          
          int index = n.indexOfThrowable(type);
          assertEquals("index of throwable " + type.getName(), expectedIndex, index);
          t = n.getThrowable(index);
          if(expectedMsg != null)
          {
              String msg = null;
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("message of indexed throwable", expectedMsg, msg);
          }
      }
      
      public void testIndexOfThrowableN()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableExceptionTester1.class;
          throwables[1] = NestableExceptionTester2.class;
          throwables[2] = NestableExceptionTester1.class;
          throwables[3] = NestableExceptionTester2.class;
          throwables[4] = Exception.class;
          int[] indexes = {0, 1, 0, 1, 4};
          n = new NestableExceptionTester1(msgs[0], new NestableExceptionTester2(msgs[1], new NestableExceptionTester1(new NestableExceptionTester2(msgs[3], new Exception(msgs[4])))));
          for(int i = 0; i < throwables.length; i++)
          {
              doNestableExceptionIndexOfThrowableN(n, throwables[i], 0, indexes[i], msgs[indexes[i]]);
          }
          doNestableExceptionIndexOfThrowableN(n, NestableExceptionTester2.class, 2, 3, msgs[3]);
          doNestableExceptionIndexOfThrowableN(n, NestableExceptionTester1.class, 1, 2, msgs[2]);
          doNestableExceptionIndexOfThrowableN(n, java.util.Date.class, 0, -1, null);
      }
  
      private void doNestableExceptionIndexOfThrowableN(Nestable n, Class type, int pos, int expectedIndex, String expectedMsg)
      {
          Throwable t = null;
          
          int index = n.indexOfThrowable(pos, type);
          assertEquals("index of throwable " + type.getName(), expectedIndex, index);
          t = n.getThrowable(index);
          if(expectedMsg != null)
          {
              String msg = null;
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("message of indexed throwable", expectedMsg, msg);
          }
      }
      
      public void testPrintPartialStackTrace()
      {
          NestableException ne9 = new NestableException("ne9", new Exception("ne9 exception"));
          ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
          PrintStream ps2 = new PrintStream(baos2);
          PrintWriter pw2 = new PrintWriter(ps2, true);
          ne9.printPartialStackTrace(pw2);
          String stack2 = baos2.toString();
          assertTrue("stack trace startsWith == org.apache.commons.lang.exception.NestableException: ne9: ne9 exception",
              stack2.startsWith("org.apache.commons.lang.exception.NestableException: ne9: ne9 exception"));
          assertEquals("stack trace indexOf rethrown == -1",
              stack2.indexOf("rethrown"), -1);
      }
      
      public void testPrintStackTrace()
      {
          NestableException ne8 = new NestableException("ne8", new Exception("ne8 exception"));
          ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
          PrintStream ps1 = new PrintStream(baos1);
          PrintWriter pw1 = new PrintWriter(ps1, true);
          ne8.printStackTrace(ps1);
          String stack1 = baos1.toString();
          assertTrue("stack trace startsWith == java.lang.Exception: ne8 exception",
              stack1.startsWith("java.lang.Exception: ne8 exception")); 
          assertTrue("stack trace indexOf org.apache.commons.lang.exception.NestableException: ne8: ne8 exception > -1",
              stack1.indexOf("org.apache.commons.lang.exception.NestableException: ne8: ne8 exception") > -1); 
      }
  
      public static void main(String args[])
      {
          TestRunner.run(suite());
      }
  }
  
  class NestableExceptionTester1 extends NestableException
  {
      public NestableExceptionTester1()
      {
          super();
      }
  
      public NestableExceptionTester1(String reason, Throwable cause)
      {
          super(reason, cause);
      }
      
      public NestableExceptionTester1(String reason)
      {
          super(reason);
      }
      
      public NestableExceptionTester1(Throwable cause)
      {
          super(cause);
      }
      
  }
  
  class NestableExceptionTester2 extends NestableException
  {
      public NestableExceptionTester2()
      {
          super();
      }
      
      public NestableExceptionTester2(String reason, Throwable cause)
      {
          super(reason, cause);
      }
      
      public NestableExceptionTester2(String reason)
      {
          super(reason);
      }
      
      public NestableExceptionTester2(Throwable cause)
      {
          super(cause);
      }
      
  }
  
  
  
  
  1.1                  jakarta-commons/lang/src/test/org/apache/commons/lang/exception/NestableRuntimeExceptionTestCase.java
  
  Index: NestableRuntimeExceptionTestCase.java
  ===================================================================
  package org.apache.commons.lang.exception;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.ByteArrayOutputStream;
  import java.io.PrintStream;
  import java.io.PrintWriter;
  
  import junit.framework.*;
  import junit.textui.TestRunner;
  /**
   * Tests the org.apache.commons.lang.exception.NestableRuntimeException class.
   *
   * @author <a href="mailto:steven@caswell.name">Steven Caswell</a>
   * @version $Id: NestableRuntimeExceptionTestCase.java,v 1.1 2002/07/19 03:35:56 bayard Exp $
   */
  public class NestableRuntimeExceptionTestCase extends junit.framework.TestCase
  {
      /**
       * Construct a new instance of NestableRuntimeExceptionTestCase with the specified name
       */
      public NestableRuntimeExceptionTestCase(String name)
      {
          super(name);
      }
  
      /**
       * Set up instance variables required by this test case.
       */
      public void setUp()
      {
      }
      
      public static Test suite()
      {
          return new TestSuite(NestableRuntimeExceptionTestCase.class);
      }
      
      /**
       * Tear down instance variables required by this test case.
       */
      public void tearDown()
      {
      }
      
      /**
       * Test the implementation
       */
      public void testGetCause()
      {
          NestableRuntimeException ne1 = new NestableRuntimeException();
          assertNull("nestable runtime exception() cause is null", ne1.getCause()); 
          
          NestableRuntimeException ne2 = new NestableRuntimeException("ne2");
          assertNull("nestable runtime exception(\"ne2\") cause is null", ne2.getCause());
  
          NestableRuntimeException ne3 = new NestableRuntimeException(new Exception("ne3 exception"));
          assertNotNull("nestable runtime exception(new Exception(\"ne3 exception\") cause is not null",
              ne3.getCause()); 
          assertTrue("nestable runtime exception(new Exception(\"ne3 exception\") cause message == ne3 exception",
              ne3.getCause().getMessage().equals("ne3 exception")); 
  
          NestableRuntimeException ne4 = new NestableRuntimeException("ne4", new Exception("ne4 exception"));
          assertNotNull("nestable runtime exception(\"ne4\", new Exception(\"ne4 exception\") cause is not null", 
              ne4.getCause()); 
  
          NestableRuntimeException ne5 = new NestableRuntimeException("ne5", null);
          assertNull("nestable runtime exception(\"ne5\", null) cause is null", 
              ne5.getCause());
  
          NestableRuntimeException ne6 = new NestableRuntimeException(null, new Exception("ne6 exception"));
          assertNotNull("nestable runtime exception(null, new Exception(\"ne6 exception\") cause is not null", 
              ne6.getCause()); 
      }
      
      public void testGetLength()
      {
          NestableRuntimeException ne1 = new NestableRuntimeException();
          assertEquals("ne1 length", 1, ne1.getLength());
  
          NestableRuntimeException ne2 = new NestableRuntimeException("ne2");
          assertEquals("ne2 length", 1, ne2.getLength());
          
          NestableRuntimeException ne3 = new NestableRuntimeException(new Exception("ne3 exception"));
          assertEquals("ne3 length", 2, ne3.getLength());
          
          NestableRuntimeException ne4 = new NestableRuntimeException("ne4", new Exception("ne4 exception"));
          assertEquals("ne4 length", 2, ne4.getLength());
          
          NestableRuntimeException ne5 = new NestableRuntimeException("ne5", null);
          assertEquals("ne 5 length", 1, ne5.getLength());
          
          NestableRuntimeException ne6 = new NestableRuntimeException(null, new Exception("ne6 exception"));
          assertEquals("ne 6 length", 2, ne6.getLength());
          
          NestableRuntimeException ne7 = new NestableRuntimeException("ne7o", new NestableRuntimeException("ne7i", new Exception("ne7 exception")));
          assertEquals("ne 7 length", 3, ne7.getLength());
  
          NestableRuntimeException ne8 = new NestableRuntimeException("level 1", new NestableRuntimeException("level 2", new NestableRuntimeException(new NestableRuntimeException("level 4", new Exception("level 5")))));
          assertEquals("ne 8 length", 5, ne8.getLength());
      }
      
      public void testGetMessage()
      {
          NestableRuntimeException ne1 = new NestableRuntimeException();
          assertNull("nestable runtime exception() message is null", ne1.getMessage()); 
          
          NestableRuntimeException ne2 = new NestableRuntimeException("ne2");
          assertNotNull("nestable runtime exception(\"ne2\") message is not null", ne2.getMessage()); 
          assertTrue("nestable runtime exception(\"ne2\") message == ne2", ne2.getMessage().equals("ne2")); 
  
          NestableRuntimeException ne3 = new NestableRuntimeException(new Exception("ne3 exception"));
          assertNotNull("nestable runtime exception(new Exception(\"ne3 exception\") message is not null",
              ne3.getMessage());
          assertTrue("nestable runtime exception(new Exception(\"ne3 exception\") message == cause message",
              ne3.getMessage().equals(ne3.getCause().getMessage())); 
  
          NestableRuntimeException ne4 = new NestableRuntimeException("ne4", new Exception("ne4 exception"));
          assertNotNull("nestable runtime exception(\"ne4\", new Exception(\"ne4 exception\") message is not null", 
              ne4.getMessage()); 
          assertTrue("nestable runtime exception(\"ne4\", new Exception(\"ne4 exception\") message == ne4: ne4 exception", 
              ne4.getMessage().equals("ne4: ne4 exception")); 
  
          NestableRuntimeException ne5 = new NestableRuntimeException("ne5", null);
          assertNotNull("nestable runtime exception(\"ne5\", new Exception(\"ne5 exception\") message is not null", 
              ne5.getMessage()); 
          assertTrue("nestable runtime exception(\"ne5\", null) message == ne5", 
              ne5.getMessage().equals("ne5")); 
  
          NestableRuntimeException ne6 = new NestableRuntimeException(null, new Exception("ne6 exception"));
          assertTrue("nestable runtime exception(null, new Exception(\"ne6 exception\") cause == ne6 exception", 
              ne6.getMessage().equals("ne6 exception")); 
  
          NestableRuntimeException ne7 = new NestableRuntimeException("ne7o", new NestableRuntimeException("ne7i", new Exception("ne7 exception")));
          assertTrue("nextable exception(\"ne7o\", new NestableRuntimeException(\"ne7i\", new Exception(\"ne7 exception\"))) message is ne7o: ne7i: ne7 exception",
              ne7.getMessage().equals("ne7o: ne7i: ne7 exception")); 
      }
      
      public void testGetMessageN()
      {
          String[] msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          NestableRuntimeException ne = new NestableRuntimeException(msgs[0], new NestableRuntimeException(msgs[1], new NestableRuntimeException(new NestableRuntimeException(msgs[3], new Exception(msgs[4])))));
          for(int i = 0; i < msgs.length; i++)
          {
              assertEquals("message " + i, msgs[i], ne.getMessage(i));
          }
          assertEquals("message -1", msgs[0], ne.getMessage(-1));
          assertEquals("message 999", msgs[4], ne.getMessage(999));
      }
      
      public void testGetMessages()
      {
          String[] msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          NestableRuntimeException ne = new NestableRuntimeException(msgs[0], new NestableRuntimeException(msgs[1], new NestableRuntimeException(new NestableRuntimeException(msgs[3], new Exception(msgs[4])))));
          String[] nMsgs = ne.getMessages();
          assertEquals("messages length", msgs.length, nMsgs.length);
          for(int i = 0; i < nMsgs.length; i++)
          {
              assertEquals("message " + i, msgs[i], nMsgs[i]);
          }
      }
  
      public void testGetThrowable()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[2];
          msgs[0] = null;
          msgs[1] = "level 2";
          throwables = new Class[2];
          throwables[0] = NestableRuntimeExceptionTester1.class;
          throwables[1] = Exception.class;
          n = new NestableRuntimeExceptionTester1(new Exception(msgs[1]));
          doNestableRuntimeExceptionGetThrowable(n, throwables, msgs);
   
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableRuntimeExceptionTester1.class;
          throwables[1] = NestableRuntimeExceptionTester2.class;
          throwables[2] = NestableRuntimeExceptionTester1.class;
          throwables[3] = NestableRuntimeExceptionTester2.class;
          throwables[4] = Exception.class;        
          n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
          doNestableRuntimeExceptionGetThrowable(n, throwables, msgs);
      }
      
      private void doNestableRuntimeExceptionGetThrowable(Nestable n, Class[] classes, String[] msgs)
      {
          Throwable t = null;
          String msg = null;
  
          for(int i = 0; i < classes.length; i++)
          {
              t = n.getThrowable(i);
              assertEquals("throwable class", classes[i], t.getClass());
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("throwable message", msgs[i], msg);
          }
          t = n.getThrowable(-1);
          assertEquals("throwable(-1)", classes[0], t.getClass());
          if(Nestable.class.isInstance(t))
          {
              msg = ((Nestable) t).getMessage(0);
          }
          else
          {
              msg = t.getMessage();
          }
          assertEquals("throwable message", msgs[0], msg);
          t = n.getThrowable(999);
          assertEquals("throwable(999)", classes[classes.length - 1], t.getClass());
          if(Nestable.class.isInstance(t))
          {
              msg = ((Nestable) t).getMessage(0);
          }
          else
          {
              msg = t.getMessage();
          }
          assertEquals("throwable message", msgs[msgs.length - 1], msg);
      }
      
      public void testGetThrowables()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[2];
          msgs[0] = null;
          msgs[1] = "level 2";
          throwables = new Class[2];
          throwables[0] = NestableRuntimeExceptionTester1.class;
          throwables[1] = Exception.class;
          n = new NestableRuntimeExceptionTester1(new Exception(msgs[1]));
          doNestableRuntimeExceptionGetThrowables(n, throwables, msgs);
   
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableRuntimeExceptionTester1.class;
          throwables[1] = NestableRuntimeExceptionTester2.class;
          throwables[2] = NestableRuntimeExceptionTester1.class;
          throwables[3] = NestableRuntimeExceptionTester2.class;
          throwables[4] = Exception.class;        
          n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
          doNestableRuntimeExceptionGetThrowables(n, throwables, msgs);
      }
      
      private void doNestableRuntimeExceptionGetThrowables(Nestable n, Class[] classes, String[] msgs)
      {
          String msg = null;
  
          Throwable throwables[] = n.getThrowables();
          assertEquals("throwables length", classes.length, throwables.length);
          for(int i = 0; i < classes.length; i++)
          {
              assertEquals("throwable class", classes[i], throwables[i].getClass());
              Throwable t = throwables[i];
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("throwable message", msgs[i], msg);
          }
      }
      
      public void testIndexOfThrowable()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableRuntimeExceptionTester1.class;
          throwables[1] = NestableRuntimeExceptionTester2.class;
          throwables[2] = NestableRuntimeExceptionTester1.class;
          throwables[3] = NestableRuntimeExceptionTester2.class;
          throwables[4] = Exception.class;
          int[] indexes = {0, 1, 0, 1, 4};
          n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
          for(int i = 0; i < throwables.length; i++)
          {
              doNestableRuntimeExceptionIndexOfThrowable(n, throwables[i], indexes[i], msgs[indexes[i]]);
          }
          doNestableRuntimeExceptionIndexOfThrowable(n, java.util.Date.class, -1, null);
      }
      
      private void doNestableRuntimeExceptionIndexOfThrowable(Nestable n, Class type, int expectedIndex, String expectedMsg)
      {
          Throwable t = null;
          
          int index = n.indexOfThrowable(type);
          assertEquals("index of throwable " + type.getName(), expectedIndex, index);
          t = n.getThrowable(index);
          if(expectedMsg != null)
          {
              String msg = null;
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("message of indexed throwable", expectedMsg, msg);
          }
      }
      
      public void testIndexOfThrowableN()
      {
          Nestable n = null;
          String msgs[] = null;
          Class[] throwables = null;
          
          msgs = new String[5];
          msgs[0] = "level 1";
          msgs[1] = "level 2";
          msgs[2] = null;
          msgs[3] = "level 4";
          msgs[4] = "level 5";
          throwables = new Class[5];
          throwables[0] = NestableRuntimeExceptionTester1.class;
          throwables[1] = NestableRuntimeExceptionTester2.class;
          throwables[2] = NestableRuntimeExceptionTester1.class;
          throwables[3] = NestableRuntimeExceptionTester2.class;
          throwables[4] = Exception.class;
          int[] indexes = {0, 1, 0, 1, 4};
          n = new NestableRuntimeExceptionTester1(msgs[0], new NestableRuntimeExceptionTester2(msgs[1], new NestableRuntimeExceptionTester1(new NestableRuntimeExceptionTester2(msgs[3], new Exception(msgs[4])))));
          for(int i = 0; i < throwables.length; i++)
          {
              doNestableRuntimeExceptionIndexOfThrowableN(n, throwables[i], 0, indexes[i], msgs[indexes[i]]);
          }
          doNestableRuntimeExceptionIndexOfThrowableN(n, NestableRuntimeExceptionTester2.class, 2, 3, msgs[3]);
          doNestableRuntimeExceptionIndexOfThrowableN(n, NestableRuntimeExceptionTester1.class, 1, 2, msgs[2]);
          doNestableRuntimeExceptionIndexOfThrowableN(n, java.util.Date.class, 0, -1, null);
      }
  
      private void doNestableRuntimeExceptionIndexOfThrowableN(Nestable n, Class type, int pos, int expectedIndex, String expectedMsg)
      {
          Throwable t = null;
          
          int index = n.indexOfThrowable(pos, type);
          assertEquals("index of throwable " + type.getName(), expectedIndex, index);
          t = n.getThrowable(index);
          if(expectedMsg != null)
          {
              String msg = null;
              if(Nestable.class.isInstance(t))
              {
                  msg = ((Nestable) t).getMessage(0);
              }
              else
              {
                  msg = t.getMessage();
              }
              assertEquals("message of indexed throwable", expectedMsg, msg);
          }
      }
      
      public void testPrintStackTrace()
      {
          NestableRuntimeException ne8 = new NestableRuntimeException("ne8", new Exception("ne8 exception"));
          ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
          PrintStream ps1 = new PrintStream(baos1);
          PrintWriter pw1 = new PrintWriter(ps1, true);
          ne8.printStackTrace(ps1);
          String stack1 = baos1.toString();
          assertTrue("stack trace startsWith == java.lang.Exception: ne8 exception",
              stack1.startsWith("java.lang.Exception: ne8 exception")); 
          assertTrue("stack trace indexOf org.apache.commons.lang.exception.NestableRuntimeException: ne8: ne8 exception > -1",
              stack1.indexOf("org.apache.commons.lang.exception.NestableRuntimeException: ne8: ne8 exception") > -1); 
      }
  
      public void testPrintPartialStackTrace()
      {
          NestableRuntimeException ne9 = new NestableRuntimeException("ne9", new Exception("ne9 exception"));
          ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
          PrintStream ps2 = new PrintStream(baos2);
          PrintWriter pw2 = new PrintWriter(ps2, true);
          ne9.printPartialStackTrace(pw2);
          String stack2 = baos2.toString();
          assertTrue("stack trace startsWith == org.apache.commons.lang.exception.NestableRuntimeException: ne9: ne9 exception",
              stack2.startsWith("org.apache.commons.lang.exception.NestableRuntimeException: ne9: ne9 exception"));
          assertEquals("stack trace indexOf rethrown == -1",
              stack2.indexOf("rethrown"), -1);
      }
  
      public static void main(String args[])
      {
          TestRunner.run(suite());
      }
  }
  
  class NestableRuntimeExceptionTester1 extends NestableRuntimeException
  {
      public NestableRuntimeExceptionTester1()
      {
          super();
      }
  
      public NestableRuntimeExceptionTester1(String reason, Throwable cause)
      {
          super(reason, cause);
      }
      
      public NestableRuntimeExceptionTester1(String reason)
      {
          super(reason);
      }
      
      public NestableRuntimeExceptionTester1(Throwable cause)
      {
          super(cause);
      }
      
  }
  
  class NestableRuntimeExceptionTester2 extends NestableRuntimeException
  {
      public NestableRuntimeExceptionTester2()
      {
          super();
      }
      
      public NestableRuntimeExceptionTester2(String reason, Throwable cause)
      {
          super(reason, cause);
      }
      
      public NestableRuntimeExceptionTester2(String reason)
      {
          super(reason);
      }
      
      public NestableRuntimeExceptionTester2(Throwable cause)
      {
          super(cause);
      }
      
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message