/** The logic here is specific to our protocol. We parse the string according to that protocol. */
  private Float executeCommand(String commandLine) throws ATMException {
    // Break out the command line into String[]
    StringTokenizer tokenizer = new StringTokenizer(commandLine);
    String commandAndParam[] = new String[tokenizer.countTokens()];
    int index = 0;
    while (tokenizer.hasMoreTokens()) {
      commandAndParam[index++] = tokenizer.nextToken();
    }

    // store the command
    String command = commandAndParam[0];

    // Dispatch BALANCE request without further ado.
    if (command.equalsIgnoreCase(Commands.BALANCE.toString())) {
      return atmImplementation.getBalance();
    }

    // Must have 2nd arg for amount when processing DEPOSIT/WITHDRAW commands
    if (commandAndParam.length < 2) {
      throw new ATMException("Missing amount for command \"" + command + "\"");
    }

    // execute deposit or withdraw command
    try {
      float amount = Float.parseFloat(commandAndParam[1]);
      if (command.equalsIgnoreCase(Commands.DEPOSIT.toString())) {
        atmImplementation.deposit(amount);
      } else if (command.equalsIgnoreCase(Commands.WITHDRAW.toString())) {
        atmImplementation.withdraw(amount);
      } else {
        throw new ATMException("Unrecognized command: " + command);
      }
    } catch (NumberFormatException nfe) {
      throw new ATMException("Unable to make float from input: " + commandAndParam[1]);
    }
    // BALANCE command returned result above.  Other commands return null;
    return null;
  }