/**
   * THIS COMMAND CAN ONLY BE CALLED FROM streamCommands UNLESS THE nextCommand OBJECT IS
   * SYNCHRONIZED.
   *
   * <p>Returns the next command with the following priority: 1. nextCommand object if set. 2. Front
   * of the commandBuffer collection. 3. Next line in the commandStream.
   *
   * @return
   */
  private GcodeCommand getNextCommand() {
    if (nextCommand != null) {
      return nextCommand;
    } else if (!this.commandBuffer.isEmpty()) {
      nextCommand = new GcodeCommand(commandBuffer.pop());
    } else
      try {
        if (rawCommandStream != null && rawCommandStream.ready()) {
          nextCommand = new GcodeCommand(rawCommandStream.readLine());
        } else if (commandStream != null && commandStream.ready()) {
          nextCommand = commandStream.getNextCommand();
        }
      } catch (IOException ex) {
        // Fall through to null handling.
      }

    if (nextCommand != null) {
      nextCommand.setCommandNumber(getNextCommandId());
      if (nextCommand.getCommandString().endsWith("\n")) {
        nextCommand.setCommand(nextCommand.getCommandString().trim());
      }
      return nextCommand;
    }
    return null;
  }
  @Override
  public String activeCommandSummary() {
    StringBuilder sb = new StringBuilder();
    String comma = "";

    for (GcodeCommand gc : activeCommandList) {
      sb.append(comma).append(gc.getCommandString());
      comma = ", ";
    }

    if (commandStream != null) {
      sb.append(comma).append(commandStream.getNumRowsRemaining()).append(" streaming commands.");
    }

    return sb.toString();
  }
 @Override
 public int numActiveCommands() {
   int streamingCount = commandStream == null ? 0 : commandStream.getNumRowsRemaining();
   return this.activeCommandList.size() + streamingCount;
 }