private EditorFragmentComponent(
      EditorEx editor, int startLine, int endLine, boolean showFolding, boolean showGutter) {
    Document doc = editor.getDocument();
    final int endOffset =
        endLine < doc.getLineCount() ? doc.getLineEndOffset(endLine) : doc.getTextLength();
    int textWidth =
        Math.min(
            editor.getMaxWidthInRange(doc.getLineStartOffset(startLine), endOffset),
            ScreenUtil.getScreenRectangle(1, 1).width);
    LOG.assertTrue(
        textWidth > 0,
        "TextWidth: " + textWidth + "; startLine:" + startLine + "; endLine:" + endLine + ";");

    FoldingModelEx foldingModel = editor.getFoldingModel();
    boolean isFoldingEnabled = foldingModel.isFoldingEnabled();
    if (!showFolding) {
      foldingModel.setFoldingEnabled(false);
    }

    Point p1 = editor.logicalPositionToXY(new LogicalPosition(startLine, 0));
    Point p2 = editor.logicalPositionToXY(new LogicalPosition(Math.max(endLine, startLine + 1), 0));
    int y1 = p1.y;
    int y2 = p2.y;
    int height = y2 - y1 == 0 ? editor.getLineHeight() : y2 - y1;
    LOG.assertTrue(
        height > 0,
        "Height: "
            + height
            + "; startLine:"
            + startLine
            + "; endLine:"
            + endLine
            + "; p1:"
            + p1
            + "; p2:"
            + p2);

    int savedScrollOffset = editor.getScrollingModel().getHorizontalScrollOffset();
    if (savedScrollOffset > 0) {
      editor.stopOptimizedScrolling();
      editor.getScrollingModel().scrollHorizontally(0);
    }

    final Image textImage = new BufferedImage(textWidth, height, BufferedImage.TYPE_INT_RGB);
    Graphics textGraphics = textImage.getGraphics();

    final JComponent rowHeader;
    final Image markersImage;
    if (showGutter) {
      rowHeader = editor.getGutterComponentEx();
      markersImage =
          new BufferedImage(Math.max(1, rowHeader.getWidth()), height, BufferedImage.TYPE_INT_RGB);
      Graphics markerGraphics = markersImage.getGraphics();

      markerGraphics.translate(0, -y1);
      markerGraphics.setClip(0, y1, rowHeader.getWidth(), height);
      markerGraphics.setColor(getBackgroundColor(editor));
      markerGraphics.fillRect(0, y1, rowHeader.getWidth(), height);
      rowHeader.paint(markerGraphics);
    } else {
      rowHeader = null;
      markersImage = null;
    }

    textGraphics.translate(0, -y1);
    textGraphics.setClip(0, y1, textWidth, height);
    final boolean wasVisible = editor.setCaretVisible(false);
    editor.setPurePaintingMode(true);
    try {
      editor.getContentComponent().paint(textGraphics);
    } finally {
      editor.setPurePaintingMode(false);
    }
    if (wasVisible) {
      editor.setCaretVisible(true);
    }

    if (!showFolding) {
      foldingModel.setFoldingEnabled(isFoldingEnabled);
    }

    if (savedScrollOffset > 0) {
      editor.stopOptimizedScrolling();
      editor.getScrollingModel().scrollHorizontally(savedScrollOffset);
    }

    JComponent component =
        new JComponent() {
          public Dimension getPreferredSize() {
            return new Dimension(
                textImage.getWidth(null) + (markersImage == null ? 0 : markersImage.getWidth(null)),
                textImage.getHeight(null));
          }

          protected void paintComponent(Graphics graphics) {
            if (markersImage != null) {
              graphics.drawImage(markersImage, 0, 0, null);
              graphics.drawImage(textImage, rowHeader.getWidth(), 0, null);
            } else {
              graphics.drawImage(textImage, 0, 0, null);
            }
          }
        };

    setLayout(new BorderLayout());
    add(component);

    final Color borderColor =
        editor.getColorsScheme().getColor(EditorColors.SELECTED_TEARLINE_COLOR);

    Border outsideBorder = BorderFactory.createLineBorder(borderColor, 1);
    Border insideBorder = BorderFactory.createEmptyBorder(2, 2, 2, 2);
    setBorder(BorderFactory.createCompoundBorder(outsideBorder, insideBorder));
  }