/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.command.internal.env.commandline;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.BitSet;
import java.util.ResourceBundle;
import java.util.Vector;
import org.eclipse.wst.command.internal.env.common.StringUtils;


/**
  * <p>This is a generic command line parsing class.  The programmer need only specify
  * the characteristics of their command line(ie. positional parameters, flags, etc)
  * and this class will perform the rest of the parsing work.  As an added bonus this
  * class will also create formated help text that displays the syntax of this
  * command line.
  *
  * <p>The main parameter to the CommandLine constructor is a two dimensional String
  * array.  There are 5 columns in this array and as many rows as needed for each
  * flag or positional parameter.  The five columns are:
  *
  * <ol>
  * <li>The name of the flag(eg. "help" or "a", etc)
  *     Note: no dash should be in the name here.  The user would specify "-help" on the
  *           command line though.
  * <li>The name of the flag parameter(if any)
  * <li>A string indicating whether this flag can appear more than once on the
  *     command line.
  * <li>A string indicating whether this flag must be specified on the command line.
  * <li>A help text string which describes this particular flag or positional parameter.
  * </ol>
  *
  * <p>Each row in the string array is associate with either a positional parameter
  * or with a flag.  For example, consider this command line:
  * <ul>
  * <li>My_prog required_parm1 -ab parm_for_ab required_parm2 -help optional_parms
  * </ul>
  *
  * <p>In this example My_prog is the name of the program.  required_parm1 and
  * required_parm2 must be specified on the command line.  Notice that they do not
  * have to be adjacent to each other on the command line. optional_parms may optionally
  * specified.  optional_parms can be 0 or more parameters.  They does not need to be
  * adjacent to the required parameters, but they do need to follow the required
  * parameters. Two flags are specified "-ab" and "-help".  The "-ab" flag has a
  * parameter "parm_for_ab" associated with it.  Note: a flag can not have an optional
  * parameter. (ie. a flag either never have a parameter or it always has a parameter)
  * In this example, the first two rows in the string array would describe required_parm1
  * and required_parm2.  The third entry would describe optional_parms.  The fourth and
  * fifth rows would describe "-ab" and "-help".  For this command line the string array
  * would look like this:
  *
  * <ul>
  * <li>{ { CommandLine.POSITIONAL, "parm1", CommandLine.NO_DUPS,
  *       CommandLine.REQUIRED, "parm1 help text" },
  * <li>{ CommandLine.POSITIONAL, "parm2", CommandLine.NO_DUPS,
  *       CommandLine.REQUIRED, "parm2 help text" },
  * <li>{ CommandLine.POSITIONAL, "optional_parms", CommandLine.DUPS_OK,
  *       CommandLine.REQUIRED, "optional help text" },
  * <li>{ "ab", "parm_for_ab", CommandLine.NO_DUPS,
  *       CommandLine.OPTIONAL, "ab help text" },
  * <li>{ "help", CommandLine.NO_PARM, CommandLine.NO_DUPS,
  *       CommandLine.OPTIONAL, "displays this help text" } }
  * </ul>
  *
  * <p>String array rules:
  *
  * <ol>
  * <li>Positional rows must always come first in the array.  These rows must
  *     have a name specified in column 2, except for one case.  If you want to indicate that
  *     there are no optional positional parameters you would put CommandLine.NO_PARM
  *     in column 2 of the positional row.  You would also need to put CommandLine.OPTIONAL
  *     in column 4 since this row is for optional parameters(or the non-existence of
  *     optional parameters as the case may be)
  * <li>Once a positional row specifies that it is optional, no further positional rows
  *     may be specified.
  * <li>At least one positional row must be specified, even if it is to just to specify that
  *     there are no optional parameters.
  * <li>Flag names must be in lower case.  Note: the user can specify upper or lower case
  *     on the command line.
  * <li>If a flag has a parameter the name of the parameter should be put into column 2.
  *     otherwise CommandLine.NO_PARM should be put in column 2.
  * <li>If a flag is allowed to appear more than once on the command line then
  *     CommandLine.DUPS_OK should be put into column 3, otherwise CommandLine.NO_DUPS
  *     should be put into column 3.
  * <li>If a flag must be specified on the command line then CommandLine.REQUIRED should
  *     be specified in column 4, otherwise CommandLine.OPTIONAL should be specified.
  * <li>A help flag must be specified.
  * <li>The strings specified in the flags column, the parameter name column, and the
  *     help column are always translated using the resource bundle specified.  Of
  *     course the special string values such as POSITIONAL and NO_PARM are not
  *     translated.
  * </ol>
  *
  * <p> Flag matching rules:
  * <ol>
  * <li>The parser will attempt to match a user specified flag with the minimum number
  *     of programmer specified flag characters.  For example, if the programmer has
  *     specified that the flag is "help" the user could specify "-h", "-he", "-hel", or
  *     "-help".  If the programmer has also specified a flag called "hello", the
  *     user would get an error message for specifing either "-h", "-he" or "-hel", since
  *     it is ambiguous which flag is being refered to.  Both "-hell" and "-hello"
  *     would be ok for the user to specify the hello flag on the command line.
  * <li>If a flag has a parameter, the parameter may be immediately adjacent to the flag.
  *     For example if "abcd" is specified as a flag with a parameter, the user could
  *     specify the following assuming there are no other ambiguous flags. "-abcdparm",
  *     "-abcparm", "-abparm", or "-aparm" where parm is the parameter for the flag.
  *     (Of course the user can always put a white space between the flag and the
  *     parameter.)
  * <li>If a flag does not have a parameter and a parameter is adjacent to it then this
  *     parameter is interpreted as a positional parameter.  For example if "abcb" is
  *     specified as a flag and the user specifies "-abhello", then the first "ab" will be
  *     interpreted as the flag and "hello" will be interpreted as a positional
  *     parameter.
  * </ol>
  *
  * @author Peter Moogk
  * @date   July 13, 2000
**/

public class CommandLine
{
  // Constant strings that the user should use in their flags_info input array.
  /**
    * Specifies that this flag or positional parameter is required.
  **/
  public static final String REQUIRED   = "required";
  /**
    * Specifies that this flag or positional parameter is optional.
  **/
  public static final String OPTIONAL   = "optional";
  /**
    * Specifies that this flag may be specified more than once on the command line.
    * Note: This string has no meaning for positional parameters.
  **/
  public static final String DUPS_OK    = "dups_ok";
  /**
    * Specifies that this flag may not be specified more than once on the command line.
    * Note: This string has no meaning for positional parameters.
  **/
  public static final String NO_DUPS    = "no_dups";
  /**
    * Specifies that a row is a positional parameter row.
  **/
  public static final String POSITIONAL = "";
  /**
    * Specifies that a flag has no parameter.  For positional parameters this
    * string indicates that there are no optional parameters.
  **/
  public static final String NO_PARM    = "";
  
  /**
    * @param flags_info This parameter specifies the characteristics of the
    *                   command line parser.  See the class description for a
    *                   definition of what this string array should look like.
    * @param help_flag  This string indicates which flag in the flags_info
    *                   array is the help flag.
    * @param tool_name  This string indicates the name of the tool that this
    *                   command line parser is being used for.  This string
    *                   is only used when creating the help text.
  **/
  public CommandLine( String[][]     flags_info,
                       String         help_flag,
                       String         tool_name,
                       ResourceBundle flagMessages )
                   
    throws InternalErrorExc
  {
    this.flags_info   = flags_info;
    this.help_flag    = help_flag;
    this.tool_name    = tool_name;
    this.flagMessages = flagMessages;
    
    messages = ResourceBundle.getBundle( "org.eclipse.wst.command.internal.env.commandline.commandline" );
    verify_flags_info();
  }

  /**
    * Call this method to parse a command line.
    * @param args This is the string array from the command line.
    * @throws Flag_error If the user has specified the command line incorrectly
    *                    a Flag_error exception will be thrown.  Use getMessage
    *                    to get a description of the user error.
    *
    * @throws Help_specified If the user specifies the help flag this exception
    *                        will be thrown.  Use getMessage to get a fully
    *                        formatted syntax description of this command line.
  **/
  public void check_flags( String[] args ) throws Flag_error
  {
    flags_specified = new Vector[flags_info.length];

    for( int index = 0; index < args.length; index++ )
    {
      boolean processed_the_next_arg = process_arg( args, index );
      if( processed_the_next_arg == true ) index++;
    }

    // If help was specified we will not check the regular rules.
    if( !flag_specified( help_flag ) )
    {
      // Check for flags breaking the rules specified in flags_info.
      check_rules();

      // Call subclassed method to see if more processing is required.
      more_processing();
    }
  }

  /**
    * This method is for subclasses of this class.  This method is called at
    * the very end of check_flags method.  It is intended that subclasses would
    * perform additional command line checking here.
  **/
  protected void more_processing() throws Flag_error, InternalErrorExc
  {
  }

  /**
    * Once the command line has been parsed by calling check_flags a
    * call can be made to this method to get the parameters for this flag.
    * If the flag was not specified on the command line null will be returned.
    * If the flag was specified, but has no parameters a valid vector will be
    * returned containing a null.
  **/
  public String[] get_flag_parms( String flag )
  {
    int     row        = 0;
    boolean flag_found = false;

    while( flag_found == false && row < flags_info.length )
    {
      if( flags_info[row][FLAG_COL].equals( flag ) )
      {
        flag_found = true;
      }
      else
      {
        row++;
      }
    }

    if( flag_found == true ) 
    {
      Vector parms = flags_specified[row];
      return parms == null ? null : (String[])(parms.toArray( new String[0] ));
    }

    return null;
  }

  /**
    * Call this method to get all of the positional parameters.
    * This method returns both the required positionals and the
    * optional positionals in that order.  If no positional parameters
    * were specified null will be returned.
  **/
  public String[] get_positionals()
  {
    return (String[])flags_specified[POSITIONAL_ROW].toArray( new String[0] );
  }

  /**
    * This method returns true if this flag was specified by the user
    * otherwise false is returned.
  **/
  public boolean flag_specified( String flag )
  {
    return get_flag_parms( flag ) != null;
  }

  /**
    * This method returns fully formated help text syntax for this
    * command line.
  **/
  public String get_help_text()
  {
    StringBuffer help_text  = new StringBuffer(400);
    int          help_width = HELP_LINE_LEN -
                              2 -              // blanks
                              1 -              // dash
                              max_flag_size -  // flag field
                              1 -              // blank
                              max_name_size -  // name field
                              1;               // blank

    help_text.append( messages.getString( FlagMessages.PARSER_INFO_SYNTAX ) +
                      ": " + tool_name + " " );

    // Display the required positionals if any.
    for( int index = 0; index < required_positionals; index++ )
    {
      help_text.append( flagMessages.getString( flags_info[index][NAME_COL] ) +
                        " " );
    }

    help_text.append( "[" + messages.getString( FlagMessages.PARSER_FLAGS ) +
                      "] " );

    if( optional_positionals_allowed == true )
    {
      help_text.append( flagMessages.getString( flags_info[optional_list_index][NAME_COL] ) );
    }

    help_text.append( "\n  " + messages.getString( FlagMessages.PARSER_INFO_WHERE ) + "\n" );

    // Create one line of description for each parameter
    for( int row = 0; row < flags_info.length; row++ )
    {
      String columnId   = flags_info[row][NAME_COL];
      String columnName = columnId == NO_PARM ? "" : flagMessages.getString( columnId );

      String flagId     = flags_info[row][FLAG_COL];
      String flagName   = flagId == POSITIONAL ? POSITIONAL : flagMessages.getString(flagId);

      int flag_padding = max_flag_size - flagName.length();
      int name_padding = max_name_size - columnName.length();

      // Skip this row if this is a marker for no optional positionals.
      if( flags_info[row][FLAG_COL] == POSITIONAL &&
          flags_info[row][NAME_COL] == NO_PARM ) continue;

      if( flagName == POSITIONAL )
      {
        help_text.append( getBlanks(3 ) );
      }
      else
      {
        help_text.append( "  -" + flagName );
      }

      help_text.append( getBlanks( flag_padding + 1 ) );
      help_text.append( columnName );
      help_text.append( getBlanks( name_padding + 1 ) );

      String   columnHelp = flagMessages.getString( flags_info[row][HELP_COL] );
      String[] split_help_text
        = StringUtils.splitter( columnHelp, help_width );

      if( split_help_text.length > 0 )
        help_text.append( split_help_text[0] + "\n" );
      else
        help_text.append( "\n" );

      for( int index = 1; index < split_help_text.length; index++ )
      {
        help_text.append( getBlanks( HELP_LINE_LEN - help_width ) );
        help_text.append( split_help_text[index] + "\n" );
      }
      
      help_text.append( "\n" );
    }

    return "" + help_text;
  }
  
  /**
   *  Return a string with the specified number of blanks.
   */
  private String getBlanks( int count )
  {
  	char[] blanks = new char[count];
  	Arrays.fill( blanks, 0, count, ' ' );
  	
  	return new String( blanks );
  }

  /**
    * This class is the base for all command line exception classes.
  **/
  static public class ErrorExc extends Exception
  {
  	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 3257567317259793720L;

	public ErrorExc( String message, String[] args )
  	{
  	  super( MessageFormat.format( message, args ) );
  	}
  }

  /**
    * This class will be thrown when an internal error is detected.
    * This usually happens if the flag description information was
    * specified incorrectly.
  **/
  static public class InternalErrorExc extends IllegalArgumentException
  {  	
  	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 3258410621136614450L;

	public InternalErrorExc( String message, String[] args )
  	{
  	  super( MessageFormat.format( message, args ) );
  	}
  	
  	public InternalErrorExc( String message )
  	{
  	  this( message, (String[])null );
  	}
  	
  	public InternalErrorExc( String message, String arg )
  	{
  	  this( message, new String[]{ arg } );
  	}
  }

  /**
    * This class will be thrown if a user error occurs while parsing the command line.
  **/
  static public class Flag_error extends ErrorExc
  {
    /**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 3832621776877663537L;

	public Flag_error( String message, String[] args )
    {
      super( message, args );
    }

    public Flag_error( String message, String arg )
    {
      super( message, new String[]{ arg } );
    }

    public Flag_error( String message )
    {
      super( message, null );
    }
  }

  /**
    * Tries to process a single flag on the command line.
    * @param  args      All the command line parameters.
    * @param  arg_index This is the index of the argument that is to be processed.
    * @return returns true if the argument we are processing is a flag that has a
    *         parameter and the parameter is specified in the next argument.
  **/
  private boolean process_arg( String[] args, int arg_index ) throws Flag_error
  {
    boolean processed_next_arg = false;

    if( args[arg_index].charAt(0) == '-' )
    {
      // This is the start of a flag.
      int flag_index = 1;
      int info_index = get_info_index( args[arg_index], flag_index );
      int max_index  = get_max_index( args[arg_index], flag_index, info_index );

      if( flags_info[info_index][NAME_COL] != NO_PARM )
      {
        // This flag takes a parameter so check if it is stuck to this
        // arg.
        if( max_index < args[arg_index].length() )
        {
          add_flag_parm( info_index,
                         args[arg_index].substring( max_index,
                                                    args[arg_index].length() ) );
        }
        else
        {
          // This flag has a parameter and it wasn't stuck to the flag,
          // so we will try to get it from the next arg.
          if( arg_index+1 < args.length &&
              args[arg_index+1].charAt(0) != '-' )
          {
            // We found an parameter in the next string so we will use this
            // one as a parameter for this flag.  Note: if was no parameter
            // after the flag at all, the error will be caught in the
            // check_rules method.
            add_flag_parm( info_index, args[arg_index+1] );
            processed_next_arg = true;
          }
          else
          {
            // Error missing paramater. This error is caught by check_rules.
            add_flag_parm( info_index, null );
          }
        }
      }
      else
      {
        // The flag does not have a parameter so we will add a null.
        add_flag_parm( info_index, null );

        // Check to see if a positional parameter is stuck to this flag.
        if( max_index < args[arg_index].length() )
        {
          add_positional( args[arg_index].substring( max_index,
                                                     args[arg_index].length() ) );
        }
      }
    }
    else
    {
      // This is a positional parameter.
      add_positional( args[arg_index] );
    }

    return processed_next_arg;
  }

  /**
    * Finds the row for the flag that uniquely matched this flag str.
    * @return returns the flags_info index of the matching flag.
  **/
  private int get_info_index( String flag_str, int start_index )
    throws Flag_error
  {
    //int info_start  = 1;
    //int info_end    = flags_info.length;
    int info_index;
    int found_count = 0;
    int info_col_index = 0;
    int last_info_index = 0;

    BitSet flags_rejected = new BitSet();

    // Loop over each char in flag_str.  Note: we will probably bail early.
    for( int flag_col_index = start_index; flag_col_index < flag_str.length(); flag_col_index++ )
    {
      // Loop over each flag in flag_info
      for( info_index = 0; info_index < flags_info.length; info_index++ )
      {
        String flagId   = flags_info[info_index][FLAG_COL];
        String flagName = flagId == POSITIONAL ? POSITIONAL : flagMessages.getString( flagId );

        if( flags_rejected.get( info_index ) == false &&
            info_col_index < flagName.length() &&
              Character.toLowerCase(flag_str.charAt(flag_col_index)) ==
              flagName.charAt(info_col_index) )
        {
          found_count++;
          last_info_index = info_index;
        }
        else
        {
          flags_rejected.set( info_index );
        }
      }

      if( found_count == 1 )
      {
        // We have a match.
        return last_info_index;
      }
      else if( found_count == 0 )
      {
        // Flag not found at all.
        throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_FLAG_NOT_FOUND ),
                              flag_str.substring( start_index ) );
      }
      else
      {
        // More than one flag was found with this char so we will go to the
        // next char to uniquely match it.
        info_col_index++;
        //info_start = last_info_index - found_count + 1;
        //info_end   = last_info_index + 1;
        found_count = 0;
      }
    }

    // The only way to get to this code is if the loop exited with
    // the found_count greater than 1.  Therefore, the flag specified is
    // ambiguous.
    throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_AMBIGUOUS_FLAG ),
                          flag_str.substring( start_index) );
  }

  /**
    * This method tries to match as many characters as possible of the user
    * specified flag with the matched flag string.
    * @return returns the position of the last matching flag chararacter.
  **/
  private int get_max_index( String flag_str, int flag_start, int info_index )
  {
    int flag_col_index = flag_start;
    int info_col_index = 0;

    String info_str = flagMessages.getString( flags_info[info_index][FLAG_COL] );

    while( flag_col_index < flag_str.length() &&
           info_col_index < info_str.length() )
    {
      if( Character.toLowerCase( flag_str.charAt(flag_col_index) ) !=
          info_str.charAt(info_col_index) )
        break;

      flag_col_index++;
      info_col_index++;
    }

    return flag_col_index;
  }

  /**
    * Adds a positional parameter to flags_specified.
  **/
  private void add_positional( String positional_parm )
  {
    if( flags_specified[POSITIONAL_ROW] == null )
      flags_specified[POSITIONAL_ROW] = new Vector(3);

    flags_specified[POSITIONAL_ROW].add( positional_parm );
  }

  /**
    * Adds a flag and its parameter to flags_specified.  If only the
    * flag was specified, then a null should be passed to flag_parm.
  **/
  private void add_flag_parm( int flag_index, String flag_parm )
    throws Flag_error
  {
    if( flags_info[flag_index][DUP_COL] == NO_DUPS &&
        flags_specified[flag_index] != null )
      throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_DUPLICATE_FLAGS_NOT_ALLOWED ),
                             flagMessages.getString( flags_info[flag_index][FLAG_COL] ) );

    if( flags_specified[flag_index] == null )
      flags_specified[flag_index] = new Vector(3);

    flags_specified[flag_index].add( flag_parm );
  }

  /**
    * Checks that the user hasn't broken any command line rules.
  **/
  private void check_rules() throws Flag_error
  {
    // Check that all of the required positionals were specified.
    int positional_count = 0;

    if( flags_specified[POSITIONAL_ROW] != null )
    {
      positional_count = flags_specified[POSITIONAL_ROW].size();
    }

    if( required_positionals > positional_count )
      throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_MISSING_POSITIONAL ),
                             flagMessages.getString( flags_info[required_positionals-1][NAME_COL] ) );

    else if( required_positionals < positional_count &&
             optional_positionals_allowed == false )
      throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_TOO_MANY_POSITIONALS ) );

    for( int row = 0; row < flags_info.length; row++ )
    {
      if( flags_info[row][FLAG_COL] == POSITIONAL ) continue;

      if( flags_specified[row] == null &&
          flags_info[row][REQUIRED_COL] == REQUIRED )
        throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_MISSING_REQUIRED_FLAG ),
                               flagMessages.getString( flags_info[row][FLAG_COL] ) );

      int parm_count = 0;

      if( flags_specified[row] != null ) parm_count = flags_specified[row].size();

      // Check for too many flag parameters.
      if( flags_info[row][DUP_COL] == NO_DUPS && parm_count > 1 )
        throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_DUPLICATE_FLAGS_NOT_ALLOWED ),
                               flagMessages.getString( flags_info[row][FLAG_COL] ) );

      // Check for missing flag parameter.
      if( parm_count > 0 && flags_info[row][NAME_COL] != NO_PARM )
      {
        for( int index = 0; index < flags_specified[row].size(); index++ )
        {
          if( flags_specified[row].elementAt(index) == null )
            throw new Flag_error( messages.getString( FlagMessages.PARSER_ERROR_MISSING_FLAG_PARAMETER ),
                                  new String[]
                                    { flagMessages.getString( flags_info[row][FLAG_COL] ),
                                      flagMessages.getString( flags_info[row][NAME_COL] ) } );

        }
      }
    }
  }

  /**
    * This method verifies that a proper flags_info string array was passed
    * to us by the programmer.
  **/
  private void verify_flags_info() throws InternalErrorExc
  {
    boolean done_positionals = false;
    boolean help_specified   = false;

    required_positionals = 0;
    optional_positionals_allowed = false;
    optional_list_index = -1;
    max_flag_size = 0;
    max_name_size = 0;

    if( flags_info == null || flags_info.length == 0 )
      throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_NO_FLAGS_DATA_SPECIFIED  ) );

    if( flags_info[POSITIONAL_ROW] != null &&
        flags_info[POSITIONAL_ROW].length > 0 &&
        flags_info[POSITIONAL_ROW][FLAG_COL] != POSITIONAL )
      throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_FIRST_FLAG_NOT_POSITIONAL ) );

    for( int row = 0; row < flags_info.length; row++ )
    {
      if( flags_info[row] == null )
        throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_NULL_FLAG_ROW ) );

      if( flags_info[row].length != 5 )
        throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_INCORRECT_ROW_SIZE ) );

      if( flags_info[row][FLAG_COL] == null ||
          flags_info[row][NAME_COL] == null ||
          flags_info[row][HELP_COL] == null )
        throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_NULL_IN_ROW ) );

      if( flags_info[row][FLAG_COL].equals( help_flag ) ) help_specified = true;

      String flagId   = flags_info[row][FLAG_COL];
      String nameId   = flags_info[row][NAME_COL];

      String flag_col = flagId == POSITIONAL ? POSITIONAL : flagMessages.getString( flagId );
      String name_col = nameId == NO_PARM ? NO_PARM : flagMessages.getString( nameId );

      if( flag_col.length() > max_flag_size )
        max_flag_size = flag_col.length();

      if( name_col != NO_PARM && name_col.length() > max_name_size )
        max_name_size = name_col.length();

      // Ensure that flags are all in lowercase.
      if( !flag_col.equals( flag_col.toLowerCase() ) )
        throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_FLAG_NOT_LOWERCASE ),
                                    flag_col );

      // Ensure that only the predefined dup strings are used.
      // Note: it's ok to use != when comparing constant strings literals.
      if( flags_info[row][DUP_COL] == null ||
          ( flags_info[row][DUP_COL] != NO_DUPS &&
            flags_info[row][DUP_COL] != DUPS_OK ) )
        throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_INCORRECT_DUP_STRING ),
                                 flags_info[row][DUP_COL] );

      // Ensure that only the predefined required strings are used.
      if( flags_info[row][REQUIRED_COL] == null ||
          ( flags_info[row][REQUIRED_COL] != REQUIRED &&
            flags_info[row][REQUIRED_COL] != OPTIONAL ) )
        throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_INCORRECT_REQUIRED_STRING ),
                                 flags_info[row][REQUIRED_COL] );

      // Count the number of required positionals.
      if( flags_info[row][FLAG_COL] == POSITIONAL )
      {
        if( flags_info[row][REQUIRED_COL] == REQUIRED )
        {
          if( flags_info[row][NAME_COL] == NO_PARM )
            throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_REQUIRED_POSITIONAL_NEEDS_NAME ) );

          required_positionals++;
        }
        else if( flags_info[row][NAME_COL] != NO_PARM )
        {
          // We use the NAME_COL field for an optional positional to denote
          // whether additional positionals are allowed or not.
          optional_positionals_allowed = true;
          optional_list_index = row;
        }
      }

      // Ensure that positionals are at the beginning of the info.
      if( flags_info[row][FLAG_COL] != POSITIONAL ||
          ( done_positionals == false &&
            flags_info[row][FLAG_COL] == POSITIONAL &&
            flags_info[row][REQUIRED_COL] == OPTIONAL ) )
      {
        done_positionals = true;
      }
      else if( done_positionals == true )
        throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_POSITIONAL_NOT_AT_BEGINNING ) );
    }

    // Ensure that a help flag was specified in the info list.
    if( help_specified == false )
      throw new InternalErrorExc( messages.getString( FlagMessages.PARSER_ERROR_HELP_FLAG_NOT_SPECIFIED ) );
  }

  /**
    * This method is used to dump internal information about a parsed
    * command line.
  **/
  public String toString()
  {
    StringBuffer b = new StringBuffer(100);

    for( int row = 0; row < flags_info.length; row++ )
    {
      b.append( "\n" );

      if( flags_info[row][FLAG_COL] == POSITIONAL )
        b.append( "Positional:" );
      else
        b.append( flagMessages.getString( flags_info[row][FLAG_COL] ) + ":" );


      if( flags_specified[row] == null )
        b.append( "no parameters" );
      else
        for( int parm_index = 0; parm_index < flags_specified[row].size(); parm_index++ )
        {
          String parm = (String)flags_specified[row].elementAt(parm_index);
          b.append( parm + ":" );
        }
      b.append( "\n" );
    }

    return ""+b;
  }

  private static final int FLAG_COL     = 0;
  private static final int NAME_COL     = 1;
  private static final int DUP_COL      = 2;
  private static final int REQUIRED_COL = 3;
  private static final int HELP_COL     = 4;

  private static final int POSITIONAL_ROW = 0;
  private static final int HELP_LINE_LEN  = 75;

  private String[][] flags_info;
  private String     help_flag;
  private String     tool_name;
  private Vector[]   flags_specified;
  private int        required_positionals;
  private boolean    optional_positionals_allowed;
  private int        optional_list_index;
  private int        max_flag_size;
  private int        max_name_size;

  protected ResourceBundle messages;
  private   ResourceBundle flagMessages;
}
