@Override
    public void visitJetFile(@NotNull JetFile file) {
      MutablePackageFragmentDescriptor packageFragment = getOrCreatePackageFragmentForFile(file);
      c.getPackageFragments().put(file, packageFragment);
      c.addFile(file);

      PackageViewDescriptor packageView =
          packageFragment.getContainingDeclaration().getPackage(packageFragment.getFqName());
      ChainedScope rootPlusPackageScope =
          new ChainedScope(
              packageView, "Root scope for " + file, packageView.getMemberScope(), outerScope);
      WriteThroughScope packageScope =
          new WriteThroughScope(
              rootPlusPackageScope,
              packageFragment.getMemberScope(),
              new TraceBasedRedeclarationHandler(trace),
              "package in file " + file.getName());
      packageScope.changeLockLevel(WritableScope.LockLevel.BOTH);
      c.getFileScopes().put(file, packageScope);

      if (file.isScript()) {
        scriptHeaderResolver.processScriptHierarchy(c, file.getScript(), packageScope);
      }

      prepareForDeferredCall(packageScope, packageFragment, file);
    }
  private void resolveFunctionAndPropertyHeaders(@NotNull TopDownAnalysisContext c) {
    for (Map.Entry<JetFile, WritableScope> entry : c.getFileScopes().entrySet()) {
      JetFile file = entry.getKey();
      WritableScope fileScope = entry.getValue();
      PackageLikeBuilder packageBuilder = c.getPackageFragments().get(file).getBuilder();

      resolveFunctionAndPropertyHeaders(
          c, file.getDeclarations(), fileScope, fileScope, fileScope, packageBuilder);
    }
    for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry :
        c.getDeclaredClasses().entrySet()) {
      JetClassOrObject classOrObject = entry.getKey();
      MutableClassDescriptor classDescriptor = (MutableClassDescriptor) entry.getValue();

      resolveFunctionAndPropertyHeaders(
          c,
          classOrObject.getDeclarations(),
          classDescriptor.getScopeForMemberDeclarationResolution(),
          classDescriptor.getScopeForInitializerResolution(),
          classDescriptor.getScopeForMemberDeclarationResolution(),
          classDescriptor.getBuilder());
    }

    // TODO : Extensions
  }
  private void checkRedeclarationsInPackages(@NotNull TopDownAnalysisContext c) {
    for (MutablePackageFragmentDescriptor packageFragment :
        Sets.newHashSet(c.getPackageFragments().values())) {
      PackageViewDescriptor packageView =
          packageFragment.getContainingDeclaration().getPackage(packageFragment.getFqName());
      JetScope packageViewScope = packageView.getMemberScope();
      Multimap<Name, DeclarationDescriptor> simpleNameDescriptors =
          packageFragment.getMemberScope().getDeclaredDescriptorsAccessibleBySimpleName();
      for (Name name : simpleNameDescriptors.keySet()) {
        // Keep only properties with no receiver
        Collection<DeclarationDescriptor> descriptors =
            Collections2.filter(
                simpleNameDescriptors.get(name),
                new Predicate<DeclarationDescriptor>() {
                  @Override
                  public boolean apply(@Nullable DeclarationDescriptor descriptor) {
                    if (descriptor instanceof PropertyDescriptor) {
                      PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
                      return propertyDescriptor.getReceiverParameter() == null;
                    }
                    return true;
                  }
                });
        ContainerUtil.addIfNotNull(descriptors, packageViewScope.getPackage(name));

        if (descriptors.size() > 1) {
          for (DeclarationDescriptor declarationDescriptor : descriptors) {
            for (PsiElement declaration : getDeclarationsByDescriptor(declarationDescriptor)) {
              assert declaration != null
                  : "Null declaration for descriptor: "
                      + declarationDescriptor
                      + " "
                      + (declarationDescriptor != null
                          ? DescriptorRenderer.FQ_NAMES_IN_TYPES.render(declarationDescriptor)
                          : "");
              trace.report(
                  REDECLARATION.on(declaration, declarationDescriptor.getName().asString()));
            }
          }
        }
      }
    }
  }