protected void doBuildFromStream(String url, Reader input, StringBuilder data, boolean searchForEncoding, boolean matchStart) throws IOException {
    ParseSettings settings = getParseSettings(url);
    Pattern startSection = settings.startPattern;
    Pattern endSection = settings.endPattern;
    boolean useDt = settings.useDt;

    data.append(HTML);
    URL baseUrl = VfsUtilCore.convertToURL(url);
    if (baseUrl != null) {
      data.append("<base href=\"").append(baseUrl).append("\">");
    }
    data.append("""
                  <style type="text/css">  ul.inheritance {
                        margin:0;
                        padding:0;
                    }
                    ul.inheritance li {
                         display:inline;
                         list-style-type:none;
                    }
                    ul.inheritance li ul.inheritance {
                      margin-left:15px;
                      padding-left:15px;
                      padding-top:1px;
                    }
                  </style>""");

    String read;
    String contentEncoding = null;
    @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") BufferedReader buf = new BufferedReader(input);
    do {
      read = buf.readLine();
      if (read != null && searchForEncoding) {
        String foundEncoding = parseContentEncoding(read);
        if (foundEncoding != null) {
          contentEncoding = foundEncoding;
        }
      }
    }
    while (read != null && matchStart && !startSection.matcher(StringUtil.toUpperCase(read)).find());

    if (input instanceof MyReader && contentEncoding != null &&
        !(contentEncoding.equalsIgnoreCase(CharsetToolkit.UTF8) || contentEncoding.equals(((MyReader)input).getEncoding()))) {
      //restart page parsing with correct encoding
      try {
        data.setLength(0);
        doBuildFromStream(url, new MyReader(((MyReader)input).myInputStream, contentEncoding), data, false, true);
      }
      catch (ProcessCanceledException ignored) { }
      return;
    }

    if (read == null) {
      data.setLength(0);
      if (matchStart && !settings.forcePatternSearch && input instanceof MyReader) {
        try {
          Reader reader = contentEncoding != null ? new MyReader(((MyReader)input).myInputStream, contentEncoding)
                                                  : new MyReader(((MyReader)input).myInputStream, ((MyReader)input).getEncoding());
          doBuildFromStream(url, reader, data, false, false);
        }
        catch (ProcessCanceledException ignored) { }
      }
      return;
    }

    if (useDt) {
      boolean skip = false;

      do {
        if (StringUtil.containsIgnoreCase(read, H2_CLOSE) && !StringUtil.containsIgnoreCase(read, H2)) { // read=class name in <H2>
          data.append(H2_CLOSE);
          skip = true;
        }
        else if (endSection.matcher(read).find() || StringUtil.indexOfIgnoreCase(read, GREATEST_END_SECTION, 0) != -1) {
          data.append(HTML_CLOSE);
          return;
        }
        else if (!skip) {
          appendLine(data, read);
        }
      }
      while (((read = buf.readLine()) != null) && !StringUtil.toUpperCase(read).trim().equals(DL) &&
             !StringUtil.containsIgnoreCase(read, "<div class=\"description\""));

      data.append(DL);

      StringBuilder classDetails = new StringBuilder();
      while (((read = buf.readLine()) != null) && !StringUtil.toUpperCase(read).equals(HR) && !StringUtil.toUpperCase(read).equals(P)) {
        if (reachTheEnd(data, read, classDetails, endSection)) return;
        if (!skipBlockList(read)) {
          appendLine(classDetails, read);
        }
      }

      while (((read = buf.readLine()) != null) && !StringUtil.toUpperCase(read).equals(HR) && !StringUtil.toUpperCase(read).equals(P)) {
        if (reachTheEnd(data, read, classDetails, endSection)) return;
        if (!skipBlockList(read)) {
          appendLine(data, StringUtil.replace(read, DT, DT + BR));
        }
      }

      data.append(classDetails);
      data.append(P);
    }
    else {
      appendLine(data, read);
    }

    while (((read = buf.readLine()) != null) &&
           !endSection.matcher(read).find() &&
           StringUtil.indexOfIgnoreCase(read, GREATEST_END_SECTION, 0) == -1) {
      if (!skipBlockList(read)) {
        appendLine(data, read);
      }
    }

    data.append(HTML_CLOSE);
  }
protected void doBuildFromStream(String url, Reader input, StringBuilder data, boolean searchForEncoding, boolean matchStart)