code: public static <T> T eachLine(Reader self, int firstLine, @ClosureParams(value=FromString.class,options={"String","String,Integer"}) Closure<T> closure) throws IOException {
          BufferedReader br;
          int count = firstLine;
          T result = null;
  
          if (self instanceof BufferedReader)
              br = (BufferedReader) self;
          else
              br = new BufferedReader(self);
  
          try {
              while (true) {
                  String line = br.readLine();
                  if (line == null) {
                      break;
                  } else {
                      result = callClosureForLine(closure, line, count);
                      count++;
                  }
              }
              Reader temp = self;
              self = null;
              temp.close();
              return result;
          } finally {
              closeWithWarning(self);
              closeWithWarning(br);
          }
      }
docs: Iterates through the given reader line by line.  Each line is passed to the
  given 1 or 2 arg closure. If the closure has two arguments, the line count is passed
  as the second argument. The Reader is closed before this method returns.
  
  @param self      a Reader, closed after the method returns
  @param firstLine the line number value used for the first line (default is 1, set to 0 to start counting from 0)
  @param closure   a closure which will be passed each line (or for 2 arg closures the line and line count)
  @return the last value returned by the closure
  @throws IOException if an IOException occurs.
  @since 1.5.7