Bug 520336 - F_CONTENT sometimes lost when merging deltas

Change-Id: I1a053232474571187f007e819b3d6189d0789c1f
Signed-off-by: Vladimir Piskarev <pisv@1c.ru>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
index c2b6ac0..f354985 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Vladimir Piskarev <pisv@1c.ru> - F_CONTENT sometimes lost when merging deltas - https://bugs.eclipse.org/520336
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.model;
 
@@ -903,7 +904,7 @@
 							+ "		p1[*]: {CHILDREN}\n"
 							+ "			X.java[-]: {MOVED_TO(Y.java [in p2 [in src [in P]]])}\n"
 							+ "		p2[*]: {CHILDREN}\n"
-							+ "			Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n"
+							+ "			Y.java[*]: {CHILDREN | CONTENT | FINE GRAINED | PRIMARY RESOURCE}\n"
 							+ "				Y[+]: {MOVED_FROM(X [in X.java [in p1 [in src [in P]]]])}", listener);
 	}
 	finally {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java
index 4602b46..c3d0528 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElementDeltaTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Vladimir Piskarev <pisv@1c.ru> - AIOOB in JavaElementDelta.addAffectedChild - https://bugs.eclipse.org/455882
+ *     Vladimir Piskarev <pisv@1c.ru> - F_CONTENT sometimes lost when merging deltas - https://bugs.eclipse.org/520336
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.model;
 
@@ -1724,7 +1725,7 @@
 		);
 		assertDeltas(
 			"Unexpected delta",
-			"P[*]: {CHILDREN}\n" +
+			"P[*]: {CHILDREN | CONTENT}\n" +
 			"	<project root>[*]: {CHILDREN}\n" +
 			"		<default>[*]: {CHILDREN}\n" +
 			"			X.java[+]: {}\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java
index a386f6f..0762818 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Vladimir Piskarev <pisv@1c.ru> - F_CONTENT sometimes lost when merging deltas - https://bugs.eclipse.org/520336
  *******************************************************************************/
 package org.eclipse.jdt.core.tests.model;
 
@@ -368,7 +369,7 @@
 				"	src[*]: {CHILDREN}\n" + 
 				"		<default>[*]: {CHILDREN}\n" + 
 				"			X.java[-]: {MOVED_TO(Y.java [in <default> [in src [in P]]])}\n" + 
-				"			Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" + 
+				"			Y.java[*]: {CHILDREN | CONTENT | FINE GRAINED | PRIMARY RESOURCE}\n" + 
 				"				Y[+]: {MOVED_FROM(X [in X.java [in <default> [in src [in P]]]])}"
 	);
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
index 133b9a8..14f28a1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Vladimir Piskarev <pisv@1c.ru> - Building large Java element deltas is really slow - https://bugs.eclipse.org/443928
+ *     Vladimir Piskarev <pisv@1c.ru> - F_CONTENT sometimes lost when merging deltas - https://bugs.eclipse.org/520336
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
@@ -183,16 +184,13 @@
 						}
 
 						// update flags
-						boolean childHadContentFlag = (child.changeFlags & F_CONTENT) != 0;
-						boolean existingChildHadChildrenFlag = (existingChild.changeFlags & F_CHILDREN) != 0;
-						existingChild.changeFlags |= child.changeFlags;
-
-						// remove F_CONTENT flag if existing child had F_CHILDREN flag set
-						// (case of fine grained delta (existing child) and delta coming from
-						// DeltaProcessor (child))
-						if (childHadContentFlag && existingChildHadChildrenFlag) {
-							existingChild.changeFlags &= ~F_CONTENT;
+						int flags = child.changeFlags;
+						// case of fine grained delta (existing child) and delta coming from
+						// DeltaProcessor (child): ensure F_CONTENT is not propagated from child
+						if ((existingChild.changeFlags & F_FINE_GRAINED) != 0 && (flags & F_FINE_GRAINED) == 0) {
+							flags &= ~F_CONTENT;
 						}
+						existingChild.changeFlags |= flags;
 
 						// add the non-java resource deltas if needed
 						// note that the child delta always takes precedence over this existing child delta