private void showNoSuggestions(boolean isExplicit) {
    hideCurrentPopup();

    if (!isExplicit) return;

    final JComponent message =
        HintUtil.createErrorLabel(IdeBundle.message("file.chooser.completion.no.suggestions"));
    final ComponentPopupBuilder builder =
        JBPopupFactory.getInstance().createComponentPopupBuilder(message, message);
    builder
        .setRequestFocus(false)
        .setResizable(false)
        .setAlpha(0.1f)
        .setFocusOwners(new Component[] {myPathTextField});
    myNoSuggestionsPopup = builder.createPopup();
    myNoSuggestionsPopup.showInScreenCoordinates(getField(), getLocationForCaret(myPathTextField));
  }
  public void show() {
    // final long time = System.currentTimeMillis();
    JComponent panel = createCenterPanel();
    new MnemonicHelper().register(panel);
    boolean shouldSetWidth =
        DimensionService.getInstance().getSize(getDimensionServiceKey(), myProject) == null;
    myPopup =
        JBPopupFactory.getInstance()
            .createComponentPopupBuilder(panel, null)
            .setTitle(myTitle)
            .setResizable(true)
            .setModalContext(false)
            .setFocusable(true)
            .setMovable(true)
            .setBelongsToGlobalPopupStack(true)
            // .setCancelOnClickOutside(false) //for debug and snapshots
            .setCancelKeyEnabled(false)
            .setDimensionServiceKey(null, getDimensionServiceKey(), false)
            .setCancelCallback(
                new Computable<Boolean>() {
                  @Override
                  public Boolean compute() {
                    DimensionService.getInstance()
                        .setLocation(
                            getDimensionServiceKey(), myPopup.getLocationOnScreen(), myProject);
                    return true;
                  }
                })
            .createPopup();

    myTree.addTreeSelectionListener(
        new TreeSelectionListener() {
          @Override
          public void valueChanged(TreeSelectionEvent e) {
            if (myPopup.isVisible()) {
              final PopupUpdateProcessor updateProcessor =
                  myPopup.getUserData(PopupUpdateProcessor.class);
              if (updateProcessor != null) {
                final AbstractTreeNode node = getSelectedNode();
                updateProcessor.updatePopup(node);
              }
            }
          }
        });
    Disposer.register(myPopup, this);
    Disposer.register(
        myPopup,
        new Disposable() {
          @Override
          public void dispose() {
            if (!myTreeHasBuilt.isDone()) {
              myTreeHasBuilt.setRejected();
            }
          }
        });
    myTree.getEmptyText().setText("Loading...");
    final Point location =
        DimensionService.getInstance().getLocation(getDimensionServiceKey(), myProject);
    if (location != null) {
      myPopup.showInScreenCoordinates(myEditor.getContentComponent(), location);
    } else {
      myPopup.showCenteredInCurrentWindow(myProject);
    }

    ((AbstractPopup) myPopup).setShowHints(true);
    if (shouldSetWidth) {
      myPopup.setSize(new Dimension(myPreferredWidth + 10, myPopup.getSize().height));
    }

    IdeFocusManager.getInstance(myProject).requestFocus(myTree, true);
    ApplicationManager.getApplication()
        .executeOnPooledThread(
            new Runnable() {
              @Override
              public void run() {
                final AccessToken token =
                    ApplicationManager.getApplication().acquireReadActionLock();
                try {
                  myFilteringStructure.rebuild();
                } finally {
                  token.finish();
                }

                SwingUtilities.invokeLater(
                    new Runnable() {
                      @Override
                      public void run() {
                        myAbstractTreeBuilder
                            .queueUpdate()
                            .doWhenDone(
                                new Runnable() {
                                  @Override
                                  public void run() {
                                    myTreeHasBuilt.setDone();
                                    //noinspection SSBasedInspection
                                    SwingUtilities.invokeLater(
                                        new Runnable() {
                                          @Override
                                          public void run() {
                                            selectPsiElement(myInitialPsiElement);
                                          }
                                        });
                                  }
                                });
                      }
                    });
                installUpdater();
              }
            });
  }
  private void showCompletionPopup(
      final CompletionResult result, int position, boolean isExplicit) {
    if (myList == null) {
      myList = new JBList();
      myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

      myList.setCellRenderer(
          new GroupedItemsListRenderer(
              new ListItemDescriptor() {
                public String getTextFor(final Object value) {
                  final LookupFile file = (LookupFile) value;

                  if (file.getMacro() != null) {
                    return file.getMacro();
                  } else {
                    return (myCurrentCompletion != null
                                && myCurrentCompletion.myKidsAfterSeparator.contains(file)
                            ? myFinder.getSeparator()
                            : "")
                        + file.getName();
                  }
                }

                public String getTooltipFor(final Object value) {
                  return null;
                }

                public Icon getIconFor(final Object value) {
                  final LookupFile file = (LookupFile) value;
                  return file.getIcon();
                }

                @Nullable
                private Separator getSeparatorAboveOf(Object value) {
                  if (myCurrentCompletion == null) return null;
                  final LookupFile file = (LookupFile) value;

                  final int fileIndex = myCurrentCompletion.myToComplete.indexOf(file);
                  if (fileIndex > 0 && !myCurrentCompletion.myMacros.contains(file)) {
                    final LookupFile prev = myCurrentCompletion.myToComplete.get(fileIndex - 1);
                    if (myCurrentCompletion.myMacros.contains(prev)) {
                      return new Separator("");
                    }
                  }

                  if (myCurrentCompletion.myKidsAfterSeparator.indexOf(file) == 0
                      && myCurrentCompletion.mySiblings.size() > 0) {
                    final LookupFile parent = file.getParent();
                    return parent == null ? new Separator("") : new Separator(parent.getName());
                  }

                  if (myCurrentCompletion.myMacros.size() > 0 && fileIndex == 0) {
                    return new Separator(
                        IdeBundle.message("file.chooser.completion.path.variables.text"));
                  }

                  return null;
                }

                public boolean hasSeparatorAboveOf(final Object value) {
                  return getSeparatorAboveOf(value) != null;
                }

                public String getCaptionAboveOf(final Object value) {
                  final FileTextFieldImpl.Separator separator = getSeparatorAboveOf(value);
                  return separator != null ? separator.getText() : null;
                }
              }));
    }

    if (myCurrentPopup != null) {
      closePopup();
    }

    myCurrentCompletion = result;
    myCurrentCompletionsPos = position;

    if (myCurrentCompletion.myToComplete.size() == 0) {
      showNoSuggestions(isExplicit);
      return;
    }

    myList.setModel(
        new AbstractListModel() {
          public int getSize() {
            return myCurrentCompletion.myToComplete.size();
          }

          public Object getElementAt(final int index) {
            return myCurrentCompletion.myToComplete.get(index);
          }
        });
    myList.getSelectionModel().clearSelection();
    final PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(myList);
    builder.addListener(
        new JBPopupListener() {
          public void beforeShown(LightweightWindowEvent event) {
            myPathTextField.registerKeyboardAction(
                myCancelAction,
                KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
                JComponent.WHEN_IN_FOCUSED_WINDOW);
            for (Action each : myDisabledTextActions) {
              each.setEnabled(false);
            }
          }

          public void onClosed(LightweightWindowEvent event) {
            myPathTextField.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0));
            for (Action each : myDisabledTextActions) {
              each.setEnabled(true);
            }
          }
        });

    myCurrentPopup =
        builder
            .setRequestFocus(false)
            .setAdText(getAdText(myCurrentCompletion))
            .setAutoSelectIfEmpty(false)
            .setResizable(false)
            .setCancelCallback(
                new Computable<Boolean>() {
                  public Boolean compute() {
                    final int caret = myPathTextField.getCaretPosition();
                    myPathTextField.setSelectionStart(caret);
                    myPathTextField.setSelectionEnd(caret);
                    myPathTextField.setFocusTraversalKeysEnabled(true);
                    SwingUtilities.invokeLater(
                        new Runnable() {
                          public void run() {
                            getField().requestFocus();
                          }
                        });
                    return Boolean.TRUE;
                  }
                })
            .setItemChoosenCallback(
                new Runnable() {
                  public void run() {
                    processChosenFromCompletion(false);
                  }
                })
            .setCancelKeyEnabled(false)
            .setAlpha(0.1f)
            .setFocusOwners(new Component[] {myPathTextField})
            .createPopup();

    if (result.myPreselected != null) {
      myList.setSelectedValue(result.myPreselected, false);
    }

    myPathTextField.setFocusTraversalKeysEnabled(false);

    myCurrentPopup.showInScreenCoordinates(getField(), getLocationForCaret(myPathTextField));
  }