@Override
  public void associate(String classFileName, Collection<String> sources, ClassReader cr, boolean isGenerated) {
    JvmClassNodeBuilder builder = JvmClassNodeBuilder.create(classFileName, cr, isGenerated);

    JvmNodeReferenceID nodeID = builder.getReferenceID();
    String nodeName = nodeID.getNodeName();
    addConstantUsages(builder, nodeName, myConstantRefs.remove(nodeName));
    Pair<Collection<String>, Collection<String>> imports = myImportRefs.remove(nodeName);
    if (imports != null) {
      addImportUsages(builder, imports.getFirst(), imports.getSecond());
    }
    Set<Usage> additionalUsages = myAdditionalUsages.remove(nodeName);
    if (additionalUsages != null) {
      for (Usage usage : additionalUsages) {
        builder.addUsage(usage);
      }
    }

    var node = builder.getResult();
    List<NodeSource> nodeSources = Iterators.collect(Iterators.map(sources, myGraphConfig.getPathMapper()::toNodeSource), new SmartList<>());

    Iterable<LookupNameUsage> lookups = Iterators.flat(Iterators.map(node.getMetadata(KotlinMeta.class), meta -> {
      KmDeclarationContainer container = meta.getDeclarationContainer();
      final JvmNodeReferenceID owner;
      LookupNameUsage clsUsage = null;
      if (container instanceof KmPackage) {
        owner = new JvmNodeReferenceID(JvmClass.getPackageName(node.getName()));
      }
      else if (container instanceof KmClass) {
        owner = new JvmNodeReferenceID(((KmClass)container).getName());
        String ownerName = owner.getNodeName();
        String scopeName = JvmClass.getPackageName(ownerName);
        String symbolName = scopeName.isEmpty()? ownerName : ownerName.substring(scopeName.length() + 1);
        clsUsage = new LookupNameUsage(scopeName, symbolName);
      }
      else {
        owner = null;
      }
      if (owner == null) {
        return Collections.emptyList();
      }
      Iterable<LookupNameUsage> memberLookups =
        Iterators.map(Iterators.unique(Iterators.flat(Iterators.map(container.getFunctions(), KmFunction::getName), Iterators.map(container.getProperties(), KmProperty::getName))), name -> new LookupNameUsage(owner, name));
      return clsUsage == null? memberLookups : Iterators.flat(Iterators.asIterable(clsUsage), memberLookups);
    }));

    for (LookupNameUsage lookup : lookups) {
      for (NodeSource src : nodeSources) {
        mySelfUsages.computeIfAbsent(src, s -> new HashSet<>()).add(lookup);
      }
    }

    myNodes.add(new Pair<>(node, nodeSources));
  }
@Override
  public void associate(String classFileName, Collection<String> sources, ClassReader cr, boolean isGenerated)