private static boolean fitsLayeredPane(
      JLayeredPane pane, JComponent component, RelativePoint desiredLocation, HintHint hintHint) {
    if (hintHint.isAwtTooltip()) {
      Dimension size = component.getPreferredSize();
      Dimension paneSize = pane.getSize();

      Point target = desiredLocation.getPointOn(pane).getPoint();
      Balloon.Position pos = hintHint.getPreferredPosition();
      int pointer = BalloonImpl.getPointerLength(pos, false) + BalloonImpl.getNormalInset();
      if (pos == Balloon.Position.above || pos == Balloon.Position.below) {
        boolean heightFit =
            target.y - size.height - pointer > 0
                || target.y + size.height + pointer < paneSize.height;
        return heightFit && size.width + pointer < paneSize.width;
      } else {
        boolean widthFit =
            target.x - size.width - pointer > 0 || target.x + size.width + pointer < paneSize.width;
        return widthFit && size.height + pointer < paneSize.height;
      }
    } else {
      final Rectangle lpRect =
          new Rectangle(
              pane.getLocationOnScreen().x,
              pane.getLocationOnScreen().y,
              pane.getWidth(),
              pane.getHeight());
      Rectangle componentRect =
          new Rectangle(
              desiredLocation.getScreenPoint().x,
              desiredLocation.getScreenPoint().y,
              component.getPreferredSize().width,
              component.getPreferredSize().height);
      return lpRect.contains(componentRect);
    }
  }
  /**
   * Shows the hint in the layered pane. Coordinates <code>x</code> and <code>y</code> are in <code>
   * parentComponent</code> coordinate system. Note that the component appears on 250 layer.
   */
  @Override
  public void show(
      @NotNull final JComponent parentComponent,
      final int x,
      final int y,
      final JComponent focusBackComponent,
      @NotNull final HintHint hintHint) {
    myParentComponent = parentComponent;
    myHintHint = hintHint;

    myFocusBackComponent = focusBackComponent;

    LOG.assertTrue(myParentComponent.isShowing());
    myEscListener = new MyEscListener();
    myComponent.registerKeyboardAction(
        myEscListener,
        KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
        JComponent.WHEN_IN_FOCUSED_WINDOW);
    myComponent.registerKeyboardAction(
        myEscListener, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED);
    final JLayeredPane layeredPane = parentComponent.getRootPane().getLayeredPane();

    myComponent.validate();

    if (!myForceShowAsPopup
        && (myForceLightweightPopup
            || fitsLayeredPane(
                layeredPane,
                myComponent,
                new RelativePoint(parentComponent, new Point(x, y)),
                hintHint))) {
      beforeShow();
      final Dimension preferredSize = myComponent.getPreferredSize();

      if (hintHint.isAwtTooltip()) {
        IdeTooltip tooltip =
            new IdeTooltip(
                hintHint.getOriginalComponent(),
                hintHint.getOriginalPoint(),
                myComponent,
                hintHint,
                myComponent) {
              @Override
              protected boolean canAutohideOn(TooltipEvent event) {
                if (event.getInputEvent() instanceof MouseEvent) {
                  return !(hintHint.isContentActive() && event.isIsEventInsideBalloon());
                } else if (event.getAction() != null) {
                  return false;
                } else {
                  return true;
                }
              }

              @Override
              protected void onHidden() {
                fireHintHidden();
                TooltipController.getInstance().resetCurrent();
              }

              @Override
              public boolean canBeDismissedOnTimeout() {
                return false;
              }
            }.setToCenterIfSmall(hintHint.isMayCenterTooltip())
                .setPreferredPosition(hintHint.getPreferredPosition())
                .setHighlighterType(hintHint.isHighlighterType())
                .setTextForeground(hintHint.getTextForeground())
                .setTextBackground(hintHint.getTextBackground())
                .setBorderColor(hintHint.getBorderColor())
                .setBorderInsets(hintHint.getBorderInsets())
                .setFont(hintHint.getTextFont())
                .setCalloutShift(hintHint.getCalloutShift())
                .setPositionChangeShift(
                    hintHint.getPositionChangeX(), hintHint.getPositionChangeY())
                .setExplicitClose(hintHint.isExplicitClose())
                .setHint(true);
        myComponent.validate();
        myCurrentIdeTooltip =
            IdeTooltipManager.getInstance()
                .show(tooltip, hintHint.isShowImmediately(), hintHint.isAnimationEnabled());
      } else {
        final Point layeredPanePoint =
            SwingUtilities.convertPoint(parentComponent, x, y, layeredPane);
        myComponent.setBounds(
            layeredPanePoint.x, layeredPanePoint.y, preferredSize.width, preferredSize.height);
        layeredPane.add(myComponent, JLayeredPane.POPUP_LAYER);

        myComponent.validate();
        myComponent.repaint();
      }
    } else {
      myIsRealPopup = true;
      Point actualPoint = new Point(x, y);
      JComponent actualComponent = new OpaquePanel(new BorderLayout());
      actualComponent.add(myComponent, BorderLayout.CENTER);
      if (isAwtTooltip()) {
        fixActualPoint(actualPoint);

        int inset = BalloonImpl.getNormalInset();
        actualComponent.setBorder(new LineBorder(hintHint.getTextBackground(), inset));
        actualComponent.setBackground(hintHint.getTextBackground());
        actualComponent.validate();
      }

      myPopup =
          JBPopupFactory.getInstance()
              .createComponentPopupBuilder(actualComponent, myFocusRequestor)
              .setRequestFocus(myFocusRequestor != null)
              .setFocusable(myFocusRequestor != null)
              .setResizable(myResizable)
              .setMovable(myTitle != null)
              .setTitle(myTitle)
              .setModalContext(false)
              .setShowShadow(isRealPopup() && !isForceHideShadow())
              .setCancelKeyEnabled(false)
              .setCancelOnClickOutside(myCancelOnClickOutside)
              .setCancelCallback(
                  new Computable<Boolean>() {
                    @Override
                    public Boolean compute() {
                      onPopupCancel();
                      return true;
                    }
                  })
              .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen)
              .createPopup();

      beforeShow();
      myPopup.show(new RelativePoint(myParentComponent, new Point(actualPoint.x, actualPoint.y)));
    }
  }