boolean isDropSiteOk(ProgramNode destNode, ProgramNode dropNode, int dropAction,
			int relativeMousePos) {

		ProgramModule mParent = destNode.getParentModule();
		Group dragGroup = dropNode.getGroup();

		if (dragGroup.equals(destNode.getGroup())) {
			return false; // can't drop a group onto itself
		}
		if (mParent == null && relativeMousePos != 0) {
			return false;// can't reorder above or below root
		}
		// if the target node is the same as the parent of the
		// fromObject (node to be dropped), then the action
		// must be a move, because this is just a reorder of the
		// children.
		if (destNode.equals(dropNode.getParent())) {
			if (dropAction != DnDConstants.ACTION_MOVE) {
				return false;
			}
			return true;
		}
		if (dropNode.getParent().equals(destNode.getParent()) &&
			dropAction != DnDConstants.ACTION_MOVE) {
			return false;
		}
		if (!dropNode.getParent().equals(destNode.getParent())) {
			// if parent nodes are different, check to make sure this
			// fragment does not already exist as a child of the
			// parent of the fromObject
			if (dropNode.isFragment()) {

				ProgramFragment frag = dropNode.getFragment();

				if (mParent != null && mParent.contains(frag)) {
					return false;
				}
				// this is the root; make sure fragment does not
				// already exist as a child of root...
				if (mParent == null && destNode.getModule().contains(frag)) {
					return false;
				}

				if (destNode.isModule()) {
					ProgramModule dm = destNode.getModule();
					if (dm.contains(frag)) {
						return false;
					}
				}
				return true;
			}

			// fromObject must be a module...
			ProgramModule m = dropNode.getModule();

			if (mParent != null && (!m.equals(mParent) && mParent.contains(m)) ||
				m.equals(mParent)) {
				return false;
			}
			// this is the root; make sure module does not
			// already exist as a child of root...
			if (mParent == null && destNode.getModule().contains(m)) {
				return false;
			}
		}
		//else parent nodes are the same, so this a reorder

		if (destNode.isModule() && dropAction == DnDConstants.ACTION_COPY) {
			ProgramModule dm = destNode.getModule();
			if (dropNode.isModule()) {
				if (dm.contains(dropNode.getModule())) {
					return false;
				}
			}
			else {
				if (dm.contains(dropNode.getFragment())) {
					return false;
				}
			}
		}
		return true;
	}
Return true if the destNode can accept the dropNode.
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ReorderManager.java