public static <T> T getOrCreateCache(
      Key<T> cacheKey, PsiElement element, CacheProvider<T> provider) {
    final PsiFile containingFile;
    if (element instanceof PsiFile) {
      containingFile = (PsiFile) element;
    } else {
      final PsiClass topLevelClass = PsiUtil.getTopLevelClass(element);

      if (topLevelClass == null) {
        return provider.provide();
      }
      containingFile = topLevelClass.getContainingFile();
    }

    if (containingFile == null) {
      return provider.provide();
    }

    final PsiFile originalFile = containingFile.getOriginalFile();
    T copyableUserData = originalFile.getCopyableUserData(cacheKey);

    if (copyableUserData != null) {
      if (!provider.isCacheValid(copyableUserData)) {
        copyableUserData = null;
      }
    }

    if (copyableUserData == null) {
      originalFile.putCopyableUserData(cacheKey, copyableUserData = provider.provide());
    }

    return copyableUserData;
  }
  @NotNull
  @Override
  public PsiPolyVariantReference getReference(PyResolveContext context) {
    final PsiFile file = getContainingFile();
    final PyExpression qualifier = getQualifier();

    // Handle import reference
    final PsiElement importParent =
        PsiTreeUtil.getParentOfType(this, PyImportElement.class, PyFromImportStatement.class);
    if (importParent != null) {
      return PyImportReference.forElement(this, importParent, context);
    }

    // Return special reference
    final ConsoleCommunication communication =
        file.getCopyableUserData(PydevConsoleRunner.CONSOLE_KEY);
    if (communication != null) {
      if (qualifier != null) {
        return new PydevConsoleReference(this, communication, qualifier.getText() + ".");
      }
      return new PydevConsoleReference(this, communication, "");
    }

    if (qualifier != null) {
      return new PyQualifiedReference(this, context);
    }

    return new PyReferenceImpl(this, context);
  }
  private void showEditorWarningMessage(final String message) {
    ApplicationManager.getApplication()
        .invokeLater(
            () -> {
              if (myEditor == null) return;
              final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
              final VirtualFile vFile = myFile.getVirtualFile();
              assert vFile != null;
              Map<FileEditor, EditorNotificationPanel> map =
                  myFile.getCopyableUserData(NOTIFICATION_PANELS);
              if (map == null) {
                map = new HashMap<FileEditor, EditorNotificationPanel>();
                myFile.putCopyableUserData(NOTIFICATION_PANELS, map);
              }

              final FileEditor[] editors = fileEditorManager.getAllEditors(vFile);
              for (final FileEditor editor : editors) {
                if (isCurrentEditor(editor)) {
                  final EditorNotificationPanel panel =
                      new EditorNotificationPanel() {
                        {
                          myLabel.setIcon(AllIcons.General.ExclMark);
                          myLabel.setText(message);
                        }
                      };
                  panel.createActionLabel(
                      "Close", () -> fileEditorManager.removeTopComponent(editor, panel));
                  map.put(editor, panel);
                  fileEditorManager.addTopComponent(editor, panel);
                  break;
                }
              }
            });
  }
  public void hideCoverageData() {
    if (myEditor == null) return;
    final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
    final List<RangeHighlighter> highlighters = myEditor.getUserData(COVERAGE_HIGHLIGHTERS);
    if (highlighters != null) {
      for (final RangeHighlighter highlighter : highlighters) {
        ApplicationManager.getApplication().invokeLater(() -> highlighter.dispose());
      }
      myEditor.putUserData(COVERAGE_HIGHLIGHTERS, null);
    }

    final Map<FileEditor, EditorNotificationPanel> map =
        myFile.getCopyableUserData(NOTIFICATION_PANELS);
    if (map != null) {
      final VirtualFile vFile = myFile.getVirtualFile();
      LOG.assertTrue(vFile != null);
      boolean freeAll = !fileEditorManager.isFileOpen(vFile);
      myFile.putCopyableUserData(NOTIFICATION_PANELS, null);
      for (FileEditor fileEditor : map.keySet()) {
        if (!freeAll && !isCurrentEditor(fileEditor)) {
          continue;
        }
        fileEditorManager.removeTopComponent(fileEditor, map.get(fileEditor));
      }
    }

    final DocumentListener documentListener = myEditor.getUserData(COVERAGE_DOCUMENT_LISTENER);
    if (documentListener != null) {
      myDocument.removeDocumentListener(documentListener);
      myEditor.putUserData(COVERAGE_DOCUMENT_LISTENER, null);
    }
  }
 @Nullable
 public static Sdk getConsoleSdk(final PsiElement element) {
   final PsiFile containingFile = element.getContainingFile();
   return containingFile != null ? containingFile.getCopyableUserData(CONSOLE_SDK) : null;
 }
 @Nullable
 public static ConsoleCommunication getConsoleCommunication(final PsiElement element) {
   final PsiFile containingFile = element.getContainingFile();
   return containingFile != null ? containingFile.getCopyableUserData(CONSOLE_KEY) : null;
 }