/*
 * Created on Mar 23, 2004
 *
 */

/*
 Copyright 2007 Robert C. Ilardi

 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.
 */

package com.roguelogic.util;

/**
 * @author rilardi
 *
 */

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

public class StringUtils {

  /**
   * This class contains some useful string utility methods
   */

  public StringUtils() {}

  public static String GetStackTraceString(Throwable t) {
    ByteArrayOutputStream baos = null;
    PrintStream ps = null;
    String temp = null;

    try {
      baos = new ByteArrayOutputStream();
      ps = new PrintStream(baos);

      t.printStackTrace(ps);
      temp = baos.toString();
    }
    catch (Exception ie) {
      t.printStackTrace();
    }
    finally {
      try {
        if (ps != null) {
          ps.close();
        }
      }
      catch (Exception ie) {}

      try {
        if (baos != null) {
          baos.close();
        }
      }
      catch (Exception ie) {}
    }

    return temp;
  }

  public static synchronized String GenerateYearlyUniqueKey() {
    StringBuffer uniqueId = new StringBuffer();

    String[] ids = TimeZone.getAvailableIDs(-5 * 60 * 60 * 1000);
    SimpleTimeZone est = new SimpleTimeZone(-5 * 60 * 60 * 1000, ids[0]);
    est.setStartRule(Calendar.APRIL, 1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
    est.setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2 * 60 * 60 * 1000);
    Calendar now = new GregorianCalendar(est);

    uniqueId.append(Integer.toString(now.get(Calendar.DAY_OF_YEAR), 36).toUpperCase().trim());
    uniqueId.append(Integer.toString(now.get(Calendar.HOUR_OF_DAY), 36).toUpperCase().trim());
    uniqueId.append(Integer.toString(now.get(Calendar.MINUTE), 36).toUpperCase().trim());
    uniqueId.append(Integer.toString(now.get(Calendar.SECOND), 36).toUpperCase().trim());

    try {
      Thread.sleep(1000);
    }
    catch (Exception e) {}

    return uniqueId.toString();
  }

  public static java.util.Date ParseDate(String dateStr, String dateFormat) throws ParseException {
    java.util.Date date;

    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
    date = sdf.parse(dateStr);

    return date;
  }

  public static String[] Tokenize(String s, char delimiter) {
    return Tokenize(s, delimiter, false);
  }

  public static String[] Tokenize(String s, char delimiter, boolean keepEmpty) {
    ArrayList<String> al = new ArrayList<String>();
    String[] tempArr = null;
    StringBuffer sb = new StringBuffer();
    char c;
    int cnt = 0;

    for (int i = 0; i < s.length(); i++) {
      c = s.charAt(i);

      if (c == delimiter) {
        if (sb.length() > 0 || keepEmpty) {
          al.add(sb.toString());
          sb.setLength(0);
        }
      }
      else {
        sb.append(c);
      }
    }

    if (sb.length() > 0) {
      al.add(sb.toString());
      sb.setLength(0);
    }

    if (al.size() > 0) {
      tempArr = new String[al.size()];
      while (!al.isEmpty()) {
        tempArr[cnt++] = al.remove(0);
      }
    }

    return tempArr;
  }

  public static String QuickDateFormat(String format) {
    return QuickDateFormat((new java.util.Date()), format);
  }

  public static String QuickDateFormat(java.util.Date date, String format) {
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    return sdf.format(date);
  }

  public static void PrintArray(String name, String[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, String[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(arr[i]).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

  public static void PrintList(String name, List lst) {
    Iterator iter;
    int cnt = 0;

    if (lst != null) {
      System.out.println("List \"" + name + "\" has " + lst.size() + " elements -");
      iter = lst.iterator();
      while (iter.hasNext()) {
        System.out.println(name + "[" + cnt + "] = " + iter.next());
        cnt++;
      }
    }
    else {
      System.out.println("List \"" + name + "\" is NULL!");
    }
  }

  public static void PrintMap(String name, Map map) {
    Set keys;
    Iterator iter;
    String key;
    Object obj;
    Object[] arr;

    if (map != null) {
      keys = map.keySet();
      iter = keys.iterator();

      System.out.println("Map \"" + name + "\" has " + map.size() + " elements -");

      while (iter.hasNext()) {
        key = (String) iter.next();
        obj = map.get(key);

        if (obj instanceof Object[]) {
          arr = (Object[]) obj;
          for (int i = 0; i < arr.length; i++) {
            System.out.println(key + "[" + i + "] = " + arr[i]);
          }
        }
        else {
          System.out.println(key + " = " + obj);
        }
      }
    }
    else {
      System.out.println("Map \"" + name + "\" is NULL!");
    }
  }

  public static String GetTimeStamp() {
    return (new java.util.Date()).toString();
  }

  public static String FormatDouble(double d, int precision) {
    BigDecimal bd = new BigDecimal(d);
    bd = bd.setScale(precision, BigDecimal.ROUND_DOWN);
    return "" + bd.toString();
  }

  /*
   * This method returns a String Array where each element is a single character
   * of the parameter "s."
   */
  public static String[] GetCharsAsStrings(String s) {
    String[] letters = null;

    if (s != null) {
      letters = new String[s.length()];
      letters[0] = "";
      for (int i = 0; i < s.length(); i++) {
        letters[i] = String.valueOf(s.charAt(i));
      }
    }

    return letters;
  }

  /*
   * This method return the boolean valud of the string. It returns true if and
   * only if the String vlaue is equal to "TRUE" The test is case insensitive,
   * and the string "s" is trimmed!
   */
  public static boolean GetBoolean(String s) {
    return s != null && s.trim().equalsIgnoreCase("TRUE");
  }

  /*
   * Generate some krapy Unique Id based on time and a few random Capital
   * Letters.
   */
  public static synchronized String GenerateTimeUniqueId() {
    StringBuffer id = new StringBuffer();

    //Some Random Character
    for (int i = 1; i <= 4; i++) {
      id.append((char) (65 + ((int) (26 * Math.random()))));
    }

    id.append(Long.toHexString(System.currentTimeMillis()).toUpperCase());

    try {
      Thread.sleep(10);
    }
    catch (Exception e) {}

    return id.toString();
  }

  public static String[] Trim(String[] arr) {
    String[] newArr = null;

    if (arr != null) {
      newArr = new String[arr.length];

      for (int i = 0; i < arr.length; i++) {
        newArr[i] = arr[i].trim();
      }
    }

    return newArr;
  }

  public static String ParseDir(String filePath) {
    String dirPath = null;
    int dirIndex;

    if (filePath != null && filePath.trim().length() > 0) {
      filePath = filePath.trim();
      dirIndex = filePath.lastIndexOf("/");

      if (dirIndex < 0) {
        dirIndex = filePath.lastIndexOf("\\");
      }

      if (dirIndex > 0) {
        dirPath = filePath.substring(0, dirIndex);
      }
      else if (dirIndex == 0 && filePath.startsWith("/")) {
        dirPath = "/";
      }
      else if (dirIndex == 0 && filePath.startsWith("\\")) {
        dirPath = "\\";
      }
      else {
        dirPath = "";
      }
    }

    return dirPath;
  }

  public static boolean ContainsOne(String s, String[] arr) {
    boolean contains = false;

    for (int i = 0; s != null && arr != null && i < arr.length; i++) {
      if (s.indexOf(arr[i]) >= 0) {
        contains = true;
        break;
      }
    }

    return contains;
  }

  public static boolean EqualsOne(String s, String[] arr, boolean caseInsensitive) {
    boolean equals = false;

    for (int i = 0; s != null && arr != null && i < arr.length; i++) {
      if (caseInsensitive && s.equalsIgnoreCase(arr[i])) {
        equals = true;
        break;
      }
      else if (!caseInsensitive && s.equals(arr[i])) {
        equals = true;
        break;
      }
    }

    return equals;
  }

  public static String Delimiterize(String[] tokens, String delimiter) {
    StringBuffer sb = new StringBuffer();

    for (int i = 0; tokens != null && i < tokens.length; i++) {
      if (i > 0) {
        sb.append(delimiter);
      }
      sb.append(tokens[i]);
    }

    return sb.toString();
  }

  /**
   * @deprecated  Replaced by {@link #ApplyParameters(String, String, String[])}
   */
  public static String ApplyParameters(String text, String placeHolder, String placeHolderRegEx, String[] parameters) {
    String parameterizedText;
    int index, cnt;

    cnt = 0;
    parameterizedText = text;
    index = parameterizedText.indexOf(placeHolder);

    while (index >= 0 && parameters != null && cnt < parameters.length) {
      parameterizedText = parameterizedText.replaceFirst(placeHolderRegEx, parameters[cnt++]);
      index = parameterizedText.indexOf(placeHolder);
    }

    return parameterizedText;
  }

  public static String ApplyParameters(String text, String placeHolder, String[] parameters) {
    StringBuffer parameterizedText;
    int index, cnt;

    cnt = 0;
    parameterizedText = new StringBuffer(text);
    index = parameterizedText.indexOf(placeHolder);

    while (index >= 0 && parameters != null && cnt < parameters.length) {
      parameterizedText.replace(index, index + placeHolder.length(), parameters[cnt]);
      index = parameterizedText.indexOf(placeHolder, index + parameters[cnt].length());
      cnt++;
    }

    return parameterizedText.toString();
  }

  public static String[] Append(String[] record, String additionalValue) {
    String[] newRecord = null;

    if (record != null && record.length > 0) {
      newRecord = new String[record.length + 1];
      System.arraycopy(record, 0, newRecord, 0, record.length);
      newRecord[newRecord.length - 1] = additionalValue;
    }

    return newRecord;
  }

  public static String[] Escape(String[] tokens, char escapee, char escapingChar) {
    String[] escapedArr = null;
    StringBuffer sb;

    if (tokens != null && tokens.length > 0) {
      escapedArr = new String[tokens.length];
      sb = new StringBuffer();

      for (int i = 0; i < tokens.length; i++) {
        sb.setLength(0);
        for (int j = 0; j < tokens[i].length(); j++) {
          if (tokens[i].charAt(j) == escapee) {
            sb.append(escapingChar);
          }
          sb.append(tokens[i].charAt(j));
        }
        escapedArr[i] = sb.toString();
      }
    }

    return escapedArr;
  }

  public static String HumanReadableTime(long milliSeconds) {
    long days, hours, inpSecs;
    int minutes, seconds;
    StringBuffer sb = new StringBuffer();

    inpSecs = milliSeconds / 1000; //Convert Milliseconds into Seconds
    days = inpSecs / 86400;
    hours = (inpSecs - (days * 86400)) / 3600;
    minutes = (int) (((inpSecs - (days * 86400)) - (hours * 3600)) / 60);
    seconds = (int) (((inpSecs - (days * 86400)) - (hours * 3600)) - (minutes * 60));

    sb.append(days);
    sb.append((days != 1 ? " Days" : " Day"));

    sb.append(", ");
    sb.append(hours);
    sb.append((hours != 1 ? " Hours" : " Hour"));

    sb.append(", ");
    sb.append(minutes);
    sb.append((minutes != 1 ? " Minutes" : " Minute"));

    sb.append(", ");
    sb.append(seconds);
    sb.append((seconds != 1 ? " Seconds" : " Second"));

    return sb.toString();
  }

  public static String StripHTML(String html) {
    StringBuffer text = new StringBuffer();
    boolean inTag = false;
    char c;

    for (int i = 0; i < html.length(); i++) {
      c = html.charAt(i);
      if (c == '<') {
        inTag = true;
      }
      else if (c == '>' && inTag) {
        inTag = false;
      }
      else if (!inTag) {
        text.append(c);
      }
    }

    return text.toString();
  }

  public static String[] QuoteSplit(String text, char splitChar) {
    String[] tempArr = null;
    ArrayList<String> al;
    StringBuffer sb;
    int cnt;
    boolean inQuotes;
    char c;

    if (text != null) {
      al = new ArrayList<String>();
      sb = new StringBuffer();
      inQuotes = false;

      for (int i = 0; i < text.length(); i++) {
        c = text.charAt(i);
        if (c == '\"') {
          inQuotes = !inQuotes;
        }
        else if (!inQuotes && c == splitChar) {
          al.add(sb.toString());
          sb.setLength(0);
        }
        else {
          sb.append(c);
        }
      }

      if (sb.length() > 0) {
        al.add(sb.toString());
        sb.setLength(0);
      }

      cnt = 0;
      tempArr = new String[al.size()];
      while (!al.isEmpty()) {
        tempArr[cnt++] = al.remove(0);
      }
    } //End text != null check

    return tempArr;
  }

  public static boolean ContainsOnly(String text, String segment) {
    boolean only = false;
    int index = 0, lastIndex;

    if (text.length() > 0 && segment.length() > 0) {
      index = text.indexOf(segment);
      only = (index == 0);
      while (only && index != -1 && (index + segment.length()) < text.length()) {
        lastIndex = index;
        index = text.indexOf(segment, index + segment.length());
        only = (index == lastIndex + segment.length());
      }
    }
    else if (text.length() == segment.length()) {
      //Same as saving text.length()==0 && segment.length==0
      only = true;
    }

    return only;
  }

  public static String LTrim(String s) {
    String lts = null;
    char c;

    if (s != null) {
      lts = "";
      for (int i = 0; i < s.length(); i++) {
        c = s.charAt(i);
        if (c != ' ' && c != '\t') {
          lts = s.substring(i);
          break;
        }
      }
    }

    return lts;
  }

  public static String RTrim(String s) {
    String rts = null;
    char c;

    if (s != null) {
      rts = "";
      for (int i = s.length() - 1; i >= 0; i--) {
        c = s.charAt(i);
        if (c != ' ' && c != '\t') {
          rts = s.substring(0, i + 1);
          break;
        }
      }
    }

    return rts;
  }

  public static String[] ReadLines(InputStream ins) throws IOException {
    InputStreamReader isr = null;
    BufferedReader br = null;
    String[] lines = null;
    String line;
    ArrayList<String> al = null;
    int cnt;

    try {
      isr = new InputStreamReader(ins);
      br = new BufferedReader(isr);
      al = new ArrayList<String>();

      line = br.readLine();
      while (line != null) {
        line = line.trim();
        if (line.length() > 0) {
          al.add(line);
        }
        line = br.readLine();
      }

      cnt = 0;
      lines = new String[al.size()];
      while (!al.isEmpty()) {
        lines[cnt++] = al.remove(0);
      }
    }
    finally {
      if (isr != null) {
        try {
          isr.close();
        }
        catch (Exception e) {}
        isr = null;
      }

      if (br != null) {
        try {
          br.close();
        }
        catch (Exception e) {}
        br = null;
      }

      if (al != null) {
        al.clear();
        al = null;
      }
    }

    return lines;
  }

  public static String GetContent(InputStream ins) throws IOException {
    InputStreamReader isr = null;
    BufferedReader br = null;
    StringBuffer content = new StringBuffer();
    String line;

    try {
      isr = new InputStreamReader(ins);
      br = new BufferedReader(isr);

      line = br.readLine();
      while (line != null) {
        content.append(line);
        line = br.readLine();
      }
    }
    finally {
      if (isr != null) {
        try {
          isr.close();
        }
        catch (Exception e) {}
        isr = null;
      }

      if (br != null) {
        try {
          br.close();
        }
        catch (Exception e) {}
        br = null;
      }
    }

    return content.toString();
  }

  public static Properties ParseInlineProperties(String inlinePropsStr) {
    Properties props = new Properties();
    String[] nvPairs, nvPair;

    if (inlinePropsStr != null && inlinePropsStr.trim().length() > 0) {
      nvPairs = inlinePropsStr.split(";");

      if (nvPairs != null && nvPairs.length > 0) {
        nvPairs = Trim(nvPairs);

        for (int i = 0; i < nvPairs.length; i++) {
          nvPair = nvPairs[i].split("=", 2);
          if (nvPair != null && nvPair.length == 2) {
            nvPair = Trim(nvPair);
            props.setProperty(nvPair[0], nvPair[1]);
          }
        }
      }
    }

    return props;
  }

  public static String BasicURLEncode(String ps) {
    String es = null;

    try {
      es = URLEncoder.encode(ps, "UTF-8");
    }
    catch (Exception e) {
      e.printStackTrace();
    }

    return es;
  }

  public static String BasicURLDecode(String es) {
    String ps = null;

    try {
      ps = URLDecoder.decode(es, "UTF-8");
    }
    catch (Exception e) {
      e.printStackTrace();
    }

    return ps;
  }

  public static String LPad(String s, char paddingChar, int fixedLen) {
    StringBuffer sb = new StringBuffer();

    for (int i = 1; i <= fixedLen - (s != null ? s.length() : 0); i++) {
      sb.append(paddingChar);
    }

    if (s != null) {
      sb.append(s);
    }

    return sb.toString();
  }

  public static String RPad(String s, char paddingChar, int fixedLen) {
    StringBuffer sb = new StringBuffer();

    if (s != null) {
      sb.append(s);
    }

    for (int i = 1; i <= fixedLen - (s != null ? s.length() : 0); i++) {
      sb.append(paddingChar);
    }

    return sb.toString();
  }

  public static String ArrayToDelimitedString(String[] arr, String delimiter, boolean trailingDelimiter) {
    StringBuffer sb = new StringBuffer();

    if (arr != null) {
      for (int i = 0; i < arr.length; i++) {
        if (i > 0) {
          sb.append(delimiter);
        }

        sb.append(arr[i]);
      }
    }

    if (sb.length() > 0 && trailingDelimiter) {
      sb.append(delimiter);
    }

    return sb.toString();
  }

  public static Properties PrefixPropNames(Properties props, String prefix) {
    Properties prefixedProps = null;
    Iterator iter;
    String name, value;
    StringBuffer prefixedName;

    if (props != null) {
      prefixedProps = new Properties();

      iter = props.keySet().iterator();

      while (iter.hasNext()) {
        name = (String) iter.next();
        value = props.getProperty(name);

        prefixedName = new StringBuffer(prefix);
        prefixedName.append(name);

        prefixedProps.setProperty(prefixedName.toString(), value);

        prefixedName = null;
      }
    }

    return prefixedProps;
  }

  public static String HtmlCharacterEncoder(String text) {
    StringBuffer html = new StringBuffer();
    int ascii;
    char c;

    if (text != null) {
      for (int i = 0; i < text.length(); i++) {
        c = text.charAt(i);
        ascii = (int) c;

        if ((ascii < 48 || ascii > 57) && (ascii < 65 || ascii > 90) && (ascii < 97 || ascii > 122) && ascii != 32) {
          html.append("&#");

          if (ascii < 10) {
            html.append("00");
          }
          else if (ascii < 100) {
            html.append("0");
          }

          html.append(ascii);
          html.append(";");
        }
        else {
          html.append(c);
        }
      }
    }

    return html.toString();
  }

  public static String HtmlCharacterEncoderIgnoreNewLines(String text) {
    StringBuffer html = new StringBuffer();
    int ascii;
    char c;

    if (text != null) {
      for (int i = 0; i < text.length(); i++) {
        c = text.charAt(i);
        ascii = (int) c;

        if ((ascii < 48 || ascii > 57) && (ascii < 65 || ascii > 90) && (ascii < 97 || ascii > 122) && ascii != 32 && ascii != 13 && ascii != 10) {
          html.append("&#");

          if (ascii < 10) {
            html.append("00");
          }
          else if (ascii < 100) {
            html.append("0");
          }

          html.append(ascii);
          html.append(";");
        }
        else {
          html.append(c);
        }
      }
    }

    return html.toString();
  }

  public static String HtmlCharacterDecoder(String html) {
    StringBuffer text = new StringBuffer();
    char c;
    String temp;

    if (html != null) {
      for (int i = 0; i < html.length(); i++) {
        c = html.charAt(i);

        if (c == '&') {
          temp = html.substring(i + 2, i + 5);
          text.append((char) Integer.parseInt(temp));
          i += 5;
        }
        else {
          text.append(c);
        }
      }
    }

    return text.toString();
  }

  public static String SimpleXMLTextEncoder(String text) {
    StringBuffer html = new StringBuffer();
    char c;

    if (text != null) {
      for (int i = 0; i < text.length(); i++) {
        c = text.charAt(i);

        switch (c) {
          case '<':
            html.append("&lt;");
            break;
          case '>':
            html.append("&gt;");
            break;
          case '&':
            html.append("&amp;");
            break;
          case '\"':
            html.append("&quot;");
            break;
          case '\'':
            html.append("&apos;");
            break;
          default:
            html.append(c);
        }
      }
    }

    return html.toString();
  }

  public static boolean IsNVL(String s) {
    return s == null || s.trim().length() == 0;
  }

  public static String[] FixedLengthSplit(String str, int[] lens) {
    String[] tokens = null;
    int startIndex = 0, endIndex = 0, sLen;

    if (str != null && (sLen = str.length()) > 0 && lens != null && lens.length > 0) {

      tokens = new String[lens.length];

      for (int i = 0; i < lens.length && startIndex < sLen; i++) {
        endIndex = startIndex + lens[i];

        if (endIndex <= sLen) {
          tokens[i] = str.substring(startIndex, endIndex);
        }
        else {
          tokens[i] = str.substring(startIndex);
        }

        startIndex = endIndex;
      } //End for i loop
    } //End input param checks

    return tokens;
  }

  public static String PrepareFixedLengthRecord(String[] tokens, char[] fieldPaddings, boolean[] padLeftDirections, int[] fieldLens, boolean appendNewLine) {
    StringBuffer record = new StringBuffer();

    if (tokens != null && fieldPaddings != null && fieldPaddings.length != 0 && fieldLens != null && fieldPaddings.length == fieldLens.length && padLeftDirections != null
        && fieldPaddings.length == padLeftDirections.length) {
      for (int i = 0; i < fieldLens.length; i++) {
        if (padLeftDirections[i]) {
          //Pad Left
          record.append(LPad((i < tokens.length ? tokens[i] : ""), fieldPaddings[i], fieldLens[i]));
        }
        else {
          //Pad Right
          record.append(RPad((i < tokens.length ? tokens[i] : ""), fieldPaddings[i], fieldLens[i]));
        }
      } //End for i loop

      if (appendNewLine) {
        record.append("\n");
      }
    } //End input param checks

    return record.toString();
  }

  public static String ParseFileFromPath(String filePath) {
    String filename = null;
    int dirIndex;

    if (filePath != null && filePath.trim().length() > 0) {
      filePath = filePath.trim();
      dirIndex = filePath.lastIndexOf("/");

      if (dirIndex < 0) {
        dirIndex = filePath.lastIndexOf("\\");
      }

      if (dirIndex >= 0) {
        filename = filePath.substring(dirIndex + 1, filePath.length());
      }
      else {
        filename = filePath;
      }
    }

    return filename;
  }

  public static String[] SplitFilePath(String filePath) {
    String[] arr = null;
    String dirPath, filename;

    if (filePath != null && filePath.trim().length() > 0) {
      dirPath = ParseDir(filePath);
      filename = ParseFileFromPath(filePath);

      arr = new String[2];
      arr[0] = dirPath;
      arr[1] = filename;
    }

    return arr;
  }

  public static synchronized String GetRandomChars(int count) {
    StringBuffer buf = new StringBuffer();

    //Some Random Character
    for (int i = 1; i <= count; i++) {
      if (((int) (100 * Math.random())) >= 50) {
        //Numbers
        buf.append((char) (48 + ((int) (10 * Math.random()))));
      }
      else {
        //Letters
        buf.append((char) (65 + ((int) (26 * Math.random()))));
      }
    }

    return buf.toString();
  }

  public static boolean IsNumeric(String s) {
    boolean numeric = false;
    char c;

    if (!IsNVL(s)) {
      numeric = true;
      s = s.trim();

      for (int i = 0; i < s.length(); i++) {
        c = s.charAt(i);

        if (i == 0 && (c == '-' || c == '+')) {
          //Ignore signs...
          continue;
        }
        else if (c < '0' || c > '9') {
          numeric = false;
          break;
        }
      }
    }

    return numeric;
  }

  public static boolean IsDouble(String s) {
    boolean numeric = false;
    char c;
    boolean foundDecimal = false;

    if (!IsNVL(s)) {
      numeric = true;
      s = s.trim();

      for (int i = 0; i < s.length(); i++) {
        c = s.charAt(i);

        if (i == 0 && (c == '-' || c == '+')) {
          //Ignore signs...
          continue;
        }
        else if (i != 0 && !foundDecimal && c == '.') {
          foundDecimal = true;
          continue;
        }
        else if (c < '0' || c > '9') {
          numeric = false;
          break;
        }
      }
    }

    return numeric;
  }

  public static String[] ReadLinesIgnoreComments(InputStream ins, String commentPrefix) throws IOException {
    InputStreamReader isr = null;
    BufferedReader br = null;
    String[] lines = null;
    String line;
    ArrayList<String> al = null;
    int cnt;

    try {
      isr = new InputStreamReader(ins);
      br = new BufferedReader(isr);
      al = new ArrayList<String>();

      line = br.readLine();
      while (line != null) {
        line = line.trim();
        if (line.length() > 0 && !line.startsWith(commentPrefix)) {
          al.add(line);
        }
        line = br.readLine();
      }

      cnt = 0;
      lines = new String[al.size()];
      while (!al.isEmpty()) {
        lines[cnt++] = al.remove(0);
      }
    }
    finally {
      if (isr != null) {
        try {
          isr.close();
        }
        catch (Exception e) {}
        isr = null;
      }

      if (br != null) {
        try {
          br.close();
        }
        catch (Exception e) {}
        br = null;
      }

      if (al != null) {
        al.clear();
        al = null;
      }
    }

    return lines;
  }

  public static String[] RemoveEmpties(String[] arr) {
    String[] neArr = null;
    ArrayList<String> al;

    if (arr != null) {
      al = new ArrayList<String>();

      for (int i = 0; i < arr.length; i++) {
        if (!IsNVL(arr[i])) {
          al.add(arr[i]);
        }
      }

      neArr = new String[al.size()];
      neArr = (String[]) al.toArray(neArr);
      al.clear();
      al = null;
    }

    return neArr;
  }

  public static boolean InArray(char c, char[] arr) {
    boolean contains = false;

    for (int i = 0; arr != null && i < arr.length; i++) {
      if (c == arr[i]) {
        contains = true;
        break;
      }
    }

    return contains;
  }

  public static boolean InArray(String s, String[] arr) {
    boolean contains = false;

    for (int i = 0; s != null && arr != null && i < arr.length; i++) {
      if (s.equals(arr[i])) {
        contains = true;
        break;
      }
    }

    return contains;
  }

  public static String toMultiLineString(Properties props) {
    StringBuffer sb = new StringBuffer();
    String name, prop;
    Iterator iter;

    if (props != null) {
      iter = props.keySet().iterator();

      while (iter.hasNext()) {
        name = (String) iter.next();
        prop = props.getProperty(name);

        sb.append(name.trim());
        sb.append("=");
        sb.append(prop.trim());
        sb.append("\n");
      }
    }

    return sb.toString();
  }

  public static String GetTrailingInteger(String s) {
    StringBuffer endNum = new StringBuffer();
    char c;

    if (s != null) {
      for (int i = s.length() - 1; i >= 0; i--) {
        c = s.charAt(i);

        if (c >= '0' && c <= '9') {
          endNum.insert(0, c);
        }
        else {
          break;
        }
      }
    }

    return endNum.toString();
  }

  public static String[] GetToStringArray(Object[] arr) {
    String[] sArr = null;

    if (arr != null) {
      sArr = new String[arr.length];

      for (int i = 0; i < sArr.length; i++) {
        if (arr[i] != null) {
          sArr[i] = arr[i].toString();
        }
      }
    }

    return sArr;
  }

  public static String GetNextWord(String stmt, int startPos) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;
    String nextWord;

    //Find first non white-space character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch != ' ') {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch == ' ') {
        break;
      }
      else {
        sb.append(ch);
      }
    }

    nextWord = sb.toString().trim();

    return nextWord;
  }

  public static int GetPositionAfterNextWord(String stmt, int startPos) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;

    //Find first non white-space character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch != ' ') {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch == ' ') {
        break;
      }
      else {
        sb.append(ch);
      }
    }

    return i;
  }

  public static boolean CharIn(char ch, char[] delimiters) {
    boolean found = false;

    for (char d : delimiters) {
      if (ch == d) {
        found = true;
        break;
      }
    }

    return found;
  }

  public static String GetNextWord(String stmt, int startPos, char[] delimiters) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;
    String nextWord;

    //Find first non delimiter character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (!CharIn(ch, delimiters)) {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (CharIn(ch, delimiters)) {
        break;
      }
      else {
        sb.append(ch);
      }
    }

    nextWord = sb.toString().trim();

    return nextWord;
  }

  public static int GetPositionAfterNextWord(String stmt, int startPos, char[] delimiters) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;

    //Find first non delimiter character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (!CharIn(ch, delimiters)) {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (CharIn(ch, delimiters)) {
        break;
      }
      else {
        sb.append(ch);
      }
    }

    return i;
  }

  public static String GetNextWordNegativeDelimiter(String stmt, int startPos, char[] delimiters) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;
    String nextWord;

    //Find first delimiter character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (CharIn(ch, delimiters)) {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (!CharIn(ch, delimiters)) {
        break;
      }
      else {
        sb.append(ch);
      }
    }

    nextWord = sb.toString().trim();

    return nextWord;
  }

  public static int GetPositionAfterNextWordNegativeDelimiter(String stmt, int startPos, char[] delimiters) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;

    //Find first delimiter character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (CharIn(ch, delimiters)) {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (!CharIn(ch, delimiters)) {
        break;
      }
      else {
        sb.append(ch);
      }
    }

    return i;
  }

  public static String[] SingleQuoteSplit(String text, char splitChar) {
    String[] tempArr = null;
    ArrayList<String> al;
    StringBuffer sb;
    int cnt;
    boolean inQuotes;
    char c;

    if (text != null) {
      al = new ArrayList<String>();
      sb = new StringBuffer();
      inQuotes = false;

      for (int i = 0; i < text.length(); i++) {
        c = text.charAt(i);
        if (c == '\'') {
          inQuotes = !inQuotes;
        }
        else if (!inQuotes && c == splitChar) {
          al.add(sb.toString());
          sb.setLength(0);
        }
        else {
          sb.append(c);
        }
      }

      if (sb.length() > 0) {
        al.add(sb.toString());
        sb.setLength(0);
      }

      cnt = 0;
      tempArr = new String[al.size()];
      while (!al.isEmpty()) {
        tempArr[cnt++] = al.remove(0);
      }
    } //End text != null check

    return tempArr;
  }

  public static String GetNextWordRespectSingleQuotes(String stmt, int startPos, char escapeChar) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;
    String nextWord;
    boolean inQuotes = false, escaped = false;

    //Find first non white-space character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch != ' ') {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch == ' ' && !inQuotes) {
        break;
      }
      else if (ch == '\'' && !escaped) {
        inQuotes = !inQuotes;
      }
      else if (!escaped && ch == escapeChar) {
        escaped = true;
      }
      else {
        escaped = false;
        sb.append(ch);
      }
    }

    nextWord = sb.toString().trim();

    return nextWord;
  }

  public static int GetPositionAfterNextWordRespectSingleQuotes(String stmt, int startPos, char escapeChar) {
    StringBuffer sb = new StringBuffer();
    char ch;
    int i;
    boolean inQuotes = false, escaped = false;

    //Find first non white-space character
    for (i = startPos; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch != ' ') {
        break;
      }
    }

    //Read next word
    for (; i < stmt.length(); i++) {
      ch = stmt.charAt(i);

      if (ch == ' ' && !inQuotes) {
        break;
      }
      else if (ch == '\'' && !escaped) {
        inQuotes = !inQuotes;
      }
      else if (!escaped && ch == escapeChar) {
        escaped = true;
      }
      else {
        escaped = false;
        sb.append(ch);
      }
    }

    return i;
  }

  public static char GetFirstNonWhiteSpaceChar(String s, int startPos) {
    char ch = '\0';

    //Find first non white-space character
    for (int i = startPos; i < s.length(); i++) {
      ch = s.charAt(i);

      if (ch != ' ') {
        break;
      }
    }

    return ch;
  }

  public static boolean EndsWithOne(String s, String[] suffix, boolean ignoreCase) {
    boolean ends = false;

    for (int i = 0; i < suffix.length; i++) {
      if (ignoreCase) {
        ends = s.toUpperCase().endsWith(suffix[i].toUpperCase());
      }
      else {
        ends = s.endsWith(suffix[i]);
      }

      if (ends) {
        break;
      }
    }

    return ends;
  }

  public static String SimpleHTMLTextEncoder(String text) {
    StringBuffer html = new StringBuffer();
    char c;

    if (text != null) {
      for (int i = 0; i < text.length(); i++) {
        c = text.charAt(i);

        switch (c) {
          case '<':
            html.append("&lt;");
            break;
          case '>':
            html.append("&gt;");
            break;
          case '&':
            html.append("&amp;");
            break;
          case '\"':
            html.append("&quot;");
            break;
          default:
            html.append(c);
        }
      }
    }

    return html.toString();
  }

  public static String Combine(String[] tokens) {
    return Combine(tokens, tokens.length);
  }

  public static String Combine(String[] tokens, int len) {
    StringBuffer sb = new StringBuffer();

    for (int i = 0; i < len && i < tokens.length; i++) {
      sb.append(tokens);
    }

    return sb.toString();
  }

  public static String CombineWithDelimiter(String[] tokens, String delimiter, int len, boolean startingDelimiter, boolean trailingDelimiter) {
    StringBuffer sb = new StringBuffer();

    if (startingDelimiter) {
      sb.append(delimiter);
    }

    for (int i = 0; i < len && i < tokens.length; i++) {
      if (i > 0) {
        sb.append(delimiter);
      }

      sb.append(tokens[i]);
    }

    if (trailingDelimiter) {
      sb.append(delimiter);
    }

    return sb.toString();
  }

  public static String[] SmartSplit(String s, char delimiter, char escapeChar) {
    String[] arr = null;
    ArrayList<String> al;
    int cnt;
    StringBuffer sb;
    char ch;
    boolean escape = false;

    if (s != null) {
      sb = new StringBuffer();
      al = new ArrayList<String>();

      for (int i = 0; i < s.length(); i++) {
        ch = s.charAt(i);

        if (escape) {
          sb.append(ch);
          escape = false;
        }
        else if (ch == escapeChar) {
          escape = true;
        }
        else if (ch == delimiter) {
          al.add(sb.toString());
          sb = new StringBuffer();
        }
        else {
          sb.append(ch);
        }
      }

      //Flush Buffer
      if (sb != null) {
        if (sb.length() > 0) {
          al.add(sb.toString());
        }
        sb = null;
      }

      cnt = 0;
      arr = new String[al.size()];
      while (!al.isEmpty()) {
        arr[cnt++] = (String) al.remove(0);
      }
    } //End defaultValuesStr NULL check

    return arr;
  }

  public static String[] SplitAtLen(String s, int maxLen) {
    String[] parts = null;
    int partCnt, startIndex, endIndex;

    if (s != null) {
      partCnt = s.length() / maxLen;
      if ((partCnt * maxLen) < s.length()) {
        partCnt++;
      }

      parts = new String[partCnt];

      for (int i = 0; i < partCnt; i++) {
        startIndex = (i * maxLen);

        if (i < (partCnt - 1)) {
          endIndex = startIndex + maxLen;
        }
        else {
          endIndex = s.length();
        }

        parts[i] = s.substring(startIndex, endIndex);
      }
    }

    return parts;
  }

  public static String Lineize(String plainText) {
    StringBuffer encodedText = new StringBuffer();

    if (plainText != null) {
      for (int i = 0; i < plainText.length(); i++) {
        if (plainText.charAt(i) == '\\') {
          encodedText.append("\\\\");
        }
        else if (plainText.charAt(i) == '\n') {
          encodedText.append("\\n");
        }
        else {
          encodedText.append(plainText.charAt(i));
        }
      }
    }

    return encodedText.toString();
  }

  public static String Delineize(String encodedText) {
    StringBuffer plainText = new StringBuffer();

    if (encodedText != null) {
      for (int i = 0; i < encodedText.length(); i++) {
        if (encodedText.charAt(i) == '\\' && i + 1 < encodedText.length()) {
          if (encodedText.charAt(i + 1) == '\\') {
            plainText.append("\\");
          }
          else if (encodedText.charAt(i + 1) == 'n') {
            plainText.append("\n");
          }
          else {
            plainText.append(encodedText.charAt(i + 1));
          }
          i++;
        }
        else {
          plainText.append(encodedText.charAt(i));
        }
      }
    }

    return plainText.toString();
  }

  public static String StripNewLines(String tmp) {
    StringBuffer sb;

    if (tmp != null) {
      sb = new StringBuffer();

      for (int i = 0; i < tmp.length(); i++) {
        if (tmp.charAt(i) != '\n') {
          sb.append(tmp.charAt(i));
        }
      }

      return sb.toString();
    }
    else {
      return null;

    }
  }

  public static boolean IsAlphaNumericOrSpace(String str) {
    boolean ret = true;

    for (int i = 0; i < str.length(); i++) {
      if (Character.isLetterOrDigit(str.charAt(i)) || Character.isSpaceChar(str.charAt(i))) {
        continue;
      }
      else {
        ret = false;
        break;
      }
    }

    return ret;
  }

  public static String ReadTextFile(InputStream ins) throws IOException {
    byte[] buf;
    String txt;

    buf = SystemUtils.LoadDataFromStream(ins);
    txt = new String(buf, 0, buf.length);

    return txt;
  }

  public static synchronized String GenerateTimeUniqueIdNumsOnly() {
    StringBuffer id = new StringBuffer();

    //Some Random Character
    for (int i = 1; i <= 4; i++) {
      id.append((char) (48 + ((int) (10 * Math.random()))));
    }

    id.append(System.currentTimeMillis());

    try {
      Thread.sleep(10);
    }
    catch (Exception e) {}

    return id.toString();
  }

  public static void PrintArray(String name, int[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, int[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(arr[i]).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

  public static void PrintArray(String name, float[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, float[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(arr[i]).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

  public static void PrintArray(String name, double[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, double[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(arr[i]).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

  public static void PrintArray(String name, short[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, short[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(arr[i]).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

  public static void PrintArray(String name, long[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, long[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(arr[i]).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

  public static void PrintArray(String name, char[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, char[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(arr[i]).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

  public static void PrintArray(String name, byte[] arr) {
    PrintArray(System.out, name, arr);
  }

  public static void PrintArray(PrintStream printer, String name, byte[] arr) {
    if (arr != null) {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" has ").append(arr.length).append(" elements -").toString());
      for (int i = 0; i < arr.length; i++) {
        printer.println((new StringBuffer()).append(name).append("[").append(i).append("] = ").append(SystemUtils.GetAsciiFromByte(arr[i])).toString());
      }
    }
    else {
      printer.println((new StringBuffer()).append("Array \"").append(name).append("\" is NULL!").toString());
    }
  }

}
