@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		OutlineItem other = (OutlineItem) obj;
		// we want items in the same position to be equal even if their ids are not equal, *except* in the case
		// where they're from different files.  By having position-based equality we can maintain state in the UI even
		// as the user types in the heading area.
		boolean isEqual = other.hashCode() == hashCode() && other.calculatePositionKey().equals(calculatePositionKey());
		if (isEqual) {
			// bug 272721 in some rare cases the content outline would not update properly due to false equality here
			OutlineItem thisRoot = computeRoot(this);
			OutlineItem otherRoot = computeRoot(other);
			if (thisRoot != otherRoot && thisRoot.getResourcePath() != otherRoot.getResourcePath()) {
				if (thisRoot.getResourcePath() == null
						|| !thisRoot.getResourcePath().equals(otherRoot.getResourcePath())) {
					isEqual = false;
				}
			}
		}
		return isEqual;
	}