https://bugs.eclipse.org/bugs/show_bug.cgi?id=170060
diff --git a/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java b/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java
index 958116f..1e97262 100755
--- a/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java
+++ b/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/dialogs/MoveDialog.java
@@ -25,6 +25,7 @@
 import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
 import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
 import org.eclipse.epf.authoring.ui.AuthoringUIResources;
+import org.eclipse.epf.authoring.ui.util.UIHelper;
 import org.eclipse.epf.authoring.ui.views.ViewHelper;
 import org.eclipse.epf.common.serviceability.MsgDialog;
 import org.eclipse.epf.library.LibraryService;
@@ -34,6 +35,7 @@
 import org.eclipse.epf.library.edit.command.MethodElementAddCommand.MoveOperation;
 import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
 import org.eclipse.epf.library.edit.util.TngUtil;
+import org.eclipse.epf.uma.Artifact;
 import org.eclipse.epf.uma.ContentCategory;
 import org.eclipse.epf.uma.MethodElement;
 import org.eclipse.jface.dialogs.Dialog;
@@ -284,6 +286,13 @@
 //			AuthoringUIPlugin.getDefault().getLogger().logError(ex);
 //			return false;
 //		}
+		
+		// Sub Artifact circular check code
+		if(destination instanceof Artifact){
+			return UIHelper.checkCircularForArtifacts((Artifact)destination, 
+					elements);
+		}
+		
 
 		Command addCommand = AddCommand.create(editingDomain, destination,
 				null, elements);
diff --git a/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java b/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java
index a6a2c23..952b0f9 100755
--- a/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java
+++ b/plugins/org.eclipse.epf.authoring.ui/src/org/eclipse/epf/authoring/ui/util/UIHelper.java
@@ -12,6 +12,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 
 import org.eclipse.core.runtime.OperationCanceledException;
@@ -32,6 +33,7 @@
 import org.eclipse.epf.library.edit.validation.internal.ValidatorFactory;
 import org.eclipse.epf.library.ui.LibraryUIText;
 import org.eclipse.epf.uma.Activity;
+import org.eclipse.epf.uma.Artifact;
 import org.eclipse.epf.uma.ContentElement;
 import org.eclipse.epf.uma.Deliverable;
 import org.eclipse.epf.uma.Guidance;
@@ -167,6 +169,73 @@
 		}
 	}
 	
+	public static boolean checkCircularForArtifacts(Artifact destination,
+			Collection sourceElements) {
+		HashSet variantSet = new HashSet();
+		collectVariantSet(destination, variantSet, VariabilityType.REPLACES_LITERAL);
+		collectVariantSet(destination, variantSet, VariabilityType.EXTENDS_LITERAL);
+		if (! checkCircularForArtifacts1(destination, sourceElements, variantSet)) {
+			return false;
+		}
+		return checkCircularForArtifacts2(destination, sourceElements);
+	}
+	
+	private static boolean checkCircularForArtifacts1(Artifact destination,
+			Collection sourceElements, HashSet variantSet) {
+		if (sourceElements == null) {
+			return true;
+		}
+		for (Iterator iter = sourceElements.iterator(); iter.hasNext();) {
+			Object obj = iter.next();
+			if(obj instanceof Artifact){
+				Artifact artifact = (Artifact) obj;
+				if (variantSet.contains(artifact)) {
+					return false;
+				}
+				if (! checkCircularForArtifacts1(destination, artifact.getContainedArtifacts(), variantSet)) {
+					return false;
+				}
+			}			
+		}
+		return true;
+	}
+	
+	private static boolean checkCircularForArtifacts2(Artifact destination,
+			Collection sourceElements) {
+		for (Iterator iter = sourceElements.iterator(); iter.hasNext();) {
+			Object obj = iter.next();
+			if (obj instanceof Artifact && sourceIsOrAboveMe((Artifact) obj, destination)) {
+				return false;
+			}			
+		}
+		return true;
+	}
+	
+	private static boolean sourceIsOrAboveMe(Artifact source, Artifact me) {
+		if (source == me) {
+			return true;
+		}
+		Object obj = me.getContainerArtifact();
+		if (obj instanceof Artifact && sourceIsOrAboveMe(source, (Artifact) obj)) {
+			return true;
+		}
+		obj = me.getVariabilityBasedOnElement();
+		if (obj instanceof Artifact && sourceIsOrAboveMe(source, (Artifact) obj)) {
+			return true;
+		}	
+		return false;
+	}
+	
+	//Collect all variants of "a" and "a"s ancestror Artifact objects
+	private static void collectVariantSet(Artifact a, HashSet variantSet, VariabilityType type) {
+		while (a != null) {
+			for (Iterator iter = TngUtil.getGeneralizers(a, type); iter.hasNext();) {
+				variantSet.add(iter.next());
+			}
+			a = a.getContainerArtifact();
+		}
+	}		
+	
 	/**
 	 * @param oldGuidance
 	 * @param newGuidance