@Override
  public void visitNamedFunction(JetNamedFunction function) {
    FunctionDescriptor functionDescriptor =
        (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);
    // working around a problem with shallow analysis
    if (functionDescriptor == null) return;
    DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
    if (containingDeclaration instanceof ClassDescriptor) {
      nameStack.push(peekFromStack(nameStack) + '$' + function.getName());
      super.visitNamedFunction(function);
      nameStack.pop();
    } else if (containingDeclaration instanceof NamespaceDescriptor) {
      String peek = peekFromStack(nameStack);
      if (peek.isEmpty()) {
        peek = JvmAbi.PACKAGE_CLASS;
      } else {
        peek += "/" + JvmAbi.PACKAGE_CLASS;
      }
      nameStack.push(peek + '$' + function.getName());
      super.visitNamedFunction(function);
      nameStack.pop();
    } else {
      String name = inventAnonymousClassName(function);
      ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor);
      recordClosure(
          bindingTrace,
          function,
          classDescriptor,
          peekFromStack(classStack),
          JvmClassName.byInternalName(name),
          true);

      classStack.push(classDescriptor);
      nameStack.push(name);
      super.visitNamedFunction(function);
      nameStack.pop();
      classStack.pop();
    }
  }
  @Override
  public void processQuery(
      @NotNull ReferencesSearch.SearchParameters queryParameters,
      @NotNull Processor<PsiReference> consumer) {
    PsiElement element = queryParameters.getElementToSearch();
    if (element instanceof JetClass) {
      processJetClassOrObject((JetClass) element, queryParameters);
    } else if (element instanceof JetNamedFunction) {
      final JetNamedFunction function = (JetNamedFunction) element;
      String name = function.getName();
      if (name != null) {
        PsiMethod method =
            ApplicationManager.getApplication()
                .runReadAction(
                    new Computable<PsiMethod>() {
                      @Override
                      public PsiMethod compute() {
                        return LightClassUtil.getLightClassMethod(function);
                      }
                    });
        searchMethod(queryParameters, method);
      }
    } else if (element instanceof JetProperty) {
      final JetProperty property = (JetProperty) element;
      LightClassUtil.PropertyAccessorsPsiMethods propertyMethods =
          ApplicationManager.getApplication()
              .runReadAction(
                  new Computable<LightClassUtil.PropertyAccessorsPsiMethods>() {
                    @Override
                    public LightClassUtil.PropertyAccessorsPsiMethods compute() {
                      return LightClassUtil.getLightClassPropertyMethods(property);
                    }
                  });

      searchMethod(queryParameters, propertyMethods.getGetter());
      searchMethod(queryParameters, propertyMethods.getSetter());
    } else if (element instanceof JetObjectDeclarationName) {
      PsiElement parent = element.getParent();
      if (parent instanceof JetObjectDeclaration) {
        processJetClassOrObject((JetObjectDeclaration) parent, queryParameters);
      }
    }
  }