@Override
  public void visitObjectDeclaration(JetObjectDeclaration declaration) {
    if (declaration.getParent() instanceof JetObjectLiteralExpression
        || declaration.getParent() instanceof JetClassObject) {
      super.visitObjectDeclaration(declaration);
    } else {
      ClassDescriptor classDescriptor = bindingContext.get(CLASS, declaration);
      // working around a problem with shallow analysis
      if (classDescriptor == null) return;

      String name = getName(classDescriptor);
      recordClosure(
          bindingTrace,
          declaration,
          classDescriptor,
          peekFromStack(classStack),
          JvmClassName.byInternalName(name),
          false);

      classStack.push(classDescriptor);
      nameStack.push(name);
      super.visitObjectDeclaration(declaration);
      nameStack.pop();
      classStack.pop();
    }
  }
    @Override
    public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
      if (declaration.isObjectLiteral()) {
        createClassDescriptorForSingleton(
            declaration, SpecialNames.NO_NAME_PROVIDED, ClassKind.CLASS);
        return;
      }

      MutableClassDescriptor descriptor =
          createClassDescriptorForSingleton(
              declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT);

      owner.addClassifierDescriptor(descriptor);
      trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getUnsafeFQName(declaration), descriptor);

      descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
    }
  private void resolveFunctionAndPropertyHeaders() {
    for (Map.Entry<JetFile, WritableScope> entry : context.getNamespaceScopes().entrySet()) {
      JetFile namespace = entry.getKey();
      WritableScope namespaceScope = entry.getValue();
      NamespaceLike namespaceDescriptor = context.getNamespaceDescriptors().get(namespace);

      resolveFunctionAndPropertyHeaders(
          namespace.getDeclarations(),
          namespaceScope,
          namespaceScope,
          namespaceScope,
          namespaceDescriptor);
    }
    for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
      JetClass jetClass = entry.getKey();
      MutableClassDescriptor classDescriptor = entry.getValue();

      resolveFunctionAndPropertyHeaders(
          jetClass.getDeclarations(),
          classDescriptor.getScopeForMemberResolution(),
          classDescriptor.getScopeForInitializers(),
          classDescriptor.getScopeForMemberResolution(),
          classDescriptor);
      //            processPrimaryConstructor(classDescriptor, jetClass);
      //            for (JetSecondaryConstructor jetConstructor :
      // jetClass.getSecondaryConstructors()) {
      //                processSecondaryConstructor(classDescriptor, jetConstructor);
      //            }
    }
    for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry :
        context.getObjects().entrySet()) {
      JetObjectDeclaration object = entry.getKey();
      MutableClassDescriptor classDescriptor = entry.getValue();

      resolveFunctionAndPropertyHeaders(
          object.getDeclarations(),
          classDescriptor.getScopeForMemberResolution(),
          classDescriptor.getScopeForInitializers(),
          classDescriptor.getScopeForMemberResolution(),
          classDescriptor);
    }

    // TODO : Extensions
  }
  @NotNull
  public Collection<ClassDescriptor> getTopLevelObjectsByName(
      @NotNull String name,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope scope) {
    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);

    if (jetScope == null) {
      return Collections.emptyList();
    }

    Set<ClassDescriptor> result = Sets.newHashSet();

    Collection<JetObjectDeclaration> topObjects =
        JetTopLevelShortObjectNameIndex.getInstance().get(name, project, scope);
    for (JetObjectDeclaration objectDeclaration : topObjects) {
      FqName fqName = JetPsiUtil.getFQName(objectDeclaration);
      assert fqName != null
          : "Local object declaration in JetTopLevelShortObjectNameIndex:"
              + objectDeclaration.getText();
      result.addAll(
          ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(resolveSession, fqName, true));
    }

    for (PsiClass psiClass :
        JetFromJavaDescriptorHelper.getCompiledClassesForTopLevelObjects(
            project, GlobalSearchScope.allScope(project))) {
      String qualifiedName = psiClass.getQualifiedName();
      if (qualifiedName != null) {
        FqName fqName = new FqName(qualifiedName);
        result.addAll(
            ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(resolveSession, fqName, true));
      }
    }

    return result;
  }