docs: protected static List<NodeInfo> findLine(NodeInfo seed, NodeInfo next, int clusterSize, List<NodeInfo> line, boolean ccw ) {
  		if( next == null )
  			return null;
  		if( line == null )
  			line = new ArrayList<>();
  		else
  			line.clear();
  
  		next.marked = true;
  		double anglePrev = direction(next, seed);
  
  		double prevDist = next.ellipse.center.distance(seed.ellipse.center);
  
  		line.add( seed );
  		line.add( next );
  
  		NodeInfo previous = seed;
  		for( int i = 0; i < clusterSize+1; i++) {
  			// find the child of next which is within tolerance and closest to it
  			double bestScore = Double.MAX_VALUE;
  			double bestDistance = Double.MAX_VALUE;
  			double bestAngle = Double.NaN;
  			double closestDistance = Double.MAX_VALUE;
  			NodeInfo best = null;
  
  			double previousLength = next.ellipse.center.distance(previous.ellipse.center);
  
  //			System.out.println("---- line connecting "+i);
  			for (int j = 0; j < next.edges.size(); j++) {
  
  				double angle = next.edges.get(j).angle;
  				NodeInfo c = next.edges.get(j).target;
  				if( c.marked )
  					continue;
  
  				double candidateLength = next.ellipse.center.distance(c.ellipse.center);
  
  				double ratioLengths = previousLength/candidateLength;
  				double ratioSize = previous.ellipse.a/c.ellipse.a;
  				if( ratioLengths > 1 ) {
  					ratioLengths = 1.0/ratioLengths;
  					ratioSize = 1.0/ratioSize;
  				}
  				if( Math.abs(ratioLengths-ratioSize) > 0.4 )
  					continue;
  
  
  				double angleDist = ccw ? UtilAngle.distanceCCW(anglePrev,angle) : UtilAngle.distanceCW(anglePrev,angle);
  
  				if( angleDist <= Math.PI+MAX_LINE_ANGLE_CHANGE ) {
  					double d = c.ellipse.center.distance(next.ellipse.center);
  
  					double score = d/prevDist+angleDist;
  
  					if( score < bestScore ) {
  //						System.out.println("  ratios: "+ratioLengths+" "+ratioSize);
  						bestDistance = d;
  						bestScore = score;
  						bestAngle = angle;
  						best = c;
  					}
  					closestDistance = Math.min(d,closestDistance);
  				}
  			}
  
  			if( best == null || bestDistance > closestDistance*2.0) {
  				return line;
  			} else {
  				best.marked = true;
  				prevDist = bestDistance;
  				line.add(best);
  				anglePrev = UtilAngle.bound(bestAngle+Math.PI);
  				previous = next;
  				next = best;
  			}
  		}
  //		if( verbose ) {
  //			System.out.println("Stuck in a loop?  Maximum line length exceeded");
  //		}
  		return null;
  	}