FileTrees switchToSpineRefs(@NotNull List<PsiElement> spine) {
    Reference<StubBasedPsiElementBase<?>>[] refToPsi = myRefToPsi;
    if (refToPsi == null) {
      //noinspection unchecked
      refToPsi = new Reference[spine.size()];
    }

    try {
      for (int i = firstNonFilePsiIndex; i < refToPsi.length; i++) {
        StubBasedPsiElementBase<?> psi = (StubBasedPsiElementBase<?>)Objects.requireNonNull(spine.get(i));
        psi.setSubstrateRef(new SpineRef(myFile, i));
        StubBasedPsiElementBase<?> existing = dereference(refToPsi[i]);
        if (existing != null) {
          assert existing == psi : "Duplicate PSI found";
        }
        else {
          refToPsi[i] = new WeakReference<>(psi);
        }
      }
      return new FileTrees(myFile, myStub, myTreeElementPointer, refToPsi);
    }
    catch (Throwable e) {
      throw new RuntimeException("Exceptions aren't allowed here", e);
      // otherwise, e.g. in case of PCE, we'd remain with PSI having SpineRef's but not registered in any "myRefToPsi"
      // and so that PSI wouldn't be updated on AST change
    }
  }
FileTrees switchToSpineRefs(@NotNull List<PsiElement> spine)