/**
   * Reads next line and notifies susbscribed observers.
   *
   * @return true if more lines would be available, false if there was no possible to read the line,
   *     since the EOF has been reached.
   */
  public boolean next() {
    if (this.isClosed) return false;
    if (this.nomore) return false;
    try {
      final boolean unpoll[] = new boolean[symbols.length];
      long minTime = nextMilliseconds[0];
      for (int i = 1; i < symbols.length; i++) {
        if (nextMilliseconds[i] > minTime) unpoll[i] = true;
        else if (nextMilliseconds[i] < minTime) {
          minTime = nextMilliseconds[i];
          for (int j = 0; j < i; j++) unpoll[j] = true;
        }
      }

      boolean somethingToReturn = false;
      final ParseResult compossedResult = new ParseResult();
      for (int i = 0; i < symbols.length; i++) {
        if (unpoll[i] || this.nextLine[i] == null) {
          // Nothing to send to listeners.
        } else {
          somethingToReturn = true;
          final ParseResult localResult = this.lineParser.parse(this.nextLine[i]);
          // Move to next valid line.
          String line = partReader[i].readLine();
          while (line != null && !this.lineParser.isValid(line)) {
            line = partReader[i].readLine();
          }
          if (line != null) {
            if (!symbols[i].equals(localResult.getSymbol(0))) {
              this.nextLine[i] = null;
            } else {
              this.nextLine[i] = line;
              this.nextMilliseconds[i] = this.lineParser.getUTCTimestamp(line).getTimeInMillis();
            }
          } else {
            this.nextLine[i] = null;
          }
          compossedResult.merge(localResult);
        }
      }
      if (somethingToReturn) {
        for (int i = 0; i < this.spreadTradesMgr.length; i++) {
          this.spreadTradesMgr[i].accumulate(compossedResult);
        }
      } else {
        this.nomore = true;
        for (int i = 0; i < this.spreadTradesMgr.length; i++) {
          this.spreadTradesMgr[i].endAccumulation();
        }
      }
      return somethingToReturn;
    } catch (Exception e) {
      log.log(Level.SEVERE, "Exception dealing with file '" + filePath + "'", e);
      return false;
    }
  }