/*
 *    Utils.java

 *
 */

package com.yahoo.labs.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;
  }

}
