void OptionsList::usage()
{
  size_t len;
  char buffer[1024], *cp;

  cp = buffer;
  len = sprintf(buffer, "Usage: %s ", program_);
  cp += len;

  bool hasSimpleFlags = false;
	
  for (list<Option>::iterator iter = begin(); iter != end(); iter++)
  {
    Option *opt = &(*iter);
    if (opt->getName() != NULL &&
        !opt->hasArgument() &&
        (len = strlen(opt->getName())) == 1)
    {
      hasSimpleFlags = true;
      break;
    }
  }

  if (hasSimpleFlags)
  {
    *cp++ = '[';
    *cp++ = '-';
		
    for (list<Option>::iterator iter = begin(); iter != end(); iter++)
    {
      Option *opt = &(*iter);
      if (opt->getName() != NULL &&
          !opt->hasArgument() &&
          (len = strlen(opt->getName())) == 1)
      {
	strcpy(cp, opt->getName());
	cp += len;
      }
    }
		
    *cp++ = ']';
  }

  char staging[128], *cp2;
  for (list<Option>::iterator iter = begin(); iter != end(); iter++)
  {
    Option *opt = &(*iter);

    if (opt->getName() != NULL && !opt->hasArgument() && (len = strlen(opt->getName())) == 1)
      continue;
		
    *cp++ = ' ';

    cp2 = staging;
    if (!opt->isRequired())
    {
      *cp2++ = '[';
    }

    if (opt->getType() == Option::eList)
    {
      *cp2++ = '{';
    }
				
    if (opt->getName() != NULL && !opt->hasArgument() && strlen(opt->getName()) > 1)
    {
      len = sprintf(cp2, "-%s", opt->getName());
      cp2 += len;
    }
    else if (opt->getName() != NULL && opt->hasArgument())
    {
      len = sprintf(cp2, "-%s <%s>", opt->getName(), opt->getArgDesc());
      cp2 += len;
    }
    else if (opt->getName() == NULL)
    {
      len = sprintf(cp2, "<%s>", opt->getArgDesc());
      cp2 += len;
    }
		
    if (opt->getType() == Option::eList)
    {
      *cp2++ = '}';
      *cp2++ = '.';
      *cp2++ = '.';
      *cp2++ = '.';
    }
				
    if (!opt->isRequired())
    {
      *cp2++ = ']';
    }

    *cp2 = '\0';
		
    if (((cp2 - staging) + (cp - buffer)) > 79)
    {
      *cp++ = '\n';
      *cp = '\0';
			
      fputs(buffer, stderr);
      strcpy(buffer, "        ");
      cp = buffer + 8;
    }
		
    strcpy(cp, staging);
    cp += cp2 - staging;
  }

  *cp++ = '\n';
  *cp = '\0';
  fputs(buffer, stderr);
	

  for (list<Option>::iterator iter = begin(); iter != end(); iter++)
  {
    Option *opt = &(*iter);
    if (opt->getName() != NULL)
    {
      if (opt->hasArgument())
	sprintf(buffer, "-%-2.2s <%s>", opt->getName(), opt->getArgDesc());
      else
	sprintf(buffer, "-%-6.6s", opt->getName());
    }
    else if (opt->getOrder() >= 0)
    {
      sprintf(buffer, "<%s>", opt->getArgDesc());
    }
    else
    {
      sprintf(buffer, "<%s>...", opt->getArgDesc());
    }
		
    fprintf(stderr, "    %-20.20s : ", buffer);
    const char *cp = opt->getUsage();
    while (*cp != '\0')
    {
      if (*cp == '\n')
      {
	fputc(*cp, stderr);
	int count = 4 + 20 + 1;
	while (count--)
	  fputc(' ', stderr);
				
	fputc('>', stderr);
	fputc(' ', stderr);
      }
      else
      {
	fputc(*cp, stderr);
      }
			
      cp++;
    }
    fputc('\n', stderr);
  }

  exit(256);
}
int OptionsList::parse(int &aArgc, const char **aArgv)
{
  sort();
  
  // This assumes that the first option (app name) has already been removed.
  
  int order = 0, count = 0;

  program_ = "agent";
	
  Option *opt;
  const char **argp = aArgv;
  const char *cp;
	
  while (aArgc > 0)
  {
    if (**argp == '-')
    {
      cp = (*argp) + 1;
      bool next = false;

      while (*cp != 0 && !next)
      {
	if (find(cp, opt))
	{
	  count++;

	  if (opt->hasArgument())
	  {
	    getArg(argp, aArgc, opt, cp);
	    next = true;
	  }
	  else
	  {
	    if (opt->type_ != Option::eBoolean)
	    {
	      cerr << "Bad argument definition: " << opt->getName() << endl;
	    }
	    else if (opt->isSet_)
	    {
	      cerr << "Option " << opt->getName() << " is already specified" << endl;
	      usage();
	    }
	    else
	    {
	      *(opt->boolPtr_) = true;
	    }
						
	    cp += strlen(opt->getName());
	  }

	  opt->isSet_ = true;
	}
	else
	{
	  cerr << "Bad argument:" << *argp << endl;
	  usage();
	}
      }
    }
    else
    {
      if (find(order, opt))
      {
	if (!opt->setValue(*argp))
	  usage();

	count++;
      }
      else if (find(-1, opt))
      {
	if (!opt->setValue(*argp))
	  usage();

	count++;
      }

      order++;
    }
		
    argp++;
    aArgc--;
  }

  for (list<Option>::iterator iter = begin(); iter != end(); iter++)
  {
    opt = &(*iter);
    if (opt->isRequired() && !opt->isSet())
    {
      if (opt->getName() != NULL)
      	cerr << "Required option -" << opt->getName() << " is not specified" << endl;
      else
      	cerr << "Required option <" << opt->getArgDesc() << "> is not specified" << endl;
      usage();
    }
  }
  
  
  return count;
}