Bug 577782: [Preferences] Add PreferenceUtils.mergeNode

Change-Id: Icf47b05e69031e401b5ba2673c6523ef25672b38
diff --git a/ecommons/org.eclipse.statet.ecommons.preferences.core/src/org/eclipse/statet/ecommons/preferences/core/PreferenceUtils.java b/ecommons/org.eclipse.statet.ecommons.preferences.core/src/org/eclipse/statet/ecommons/preferences/core/PreferenceUtils.java
index 12c0a3c..a3ac241 100644
--- a/ecommons/org.eclipse.statet.ecommons.preferences.core/src/org/eclipse/statet/ecommons/preferences/core/PreferenceUtils.java
+++ b/ecommons/org.eclipse.statet.ecommons.preferences.core/src/org/eclipse/statet/ecommons/preferences/core/PreferenceUtils.java
@@ -14,6 +14,8 @@
 
 package org.eclipse.statet.ecommons.preferences.core;
 
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+
 import java.util.List;
 import java.util.Map;
 
@@ -26,6 +28,7 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
 
 import org.eclipse.statet.jcommons.lang.NonNullByDefault;
 
@@ -132,6 +135,29 @@
 	}
 	
 	
+	public static boolean mergeNode(final String fromQualifier, final String toQualifier)
+			throws BackingStoreException {
+		final IScopeContext scope= InstanceScope.INSTANCE;
+		if (scope.getNode("").nodeExists(fromQualifier)) { //$NON-NLS-1$
+			final var fromNode= scope.getNode(fromQualifier);
+			final var fromParent= nonNullAssert(fromNode.parent());
+			final var toNode= scope.getNode(toQualifier);
+			for (final String key : fromNode.keys()) {
+				final String value= fromNode.get(key, null);
+				if (value != null && toNode.get(key, null) == null) {
+					toNode.put(key, value);
+				}
+			}
+			
+			toNode.flush();
+			fromNode.removeNode();
+			fromParent.flush();
+			return true;
+		}
+		return false;
+	}
+	
+	
 	private PreferenceUtils() {
 	}