code: private void organizeCells(ArrayList<TextPiece> linesOfAPage,
  	    TableCandidate tc) {
  	float captionY = linesOfAPage.get(tc.getCaptionStartLine()).getY();
  	float captionEndY = linesOfAPage.get(tc.getCaptionEndLine()).getEndY();
  	ArrayList<TextPiece> rawCells = new ArrayList<TextPiece>();
  	/*
  	 * Copy & sort
  	 */
  	for (int i = tc.getBodyStartLine(); i <= tc.getBodyEndLine(); i++) {
  	    rawCells.add(linesOfAPage.get(i));
  	}
  
  	Collections.sort(rawCells);
  	assert rawCells.size() >= 4; // due to previous check
  	TableRow currentRow = null; // creates first row
  
  	for (TextPiece cell : rawCells) {
  	    /*
  	     * Skips lines beyond caption //TODO: remove the far Y
  	     */
  	    if (tc.isTopCaption() && (cell.getY() < captionY))
  		continue;
  	    if (!tc.isTopCaption() && (cell.getEndY() > captionEndY))
  		continue;
  
  	    /*
  	     * Lines too close to each other are treated as a single line
  	     */
  	    if (currentRow != null
  		    && cell.getY() - currentRow.getY() < m_docInfo
  			    .getAverageLineGap() / 2.0)
  		currentRow.addCell(cell);
  	    else {
  		/*
  		 * Creates a new row
  		 */
  		currentRow = new TableRow();
  		currentRow.setY(cell.getY());
  		if (cell.isSuperScriptBeginning())
  		    currentRow.setSuperScriptRow(true);
  		currentRow.addCell(cell);
  		tc.addRow(currentRow);
  	    }
  	}
  	if (tc.getRows().size() < 2)
  	    tc.setValid(false);
      }
docs: Organizes cells into rows based on the coordinate information
  
  @param linesOfAPage
  the list of lines of this document page
  @param tc
  the object of the table candidate