Buggy code:
private ScreenVertexPool screenVertexPool ; private ScreenVertexPool screenVertexPool2 ; private ScreenEdgePool screenEdgePool ; private ScreenEdgePool screenEdgePool2 ; private ScreenVertexList screenVertices ; private ScreenVertexList screenVertices2 ; private ScreenEdgeList screenEdges ; private ScreenEdgeList screenEdges2 ; public VertexOrder ( final TrackSchemeGraph graph ) { } private void swapPools ( ) { } public void build ( ) { } public void print ( ) { } private void build ( final TrackSchemeVertex v ) { } public TrackSchemeVertex getMinVertex ( final int timepoint , final TrackSchemeVertex vertex ) { } public TrackSchemeVertex getMaxVertex ( final int timepoint , final TrackSchemeVertex vertex ) { } public double getMinX ( final int timepoint ) { } public double getMaxX ( final int timepoint ) { } public double getMinX ( ) { } public double getMaxX ( ) { } public int getMinTimepoint ( ) { } public int getMaxTimepoint ( ) { } public ScreenEntities cropAndScale ( final double minX , final double maxX , final double minY , final double maxY , final int screenWidth , final int screenHeight ) { swapPools ( ) ; final TrackSchemeVertex v1 = graph . vertexRef ( ) ; final TrackSchemeVertex v2 = graph . vertexRef ( ) ; final ScreenVertex sv = screenVertexPool . createRef ( ) ; final ScreenEdge se = screenEdgePool . createRef ( ) ; final ArrayList < ScreenVertexRange > vertexRanges = new ArrayList < ScreenVertexRange > ( ) ; final double yScale = ( ( double ) ( screenHeight - 1 ) ) // ( maxY - minY ) ; final double xScale = ( ( double ) ( screenWidth - 1 ) ) // ( maxX - minX ) ; final double allowedMinD = 2.0 // xScale ; final long t0 = System . currentTimeMillis ( ) ; final TIntIterator iter = timepoints . iterator ( ) ; while ( iter . hasNext ( ) ) { final int timepoint = iter . next ( ) ; if ( ( ( timepoint + 1 ) >= minY ) && ( ( timepoint - 1 ) <= maxY ) ) { final int timepointStartScreenVertexIndex = screenVertices . size ( ) ; final double y = ( timepoint - minY ) * yScale ; final double prevY = ( ( timepoint - 1 ) - minY ) * yScale ; final TrackSchemeVertexList vertexList = timepointToOrderedVertices . get ( timepoint ) ; int minIndex = vertexList . binarySearch ( minX ) ; minIndex -- ; if ( minIndex < 0 ) minIndex = 0 ; int maxIndex = vertexList . binarySearch ( maxX , minIndex , vertexList . size ( ) ) ; if ( maxIndex < ( ( vertexList . size ( ) ) - 1 ) ) maxIndex ++ ; final double minLayoutX = vertexList . getMinLayoutXDistance ( ) ; TIntArrayList denseRanges = vertexList . getDenseRanges ( minIndex , ( maxIndex + 1 ) , minLayoutX , allowedMinD , 3 , v1 ) ; if ( denseRanges == null ) denseRanges = new TIntArrayList ( ) ; denseRanges . add ( ( maxIndex + 1 ) ) ; final TIntIterator riter = denseRanges . iterator ( ) ; int nextRangeStart = riter . next ( ) ; double prevX = Double . NEGATIVE_INFINITY ; double minVertexScreenDist = yScale ; for ( int i = minIndex ; i <= maxIndex ; ++ i ) { if ( i < nextRangeStart ) { vertexList . get ( i , v1 ) ; final int v1si = screenVertices . size ( ) ; v1 . setScreenVertexIndex ( v1si ) ; final int id = v1 . getInternalPoolIndex ( ) ; final double x = ( ( v1 . getLayoutX ( ) ) - minX ) * xScale ; final boolean selected = false ; screenVertexPool . create ( sv ) . init ( id , x , y , selected ) ; screenVertices . add ( sv ) ; minVertexScreenDist = Math . min ( minVertexScreenDist , ( x - prevX ) ) ; prevX = x ; for ( final TrackSchemeEdge edge : v1 . incomingEdges ( ) ) { edge . getSource ( v2 ) ; final int v2si = v2 . getScreenVertexIndex ( ) ; <START_BUG> if ( ( ( v2si > 0 ) && ( v2si < ( screenVertices . size ( ) ) ) ) && ( ( screenVertices . get ( v2si , sv ) . getId ( ) ) == ( v2 . getInternalPoolIndex ( ) ) ) ) { <END_BUG> final int eid = edge . getInternalPoolIndex ( ) ; final int sourceScreenVertexIndex = v2si ; final int targetScreenVertexIndex = v1si ; final boolean eselected = false ; screenEdgePool . create ( se ) . init ( eid , sourceScreenVertexIndex , targetScreenVertexIndex , eselected ) ; screenEdges . add ( se ) ; } } } else { final int rangeMinIndex = nextRangeStart ; final int rangeMaxIndex = riter . next ( ) ; nextRangeStart = riter . next ( ) ; i = rangeMaxIndex ; final double svMinX = ( ( vertexList . get ( rangeMinIndex , v1 ) . getLayoutX ( ) ) - minX ) * xScale ; final double svMaxX = ( ( vertexList . get ( rangeMaxIndex , v1 ) . getLayoutX ( ) ) - minX ) * xScale ; vertexRanges . add ( new ScreenVertexRange ( svMinX , svMaxX , prevY , y ) ) ; minVertexScreenDist = 0 ; } } for ( int i = timepointStartScreenVertexIndex ; i < ( screenVertices . size ( ) ) ; ++ i ) { screenVertices . get ( i , sv ) . setVertexDist ( minVertexScreenDist ) ; } } } screenEdgePool . releaseRef ( se ) ; screenVertexPool . releaseRef ( sv ) ; graph . releaseRef ( v1 ) ; graph . releaseRef ( v2 ) ; return new ScreenEntities ( screenVertices , screenEdges , vertexRanges ) ; } public static TrackSchemeVertexList getOrderedRoots ( final TrackSchemeGraph graph ) { }

Fix:
if ( ( ( v2si >= 0 ) && ( v2si < ( screenVertices . size ( ) ) ) ) && ( ( screenVertices . get ( v2si , sv ) . getId ( ) ) == ( v2 . getInternalPoolIndex ( ) ) ) ) {