MergeConflictType (@NotNull Predicate<? super ThreeSide> emptiness, @NotNull BiPredicate<? super ThreeSide, ? super ThreeSide> equality) { boolean isLeftEmpty = emptiness.test(ThreeSide.LEFT); boolean isBaseEmpty = emptiness.test(ThreeSide.BASE); boolean isRightEmpty = emptiness.test(ThreeSide.RIGHT); assert !isLeftEmpty || !isBaseEmpty || !isRightEmpty; if (isBaseEmpty) { if (isLeftEmpty) { // --= return new MergeConflictType(MergeConflictType.Type.INSERTED, false, true); } else if (isRightEmpty) { // =-- return new MergeConflictType(MergeConflictType.Type.DELETED, true, false); } else { // =-= return new MergeConflictType(MergeConflictType.Type.MODIFIED, true, true); } } else { if (isLeftEmpty && isRightEmpty) { // -=- return new MergeConflictType(MergeConflictType.Type.MODIFIED, true, true); } else { // -==, ==-, === boolean unchangedLeft = equality.test(ThreeSide.BASE, ThreeSide.LEFT); boolean unchangedRight = equality.test(ThreeSide.BASE, ThreeSide.RIGHT); assert !unchangedLeft || !unchangedRight; if (unchangedLeft) { return new MergeConflictType(isRightEmpty ? MergeConflictType.Type.DELETED : MergeConflictType.Type.MODIFIED, false, true); } if (unchangedRight) { return new MergeConflictType(isLeftEmpty ? MergeConflictType.Type.INSERTED : MergeConflictType.Type.MODIFIED, true, false); } return new MergeConflictType(MergeConflictType.Type.MODIFIED, true, true); } } }