public static List<TransformAction> checkAndGenerateActions(
			DTD originalDTD, Map<FDPath, FDPath> xfds) {
		List<TransformAction> actions = new ArrayList<TransformAction>();
		boolean invalid = true;
		int newETCount = 0;
		while (invalid) {
			invalid = false;
			for (Entry<FDPath, FDPath> xfd : xfds.entrySet()) {
				for (String rhs : xfd.getValue()) {
					if (!XNFValidator.isTrivial(xfd.getKey(), rhs)) {
						LOGGER.info("Non-trivial XFD found: " + xfd.getKey()
								+ " -> " + rhs);
						if (!XNFValidator.isXNF(xfd.getKey(), rhs, xfds,
								originalDTD)) {
							LOGGER.info("XFD does not satisfy XNF: "
									+ xfd.getKey() + " -> " + rhs);
							invalid = true;
							boolean moveAttribute = true;
							for (String lhs : xfd.getKey()) {
								moveAttribute = moveAttribute
										&& (lhs.indexOf('@') == -1);
							}
							if (moveAttribute) {
								LOGGER.info("Moving attributes...");
								actions.add(XNFTransformation.moveAttribute(
										xfd.getKey(), rhs, xfds, originalDTD));
							} else {
								LOGGER.info("Creating new element types...");
								actions.add(XNFTransformation.createNewET(
										newETCount, "newET", xfd.getKey(), rhs,
										xfds, originalDTD));
								newETCount++;
							}
							break;
						} else {
							LOGGER.info("XFD satisfies XNF: " + xfd.getKey()
									+ " -> " + rhs);
						}
					} else {
						LOGGER.info("Trivial XFD: " + xfd.getKey() + " -> "
								+ rhs);
					}
				}

			}
		}
		return actions;
	}