/*::.
==================================================================================================================================
=================================================¦ Copyright © 2014 Allen Baker ¦=================================================
                                                 +------------------------------+
File:       UStringPairs.java
Originator: Allen Baker (2014.06.12 14:30)
LayoutRev:  5
================================================================================================================================== */
package cosmicabyss.com.lib;

import java.io.*;
import java.util.*;



/*::
======================================================================================================================== *//**
This is a utilities class containing static methods for reading pairs of strings from a text file.<P>

Each line of the file must contain 1 pair of strings, separated from each other by a comma.<P>

The file may contain blank lines (lines that are empty or that contain only SPACE characters). These blank lines are
ignored.
   <BLOCKQUOTE>
      Note: A line containing any other whitespace character such as a tab, backspace, formfeed,
            Etc., IS NOT A BLANK LINE. A blank line must be entirely empty or contain ONLY SPACES.
   </BLOCKQUOTE>

The comma, known as the default "string separator", may be changed to any other single character EXCEPT A SPACE.
   <BLOCKQUOTE>
      The string separator can ONLY be changed by placing a single non-space character on the FIRST non-blank line of
      the file. If the first non-blank line of the file is found to contain just one non-space character, that character
      is used as the string separator instead of the default, which is a comma.
   </BLOCKQUOTE>

The file may contain comments. Comments are demarcated by a comment delimiter character. There is no default comment
delimiter and consequently, by default, comments are not allowed in the file.<P>
   <BLOCKQUOTE>
      The comment delimiter can ONLY be set by placing a single non-space character on the FIRST non-blank line of the
      file AFTER a string separator line. If the first non-blank line after a string separator line of the file is found
      to contain just one non-space character, that character is used as the comment delimiter.
         <BLOCKQUOTE>
            Notice: A comment delimiter may only be defined if a string separator has already been
                    Defined in the file.
         </BLOCKQUOTE>
         <BLOCKQUOTE>
            When a comment delimiter is included in the file, comments may be placed anywhere else in the file. The span
            of a comment is from each comment delimiter [inclusive] to the end of the line on which the comment
            delimiter is found. Comments are ignored.
         </BLOCKQUOTE>
         <BLOCKQUOTE>
            Warning: If spaces are placed between the end of the second string on a line and the
                     Start of a comment, those spaces will be considered part of the second string [unless trim and/or
                     squeeze are set to true].
         </BLOCKQUOTE>
   </BLOCKQUOTE>

Metacharacters (escape sequences) may be include in the strings in the file. These are translated into the actual
character when the string is read. These metacharacters are translated as follows:
   <BLOCKQUOTE>
      <PRE id="unindent">
         +---------------+----------------------+
         | Metacharacter | Is Translated Into a |
         +---------------+----------------------+
         |      \n       |      newline         |
         |      \t       |      tab             |
         |      \b       |      backspace       |
         |      \f       |      formfeed        |
         |      \r       |      carriage return |
         +---------------+----------------------+
      </PRE>
   </BLOCKQUOTE>

By setting the "trim" and/or "squeeze" parameters of the method that reads the file, space characters may be included in
the file for formatting purposes to improve readability and yet not be considered part of either of the strings on any
line.
   <BLOCKQUOTE>
      => the "trim" setting will strip away all leading and trailing spaces from each string in the
         File.<BR>
      => the "squeeze" setting will strip away all leading and trailing and interspersed spaces from
         Each string in the file.
   </BLOCKQUOTE>

Example File
   <BLOCKQUOTE>
      This is a simple file (no adornments). The default string separator (comma) is used and no comments are allowed.
         <BLOCKQUOTE>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  replace me,with me
                  old,new #comment
               </PRE>
            </BLOCKQUOTE>
         This file will result in the following string pairs being returned by the methods of this class
            <BLOCKQUOTE>
               <PRE id="unindent">
                  +------+-----------------+-----------------+
                  | Pair |  First String   |  Second String  |
                  +------+-----------------+-----------------+
                  |  1   | [replace me]    | [with me]       |
                  |  2   | [old]           | [new #comment]  |
                  +------+-----------------+-----------------+
               </PRE>
            </BLOCKQUOTE>
         </BLOCKQUOTE>
   </BLOCKQUOTE>
Example File
   <BLOCKQUOTE>
      This is a file that redefines the string separator (comma) to be a colon instead. Again, no comments are allowed.
         <BLOCKQUOTE>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  :
                  replace:me,with me
                  old:new #comment
               </PRE>
            </BLOCKQUOTE>
         This file will result in the following string pairs being returned by the methods of this class
            <BLOCKQUOTE>
               <PRE id="unindent">
                  +------+-----------------+-----------------+
                  | Pair |  First String   |  Second String  |
                  +------+-----------------+-----------------+
                  |  1   | [replace]       | [me,with me]    |
                  |  2   | [old]           | [new #comment]  |
                  +------+-----------------+-----------------+
               </PRE>
            </BLOCKQUOTE>
         </BLOCKQUOTE>
   </BLOCKQUOTE>
Example File
   <BLOCKQUOTE>
      This is a file that redefines the string separator (comma) to be a colon instead and defines the hash as a comment
      delimiter. So, comments are allowed.
         <BLOCKQUOTE>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  :
                  #
                  replace:me,with me#comment
                  old:new   # comment
                  # old:new
               </PRE>
            </BLOCKQUOTE>
         This file will result in the following string pairs being returned by the methods of this class
            <BLOCKQUOTE>
               <PRE id="unindent">
                  +------+-----------------+-----------------+
                  | Pair |  First String   |  Second String  |
                  +------+-----------------+-----------------+
                  |  1   | [replace]       | [me,with me]    |
                  |  2   | [old]           | [new   ]        |
                  +------+-----------------+-----------------+
               </PRE>
            </BLOCKQUOTE>
         </BLOCKQUOTE>
   </BLOCKQUOTE>
Example File
   <BLOCKQUOTE>
      This is a file that redefines the string separator (comma) to be a colon instead and defines the hash as a comment
      delimiter. So, comments are allowed.
         <BLOCKQUOTE>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  :
                  #
                  replace:me,with me#comment
                  old:new   # comment
                  # old:new
               </PRE>
            </BLOCKQUOTE>
         This file will result in the following string pairs being returned by the methods of this class IF TRIM is used
            <BLOCKQUOTE>
               <PRE id="unindent">
                  +------+-----------------+-----------------+
                  | Pair |  First String   |  Second String  |
                  +------+-----------------+-----------------+
                  |  1   | [replace]       | [me,with me]    |
                  |  2   | [old]           | [new]           |
                  +------+-----------------+-----------------+
               </PRE>
            </BLOCKQUOTE>
         </BLOCKQUOTE>
   </BLOCKQUOTE>
Example File
   <BLOCKQUOTE>
      This is a file that redefines the string separator (comma) to be a colon instead and defines the hash as a comment
      delimiter. So, comments are allowed.
         <BLOCKQUOTE>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  :
                  #
                  replace:me,with me#comment
                  old:new   # comment
                  # old:new
               </PRE>
            </BLOCKQUOTE>
         This file will result in the following string pairs being returned by the methods of this class IF SQUEEZE is
         used or if TRIM and SQUEEZE are used
            <BLOCKQUOTE>
               <PRE id="unindent">
                  +------+-----------------+-----------------+
                  | Pair |  First String   |  Second String  |
                  +------+-----------------+-----------------+
                  |  1   | [replace]       | [me,withme]     |
                  |  2   | [old]           | [new]           |
                  +------+-----------------+-----------------+
               </PRE>
            </BLOCKQUOTE>
         </BLOCKQUOTE>
   </BLOCKQUOTE>

<P>
   <DL>
      <DT>
         <B>
            Example usage:
         </B>
         <DD>
            <BLOCKQUOTE>
               <PRE id="unindent">
                  *java cosmicabyss.com.app.UStringPairs -t cpp
               </PRE>
            </BLOCKQUOTE>
         </DD>
      </DT>
      <DT>
         <B>
            View Source:
         </B>
         <DD>
            <A href="UStringPairs.java.html">
               uStringPairs.java
            </A>
         </DD>
      </DT>
      <DT>
         <B>
            Author:
         </B>
         <DD>
            <A href="mailto:sourcecode.v01@cosmicabyss.com">
               Allen Baker
            </A>
         </DD>
      </DT>
   </DL>
*//*
======================================================================================================================== */
public class UStringPairs
   {



   /*
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Constants  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*.
   ==========================================================================================
   CLASS_NAME:
      The name of this class
   DFLT_LINE_LEN:
      The default line length for word wrapping
   ------------------------------------------------------------------------------------------ */
   private static final XString  CLASS_NAME    = new XString(UStringPairs.class.getName());
   private static final int      DFLT_LINE_LEN = ConsoleMessage.defaultLineLength();



   /*
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Types  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */
   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Enums  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Structs  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Classes  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Interfaces  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Variables  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */



   /*.
   ==========================================================================================
   cOut:
      Formatted and time-stamped console output.
   ------------------------------------------------------------------------------------------ */
   private static ConsoleStream  cOut = ConsoleStream.getSingleton();



   /*
   ==============================================================================================================
   @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@[  Functions  ]@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
   ============================================================================================================== */
   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Constructors  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */
   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Initialization  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Methods  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method reads pairs of strings from a text file with NO option to turn on trimming, NO option to
   turn on squeezing, and NO option to interpret the strings as regular expressions.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#000">View source</A>

   @return
      An array of string pairs.

   @param
      pFileName is the name of the file containing the string pairs.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static XString[][] readStrings(XString pFileName)  throws Exception
      {
      return UStringPairs.readStrings(pFileName, false);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method reads pairs of strings from a text file with the option to turn on trimming, NO option
   to turn on squeezing, and NO option to interpret the strings as regular expressions.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#001">View source</A>

   @return
      An array of string pairs.

   @param
      pFileName is the name of the file containing the string pairs.
   @param
      pTrim allows trimming to be requested. If set to true, trim the leading and trailing whitespace
      from both strings.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static XString[][] readStrings(XString pFileName, boolean pTrim)  throws Exception
      {
      return UStringPairs.readStrings(pFileName, pTrim, false);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method reads pairs of strings from a text file with the option to turn on trimming, the option
   to turn on squeezing, and NO option to interpret the strings as regular expressions.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#002">View source</A>

   @return
      An array of string pairs.

   @param
      pFileName is the name of the file containing the string pairs.
   @param
      pTrim allows trimming to be requested. If set to true, trim the leading and trailing whitespace
      from both strings.
   @param
      pSqueeze allows squeezing to be requested. If set to true, delete all the blanks from both
      strings.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static XString[][] readStrings(XString pFileName, boolean pTrim, boolean pSqueeze)  throws Exception
      {
      return readStrings(pFileName, pTrim, pSqueeze, false);
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method reads pairs of strings from a text file with the option to turn on trimming, the option
   to turn on squeezing, and the option to interpret the strings as regular expressions.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#003">View source</A>

   @return
      An array of string pairs.

   @param
      pFileName is the name of the file containing the string pairs.
   @param
      pTrim allows trimming to be requested. If set to true, trim the leading and trailing whitespace
      from both strings.
   @param
      pSqueeze allows squeezing to be requested. If set to true, delete all the blanks from both
      strings.
   @param
      pRegex tells this method that the strings it reads are regular expressions. If set to true,
      interpret both strings as regular expressions.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static XString[][] readStrings(XString pFileName, boolean pTrim, boolean pSqueeze, boolean pRegex)  throws Exception
      {
      /*.
      ==========================================================================================
      Define a default return array as being empty in case there is nothing in the string pairs
      file.
      ------------------------------------------------------------------------------------------ */
      XString[][] strPairs = new XString[0][0];
      /*.
      ==========================================================================================
      Read the file of string pairs.
      ------------------------------------------------------------------------------------------ */
      ArrayList<ArrayList<XString>>  pairs = preparedListList(readStringPairsFromFile(pFileName), pTrim, pSqueeze, pRegex);
      /*.
      ==========================================================================================
      If there were no string pairs in the file, return
      ------------------------------------------------------------------------------------------ */
      if (pairs == null)
         {
         return strPairs;
         }
      /*.
      ==========================================================================================
      Get a reference to each of the two arrays of XStrings
      ------------------------------------------------------------------------------------------ */
      ArrayList<XString>  oldStrings = pairs.get(0);
      ArrayList<XString>  newStrings = pairs.get(1);
      /*.
      ==========================================================================================
      Put the string pairs into the kind of data structure that is expected as a return value
      and then return it.
      ------------------------------------------------------------------------------------------ */
      strPairs = new XString[oldStrings.size()][2];
      for (int idx = 0; idx < oldStrings.size(); idx++)
         {
         strPairs[idx][0] = oldStrings.get(idx);
         strPairs[idx][1] = newStrings.get(idx);
         }
      return strPairs;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method reads pairs of strings from a text file.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#004">View source</A>

   @return
      An ArrayList containing two ArrayLists, each of which contains XStrings. If this method can't
      read any string pairs from the file, it returns null. If it can read string pairs from the file,
      the first of the two ArrayLists of XStrings contains the first string read from each line of the
      file. The second of the two ArrayLists of XStrings contains the corresponding second string read
      from each line of the file.

   @param
      pFileName is the name of the file containing the string pairs.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static ArrayList<ArrayList<XString>> readStringPairsFromFile(XString pFileName)  throws Exception
      {
      /*.
      ==========================================================================================
      Load the entire contents of the string pairs file into an array, leaving out any empty
      lines in the file. An empty line is one containing nothing or nothing but spaces.
      ------------------------------------------------------------------------------------------ */
      ArrayList<XString>  linesArray = new ArrayList<XString>();
      XStringsIterator    iter       = new XStringsIterator(pFileName);
      while (iter.hasNext())
         {
         XString  line = iter.next();
         if ( ! line.trimCharset(" ").equals(XString.EMPTY))
            {
            linesArray.add(line);
            }
         }
      /*.
      ==========================================================================================
      If there was nothing at all or nothing but blank lines in the file, return
      ------------------------------------------------------------------------------------------ */
      if (linesArray.size() == 0)
         {
         return null;
         }
      /*.
      ==========================================================================================
      If the first line of the file has only one non-blank character then it is the character
      that the user wants us to use as the string separator. If it's there, record it and delete
      it from the array.
      ------------------------------------------------------------------------------------------ */
      boolean  stringSeparatorSpecified = false;
      XString  stringSeparator          = new XString(",");    // the default string separator is a comma
      XString  line                     = linesArray.get(0).trimCharset(" ");
      if (line.length() == 1)
         {
         stringSeparator = line;
         stringSeparatorSpecified = true;
         linesArray.remove(0);
         }
      /*.
      ==========================================================================================
      If after removing the string separator nothing is left in the array, return
      ------------------------------------------------------------------------------------------ */
      if (linesArray.size() == 0)
         {
         return null;
         }
      /*.
      ==========================================================================================
      If the [new] first line of the file has only one non-blank character then it is the
      character that the user wants us to use as the comment delimiter. If it's there, record it
      and delete it from the array.
      ------------------------------------------------------------------------------------------ */
      boolean  commentDelimiterSpecified = false;
      XString  commentDelimiter          = new XString("");    // by default, there is no comment delimiter
      line = linesArray.get(0).trimCharset(" ");
      if (line.length() == 1)
         {
         commentDelimiter = line;
         commentDelimiterSpecified = true;
         linesArray.remove(0);
         }
      /*.
      ==========================================================================================
      If after removing the comment delimiter nothing is left in the array, return
      ------------------------------------------------------------------------------------------ */
      if (linesArray.size() == 0)
         {
         return null;
         }
      /*.
      ==========================================================================================
      If a comment delimiter was specified then the string pairs file may contain comments.
      Delete them.
      ------------------------------------------------------------------------------------------ */
      if (commentDelimiterSpecified)
         {
         ArrayList<XString>  tmp = new ArrayList<XString>();
         for (XString aLine : linesArray)
            {
            int  idx = aLine.indexOf(commentDelimiter);
            /*.
            ==========================================================================================
            Delete comment to end of line
            ------------------------------------------------------------------------------------------ */
            if (idx != (-1))
               {
               aLine = aLine.substring(0, idx);
               }
            /*.
            ==========================================================================================
            Delete full line comment
            ------------------------------------------------------------------------------------------ */
            if ( ! aLine.trimCharset(" ").equals(XString.EMPTY))
               {
               tmp.add(aLine);
               }
            }
         linesArray = tmp;
         }
      /*.
      ==========================================================================================
      If after removing the comments nothing is left in the array, return
      ------------------------------------------------------------------------------------------ */
      if (linesArray.size() == 0)
         {
         return null;
         }
      /*.
      ==========================================================================================
      Separate the string pairs
      ------------------------------------------------------------------------------------------ */
      ArrayList<XString>  oldStrings = new ArrayList<XString>();
      ArrayList<XString>  newStrings = new ArrayList<XString>();
      for (XString aLine : linesArray)
         {
         int  idx = aLine.indexOf(stringSeparator);
         if (idx != (-1))
            {
            oldStrings.add(aLine.substring(0,       idx));
            newStrings.add(aLine.substring(idx + 1, aLine.length()));
            }
         }
      /*.
      ==========================================================================================
      Put the two parallel lists into one data structure to return
      ------------------------------------------------------------------------------------------ */
      ArrayList<ArrayList<XString>>  twoArrayLists = new ArrayList<ArrayList<XString>>();
      twoArrayLists.add(oldStrings);
      twoArrayLists.add(newStrings);
      return twoArrayLists;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method optionally trims, squeezes, and replaces metacharacters in all the XStrings in all the
   lists of XStrings contained in a list or lists.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#005">View source</A>

   @return
      A copy of the XString list list passed in through the pListList parameter that this method
      optionally trimed, squeezed, and replaced the metacharacters in. If the XString list list
      argument passed in through the pListList parameter is null, then this method will returns null.

   @param
      pListList is the XString list list that is copied and operated upon. If the XString list list
      argument passed in through this parameter is null, then this method will return null.
   @param
      pTrim allows trimming to be requested. If set to true, trim the leading and trailing whitespace
      from all the XStrings in the list list.
   @param
      pSqueeze allows squeezing to be requested. If set to true, delete all the blanks from all the
      xStrings in the list list.
   @param
      pRegex tells this method that the XStrings in the list list are regular expressions. If set to
      true, interpret the XStrings as regular expressions.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static ArrayList<ArrayList<XString>> preparedListList(ArrayList<ArrayList<XString>> pListList, boolean pTrim, boolean pSqueeze, boolean pRegex)
      {
      if (pListList == null)
         {
         return null;
         }

      ArrayList<ArrayList<XString>>  listList = new ArrayList<ArrayList<XString>>();
      for (ArrayList<XString>  list : pListList)
         {
         listList.add(preparedList(list, pTrim, pSqueeze, pRegex));
         }
      return listList;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method optionally trims, squeezes, and replaces metacharacters in all the XStrings in a list.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#006">View source</A>

   @return
      A copy of the XString list passed in through the pList parameter that this method optionally
      trimed, squeezed, and replaced the metacharacters in. If the XString list argument passed in
      through the pList parameter is null, then this method will return an empty list.

   @param
      pList is the XString list that is copied and operated upon. If the XString list argument passed
      in through this parameter is null, then this method will return an empty list.
   @param
      pTrim allows trimming to be requested. If set to true, trim the leading and trailing whitespace
      from all the XStrings in the list.
   @param
      pSqueeze allows squeezing to be requested. If set to true, delete all the blanks from all the
      xStrings in the list.
   @param
      pRegex tells this method that the XStrings in the list are regular expressions. If set to true,
      interpret the XStrings as regular expressions.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static ArrayList<XString> preparedList(ArrayList<XString> pList, boolean pTrim, boolean pSqueeze, boolean pRegex)
      {
      ArrayList<XString>  list = new ArrayList<XString>();
      if (pList == null)
         {
         return list;
         }

      for (XString  str : pList)
         {
         list.add(preparedString(str, pTrim, pSqueeze, pRegex));
         }
      return list;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method optionally trims, squeezes, and replaces metacharacters in an XString.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#007">View source</A>

   @return
      A copy of the XString passed in through the pStr parameter that this method optionally trimed,
      squeezed, and replaced the metacharacters in. If the XString argument passed in through the pStr
      parameter is null, then this method will return an empty XString.

   @param
      pStr is the XString that is copied and operated upon. If the XString argument passed in through
      this parameter is null, then this method will return an empty XString.
   @param
      pTrim allows trimming to be requested. If set to true, trim the leading and trailing whitespace
      from the XString.
   @param
      pSqueeze allows squeezing to be requested. If set to true, delete all the blanks from the
      xString.
   @param
      pRegex tells this method that the XString is a regular expressions. If set to true, interpret the
      xString as regular expressions.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static XString preparedString(XString pStr, boolean pTrim, boolean pSqueeze, boolean pRegex)
      {
      if (pStr == null)
         {
         return XString.EMPTY;
         }

      XString  str = pStr;
      if (pTrim)
         {
         str = str.trim();
         }
      if (pSqueeze)
         {
         str = str.replace(" ", "");
         }
      if (!pRegex)
         {
         str = str.replace("\\n", "\n");
         str = str.replace("\\t", "\t");
         str = str.replace("\\b", "\b");
         str = str.replace("\\f", "\f");
         str = str.replace("\\r", "\r");
         }
      return str;
      }



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This boilerplate method is used for testing this class and may include any code the developer
   chooses.

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#008">View source</A>

   @return
      A reference to this object
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static void test() throws Exception
      {
      /*.
      ==========================================================================================
      Say hello and identify yourself
      ------------------------------------------------------------------------------------------ */
      cOut.titledPrintf
         (
         "\"HELLO WORLD!\"",
         "%s  %s  %s",
         "I'm the", CLASS_NAME, "class, and I approved this message."
         );
      /*.
      ==========================================================================================
      Create a test file of string pairs
      ------------------------------------------------------------------------------------------ */
      XString     pathname  = Util.getTempFileName();
      TextWriter  pairsFile = new TextWriter(pathname);

      System.out.println(pathname);

      pairsFile.println(":"                             );   // string seperator
      pairsFile.println("#"                             );   // comment delimiter
      pairsFile.println("old:new"                       );
      pairsFile.println(""                              );
      pairsFile.println("   old   :   new   "           );
      pairsFile.println("# comment"                     );
      pairsFile.println("   # comment"                  );
      pairsFile.println(""                              );
      pairsFile.println("old:new# comment"              );
      pairsFile.println(""                              );
      pairsFile.println("   old   :   new   # comment"  );
      pairsFile.println("   old   :   new blank  "      );
      pairsFile.println("   old blank  :   new blank  " );

      pairsFile.println(":  ");
      pairsFile.println("x:");
      pairsFile.println("x:c");
      pairsFile.println("x:c:v");
      pairsFile.println("x:c:v:");
      pairsFile.println("x:c:v:# comment");
      pairsFile.println("::");
      pairsFile.println(":x:");
      pairsFile.println("tab\ttab:tab\\ttab");
      pairsFile.println();
      pairsFile.println();
      pairsFile.flush();
      pairsFile.close();
      /*.
      ==========================================================================================
      Test code
      ------------------------------------------------------------------------------------------ */
      XString[][]  pairs = UStringPairs.readStrings(pathname);
      System.out.println();
      System.out.println();
      System.out.println("============================================================");
      System.out.println("                      TRIM  SQUEEZE"                         );
      System.out.println("                       NO     NO"                            );
      System.out.println("------------------------------------------------------------");
      System.out.println(pairs.length                                                  );
      for (int idx = 0; idx < pairs.length; idx++)
         {
         XString  oldS = pairs[idx][0];
         XString  newS = pairs[idx][1];
         XString  prtS = (new XString("<" + oldS.toString() + "> ")).alignLeft(25, '-').concat(" <" + newS.toString() + ">");
         System.out.println(prtS);
         }
      /*.
      ==========================================================================================
      Test code
      ------------------------------------------------------------------------------------------ */
      pairs = UStringPairs.readStrings(pathname, true);
      System.out.println();
      System.out.println();
      System.out.println("============================================================");
      System.out.println("                      TRIM  SQUEEZE"                         );
      System.out.println("                      YES     NO"                            );
      System.out.println("------------------------------------------------------------");
      System.out.println(pairs.length                                                  );
      for (int idx = 0; idx < pairs.length; idx++)
         {
         XString  oldS = pairs[idx][0];
         XString  newS = pairs[idx][1];
         XString  prtS = (new XString("<" + oldS.toString() + "> ")).alignLeft(25, '-').concat(" <" + newS.toString() + ">");
         System.out.println(prtS);
         }
      /*.
      ==========================================================================================
      Test code
      ------------------------------------------------------------------------------------------ */
      pairs = UStringPairs.readStrings(pathname, true, true);
      System.out.println();
      System.out.println();
      System.out.println("============================================================");
      System.out.println("                      TRIM  SQUEEZE"                         );
      System.out.println("                      YES     YES"                           );
      System.out.println("------------------------------------------------------------");
      System.out.println(pairs.length                                                  );
      for (int idx = 0; idx < pairs.length; idx++)
         {
         XString  oldS = pairs[idx][0];
         XString  newS = pairs[idx][1];
         XString  prtS = (new XString("<" + oldS.toString() + "> ")).alignLeft(25, '-').concat(" <" + newS.toString() + ">");
         System.out.println(prtS);
         }
      /*.
      ==========================================================================================
      Delete the test file
      ------------------------------------------------------------------------------------------ */
      XFile  junk = new XFile(pathname);
      junk.delete();
      }



   /*
   ==============================================================================================================
   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[  Main  ]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
   ============================================================================================================== */



   /*:                                    
   ====================================================================================================
   [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
   ==================================================================================================== *//**
   This method allows this class file to be unit tested as a standalone application. It's the method
   that's called when the class is invoked from the command line by using the java application launcher
   - "java". Main() is not a required method, but the practice of putting one in each class and
   wrapping class test code within it allows easy unit testing of the class; and main does not need to
   be removed when testing is complete.

   <P>
      <DL>
         <DT>
            <B>
               Command line usage:
            </B>
            <DD>
               Java cosmicabyss.com.lib.UStringPairs
            </DD>
         </DT>
      </DL>

   <P><B>Implementation: </B><A HREF="UStringPairs.java.html#009">View source</A>

   @param
      pArgs contains the command line arguments with which this class was invoked as an application.
   *//*
   ---------------------------------------------------------------------------------------------------- */
   public static void main(String[] pArgs) throws Exception
      {
      cOut.banner(CLASS_NAME);
      UStringPairs.test();
      }



   }  // End of Class UStringPairs