public void serialByteReceivedEvent(ByteFifo fifo) {
    readResponseLock.lock();

    serialInUse.lock();
    byte[] response = fifo.dequeueLine();
    int responseLength = response.length;
    serialInUse.unlock();

    // 0 is now an acceptable value; it merely means that we timed out
    // waiting for input
    if (responseLength < 0) {
      // This signifies EOF. FIXME: How do we handle this?
      Base.logger.severe("SerialPassthroughDriver.readResponse(): EOF occured");
      readResponseLock.unlock();
      return;
    } else if (responseLength != 0) {
      String line;
      try {
        // convert to string and remove any trailing \r or \n's
        line = new String(response, 0, responseLength, "US-ASCII").trim().toLowerCase();
      } catch (UnsupportedEncodingException e) {
        Base.logger.severe("US-ASCII required. Terminating.");
        readResponseLock.unlock();
        throw new RuntimeException(e);
      }

      // System.out.println("received: " + line);
      if (debugLevel > 1) Base.logger.info("<< " + line);

      if (line.length() == 0) Base.logger.fine("empty line received");
      else if (line.startsWith("echo:")) {
        // if echo is turned on relay it to the user for debugging
        Base.logger.info(line);
      } else if (line.startsWith("ok t:") || line.startsWith("t:")) {
        Pattern r = Pattern.compile("t:([0-9\\.]+)");
        Matcher m = r.matcher(line);
        if (m.find()) {
          String temp = m.group(1);

          machine.currentTool().setCurrentTemperature(Double.parseDouble(temp));
        }
        r = Pattern.compile("^ok.*b:([0-9\\.]+)$");
        m = r.matcher(line);
        if (m.find()) {
          String bedTemp = m.group(1);
          machine.currentTool().setPlatformCurrentTemperature(Double.parseDouble(bedTemp));
        }
      } else if (line.startsWith("ok c:") || line.startsWith("c:")) {
        Pattern r = Pattern.compile("c: *x:?([-0-9\\.]+) *y:?([-0-9\\.]+) *z:?([-0-9\\.]+)");
        Matcher m = r.matcher(line);
        if (m.find()) {
          double x = Double.parseDouble(m.group(1));
          double y = Double.parseDouble(m.group(2));
          double z = Double.parseDouble(m.group(3));
          // super to avoid parroting back a G92
          try {
            super.setCurrentPosition(new Point5d(x, y, z));
            // Base.logger.fine("setting currentposition to:"+x+","+y+","+z+".");
          } catch (RetryException e) {
            // do or do not, there is no retry
          }
        }
      }
      if (line.startsWith("ok")) {

        synchronized (okReceived) {
          okReceived.set(true);
          okReceived.notifyAll();
        }

        bufferLock.lock();
        // Notify the thread waitining in this gcode's sendCommand method that the gcode has been
        // received.
        if (buffer.isEmpty()) {
          Base.logger.severe("Received OK with nothing queued!");
        } else {
          String notifier = buffer.removeLast();
          if (debugLevel > 1) Base.logger.info("FW Accepted: " + notifier);
          synchronized (notifier) {
            notifier.notifyAll();
          }
        }
        bufferLock.unlock();

        synchronized (bufferLock) {
          /*let any sendCommand method waiting to send know that the buffer is
          now smaller and may be able to fit their command.*/
          bufferLock.notifyAll();
        }
      }

      // old arduino firmware sends "start"
      else if (line.contains("start")) {
        // Reset line number first in case gcode is sent below
        lineNumber.set(-1);

        boolean active = !buffer.isEmpty();
        flushBuffer();

        if (isInitialized()) {
          sendInitializationGcode(false);

          // If there were outstanding commands try to abort any print in progress.
          // This is a poor test:  but do we know if we're printing at this level?
          // tried setInitialized(false); but that didn't work well
          if (active) {
            Base.logger.severe("Firmware reset with active commands!");
            setError("Firmware reset with active commands!");
          }
        }
        if (okAfterStart) {
          // firmware sends "ok" after start, put something here to consume it:
          bufferLock.lock();
          buffer.addLast(";start-ok");
          bufferLock.unlock();
        }

        // todo: set version
        synchronized (startReceived) {
          startReceived.set(true);
          startReceived.notifyAll();
        }

        // Wake up connect task to try again
        synchronized (okReceived) {
          okReceived.set(false);
          okReceived.notifyAll();
        }

      } else if (line.startsWith("extruder fail")) {
        setError("Extruder failed:  cannot extrude as this rate.");

      } else if (line.startsWith("resend:") || line.startsWith("rs ")) {
        // Bad checksum, resend requested
        Matcher badLineMatch = resendLinePattern.matcher(line);

        // Is it a Dud M or G code?
        String dudLetter = getRegexMatch("dud ([a-z]) code", line, 1);

        if (badLineMatch.find()) {
          int badLineNumber = Integer.parseInt(badLineMatch.group(1));
          if (debugLevel > 1)
            Base.logger.warning("Received resend request for line " + badLineNumber);

          Queue<String> resend = new LinkedList<String>();
          boolean found = false;
          // Search backwards for the bad line in our buffer.
          // Firmware flushed everything after this line, so
          // build a queue of lines to resend.
          bufferLock.lock();
          lineSearch:
          while (!buffer.isEmpty()) {
            String bufferedLine = buffer.removeLast();
            if (debugLevel > 1) Base.logger.info("Searching: " + bufferedLine);
            int bufferedLineNumber =
                Integer.parseInt(
                    getRegexMatch(gcodeLineNumberPattern, bufferedLine.toLowerCase(), 1));
            if (dudLetter != null && bufferedLineNumber == badLineNumber) {
              Base.logger.info("Dud " + dudLetter + " code: Dropping " + bufferedLine);
              synchronized (bufferedLine) {
                bufferedLine.notifyAll();
              }
              found = true;
              break lineSearch;
            }
            resend.add(bufferedLine);
            if (bufferedLineNumber == badLineNumber) {
              found = true;
              break lineSearch;
            }
          }
          if (okAfterResend) {
            // firmware sends "ok" after resend, put something here to consume it:
            buffer.addLast(";resend-ok");
          }
          bufferLock.unlock();

          if (!found) {
            int restartLineNumber =
                Integer.parseInt(
                    getRegexMatch(gcodeLineNumberPattern, resend.element().toLowerCase(), 1));
            Base.logger.severe(
                "resend for line "
                    + badLineNumber
                    + " not in our buffer.  Resuming from "
                    + restartLineNumber);
            this.resendCommand(applyChecksum("N" + (restartLineNumber - 1) + " M110"));
          }
          // resend the lines
          while (!resend.isEmpty()) {
            String bufferedLine = resend.remove();
            this.resendCommand(bufferedLine);
          }
        } else {
          // Malformed resend line request received. Resetting the line number
          Base.logger.warning(
              "malformed line resend request, "
                  + "resetting line number. Malformed Data: \n"
                  + line);
          this.resendCommand(applyChecksum("N" + (lineNumber.get() - 1) + " M110"));
        }

      } else if (line.startsWith("t:") || line.startsWith("c:")) {
        // temperature, position handled above
      } else {
        Base.logger.severe("Unknown: " + line);
      }
    }

    readResponseLock.unlock();
  }