/*******************************************************************************
 * 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;
}
