String (@Nullable Object existing, @Nullable Object fresh) { if (existing == fresh) return null; String eqMsg = checkClassEquivalence(existing, fresh); if (eqMsg != null) return eqMsg; Object[] eArray = asArray(existing); if (eArray != null) { return checkArrayEquivalence(eArray, Objects.requireNonNull(asArray(fresh)), existing); } if (existing instanceof ResultWithLog) { return whichIsField("result", existing, fresh, checkValueEquivalence(((ResultWithLog<?>)existing).getResult(), ((ResultWithLog<?>)fresh).getResult())); } if (existing instanceof CachedValueBase.Data) { return checkCachedValueData((CachedValueBase.Data<?>)existing, (CachedValueBase.Data<?>)fresh); } if (existing instanceof List || isOrderedSet(existing)) { return checkCollectionElements((Collection<?>)existing, (Collection<?>)fresh); } if (isOrderedMap(existing)) { return checkCollectionElements(((Map<?,?>)existing).entrySet(), ((Map<?,?>)fresh).entrySet()); } if (existing instanceof Set) { return whichIsField("size", existing, fresh, checkCollectionSizes(((Set<?>)existing).size(), ((Set<?>)fresh).size())); } if (existing instanceof Map) { if (existing instanceof ConcurrentMap) { return null; // likely to be filled lazily } return whichIsField("size", existing, fresh, checkCollectionSizes(((Map<?,?>)existing).size(), ((Map<?,?>)fresh).size())); } if (isExpectedToHaveSaneEquals(existing) && !existing.equals(fresh)) { return reportProblem(existing, fresh); } if (existing instanceof PsiNamedElement) { return checkPsiEquivalence((PsiElement)existing, (PsiElement)fresh); } if (existing instanceof ResolveResult) { PsiElement existingPsi = ((ResolveResult)existing).getElement(); PsiElement freshPsi = ((ResolveResult)fresh).getElement(); if (existingPsi != freshPsi) { String s = checkClassEquivalence(existingPsi, freshPsi); if (s == null) s = checkPsiEquivalence(existingPsi, freshPsi); return whichIsField("element", existing, fresh, s); } return null; } return null; }