docs: protected void trace( int x , int y , int indexInten ) {
  
  		e = new EdgeContour();
  		contours.add(e);
  
  		int dx,dy;
  
  		addFirstSegment(x, y);
  		intensity.data[ indexInten ] = MARK_TRAVERSED;
  
  		while( open.size() > 0 ) {
  			EdgeSegment s = open.remove( open.size()-1 );
  			Point2D_I32 p = s.points.get(0);
  			indexInten = intensity.getIndex(p.x,p.y);
  			int indexDir = direction.getIndex(p.x,p.y);
  
  			boolean first = true;
  
  			while( true ) {
  				//----- First check along the direction of the edge.  Only need to check 2 points this way
  				switch( direction.data[ indexDir ] ) {
  					case  0: dx =  0;dy=  1; break;
  					case  1: dx =  1;dy= -1; break;
  					case  2: dx =  1;dy=  0; break;
  					case -1: dx =  1;dy=  1; break;
  					default: throw new RuntimeException("Unknown direction: "+direction.data[ indexDir ]);
  				}
  
  				int indexForward = indexInten + dy*intensity.stride + dx;
  				int indexBackward = indexInten - dy*intensity.stride - dx;
  
  				int prevIndexDir = indexDir;
  
  				boolean match = false;
  
  				// pixel coordinate of forward and backward point
  				x = p.x; y = p.y;
  				int fx = p.x+dx, fy = p.y+dy;
  				int bx = p.x-dx, by = p.y-dy;
  
  				// See if the forward point is in bounds and above the lower threshold
  				if( intensity.isInBounds(fx,fy) && intensity.data[ indexForward ] >= lower ) {
  					intensity.data[ indexForward ] = MARK_TRAVERSED;
  					p = queuePoints.grow();
  					p.set(fx,fy);
  					s.points.add(p);
  					match = true; // note that a match has already been found
  					indexInten = indexForward;
  					indexDir = prevIndexDir  + dy*intensity.stride + dx;
  				}
  				// See if the backwards point is in bounds and above the lower threshold
  				if( intensity.isInBounds(bx,by) && intensity.data[ indexBackward ] >= lower ) {
  					intensity.data[ indexBackward ] = MARK_TRAVERSED;
  					if( match ) {
  						// a match was found in the forwards direction, so start a new segment here
  						startNewSegment(bx, by,s);
  					} else {
  						p = queuePoints.grow();
  						p.set(bx,by);
  						s.points.add(p);
  						match = true;
  						indexInten = indexBackward;
  						indexDir = prevIndexDir  - dy*intensity.stride - dx;
  					}
  				}
  
  				// if it failed to find a match in the forwards/backwards direction or its the first pixel
  				// search the whole 8-neighborhood.
  				if( first || !match ) {
  					boolean priorMatch = match;
  					// Check local neighbors if its one of the end points, which would be the first point or
  					// any point for which no matches were found
  					match = checkAllNeighbors(x,y,s,match);
  
  					if( !match )
  						break;
  					else {
  						// if it was the first it's no longer the first
  						first = false;
  
  						// the point at the end was just added and is to be searched in the next iteration
  						if( !priorMatch ) {
  							p = s.points.get( s.points.size()-1 );
  							indexInten = intensity.getIndex(p.x, p.y);
  							indexDir = direction.getIndex(p.x,p.y);
  						}
  					}
  				}
  			}
  		}
  	}