if (!safeEquals(a.getNodeValue(), b.getNodeValue())) return false;
if (b.getNodeType() == NodeImpl.REFERENCE_NODE) { if (!safeEquals(a.getNodeValue(), ((ReferenceNode)b).getReference().getNodeValue())) return false; } else if (!safeEquals(a.getNodeValue(), b.getNodeValue())) return false;
	private boolean compareContents(Node a, Node b) {		a = findNextTextOrElementNode(a.getFirstChild());		b = findNextTextOrElementNode(b.getFirstChild());		while (!(a == null || b == null)) {			int nodeTypeA = getEffectiveNodeType(a);			int nodeTypeB = getEffectiveNodeType(b);			if (nodeTypeA != nodeTypeB) return false;			switch (nodeTypeA) {				case Node.TEXT_NODE:					if (!safeEquals(a.getNodeValue(), b.getNodeValue())) return false;					break;				case Node.ELEMENT_NODE:					if (!compareElements(a, b)) return false;					break;				default:					throw new RuntimeException("unexpected node type " + nodeTypeA);			}			a = findNextTextOrElementNode(a.getNextSibling());			b = findNextTextOrElementNode(b.getNextSibling());		}		return a == b;		// both null	}