Program: 63417
Project: 63417
Buggy source:
@Override public List<Rectangle> detect(Page page,File referenceDocument){
  PDDocument pdfDocument;
  try {
    pdfDocument=PDDocument.load(referenceDocument);
  }
 catch (  Exception e) {
    return new ArrayList<Rectangle>();
  }
  PDPage pdfPage=(PDPage)pdfDocument.getDocumentCatalog().getAllPages().get(page.getPageNumber() - 1);
  debugFileOut=referenceDocument.getAbsolutePath().replace("String_Node_Str","String_Node_Str" + page.getPageNumber() + "String_Node_Str");
  BufferedImage image;
  try {
    image=pdfPage.convertToImage(BufferedImage.TYPE_BYTE_GRAY,144);
    debugImage=pdfPage.convertToImage(BufferedImage.TYPE_INT_RGB,72);
  }
 catch (  IOException e) {
    return new ArrayList<Rectangle>();
  }
  List<Line2D.Float> horizontalRulings=this.getHorizontalRulings(image);
  try {
    this.removeText(pdfDocument,pdfPage);
    image=pdfPage.convertToImage(BufferedImage.TYPE_BYTE_GRAY,144);
  }
 catch (  Exception e) {
    return new ArrayList<Rectangle>();
  }
  List<Line2D.Float> verticalRulings=this.getVerticalRulings(image);
  List<Line2D.Float> allEdges=new ArrayList<Line2D.Float>(horizontalRulings);
  allEdges.addAll(verticalRulings);
  List<Rectangle> tableAreas=new ArrayList<Rectangle>();
  List<Rectangle> cells=null;
  Set<Point2D.Float> crossingPoints=null;
  if (allEdges.size() > 0) {
    Utils.snapPoints(allEdges,8f,8f);
    crossingPoints=this.getCrossingPoints(horizontalRulings,verticalRulings);
    cells=this.findRectangles(crossingPoints,horizontalRulings,verticalRulings);
    if (cells.size() >= 4) {
      tableAreas=this.getTableAreasFromCells(cells);
    }
  }
  List<TextChunk> textChunks=TextElement.mergeWords(page.getText());
  List<Line> lines=TextChunk.groupByLines(textChunks);
  List<Line2D.Float> leftTextEdges=new ArrayList<Line2D.Float>();
  List<Line2D.Float> midTextEdges=new ArrayList<Line2D.Float>();
  List<Line2D.Float> rightTextEdges=new ArrayList<Line2D.Float>();
  Map<Integer,List<TextChunk>> currLeftEdges=new HashMap<Integer,List<TextChunk>>();
  Map<Integer,List<TextChunk>> currMidEdges=new HashMap<Integer,List<TextChunk>>();
  Map<Integer,List<TextChunk>> currRightEdges=new HashMap<Integer,List<TextChunk>>();
  for (  Line textRow : lines) {
    for (    TextChunk text : textRow.getTextElements()) {
      Integer left=new Integer((int)Math.floor(text.getLeft()));
      Integer right=new Integer((int)Math.floor(text.getRight()));
      Integer mid=new Integer(left + ((right - left) / 2));
      List<TextChunk> leftEdge=currLeftEdges.getOrDefault(left,new ArrayList<TextChunk>());
      leftEdge.add(text);
      currLeftEdges.put(left,leftEdge);
      List<TextChunk> midEdge=currMidEdges.getOrDefault(mid,new ArrayList<TextChunk>());
      midEdge.add(text);
      currMidEdges.put(mid,midEdge);
      List<TextChunk> rightEdge=currRightEdges.getOrDefault(right,new ArrayList<TextChunk>());
      rightEdge.add(text);
      currRightEdges.put(right,rightEdge);
      for (Iterator<Map.Entry<Integer,List<TextChunk>>> iterator=currLeftEdges.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Integer,List<TextChunk>> entry=iterator.next();
        Integer key=entry.getKey();
        if (key > left && key < right) {
          iterator.remove();
          List<TextChunk> edgeChunks=entry.getValue();
          if (edgeChunks.size() >= 4) {
            TextChunk first=edgeChunks.get(0);
            TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
            leftTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
          }
        }
      }
      for (Iterator<Map.Entry<Integer,List<TextChunk>>> iterator=currMidEdges.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Integer,List<TextChunk>> entry=iterator.next();
        Integer key=entry.getKey();
        if (key > left && key < right && Math.abs(key - mid) > 2) {
          iterator.remove();
          List<TextChunk> edgeChunks=entry.getValue();
          if (edgeChunks.size() >= 4) {
            TextChunk first=edgeChunks.get(0);
            TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
            midTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
          }
        }
      }
      for (Iterator<Map.Entry<Integer,List<TextChunk>>> iterator=currRightEdges.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Integer,List<TextChunk>> entry=iterator.next();
        Integer key=entry.getKey();
        if (key > left && key < right) {
          iterator.remove();
          List<TextChunk> edgeChunks=entry.getValue();
          if (edgeChunks.size() >= 4) {
            TextChunk first=edgeChunks.get(0);
            TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
            rightTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
          }
        }
      }
    }
  }
  for (  Integer key : currLeftEdges.keySet()) {
    List<TextChunk> edgeChunks=currLeftEdges.get(key);
    if (edgeChunks.size() >= 4) {
      TextChunk first=edgeChunks.get(0);
      TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
      leftTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
    }
  }
  for (  Integer key : currMidEdges.keySet()) {
    List<TextChunk> edgeChunks=currMidEdges.get(key);
    if (edgeChunks.size() >= 4) {
      TextChunk first=edgeChunks.get(0);
      TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
      midTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
    }
  }
  for (  Integer key : currRightEdges.keySet()) {
    List<TextChunk> edgeChunks=currRightEdges.get(key);
    if (edgeChunks.size() >= 4) {
      TextChunk first=edgeChunks.get(0);
      TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
      rightTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
    }
  }
  for (  Rectangle area : tableAreas) {
    area.x=area.x / 2;
    area.y=area.y / 2;
    area.width=area.width / 2;
    area.height=area.height / 2;
  }
  return tableAreas;
}

Fixed version (ground truth):
@Override public List<Rectangle> detect(Page page,File referenceDocument){
  PDDocument pdfDocument;
  try {
    pdfDocument=PDDocument.load(referenceDocument);
  }
 catch (  Exception e) {
    return new ArrayList<Rectangle>();
  }
  PDPage pdfPage=(PDPage)pdfDocument.getDocumentCatalog().getAllPages().get(page.getPageNumber() - 1);
  debugFileOut=referenceDocument.getAbsolutePath().replace("String_Node_Str","String_Node_Str" + page.getPageNumber() + "String_Node_Str");
  BufferedImage image;
  try {
    image=pdfPage.convertToImage(BufferedImage.TYPE_BYTE_GRAY,144);
    debugImage=pdfPage.convertToImage(BufferedImage.TYPE_INT_RGB,72);
  }
 catch (  IOException e) {
    return new ArrayList<Rectangle>();
  }
  List<Line2D.Float> horizontalRulings=this.getHorizontalRulings(image);
  try {
    this.removeText(pdfDocument,pdfPage);
    image=pdfPage.convertToImage(BufferedImage.TYPE_BYTE_GRAY,144);
  }
 catch (  Exception e) {
    return new ArrayList<Rectangle>();
  }
  List<Line2D.Float> verticalRulings=this.getVerticalRulings(image);
  List<Line2D.Float> allEdges=new ArrayList<Line2D.Float>(horizontalRulings);
  allEdges.addAll(verticalRulings);
  List<Rectangle> tableAreas=new ArrayList<Rectangle>();
  List<Rectangle> cells=null;
  Set<Point2D.Float> crossingPoints=null;
  if (allEdges.size() > 0) {
    Utils.snapPoints(allEdges,8f,8f);
    crossingPoints=this.getCrossingPoints(horizontalRulings,verticalRulings);
    horizontalRulings=this.mergeHorizontalEdges(horizontalRulings);
    verticalRulings=this.mergeVerticalEdges(verticalRulings);
    cells=this.findRectangles(crossingPoints,horizontalRulings,verticalRulings);
    tableAreas=this.getTableAreasFromCells(cells);
  }
  List<TextChunk> textChunks=TextElement.mergeWords(page.getText());
  List<Line> lines=TextChunk.groupByLines(textChunks);
  List<Line2D.Float> leftTextEdges=new ArrayList<Line2D.Float>();
  List<Line2D.Float> midTextEdges=new ArrayList<Line2D.Float>();
  List<Line2D.Float> rightTextEdges=new ArrayList<Line2D.Float>();
  Map<Integer,List<TextChunk>> currLeftEdges=new HashMap<Integer,List<TextChunk>>();
  Map<Integer,List<TextChunk>> currMidEdges=new HashMap<Integer,List<TextChunk>>();
  Map<Integer,List<TextChunk>> currRightEdges=new HashMap<Integer,List<TextChunk>>();
  for (  Line textRow : lines) {
    for (    TextChunk text : textRow.getTextElements()) {
      Integer left=new Integer((int)Math.floor(text.getLeft()));
      Integer right=new Integer((int)Math.floor(text.getRight()));
      Integer mid=new Integer(left + ((right - left) / 2));
      List<TextChunk> leftEdge=currLeftEdges.getOrDefault(left,new ArrayList<TextChunk>());
      leftEdge.add(text);
      currLeftEdges.put(left,leftEdge);
      List<TextChunk> midEdge=currMidEdges.getOrDefault(mid,new ArrayList<TextChunk>());
      midEdge.add(text);
      currMidEdges.put(mid,midEdge);
      List<TextChunk> rightEdge=currRightEdges.getOrDefault(right,new ArrayList<TextChunk>());
      rightEdge.add(text);
      currRightEdges.put(right,rightEdge);
      for (Iterator<Map.Entry<Integer,List<TextChunk>>> iterator=currLeftEdges.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Integer,List<TextChunk>> entry=iterator.next();
        Integer key=entry.getKey();
        if (key > left && key < right) {
          iterator.remove();
          List<TextChunk> edgeChunks=entry.getValue();
          if (edgeChunks.size() >= 4) {
            TextChunk first=edgeChunks.get(0);
            TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
            leftTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
          }
        }
      }
      for (Iterator<Map.Entry<Integer,List<TextChunk>>> iterator=currMidEdges.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Integer,List<TextChunk>> entry=iterator.next();
        Integer key=entry.getKey();
        if (key > left && key < right && Math.abs(key - mid) > 2) {
          iterator.remove();
          List<TextChunk> edgeChunks=entry.getValue();
          if (edgeChunks.size() >= 4) {
            TextChunk first=edgeChunks.get(0);
            TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
            midTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
          }
        }
      }
      for (Iterator<Map.Entry<Integer,List<TextChunk>>> iterator=currRightEdges.entrySet().iterator(); iterator.hasNext(); ) {
        Map.Entry<Integer,List<TextChunk>> entry=iterator.next();
        Integer key=entry.getKey();
        if (key > left && key < right) {
          iterator.remove();
          List<TextChunk> edgeChunks=entry.getValue();
          if (edgeChunks.size() >= 4) {
            TextChunk first=edgeChunks.get(0);
            TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
            rightTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
          }
        }
      }
    }
  }
  for (  Integer key : currLeftEdges.keySet()) {
    List<TextChunk> edgeChunks=currLeftEdges.get(key);
    if (edgeChunks.size() >= 4) {
      TextChunk first=edgeChunks.get(0);
      TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
      leftTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
    }
  }
  for (  Integer key : currMidEdges.keySet()) {
    List<TextChunk> edgeChunks=currMidEdges.get(key);
    if (edgeChunks.size() >= 4) {
      TextChunk first=edgeChunks.get(0);
      TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
      midTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
    }
  }
  for (  Integer key : currRightEdges.keySet()) {
    List<TextChunk> edgeChunks=currRightEdges.get(key);
    if (edgeChunks.size() >= 4) {
      TextChunk first=edgeChunks.get(0);
      TextChunk last=edgeChunks.get(edgeChunks.size() - 1);
      rightTextEdges.add(new Line2D.Float(key,first.getTop(),key,last.getBottom()));
    }
  }
  this.debug(leftTextEdges);
  this.debug(midTextEdges);
  this.debug(rightTextEdges);
  for (  Rectangle area : tableAreas) {
    area.x=(float)Math.floor(area.x / 2);
    area.y=(float)Math.floor(area.y / 2);
    area.width=(float)Math.ceil(area.width / 2);
    area.height=(float)Math.ceil(area.height / 2);
  }
  this.debug(tableAreas);
  return tableAreas;
}