/*
 *    Utils.java

 *
 */

package org.apache.samoa.moa.core;

/*
 * #%L
 * SAMOA
 * %%
 * Copyright (C) 2014 - 2015 Apache Software Foundation
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.lang.reflect.Array;
import java.net.URL;
import java.text.BreakIterator;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Random;
import java.util.Vector;

/**
 * Class implementing some simple utility methods.
 * 
 * @author Eibe Frank
 * @author Yong Wang
 * @author Len Trigg
 * @author Julien Prados
 * @version $Revision: 8080 $
 */
public final class Utils {

  /** The natural logarithm of 2. */
  public static double log2 = Math.log(2);

  /** The small deviation allowed in double comparisons. */
  public static double SMALL = 1e-6;

  /**
   * Tests if the given value codes "missing".
   * 
   * @param val
   *          the value to be tested
   * @return true if val codes "missing"
   */
  public static boolean isMissingValue(double val) {

    return Double.isNaN(val);
  }

  /**
   * Returns the value used to code a missing value. Note that equality tests on this value will always return false, so
   * use isMissingValue(double val) for testing..
   * 
   * @return the value used as missing value.
   */
  public static double missingValue() {

    return Double.NaN;
  }

  /**
   * Casting an object without "unchecked" compile-time warnings. Use only when absolutely necessary (e.g. when using
   * clone()).
   */
  @SuppressWarnings("unchecked")
  public static <T> T cast(Object x) {
    return (T) x;
  }

  /**
   * Returns the correlation coefficient of two double vectors.
   * 
   * @param y1
   *          double vector 1
   * @param y2
   *          double vector 2
   * @param n
   *          the length of two double vectors
   * @return the correlation coefficient
   */
  public static final double correlation(double y1[], double y2[], int n) {

    int i;
    double av1 = 0.0, av2 = 0.0, y11 = 0.0, y22 = 0.0, y12 = 0.0, c;

    if (n <= 1) {
      return 1.0;
    }
    for (i = 0; i < n; i++) {
      av1 += y1[i];
      av2 += y2[i];
    }
    av1 /= (double) n;
    av2 /= (double) n;
    for (i = 0; i < n; i++) {
      y11 += (y1[i] - av1) * (y1[i] - av1);
      y22 += (y2[i] - av2) * (y2[i] - av2);
      y12 += (y1[i] - av1) * (y2[i] - av2);
    }
    if (y11 * y22 == 0.0) {
      c = 1.0;
    } else {
      c = y12 / Math.sqrt(Math.abs(y11 * y22));
    }

    return c;
  }

  /**
   * Removes all occurrences of a string from another string.
   * 
   * @param inString
   *          the string to remove substrings from.
   * @param substring
   *          the substring to remove.
   * @return the input string with occurrences of substring removed.
   */
  public static String removeSubstring(String inString, String substring) {

    StringBuffer result = new StringBuffer();
    int oldLoc = 0, loc = 0;
    while ((loc = inString.indexOf(substring, oldLoc)) != -1) {
      result.append(inString.substring(oldLoc, loc));
      oldLoc = loc + substring.length();
    }
    result.append(inString.substring(oldLoc));
    return result.toString();
  }

  /**
   * Replaces with a new string, all occurrences of a string from another string.
   * 
   * @param inString
   *          the string to replace substrings in.
   * @param subString
   *          the substring to replace.
   * @param replaceString
   *          the replacement substring
   * @return the input string with occurrences of substring replaced.
   */
  public static String replaceSubstring(String inString, String subString,
      String replaceString) {

    StringBuffer result = new StringBuffer();
    int oldLoc = 0, loc = 0;
    while ((loc = inString.indexOf(subString, oldLoc)) != -1) {
      result.append(inString.substring(oldLoc, loc));
      result.append(replaceString);
      oldLoc = loc + subString.length();
    }
    result.append(inString.substring(oldLoc));
    return result.toString();
  }

  /**
   * Pads a string to a specified length, inserting spaces on the left as required. If the string is too long,
   * characters are removed (from the right).
   * 
   * @param inString
   *          the input string
   * @param length
   *          the desired length of the output string
   * @return the output string
   */
  public static String padLeft(String inString, int length) {

    return fixStringLength(inString, length, false);
  }

  /**
   * Pads a string to a specified length, inserting spaces on the right as required. If the string is too long,
   * characters are removed (from the right).
   * 
   * @param inString
   *          the input string
   * @param length
   *          the desired length of the output string
   * @return the output string
   */
  public static String padRight(String inString, int length) {

    return fixStringLength(inString, length, true);
  }

  /**
   * Pads a string to a specified length, inserting spaces as required. If the string is too long, characters are
   * removed (from the right).
   * 
   * @param inString
   *          the input string
   * @param length
   *          the desired length of the output string
   * @param right
   *          true if inserted spaces should be added to the right
   * @return the output string
   */
  private static/* @pure@ */String fixStringLength(String inString, int length,
      boolean right) {

    if (inString.length() < length) {
      while (inString.length() < length) {
        inString = (right ? inString.concat(" ") : " ".concat(inString));
      }
    } else if (inString.length() > length) {
      inString = inString.substring(0, length);
    }
    return inString;
  }

  /**
   * Rounds a double and converts it into String.
   * 
   * @param value
   *          the double value
   * @param afterDecimalPoint
   *          the (maximum) number of digits permitted after the decimal point
   * @return the double as a formatted string
   */
  public static/* @pure@ */String doubleToString(double value, int afterDecimalPoint) {

    StringBuffer stringBuffer;
    double temp;
    int dotPosition;
    long precisionValue;

    temp = value * Math.pow(10.0, afterDecimalPoint);
    if (Math.abs(temp) < Long.MAX_VALUE) {
      precisionValue = (temp > 0) ? (long) (temp + 0.5)
          : -(long) (Math.abs(temp) + 0.5);
      if (precisionValue == 0) {
        stringBuffer = new StringBuffer(String.valueOf(0));
      } else {
        stringBuffer = new StringBuffer(String.valueOf(precisionValue));
      }
      if (afterDecimalPoint == 0) {
        return stringBuffer.toString();
      }
      dotPosition = stringBuffer.length() - afterDecimalPoint;
      while (((precisionValue < 0) && (dotPosition < 1)) ||
          (dotPosition < 0)) {
        if (precisionValue < 0) {
          stringBuffer.insert(1, '0');
        } else {
          stringBuffer.insert(0, '0');
        }
        dotPosition++;
      }
      stringBuffer.insert(dotPosition, '.');
      if ((precisionValue < 0) && (stringBuffer.charAt(1) == '.')) {
        stringBuffer.insert(1, '0');
      } else if (stringBuffer.charAt(0) == '.') {
        stringBuffer.insert(0, '0');
      }
      int currentPos = stringBuffer.length() - 1;
      while ((currentPos > dotPosition) &&
          (stringBuffer.charAt(currentPos) == '0')) {
        stringBuffer.setCharAt(currentPos--, ' ');
      }
      if (stringBuffer.charAt(currentPos) == '.') {
        stringBuffer.setCharAt(currentPos, ' ');
      }

      return stringBuffer.toString().trim();
    }
    return new String("" + value);
  }

  /**
   * Rounds a double and converts it into a formatted decimal-justified String. Trailing 0's are replaced with spaces.
   * 
   * @param value
   *          the double value
   * @param width
   *          the width of the string
   * @param afterDecimalPoint
   *          the number of digits after the decimal point
   * @return the double as a formatted string
   */
  public static/* @pure@ */String doubleToString(double value, int width,
      int afterDecimalPoint) {

    String tempString = doubleToString(value, afterDecimalPoint);
    char[] result;
    int dotPosition;

    if ((afterDecimalPoint >= width)
        || (tempString.indexOf('E') != -1)) { // Protects sci notation
      return tempString;
    }

    // Initialize result
    result = new char[width];
    for (int i = 0; i < result.length; i++) {
      result[i] = ' ';
    }

    if (afterDecimalPoint > 0) {
      // Get position of decimal point and insert decimal point
      dotPosition = tempString.indexOf('.');
      if (dotPosition == -1) {
        dotPosition = tempString.length();
      } else {
        result[width - afterDecimalPoint - 1] = '.';
      }
    } else {
      dotPosition = tempString.length();
    }

    int offset = width - afterDecimalPoint - dotPosition;
    if (afterDecimalPoint > 0) {
      offset--;
    }

    // Not enough room to decimal align within the supplied width
    if (offset < 0) {
      return tempString;
    }

    // Copy characters before decimal point
    for (int i = 0; i < dotPosition; i++) {
      result[offset + i] = tempString.charAt(i);
    }

    // Copy characters after decimal point
    for (int i = dotPosition + 1; i < tempString.length(); i++) {
      result[offset + i] = tempString.charAt(i);
    }

    return new String(result);
  }

  /**
   * Returns the basic class of an array class (handles multi-dimensional arrays).
   * 
   * @param c
   *          the array to inspect
   * @return the class of the innermost elements
   */
  public static Class getArrayClass(Class c) {
    if (c.getComponentType().isArray())
      return getArrayClass(c.getComponentType());
    else
      return c.getComponentType();
  }

  /**
   * Returns the dimensions of the given array. Even though the parameter is of type "Object" one can hand over primitve
   * arrays, e.g. int[3] or double[2][4].
   * 
   * @param array
   *          the array to determine the dimensions for
   * @return the dimensions of the array
   */
  public static int getArrayDimensions(Class array) {
    if (array.getComponentType().isArray())
      return 1 + getArrayDimensions(array.getComponentType());
    else
      return 1;
  }

  /**
   * Returns the dimensions of the given array. Even though the parameter is of type "Object" one can hand over primitve
   * arrays, e.g. int[3] or double[2][4].
   * 
   * @param array
   *          the array to determine the dimensions for
   * @return the dimensions of the array
   */
  public static int getArrayDimensions(Object array) {
    return getArrayDimensions(array.getClass());
  }

  /**
   * Returns the given Array in a string representation. Even though the parameter is of type "Object" one can hand over
   * primitve arrays, e.g. int[3] or double[2][4].
   * 
   * @param array
   *          the array to return in a string representation
   * @return the array as string
   */
  public static String arrayToString(Object array) {
    String result;
    int dimensions;
    int i;

    result = "";
    dimensions = getArrayDimensions(array);

    if (dimensions == 0) {
      result = "null";
    }
    else if (dimensions == 1) {
      for (i = 0; i < Array.getLength(array); i++) {
        if (i > 0)
          result += ",";
        if (Array.get(array, i) == null)
          result += "null";
        else
          result += Array.get(array, i).toString();
      }
    }
    else {
      for (i = 0; i < Array.getLength(array); i++) {
        if (i > 0)
          result += ",";
        result += "[" + arrayToString(Array.get(array, i)) + "]";
      }
    }

    return result;
  }

  /**
   * Tests if a is equal to b.
   * 
   * @param a
   *          a double
   * @param b
   *          a double
   */
  public static/* @pure@ */boolean eq(double a, double b) {

    return (a - b < SMALL) && (b - a < SMALL);
  }

  /**
   * Checks if the given array contains any non-empty options.
   * 
   * @param options
   *          an array of strings
   * @exception Exception
   *              if there are any non-empty options
   */
  public static void checkForRemainingOptions(String[] options)
      throws Exception {

    int illegalOptionsFound = 0;
    StringBuffer text = new StringBuffer();

    if (options == null) {
      return;
    }
    for (int i = 0; i < options.length; i++) {
      if (options[i].length() > 0) {
        illegalOptionsFound++;
        text.append(options[i] + ' ');
      }
    }
    if (illegalOptionsFound > 0) {
      throw new Exception("Illegal options: " + text);
    }
  }

  /**
   * Checks if the given array contains the flag "-Char". Stops searching at the first marker "--". If the flag is
   * found, it is replaced with the empty string.
   * 
   * @param flag
   *          the character indicating the flag.
   * @param options
   *          the array of strings containing all the options.
   * @return true if the flag was found
   * @exception Exception
   *              if an illegal option was found
   */
  public static boolean getFlag(char flag, String[] options)
      throws Exception {

    return getFlag("" + flag, options);
  }

  /**
   * Checks if the given array contains the flag "-String". Stops searching at the first marker "--". If the flag is
   * found, it is replaced with the empty string.
   * 
   * @param flag
   *          the String indicating the flag.
   * @param options
   *          the array of strings containing all the options.
   * @return true if the flag was found
   * @exception Exception
   *              if an illegal option was found
   */
  public static boolean getFlag(String flag, String[] options)
      throws Exception {

    int pos = getOptionPos(flag, options);

    if (pos > -1)
      options[pos] = "";

    return (pos > -1);
  }

  /**
   * Gets an option indicated by a flag "-Char" from the given array of strings. Stops searching at the first marker
   * "--". Replaces flag and option with empty strings.
   * 
   * @param flag
   *          the character indicating the option.
   * @param options
   *          the array of strings containing all the options.
   * @return the indicated option or an empty string
   * @exception Exception
   *              if the option indicated by the flag can't be found
   */
  public static/* @non_null@ */String getOption(char flag, String[] options)
      throws Exception {

    return getOption("" + flag, options);
  }

  /**
   * Gets an option indicated by a flag "-String" from the given array of strings. Stops searching at the first marker
   * "--". Replaces flag and option with empty strings.
   * 
   * @param flag
   *          the String indicating the option.
   * @param options
   *          the array of strings containing all the options.
   * @return the indicated option or an empty string
   * @exception Exception
   *              if the option indicated by the flag can't be found
   */
  public static/* @non_null@ */String getOption(String flag, String[] options)
      throws Exception {

    String newString;
    int i = getOptionPos(flag, options);

    if (i > -1) {
      if (options[i].equals("-" + flag)) {
        if (i + 1 == options.length) {
          throw new Exception("No value given for -" + flag + " option.");
        }
        options[i] = "";
        newString = new String(options[i + 1]);
        options[i + 1] = "";
        return newString;
      }
      if (options[i].charAt(1) == '-') {
        return "";
      }
    }

    return "";
  }

  /**
   * Gets the index of an option or flag indicated by a flag "-Char" from the given array of strings. Stops searching at
   * the first marker "--".
   * 
   * @param flag
   *          the character indicating the option.
   * @param options
   *          the array of strings containing all the options.
   * @return the position if found, or -1 otherwise
   */
  public static int getOptionPos(char flag, String[] options) {
    return getOptionPos("" + flag, options);
  }

  /**
   * Gets the index of an option or flag indicated by a flag "-String" from the given array of strings. Stops searching
   * at the first marker "--".
   * 
   * @param flag
   *          the String indicating the option.
   * @param options
   *          the array of strings containing all the options.
   * @return the position if found, or -1 otherwise
   */
  public static int getOptionPos(String flag, String[] options) {
    if (options == null)
      return -1;

    for (int i = 0; i < options.length; i++) {
      if ((options[i].length() > 0) && (options[i].charAt(0) == '-')) {
        // Check if it is a negative number
        try {
          Double.valueOf(options[i]);
        } catch (NumberFormatException e) {
          // found?
          if (options[i].equals("-" + flag))
            return i;
          // did we reach "--"?
          if (options[i].charAt(1) == '-')
            return -1;
        }
      }
    }

    return -1;
  }

  /**
   * Quotes a string if it contains special characters.
   * 
   * The following rules are applied:
   * 
   * A character is backquoted version of it is one of <tt>" ' % \ \n \r \t</tt> .
   * 
   * A string is enclosed within single quotes if a character has been backquoted using the previous rule above or
   * contains <tt>{ }</tt> or is exactly equal to the strings <tt>, ? space or ""</tt> (empty string).
   * 
   * A quoted question mark distinguishes it from the missing value which is represented as an unquoted question mark in
   * arff files.
   * 
   * @param string
   *          the string to be quoted
   * @return the string (possibly quoted)
   * @see #unquote(String)
   */
  public static/* @pure@ */String quote(String string) {
    boolean quote = false;

    // backquote the following characters
    if ((string.indexOf('\n') != -1) || (string.indexOf('\r') != -1) ||
        (string.indexOf('\'') != -1) || (string.indexOf('"') != -1) ||
        (string.indexOf('\\') != -1) ||
        (string.indexOf('\t') != -1) || (string.indexOf('%') != -1) ||
        (string.indexOf('\u001E') != -1)) {
      string = backQuoteChars(string);
      quote = true;
    }

    // Enclose the string in 's if the string contains a recently added
    // backquote or contains one of the following characters.
    if ((quote == true) ||
        (string.indexOf('{') != -1) || (string.indexOf('}') != -1) ||
        (string.indexOf(',') != -1) || (string.equals("?")) ||
        (string.indexOf(' ') != -1) || (string.equals(""))) {
      string = ("'".concat(string)).concat("'");
    }

    return string;
  }

  /**
   * unquotes are previously quoted string (but only if necessary), i.e., it removes the single quotes around it.
   * Inverse to quote(String).
   * 
   * @param string
   *          the string to process
   * @return the unquoted string
   * @see #quote(String)
   */
  public static String unquote(String string) {
    if (string.startsWith("'") && string.endsWith("'")) {
      string = string.substring(1, string.length() - 1);

      if ((string.indexOf("\\n") != -1) || (string.indexOf("\\r") != -1) ||
          (string.indexOf("\\'") != -1) || (string.indexOf("\\\"") != -1) ||
          (string.indexOf("\\\\") != -1) ||
          (string.indexOf("\\t") != -1) || (string.indexOf("\\%") != -1) ||
          (string.indexOf("\\u001E") != -1)) {
        string = unbackQuoteChars(string);
      }
    }

    return string;
  }

  /**
   * Converts carriage returns and new lines in a string into \r and \n. Backquotes the following characters: ` " \ \t
   * and %
   * 
   * @param string
   *          the string
   * @return the converted string
   * @see #unbackQuoteChars(String)
   */
  public static/* @pure@ */String backQuoteChars(String string) {

    int index;
    StringBuffer newStringBuffer;

    // replace each of the following characters with the backquoted version
    char charsFind[] = { '\\', '\'', '\t', '\n', '\r', '"', '%',
        '\u001E' };
    String charsReplace[] = { "\\\\", "\\'", "\\t", "\\n", "\\r", "\\\"", "\\%",
        "\\u001E" };
    for (int i = 0; i < charsFind.length; i++) {
      if (string.indexOf(charsFind[i]) != -1) {
        newStringBuffer = new StringBuffer();
        while ((index = string.indexOf(charsFind[i])) != -1) {
          if (index > 0) {
            newStringBuffer.append(string.substring(0, index));
          }
          newStringBuffer.append(charsReplace[i]);
          if ((index + 1) < string.length()) {
            string = string.substring(index + 1);
          } else {
            string = "";
          }
        }
        newStringBuffer.append(string);
        string = newStringBuffer.toString();
      }
    }

    return string;
  }

  /**
   * Converts carriage returns and new lines in a string into \r and \n.
   * 
   * @param string
   *          the string
   * @return the converted string
   */
  public static String convertNewLines(String string) {
    int index;

    // Replace with \n
    StringBuffer newStringBuffer = new StringBuffer();
    while ((index = string.indexOf('\n')) != -1) {
      if (index > 0) {
        newStringBuffer.append(string.substring(0, index));
      }
      newStringBuffer.append('\\');
      newStringBuffer.append('n');
      if ((index + 1) < string.length()) {
        string = string.substring(index + 1);
      } else {
        string = "";
      }
    }
    newStringBuffer.append(string);
    string = newStringBuffer.toString();

    // Replace with \r
    newStringBuffer = new StringBuffer();
    while ((index = string.indexOf('\r')) != -1) {
      if (index > 0) {
        newStringBuffer.append(string.substring(0, index));
      }
      newStringBuffer.append('\\');
      newStringBuffer.append('r');
      if ((index + 1) < string.length()) {
        string = string.substring(index + 1);
      } else {
        string = "";
      }
    }
    newStringBuffer.append(string);
    return newStringBuffer.toString();
  }

  /**
   * Reverts \r and \n in a string into carriage returns and new lines.
   * 
   * @param string
   *          the string
   * @return the converted string
   */
  public static String revertNewLines(String string) {
    int index;

    // Replace with \n
    StringBuffer newStringBuffer = new StringBuffer();
    while ((index = string.indexOf("\\n")) != -1) {
      if (index > 0) {
        newStringBuffer.append(string.substring(0, index));
      }
      newStringBuffer.append('\n');
      if ((index + 2) < string.length()) {
        string = string.substring(index + 2);
      } else {
        string = "";
      }
    }
    newStringBuffer.append(string);
    string = newStringBuffer.toString();

    // Replace with \r
    newStringBuffer = new StringBuffer();
    while ((index = string.indexOf("\\r")) != -1) {
      if (index > 0) {
        newStringBuffer.append(string.substring(0, index));
      }
      newStringBuffer.append('\r');
      if ((index + 2) < string.length()) {
        string = string.substring(index + 2);
      } else {
        string = "";
      }
    }
    newStringBuffer.append(string);

    return newStringBuffer.toString();
  }

  /**
   * Returns the secondary set of options (if any) contained in the supplied options array. The secondary set is defined
   * to be any options after the first "--". These options are removed from the original options array.
   * 
   * @param options
   *          the input array of options
   * @return the array of secondary options
   */
  public static String[] partitionOptions(String[] options) {

    for (int i = 0; i < options.length; i++) {
      if (options[i].equals("--")) {
        options[i++] = "";
        String[] result = new String[options.length - i];
        for (int j = i; j < options.length; j++) {
          result[j - i] = options[j];
          options[j] = "";
        }
        return result;
      }
    }
    return new String[0];
  }

  /**
   * The inverse operation of backQuoteChars(). Converts back-quoted carriage returns and new lines in a string to the
   * corresponding character ('\r' and '\n'). Also "un"-back-quotes the following characters: ` " \ \t and %
   * 
   * @param string
   *          the string
   * @return the converted string
   * @see #backQuoteChars(String)
   */
  public static String unbackQuoteChars(String string) {

    int index;
    StringBuffer newStringBuffer;

    // replace each of the following characters with the backquoted version
    String charsFind[] = { "\\\\", "\\'", "\\t", "\\n", "\\r", "\\\"", "\\%",
        "\\u001E" };
    char charsReplace[] = { '\\', '\'', '\t', '\n', '\r', '"', '%',
        '\u001E' };
    int pos[] = new int[charsFind.length];
    int curPos;

    String str = new String(string);
    newStringBuffer = new StringBuffer();
    while (str.length() > 0) {
      // get positions and closest character to replace
      curPos = str.length();
      index = -1;
      for (int i = 0; i < pos.length; i++) {
        pos[i] = str.indexOf(charsFind[i]);
        if ((pos[i] > -1) && (pos[i] < curPos)) {
          index = i;
          curPos = pos[i];
        }
      }

      // replace character if found, otherwise finished
      if (index == -1) {
        newStringBuffer.append(str);
        str = "";
      }
      else {
        newStringBuffer.append(str.substring(0, pos[index]));
        newStringBuffer.append(charsReplace[index]);
        str = str.substring(pos[index] + charsFind[index].length());
      }
    }

    return newStringBuffer.toString();
  }

  /**
   * Split up a string containing options into an array of strings, one for each option.
   * 
   * @param quotedOptionString
   *          the string containing the options
   * @return the array of options
   * @throws Exception
   *           in case of an unterminated string, unknown character or a parse error
   */
  public static String[] splitOptions(String quotedOptionString) throws Exception {

    Vector<String> optionsVec = new Vector<String>();
    String str = new String(quotedOptionString);
    int i;

    while (true) {

      // trimLeft
      i = 0;
      while ((i < str.length()) && (Character.isWhitespace(str.charAt(i))))
        i++;
      str = str.substring(i);

      // stop when str is empty
      if (str.length() == 0)
        break;

      // if str start with a double quote
      if (str.charAt(0) == '"') {

        // find the first not anti-slached double quote
        i = 1;
        while (i < str.length()) {
          if (str.charAt(i) == str.charAt(0))
            break;
          if (str.charAt(i) == '\\') {
            i += 1;
            if (i >= str.length())
              throw new Exception("String should not finish with \\");
          }
          i += 1;
        }
        if (i >= str.length())
          throw new Exception("Quote parse error.");

        // add the founded string to the option vector (without quotes)
        String optStr = str.substring(1, i);
        optStr = unbackQuoteChars(optStr);
        optionsVec.addElement(optStr);
        str = str.substring(i + 1);
      } else {
        // find first whiteSpace
        i = 0;
        while ((i < str.length()) && (!Character.isWhitespace(str.charAt(i))))
          i++;

        // add the founded string to the option vector
        String optStr = str.substring(0, i);
        optionsVec.addElement(optStr);
        str = str.substring(i);
      }
    }

    // convert optionsVec to an array of String
    String[] options = new String[optionsVec.size()];
    for (i = 0; i < optionsVec.size(); i++) {
      options[i] = (String) optionsVec.elementAt(i);
    }
    return options;
  }

  /**
   * Joins all the options in an option array into a single string, as might be used on the command line.
   * 
   * @param optionArray
   *          the array of options
   * @return the string containing all options.
   */
  public static String joinOptions(String[] optionArray) {

    String optionString = "";
    for (int i = 0; i < optionArray.length; i++) {
      if (optionArray[i].equals("")) {
        continue;
      }
      boolean escape = false;
      for (int n = 0; n < optionArray[i].length(); n++) {
        if (Character.isWhitespace(optionArray[i].charAt(n))) {
          escape = true;
          break;
        }
      }
      if (escape) {
        optionString += '"' + backQuoteChars(optionArray[i]) + '"';
      } else {
        optionString += optionArray[i];
      }
      optionString += " ";
    }
    return optionString.trim();
  }

  /**
   * Computes entropy for an array of integers.
   * 
   * @param counts
   *          array of counts
   * @return - a log2 a - b log2 b - c log2 c + (a+b+c) log2 (a+b+c) when given array [a b c]
   */
  public static/* @pure@ */double info(int counts[]) {

    int total = 0;
    double x = 0;
    for (int j = 0; j < counts.length; j++) {
      x -= xlogx(counts[j]);
      total += counts[j];
    }
    return x + xlogx(total);
  }

  /**
   * Tests if a is smaller or equal to b.
   * 
   * @param a
   *          a double
   * @param b
   *          a double
   */
  public static/* @pure@ */boolean smOrEq(double a, double b) {

    return (a - b < SMALL);
  }

  /**
   * Tests if a is greater or equal to b.
   * 
   * @param a
   *          a double
   * @param b
   *          a double
   */
  public static/* @pure@ */boolean grOrEq(double a, double b) {

    return (b - a < SMALL);
  }

  /**
   * Tests if a is smaller than b.
   * 
   * @param a
   *          a double
   * @param b
   *          a double
   */
  public static/* @pure@ */boolean sm(double a, double b) {

    return (b - a > SMALL);
  }

  /**
   * Tests if a is greater than b.
   * 
   * @param a
   *          a double
   * @param b
   *          a double
   */
  public static/* @pure@ */boolean gr(double a, double b) {

    return (a - b > SMALL);
  }

  /**
   * Returns the kth-smallest value in the array.
   * 
   * @param array
   *          the array of integers
   * @param k
   *          the value of k
   * @return the kth-smallest value
   */
  public static double kthSmallestValue(int[] array, int k) {

    int[] index = new int[array.length];

    for (int i = 0; i < index.length; i++) {
      index[i] = i;
    }

    return array[index[select(array, index, 0, array.length - 1, k)]];
  }

  /**
   * Returns the kth-smallest value in the array
   * 
   * @param array
   *          the array of double
   * @param k
   *          the value of k
   * @return the kth-smallest value
   */
  public static double kthSmallestValue(double[] array, int k) {

    int[] index = new int[array.length];

    for (int i = 0; i < index.length; i++) {
      index[i] = i;
    }

    return array[index[select(array, index, 0, array.length - 1, k)]];
  }

  /**
   * Returns the logarithm of a for base 2.
   * 
   * @param a
   *          a double
   * @return the logarithm for base 2
   */
  public static/* @pure@ */double log2(double a) {

    return Math.log(a) / log2;
  }

  /**
   * Returns index of maximum element in a given array of doubles. First maximum is returned.
   * 
   * @param doubles
   *          the array of doubles
   * @return the index of the maximum element
   */
  public static/* @pure@ */int maxIndex(double[] doubles) {

    double maximum = 0;
    int maxIndex = 0;

    for (int i = 0; i < doubles.length; i++) {
      if ((i == 0) || (doubles[i] > maximum)) {
        maxIndex = i;
        maximum = doubles[i];
      }
    }

    return maxIndex;
  }

  /**
   * Returns index of maximum element in a given array of integers. First maximum is returned.
   * 
   * @param ints
   *          the array of integers
   * @return the index of the maximum element
   */
  public static/* @pure@ */int maxIndex(int[] ints) {

    int maximum = 0;
    int maxIndex = 0;

    for (int i = 0; i < ints.length; i++) {
      if ((i == 0) || (ints[i] > maximum)) {
        maxIndex = i;
        maximum = ints[i];
      }
    }

    return maxIndex;
  }

  /**
   * Computes the mean for an array of doubles.
   * 
   * @param vector
   *          the array
   * @return the mean
   */
  public static/* @pure@ */double mean(double[] vector) {

    double sum = 0;

    if (vector.length == 0) {
      return 0;
    }
    for (int i = 0; i < vector.length; i++) {
      sum += vector[i];
    }
    return sum / (double) vector.length;
  }

  /**
   * Returns index of minimum element in a given array of integers. First minimum is returned.
   * 
   * @param ints
   *          the array of integers
   * @return the index of the minimum element
   */
  public static/* @pure@ */int minIndex(int[] ints) {

    int minimum = 0;
    int minIndex = 0;

    for (int i = 0; i < ints.length; i++) {
      if ((i == 0) || (ints[i] < minimum)) {
        minIndex = i;
        minimum = ints[i];
      }
    }

    return minIndex;
  }

  /**
   * Returns index of minimum element in a given array of doubles. First minimum is returned.
   * 
   * @param doubles
   *          the array of doubles
   * @return the index of the minimum element
   */
  public static/* @pure@ */int minIndex(double[] doubles) {

    double minimum = 0;
    int minIndex = 0;

    for (int i = 0; i < doubles.length; i++) {
      if ((i == 0) || (doubles[i] < minimum)) {
        minIndex = i;
        minimum = doubles[i];
      }
    }

    return minIndex;
  }

  /**
   * Normalizes the doubles in the array by their sum.
   * 
   * @param doubles
   *          the array of double
   * @exception IllegalArgumentException
   *              if sum is Zero or NaN
   */
  public static void normalize(double[] doubles) {

    double sum = 0;
    for (int i = 0; i < doubles.length; i++) {
      sum += doubles[i];
    }
    normalize(doubles, sum);
  }

  /**
   * Normalizes the doubles in the array using the given value.
   * 
   * @param doubles
   *          the array of double
   * @param sum
   *          the value by which the doubles are to be normalized
   * @exception IllegalArgumentException
   *              if sum is zero or NaN
   */
  public static void normalize(double[] doubles, double sum) {

    if (Double.isNaN(sum)) {
      throw new IllegalArgumentException("Can't normalize array. Sum is NaN.");
    }
    if (sum == 0) {
      // Maybe this should just be a return.
      throw new IllegalArgumentException("Can't normalize array. Sum is zero.");
    }
    for (int i = 0; i < doubles.length; i++) {
      doubles[i] /= sum;
    }
  }

  /**
   * Converts an array containing the natural logarithms of probabilities stored in a vector back into probabilities.
   * The probabilities are assumed to sum to one.
   * 
   * @param a
   *          an array holding the natural logarithms of the probabilities
   * @return the converted array
   */
  public static double[] logs2probs(double[] a) {

    double max = a[maxIndex(a)];
    double sum = 0.0;

    double[] result = new double[a.length];
    for (int i = 0; i < a.length; i++) {
      result[i] = Math.exp(a[i] - max);
      sum += result[i];
    }

    normalize(result, sum);

    return result;
  }

  /**
   * Returns the log-odds for a given probabilitiy.
   * 
   * @param prob
   *          the probabilitiy
   * 
   * @return the log-odds after the probability has been mapped to [Utils.SMALL, 1-Utils.SMALL]
   */
  public static/* @pure@ */double probToLogOdds(double prob) {

    if (gr(prob, 1) || (sm(prob, 0))) {
      throw new IllegalArgumentException("probToLogOdds: probability must " +
          "be in [0,1] " + prob);
    }
    double p = SMALL + (1.0 - 2 * SMALL) * prob;
    return Math.log(p / (1 - p));
  }

  /**
   * Rounds a double to the next nearest integer value. The JDK version of it doesn't work properly.
   * 
   * @param value
   *          the double value
   * @return the resulting integer value
   */
  public static/* @pure@ */int round(double value) {

    int roundedValue = value > 0
        ? (int) (value + 0.5)
        : -(int) (Math.abs(value) + 0.5);

    return roundedValue;
  }

  /**
   * Rounds a double to the next nearest integer value in a probabilistic fashion (e.g. 0.8 has a 20% chance of being
   * rounded down to 0 and a 80% chance of being rounded up to 1). In the limit, the average of the rounded numbers
   * generated by this procedure should converge to the original double.
   * 
   * @param value
   *          the double value
   * @param rand
   *          the random number generator
   * @return the resulting integer value
   */
  public static int probRound(double value, Random rand) {

    if (value >= 0) {
      double lower = Math.floor(value);
      double prob = value - lower;
      if (rand.nextDouble() < prob) {
        return (int) lower + 1;
      } else {
        return (int) lower;
      }
    } else {
      double lower = Math.floor(Math.abs(value));
      double prob = Math.abs(value) - lower;
      if (rand.nextDouble() < prob) {
        return -((int) lower + 1);
      } else {
        return -(int) lower;
      }
    }
  }

  /**
   * Rounds a double to the given number of decimal places.
   * 
   * @param value
   *          the double value
   * @param afterDecimalPoint
   *          the number of digits after the decimal point
   * @return the double rounded to the given precision
   */
  public static/* @pure@ */double roundDouble(double value, int afterDecimalPoint) {

    double mask = Math.pow(10.0, (double) afterDecimalPoint);

    return (double) (Math.round(value * mask)) / mask;
  }

  /**
   * Sorts a given array of integers in ascending order and returns an array of integers with the positions of the
   * elements of the original array in the sorted array. The sort is stable. (Equal elements remain in their original
   * order.)
   * 
   * @param array
   *          this array is not changed by the method!
   * @return an array of integers with the positions in the sorted array.
   */
  public static/* @pure@ */int[] sort(int[] array) {

    int[] index = new int[array.length];
    int[] newIndex = new int[array.length];
    int[] helpIndex;
    int numEqual;

    for (int i = 0; i < index.length; i++) {
      index[i] = i;
    }
    quickSort(array, index, 0, array.length - 1);

    // Make sort stable
    int i = 0;
    while (i < index.length) {
      numEqual = 1;
      for (int j = i + 1; ((j < index.length)
      && (array[index[i]] == array[index[j]])); j++) {
        numEqual++;
      }
      if (numEqual > 1) {
        helpIndex = new int[numEqual];
        for (int j = 0; j < numEqual; j++) {
          helpIndex[j] = i + j;
        }
        quickSort(index, helpIndex, 0, numEqual - 1);
        for (int j = 0; j < numEqual; j++) {
          newIndex[i + j] = index[helpIndex[j]];
        }
        i += numEqual;
      } else {
        newIndex[i] = index[i];
        i++;
      }
    }
    return newIndex;
  }

  /**
   * Sorts a given array of doubles in ascending order and returns an array of integers with the positions of the
   * elements of the original array in the sorted array. NOTE THESE CHANGES: the sort is no longer stable and it doesn't
   * use safe floating-point comparisons anymore. Occurrences of Double.NaN are treated as Double.MAX_VALUE
   * 
   * @param array
   *          this array is not changed by the method!
   * @return an array of integers with the positions in the sorted array.
   */
  public static/* @pure@ */int[] sort(/* @non_null@ */double[] array) {

    int[] index = new int[array.length];
    array = (double[]) array.clone();
    for (int i = 0; i < index.length; i++) {
      index[i] = i;
      if (Double.isNaN(array[i])) {
        array[i] = Double.MAX_VALUE;
      }
    }
    quickSort(array, index, 0, array.length - 1);
    return index;
  }

  /**
   * Sorts a given array of doubles in ascending order and returns an array of integers with the positions of the
   * elements of the original array in the sorted array. The sort is stable (Equal elements remain in their original
   * order.) Occurrences of Double.NaN are treated as Double.MAX_VALUE
   * 
   * @param array
   *          this array is not changed by the method!
   * @return an array of integers with the positions in the sorted array.
   */
  public static/* @pure@ */int[] stableSort(double[] array) {

    int[] index = new int[array.length];
    int[] newIndex = new int[array.length];
    int[] helpIndex;
    int numEqual;

    array = (double[]) array.clone();
    for (int i = 0; i < index.length; i++) {
      index[i] = i;
      if (Double.isNaN(array[i])) {
        array[i] = Double.MAX_VALUE;
      }
    }
    quickSort(array, index, 0, array.length - 1);

    // Make sort stable

    int i = 0;
    while (i < index.length) {
      numEqual = 1;
      for (int j = i + 1; ((j < index.length) && Utils.eq(array[index[i]],
          array[index[j]])); j++)
        numEqual++;
      if (numEqual > 1) {
        helpIndex = new int[numEqual];
        for (int j = 0; j < numEqual; j++)
          helpIndex[j] = i + j;
        quickSort(index, helpIndex, 0, numEqual - 1);
        for (int j = 0; j < numEqual; j++)
          newIndex[i + j] = index[helpIndex[j]];
        i += numEqual;
      } else {
        newIndex[i] = index[i];
        i++;
      }
    }

    return newIndex;
  }

  /**
   * Computes the variance for an array of doubles.
   * 
   * @param vector
   *          the array
   * @return the variance
   */
  public static/* @pure@ */double variance(double[] vector) {

    double sum = 0, sumSquared = 0;

    if (vector.length <= 1) {
      return 0;
    }
    for (int i = 0; i < vector.length; i++) {
      sum += vector[i];
      sumSquared += (vector[i] * vector[i]);
    }
    double result = (sumSquared - (sum * sum / (double) vector.length)) /
        (double) (vector.length - 1);

    // We don't like negative variance
    if (result < 0) {
      return 0;
    } else {
      return result;
    }
  }

  /**
   * Computes the sum of the elements of an array of doubles.
   * 
   * @param doubles
   *          the array of double
   * @return the sum of the elements
   */
  public static/* @pure@ */double sum(double[] doubles) {

    double sum = 0;

    for (int i = 0; i < doubles.length; i++) {
      sum += doubles[i];
    }
    return sum;
  }

  /**
   * Computes the sum of the elements of an array of integers.
   * 
   * @param ints
   *          the array of integers
   * @return the sum of the elements
   */
  public static/* @pure@ */int sum(int[] ints) {

    int sum = 0;

    for (int i = 0; i < ints.length; i++) {
      sum += ints[i];
    }
    return sum;
  }

  /**
   * Returns c*log2(c) for a given integer value c.
   * 
   * @param c
   *          an integer value
   * @return c*log2(c) (but is careful to return 0 if c is 0)
   */
  public static/* @pure@ */double xlogx(int c) {

    if (c == 0) {
      return 0.0;
    }
    return c * Utils.log2((double) c);
  }

  /**
   * Partitions the instances around a pivot. Used by quicksort and kthSmallestValue.
   * 
   * @param array
   *          the array of doubles to be sorted
   * @param index
   *          the index into the array of doubles
   * @param l
   *          the first index of the subset
   * @param r
   *          the last index of the subset
   * 
   * @return the index of the middle element
   */
  private static int partition(double[] array, int[] index, int l, int r) {

    double pivot = array[index[(l + r) / 2]];
    int help;

    while (l < r) {
      while ((array[index[l]] < pivot) && (l < r)) {
        l++;
      }
      while ((array[index[r]] > pivot) && (l < r)) {
        r--;
      }
      if (l < r) {
        help = index[l];
        index[l] = index[r];
        index[r] = help;
        l++;
        r--;
      }
    }
    if ((l == r) && (array[index[r]] > pivot)) {
      r--;
    }

    return r;
  }

  /**
   * Partitions the instances around a pivot. Used by quicksort and kthSmallestValue.
   * 
   * @param array
   *          the array of integers to be sorted
   * @param index
   *          the index into the array of integers
   * @param l
   *          the first index of the subset
   * @param r
   *          the last index of the subset
   * 
   * @return the index of the middle element
   */
  private static int partition(int[] array, int[] index, int l, int r) {

    double pivot = array[index[(l + r) / 2]];
    int help;

    while (l < r) {
      while ((array[index[l]] < pivot) && (l < r)) {
        l++;
      }
      while ((array[index[r]] > pivot) && (l < r)) {
        r--;
      }
      if (l < r) {
        help = index[l];
        index[l] = index[r];
        index[r] = help;
        l++;
        r--;
      }
    }
    if ((l == r) && (array[index[r]] > pivot)) {
      r--;
    }

    return r;
  }

  /**
   * Implements quicksort according to Manber's "Introduction to Algorithms".
   * 
   * @param array
   *          the array of doubles to be sorted
   * @param index
   *          the index into the array of doubles
   * @param left
   *          the first index of the subset to be sorted
   * @param right
   *          the last index of the subset to be sorted
   */
  // @ requires 0 <= first && first <= right && right < array.length;
  // @ requires (\forall int i; 0 <= i && i < index.length; 0 <= index[i] &&
  // index[i] < array.length);
  // @ requires array != index;
  // assignable index;
  private static void quickSort(/* @non_null@ */double[] array, /* @non_null@ */int[] index,
      int left, int right) {

    if (left < right) {
      int middle = partition(array, index, left, right);
      quickSort(array, index, left, middle);
      quickSort(array, index, middle + 1, right);
    }
  }

  /**
   * Implements quicksort according to Manber's "Introduction to Algorithms".
   * 
   * @param array
   *          the array of integers to be sorted
   * @param index
   *          the index into the array of integers
   * @param left
   *          the first index of the subset to be sorted
   * @param right
   *          the last index of the subset to be sorted
   */
  // @ requires 0 <= first && first <= right && right < array.length;
  // @ requires (\forall int i; 0 <= i && i < index.length; 0 <= index[i] &&
  // index[i] < array.length);
  // @ requires array != index;
  // assignable index;
  private static void quickSort(/* @non_null@ */int[] array, /* @non_null@ */int[] index,
      int left, int right) {

    if (left < right) {
      int middle = partition(array, index, left, right);
      quickSort(array, index, left, middle);
      quickSort(array, index, middle + 1, right);
    }
  }

  /**
   * Implements computation of the kth-smallest element according to Manber's "Introduction to Algorithms".
   * 
   * @param array
   *          the array of double
   * @param index
   *          the index into the array of doubles
   * @param left
   *          the first index of the subset
   * @param right
   *          the last index of the subset
   * @param k
   *          the value of k
   * 
   * @return the index of the kth-smallest element
   */
  // @ requires 0 <= first && first <= right && right < array.length;
  private static int select(/* @non_null@ */double[] array, /* @non_null@ */int[] index,
      int left, int right, int k) {

    if (left == right) {
      return left;
    } else {
      int middle = partition(array, index, left, right);
      if ((middle - left + 1) >= k) {
        return select(array, index, left, middle, k);
      } else {
        return select(array, index, middle + 1, right, k - (middle - left + 1));
      }
    }
  }

  /**
   * Converts a File's absolute path to a path relative to the user (ie start) directory. Includes an additional
   * workaround for Cygwin, which doesn't like upper case drive letters.
   * 
   * @param absolute
   *          the File to convert to relative path
   * @return a File with a path that is relative to the user's directory
   * @exception Exception
   *              if the path cannot be constructed
   */
  public static File convertToRelativePath(File absolute) throws Exception {
    File result;
    String fileStr;

    result = null;

    // if we're running windows, it could be Cygwin
    if (File.separator.equals("\\")) {
      // Cygwin doesn't like upper case drives -> try lower case drive
      try {
        fileStr = absolute.getPath();
        fileStr = fileStr.substring(0, 1).toLowerCase()
            + fileStr.substring(1);
        result = createRelativePath(new File(fileStr));
      } catch (Exception e) {
        // no luck with Cygwin workaround, convert it like it is
        result = createRelativePath(absolute);
      }
    }
    else {
      result = createRelativePath(absolute);
    }

    return result;
  }

  /**
   * Converts a File's absolute path to a path relative to the user (ie start) directory.
   * 
   * @param absolute
   *          the File to convert to relative path
   * @return a File with a path that is relative to the user's directory
   * @exception Exception
   *              if the path cannot be constructed
   */
  protected static File createRelativePath(File absolute) throws Exception {
    File userDir = new File(System.getProperty("user.dir"));
    String userPath = userDir.getAbsolutePath() + File.separator;
    String targetPath = (new File(absolute.getParent())).getPath()
        + File.separator;
    String fileName = absolute.getName();
    StringBuffer relativePath = new StringBuffer();
    // relativePath.append("."+File.separator);
    // System.err.println("User dir "+userPath);
    // System.err.println("Target path "+targetPath);

    // file is in user dir (or subdir)
    int subdir = targetPath.indexOf(userPath);
    if (subdir == 0) {
      if (userPath.length() == targetPath.length()) {
        relativePath.append(fileName);
      } else {
        int ll = userPath.length();
        relativePath.append(targetPath.substring(ll));
        relativePath.append(fileName);
      }
    } else {
      int sepCount = 0;
      String temp = new String(userPath);
      while (temp.indexOf(File.separator) != -1) {
        int ind = temp.indexOf(File.separator);
        sepCount++;
        temp = temp.substring(ind + 1, temp.length());
      }

      String targetTemp = new String(targetPath);
      String userTemp = new String(userPath);
      int tcount = 0;
      while (targetTemp.indexOf(File.separator) != -1) {
        int ind = targetTemp.indexOf(File.separator);
        int ind2 = userTemp.indexOf(File.separator);
        String tpart = targetTemp.substring(0, ind + 1);
        String upart = userTemp.substring(0, ind2 + 1);
        if (tpart.compareTo(upart) != 0) {
          if (tcount == 0) {
            tcount = -1;
          }
          break;
        }
        tcount++;
        targetTemp = targetTemp.substring(ind + 1, targetTemp.length());
        userTemp = userTemp.substring(ind2 + 1, userTemp.length());
      }
      if (tcount == -1) {
        // then target file is probably on another drive (under windows)
        throw new Exception("Can't construct a path to file relative to user "
            + "dir.");
      }
      if (targetTemp.indexOf(File.separator) == -1) {
        targetTemp = "";
      }
      for (int i = 0; i < sepCount - tcount; i++) {
        relativePath.append(".." + File.separator);
      }
      relativePath.append(targetTemp + fileName);
    }
    // System.err.println("new path : "+relativePath.toString());
    return new File(relativePath.toString());
  }

  /**
   * Implements computation of the kth-smallest element according to Manber's "Introduction to Algorithms".
   * 
   * @param array
   *          the array of integers
   * @param index
   *          the index into the array of integers
   * @param left
   *          the first index of the subset
   * @param right
   *          the last index of the subset
   * @param k
   *          the value of k
   * 
   * @return the index of the kth-smallest element
   */
  // @ requires 0 <= first && first <= right && right < array.length;
  private static int select(/* @non_null@ */int[] array, /* @non_null@ */int[] index,
      int left, int right, int k) {

    if (left == right) {
      return left;
    } else {
      int middle = partition(array, index, left, right);
      if ((middle - left + 1) >= k) {
        return select(array, index, left, middle, k);
      } else {
        return select(array, index, middle + 1, right, k - (middle - left + 1));
      }
    }
  }

  /**
   * Breaks up the string, if wider than "columns" characters.
   * 
   * @param s
   *          the string to process
   * @param columns
   *          the width in columns
   * @return the processed string
   */
  public static String[] breakUp(String s, int columns) {
    Vector<String> result;
    String line;
    BreakIterator boundary;
    int boundaryStart;
    int boundaryEnd;
    String word;
    String punctuation;
    int i;
    String[] lines;

    result = new Vector<String>();
    punctuation = " .,;:!?'\"";
    lines = s.split("\n");

    for (i = 0; i < lines.length; i++) {
      boundary = BreakIterator.getWordInstance();
      boundary.setText(lines[i]);
      boundaryStart = boundary.first();
      boundaryEnd = boundary.next();
      line = "";

      while (boundaryEnd != BreakIterator.DONE) {
        word = lines[i].substring(boundaryStart, boundaryEnd);
        if (line.length() >= columns) {
          if (word.length() == 1) {
            if (punctuation.indexOf(word.charAt(0)) > -1) {
              line += word;
              word = "";
            }
          }
          result.add(line);
          line = "";
        }
        line += word;
        boundaryStart = boundaryEnd;
        boundaryEnd = boundary.next();
      }
      if (line.length() > 0)
        result.add(line);
    }

    return result.toArray(new String[result.size()]);
  }

  /**
   * Creates a new instance of an object given it's class name and (optional) arguments to pass to it's setOptions
   * method. If the object implements OptionHandler and the options parameter is non-null, the object will have it's
   * options set. Example use:
   * <p>
   * 
   * <code> <pre>
   * String classifierName = Utils.getOption('W', options);
   * Classifier c = (Classifier)Utils.forName(Classifier.class,
   *                                          classifierName,
   *                                          options);
   * setClassifier(c);
   * </pre></code>
   * 
   * @param classType
   *          the class that the instantiated object should be assignable to -- an exception is thrown if this is not
   *          the case
   * @param className
   *          the fully qualified class name of the object
   * @param options
   *          an array of options suitable for passing to setOptions. May be null. Any options accepted by the object
   *          will be removed from the array.
   * @return the newly created object, ready for use.
   * @exception Exception
   *              if the class name is invalid, or if the class is not assignable to the desired class type, or the
   *              options supplied are not acceptable to the object
   */
  public static Object forName(Class<?> classType,
      String className,
      String[] options) throws Exception {

    Class<?> c = null;
    try {
      c = Class.forName(className);
    } catch (Exception ex) {
      throw new Exception("Can't find class called: " + className);
    }
    if (!classType.isAssignableFrom(c)) {
      throw new Exception(classType.getName() + " is not assignable from "
          + className);
    }
    Object o = c.newInstance();
    /*
     * if ((o instanceof OptionHandler) && (options != null)) {
     * ((OptionHandler)o).setOptions(options);
     * Utils.checkForRemainingOptions(options); }
     */
    return o;
  }

}
