public int run(TraceReader traceReader, LoopDetector loopDetector) throws InterruptedException {

    // Stats
    int loopInstCount = 0;
    int traceCount = 0;

    String instruction = null;
    while ((instruction = traceReader.nextInstruction()) != null) {
      traceCount++;
      int address = traceReader.getAddress();
      loopDetector.step(address, instruction);

      List<CodeSegment> loops = getLoops(loopDetector, traceReader);

      loopInstCount += processLoops(loops);

      // Check if work should be interrupted
      if (Thread.currentThread().isInterrupted()) {
        throw new InterruptedException("Application Interrupted");
      }
    }

    loopDetector.close();
    List<CodeSegment> loops = getLoops(loopDetector, traceReader);

    loopInstCount += processLoops(loops);

    // Test #instructions
    testInstructionNumber(traceCount, loopInstCount);

    // return new LoopProcessorResults(traceCount);
    return traceCount;
  }
  private List<CodeSegment> getLoops(LoopDetector loopDetector, TraceReader traceReader) {
    List<CodeSegment> loops = loopDetector.getAndClearUnits();
    addRegisterValuesToLoop(loops, traceReader);

    return loops;
  }