/*******************************************************************************
 * Copyright (c) 2001, 2005 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
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.wst.dtd.core.internal.emf.util;

import java.util.Enumeration;
import java.util.Iterator;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.dtd.core.internal.DTDCoreMessages;
import org.eclipse.wst.dtd.core.internal.emf.DTDAnyContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDAttribute;
import org.eclipse.wst.dtd.core.internal.emf.DTDBasicType;
import org.eclipse.wst.dtd.core.internal.emf.DTDBasicTypeKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDDefaultKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDElement;
import org.eclipse.wst.dtd.core.internal.emf.DTDElementReferenceContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDEmptyContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDEntity;
import org.eclipse.wst.dtd.core.internal.emf.DTDEntityReferenceContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDEnumGroupKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDEnumerationType;
import org.eclipse.wst.dtd.core.internal.emf.DTDExternalEntity;
import org.eclipse.wst.dtd.core.internal.emf.DTDFactory;
import org.eclipse.wst.dtd.core.internal.emf.DTDFile;
import org.eclipse.wst.dtd.core.internal.emf.DTDGroupContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDGroupKind;
import org.eclipse.wst.dtd.core.internal.emf.DTDInternalEntity;
import org.eclipse.wst.dtd.core.internal.emf.DTDNotation;
import org.eclipse.wst.dtd.core.internal.emf.DTDOccurrenceType;
import org.eclipse.wst.dtd.core.internal.emf.DTDPCDataContent;
import org.eclipse.wst.dtd.core.internal.emf.DTDParameterEntityReference;
import org.eclipse.wst.dtd.core.internal.emf.DTDType;
import org.eclipse.wst.dtd.core.internal.emf.impl.DTDFactoryImpl;
import org.eclipse.wst.dtd.core.internal.saxparser.AttNode;
import org.eclipse.wst.dtd.core.internal.saxparser.Attlist;
import org.eclipse.wst.dtd.core.internal.saxparser.CMBasicNode;
import org.eclipse.wst.dtd.core.internal.saxparser.CMGroupNode;
import org.eclipse.wst.dtd.core.internal.saxparser.CMNode;
import org.eclipse.wst.dtd.core.internal.saxparser.CMNodeType;
import org.eclipse.wst.dtd.core.internal.saxparser.CMReferenceNode;
import org.eclipse.wst.dtd.core.internal.saxparser.CMRepeatableNode;
import org.eclipse.wst.dtd.core.internal.saxparser.DTD;
import org.eclipse.wst.dtd.core.internal.saxparser.DTDSaxArtifactVisitor;
import org.eclipse.wst.dtd.core.internal.saxparser.ElementDecl;
import org.eclipse.wst.dtd.core.internal.saxparser.EntityDecl;
import org.eclipse.wst.dtd.core.internal.saxparser.ErrorMessage;
import org.eclipse.wst.dtd.core.internal.saxparser.NotationDecl;

public class DTDModelBuilder extends DTDSaxArtifactVisitor {
	DTD dtd;
	DTDUtil dtdUtil;
	DTDFile dtdFile;
	ResourceSet resources;

	public DTDModelBuilder(ResourceSet resources, DTDUtil dtdUtil, DTD dtd, DTDFile dtdFile) {
		this.resources = resources;
		this.dtdUtil = dtdUtil;
		this.dtd = dtd;
		this.dtdFile = dtdFile;
	}

	public DTDFactoryImpl getFactory() {
		return (DTDFactoryImpl) dtdUtil.getFactory();
	}

	public DTDFile getDTDFile() {
		return dtdFile;
	}

	public void visitDTD(DTD dtd) {
		super.visitDTD(dtd);

		// - 2nd pass -
		// do final processing for Attlists and adding contentModel
		addAttlistAndContentModel(dtd, dtdFile);
	}

	public void visitElementDecl(ElementDecl element) {
		// Element might have been added earlier because it is referenced
		String declName = element.getNodeName();
		// System.out.println("process ElementDecl:" + declName );
		DTDElement dtdelement = (DTDElement) dtdUtil.getElementPool().get(declName);
		if (dtdelement == null) {
			// System.out.println("process ElementDecl - not found - create"
			// );
			dtdelement = getFactory().createDTDElement();
			dtdelement.setName(declName);
			dtdFile.getDTDObject().add(dtdelement);
			dtdUtil.getElementPool().put(declName, dtdelement);
		}

		super.visitElementDecl(element);
	}

	public void visitNotationDecl(NotationDecl notation) {
		// Notation might have been added earlier because it is referenced
		// by an entity
		DTDNotation dtdnot = dtdFile.findNotation(notation.getNodeName());
		if (dtdnot == null) {
			dtdnot = getFactory().createDTDNotation();
			dtdFile.getDTDObject().add(dtdnot);
		}
		dtdnot.setName(notation.getNodeName());

		if (notation.getSystemId() != null)
			dtdnot.setSystemID(notation.getSystemId());
		if (notation.getPublicId() != null)
			dtdnot.setPublicID(notation.getPublicId());

		if (notation.getComment() != null)
			dtdnot.setComment(notation.getComment());
		if (notation.getErrorMessage() != null) {
			addErrorMessage(notation.getErrorMessage(), dtdnot);
		}

		super.visitNotationDecl(notation);
	}

	public void visitParameterEntityReferenceDecl(EntityDecl entity) {
		// This is a parameter entity reference.
		// Add the link to the real entity that it references
		DTDParameterEntityReference parmEntRef = getFactory().createDTDParameterEntityReference();
		dtdFile.getDTDObject().add(parmEntRef);

		String entityName = entity.getNodeName();

		// Add the reference to the DTDEntity
		DTDEntity dtdentity = getDTDFile().findEntity(entityName);
		if (dtdentity != null) {
			parmEntRef.setEntity(dtdentity);
		}
		if (entity.getErrorMessage() != null) {
			addErrorMessage(entity.getErrorMessage(), dtdentity);
		}
		// System.out.println("adding PE reference: " + declName);

		super.visitParameterEntityReferenceDecl(entity);
	}

	public void visitExternalEntityDecl(EntityDecl entity) {
		DTDEntity dtdEntity = createDTDEntity(entity);
		// System.out.println("adding entity: " + declName);
		DTDExternalEntity extEntity = getFactory().createDTDExternalEntity();
		dtdEntity.setContent(extEntity);

		finishExternalEntity(extEntity, entity);
		// System.out.println(" ext entity toMof: " );
		if (dtdEntity.isParameterEntity()) {

			dtdUtil.getPEPool().put("%" + entity.getNodeName() + ";", dtdEntity); //$NON-NLS-1$ //$NON-NLS-2$
		}

		super.visitExternalEntityDecl(entity);
	}

	public void visitInternalEntityDecl(EntityDecl entity) {
		DTDEntity dtdEntity = createDTDEntity(entity);

		DTDInternalEntity intEntity = getFactory().createDTDInternalEntity();
		dtdEntity.setContent(intEntity);
		intEntity.setValue(entity.getValue());
		// System.out.println(" int entity toMof: " );
		if (dtdEntity.isParameterEntity()) {
			dtdUtil.getPEPool().put("%" + entity.getNodeName() + ";", dtdEntity); //$NON-NLS-1$ //$NON-NLS-2$
		}

		super.visitInternalEntityDecl(entity);
	}

	private void addAttlistAndContentModel(DTD dtd, DTDFile dFile) {
		// System.out.println("addAttListAndCotentModel - dtd:" +
		// dtd.getName());
		Enumeration en = dtd.externalElements();
		while (en.hasMoreElements()) {
			Object e = en.nextElement();
			if (e instanceof ElementDecl) {
				DTDElement dtdelement = (DTDElement) dtdUtil.getElementPool().get(((ElementDecl) e).getNodeName());
				if (dtdelement == null) {
					dtdelement = getFactory().createDTDElement();
					dtdFile.getDTDObject().add(dtdelement);
				}
				finishElementDecl(dtdelement, (ElementDecl) e);
			}
			else if (e instanceof Attlist) {
				processAttList((Attlist) e);
			}
		}
	}


	private void processAttList(Attlist attList) {
		DTDElement e = (DTDElement) dtdUtil.getElementPool().get(attList.getNodeName());
		if (e != null) {
			// Element has been added. Add the attributes
			// System.out.println(" processAttlist - adding Attlist:" +
			// attList.getNodeName());
			createAttributes(e, attList);
		}
		else {
			// System.out.println("!!!!!!!!! element is null ");
		}
	}

	// /////////////////////////////////////////////////////////////
	//
	// Methods for finishing the import of a DTDExternalEntity
	//
	// /////////////////////////////////////////////////////////////
	void finishExternalEntity(DTDExternalEntity extEntity, EntityDecl entityDecl) {
		updateSystemID(extEntity, entityDecl);
		extEntity.setPublicID(entityDecl.getPublicId());

		String notationName = entityDecl.getNotationName();
		if (notationName != null) {
			DTDNotation dtdNotation = createOrFindNotation(extEntity, notationName, true);
			extEntity.setNotation(dtdNotation);
		}
	}

	public DTDNotation createOrFindNotation(DTDExternalEntity extEntity, String name, boolean create) {
		DTDNotation aNotation = extEntity.getDTDEntity().getDTDFile().findNotation(name);
		if (aNotation != null) {
			return aNotation;
		}

		//
		// Create a notation for the reference
		//
		if (create) {
			aNotation = getFactory().createDTDNotation();
			dtdFile.getDTDObject().add(aNotation);
			aNotation.setName(name);
		}
		return aNotation;
	}

	/**
	 * The SystemID attribute is set to whatever the user enters e.g.
	 * com/ibm/b2b/xmimodels/xxx.dtd.xmi
	 * 
	 * In the unparse() method, parse out the DTD file name from the classpath
	 * name. e.g. returns xxx.dtd
	 */
	private void updateSystemID(DTDExternalEntity extEntity, EntityDecl entityDecl) {
		String systemId = entityDecl.getSystemId();
		String publicId = entityDecl.getPublicId();
		if (systemId != null) {
			URIResolver idResolver = URIResolverPlugin.createResolver();
			String uri = idResolver.resolve(dtd.getName(), publicId, systemId);
			ExternalDTDModel ed = dtdUtil.getExternalDTDModel(resources, uri);
			if (ed != null) {
				DTDFile referenceDtdFile = ed.getExternalDTDFile();
				extEntity.setEntityReferencedFromAnotherFile(referenceDtdFile);
				extEntity.setSystemID(systemId);
			}
			else {
				if (entityDecl.getErrorMessage() == null) {
					ErrorMessage dtdError = new ErrorMessage();
					dtdError.setErrorMessage(DTDCoreMessages._ERROR_INCL_FILE_LOAD_FAILURE + " '" + systemId + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					addErrorMessage(dtdError, extEntity.getDTDEntity());
				}

				if (systemId != null) {
					extEntity.setSystemID(systemId);
				}
				else {
					extEntity.setSystemID(""); //$NON-NLS-1$
				}
			}
		} // end of if ()
		else {
			// set the system id to be ""
			extEntity.setSystemID(""); //$NON-NLS-1$
		}
	}

	public DTDEntity createDTDEntity(EntityDecl entity) {
		// create and do what we can to fill in some basic things
		DTDEntity dtdEntity = getFactory().createDTDEntity();
		dtdFile.getDTDObject().add(dtdEntity);

		dtdEntity.setName(entity.getNodeName());
		dtdEntity.setParameterEntity(entity.isParameter());
		if (entity.getComment() != null) {
			dtdEntity.setComment(entity.getComment());
		}
		if (entity.getErrorMessage() != null) {
			addErrorMessage(entity.getErrorMessage(), dtdEntity);
		}

		return dtdEntity;
	}


	// /////////////////////////////////////////////////////////////
	//
	// Methods for finishing the import of a DTDElement
	//
	// /////////////////////////////////////////////////////////////
	public void finishElementDecl(DTDElement dtdElement, ElementDecl ed) {
		dtdElement.setName(ed.getNodeName());

		CMNode cmNode = ed.getContentModelNode();

		if (ed.getComment() != null) {
			dtdElement.setComment(ed.getComment());
		}
		if (ed.getErrorMessage() != null) {
			addErrorMessage(ed.getErrorMessage(), dtdElement);
		}

		if (cmNode instanceof CMBasicNode) {
			CMBasicNode bn = (CMBasicNode) cmNode;
			switch (bn.getType()) {
				case CMNodeType.EMPTY :
					DTDEmptyContent emptyContent = getFactory().createDTDEmptyContent();
					dtdElement.setContent(emptyContent);
					break;

				case CMNodeType.ANY :
					DTDAnyContent anyContent = getFactory().createDTDAnyContent();
					dtdElement.setContent(anyContent);
					break;

				case CMNodeType.PCDATA :
					DTDPCDataContent pcData = getFactory().createDTDPCDataContent();
					dtdElement.setContent(pcData);
			}

		}
		else if (cmNode instanceof CMReferenceNode) {
			CMReferenceNode rn = (CMReferenceNode) cmNode;
			if (rn.getType() == CMNodeType.ENTITY_REFERENCE) {
				String entityName = rn.getName().trim();

				DTDEntity anEntity = (DTDEntity) dtdUtil.getPEPool().get(entityName);
				if (anEntity != null) {
					//
					// Create an DTDEntityReference and set its referenced
					// element
					//
					DTDEntityReferenceContent enRef = getFactory().createDTDEntityReferenceContent();
					enRef.setElementReferencedEntity(anEntity);

					DTDOccurrenceType occurrenceType = DTDOccurrenceType.get(computeMofOccurrence(rn));
					enRef.setOccurrence(occurrenceType);

					dtdElement.setContent(enRef);
				}
				else { // create default content
					DTDEmptyContent emptyContent = getFactory().createDTDEmptyContent();
					dtdElement.setContent(emptyContent);
				}
			}
			else {
				//
				// Find the real element for this element references
				// If the real element does not yet exist, create it
				//
				DTDElement anElement = createOrFindElement(rn.getName(), dtdElement);

				//
				// Create an DTDElementReference and set its referenced
				// element
				//
				DTDElementReferenceContent elemRef = getFactory().createDTDElementReferenceContent();
				elemRef.setReferencedElement(anElement);

				DTDOccurrenceType occurrenceType = DTDOccurrenceType.get(computeMofOccurrence(rn));
				elemRef.setOccurrence(occurrenceType);

				// setContent to DTDElementReference
				dtdElement.setContent(elemRef);

			}
		}
		else if (cmNode instanceof CMGroupNode) {
			CMGroupNode grpNode = (CMGroupNode) cmNode;
			DTDGroupContent groupContent = getFactory().createDTDGroupContent();
			DTDGroupKind groupKind = DTDGroupKind.get(computeMofGroupKind(grpNode.getGroupKind()));
			groupContent.setGroupKind(groupKind);
			DTDOccurrenceType occurrenceType = DTDOccurrenceType.get(computeMofOccurrence(grpNode));
			groupContent.setOccurrence(occurrenceType);

			// just use the locator for the element as the closest guess
			processGroupContent(groupContent, grpNode);
			dtdElement.setContent(groupContent);
		}
		else if (cmNode == null) {
			// bad thing happened here, just create a pcdata
			DTDEmptyContent emptyContent = getFactory().createDTDEmptyContent();
			dtdElement.setContent(emptyContent);
		}


	}


	/**
	 * Add a new group to the current group
	 * 
	 * @param parent -
	 *            the parent node for this group element
	 * @param op1Node -
	 *            the group e.g. (a,b)
	 * @param op2Node -
	 *            set only if called by processCM1op e.g. (a,b)+
	 */
	void processGroupContent(DTDGroupContent parent, CMGroupNode grpNode) {
		Enumeration children = grpNode.getChildren().elements();
		DTDFactory factory = getFactory();
		while (children.hasMoreElements()) {
			CMNode cnode = (CMNode) children.nextElement();

			if (cnode instanceof CMGroupNode) {
				CMGroupNode gNode = (CMGroupNode) cnode;
				DTDGroupContent groupContent = factory.createDTDGroupContent();
				DTDGroupKind groupKind = DTDGroupKind.get(computeMofGroupKind(gNode.getGroupKind()));
				groupContent.setGroupKind(groupKind);
				DTDOccurrenceType occurrenceType = DTDOccurrenceType.get(computeMofOccurrence(gNode));
				groupContent.setOccurrence(occurrenceType);

				parent.getContent().add(groupContent);
				processGroupContent(groupContent, gNode);
			}
			else if (cnode instanceof CMBasicNode) {
				CMBasicNode n = (CMBasicNode) cnode;
				if (n.getType() == CMNodeType.PCDATA) {
					// Create a DTDPCDataContent for a leaf PCData node
					//
					DTDPCDataContent pcData = factory.createDTDPCDataContent();
					// Add #PCDATA to the Group, i.e Mixed content model
					parent.getContent().add(pcData);
				}
			}
			else if (cnode instanceof CMReferenceNode) {
				CMReferenceNode rn = (CMReferenceNode) cnode;
				if (rn.getType() == CMNodeType.ELEMENT_REFERENCE) {
					// System.out.println("CM Element Ref name: " +
					// rn.getName());
					//
					// Create an DTDElementReference and set its referenced
					// element
					//
					DTDElementReferenceContent elemRef = factory.createDTDElementReferenceContent();

					//
					// Find the real element for this element references
					// If the real element does not yet exist, create it
					//
					DTDElement anElement = createOrFindElement(rn.getName(), elemRef);

					elemRef.setReferencedElement(anElement);

					DTDOccurrenceType occurrenceType = DTDOccurrenceType.get(computeMofOccurrence(rn));
					elemRef.setOccurrence(occurrenceType);

					// Add DTDElementReference to the Group
					parent.getContent().add(elemRef);
				}
				else // PE Reference
				{
					String entityName = rn.getName().trim();

					// System.out.println("CM PE Ref name: " + entityName);
					DTDEntity anEntity = (DTDEntity) dtdUtil.getPEPool().get(entityName);
					if (anEntity != null) {
						//
						// Create an DTDEntityReference and set its referenced
						// element
						//
						DTDEntityReferenceContent enRef = factory.createDTDEntityReferenceContent();
						enRef.setElementReferencedEntity(anEntity);

						DTDOccurrenceType occurrenceType = DTDOccurrenceType.get(computeMofOccurrence(rn));
						enRef.setOccurrence(occurrenceType);

						// Add DTDEntityReference to the Group
						parent.getContent().add(enRef);

					}
				}
			}
		}
	}

	/**
	 * Find the real element that is referenced by the current element
	 */
	private DTDElement createOrFindElement(String name, Object obj) {
		// DTDElement aElement = getDTDFile().findElement(name);

		DTDElement aElement = (DTDElement) dtdUtil.getElementPool().get(name);

		if (aElement != null) {
			return aElement;
		}

		String errorMsg = DTDCoreMessages._ERROR_UNDECLARED_ELEMENT_1; //$NON-NLS-1$
		errorMsg += "\"" + name + "\""; //$NON-NLS-1$ //$NON-NLS-2$
		errorMsg += DTDCoreMessages._UI_ERRORPART_UNDECLARED_ELEMENT_2; //$NON-NLS-1$

		ErrorMessage dtdError = new ErrorMessage();

		dtdError.setErrorMessage(errorMsg);
		addErrorMessage(dtdError, obj);
		// System.out.println(errorMsg);
		// setDTDErrorMessage(errorMsg);
		getDTDFile().setParseError(true);

		//
		// Create an empty element for the reference to make it valid
		//

		DTDFactory factory = getFactory();
		DTDElement dtdelement = factory.createDTDElement();
		dtdelement.setName(name);

		DTDEmptyContent emptyContent = factory.createDTDEmptyContent();
		dtdelement.setContent(emptyContent);

		getDTDFile().getDTDObject().add(dtdelement);
		dtdUtil.getElementPool().put(name, dtdelement);
		return dtdelement;
	}


	/**
	 * Compute the MOF occurrence from the xml4j occurrence
	 */
	private int computeMofOccurrence(CMRepeatableNode rnode) {
		int occurrence = rnode.getOccurrence();
		int mofoccur = DTDOccurrenceType.ONE;

		if (occurrence == CMNodeType.ZERO_OR_MORE) {
			mofoccur = DTDOccurrenceType.ZERO_OR_MORE;
		}
		else if (occurrence == CMNodeType.ONE_OR_MORE) {
			mofoccur = DTDOccurrenceType.ONE_OR_MORE;
		}
		else if (occurrence == CMNodeType.OPTIONAL) {
			mofoccur = DTDOccurrenceType.OPTIONAL;
		}
		return mofoccur;
	}

	/**
	 * Compute the MOF model group from the xml4j model group
	 */
	private int computeMofGroupKind(int type) {
		if (type == CMNodeType.GROUP_CHOICE) {
			return DTDGroupKind.CHOICE;
		}
		else {
			return DTDGroupKind.SEQUENCE;
		}
	}


	// /////////////////////////////////////////////////////////////
	//
	// Methods for creating the attributes of a DTDElement
	//
	// /////////////////////////////////////////////////////////////
	public void createAttributes(DTDElement element, Attlist attList) {
		if (attList.getErrorMessage() != null) {
			addErrorMessage(attList.getErrorMessage(), element);
		}

		for (int i = 0; i < attList.size(); i++) {
			AttNode ad = attList.elementAt(i);
			// DTDAttributeElement dtdAtt=
			// getDTDAttributeElement(a.getName());

			// only add the AttDef if it is not added yet
			// ignore the dup AttDef as documented in the XML 1.0 specs
			// if( dtdAtt==null)
			addAttribute(element, ad);
		}

	}

	/**
	 * Create a DTDAttribute from the xml4j attribute
	 */
	public void addAttribute(DTDElement dtdelement, AttNode ad) {
		DTDAttribute dtdattr = getFactory().createDTDAttribute();
		dtdelement.getDTDAttribute().add(dtdattr);
		finishAttribute(dtdattr, ad);
	}

	// Stuff for populating attribute
	public void finishAttribute(DTDAttribute dtdattr, AttNode attdef) {
		boolean parseError = false;

		if (attdef.name.startsWith("%")) { //$NON-NLS-1$
			String peName = attdef.name.trim();
			DTDEntity en = (DTDEntity) dtdUtil.getPEPool().get(peName);
			if (en != null) {
				dtdattr.setAttributeNameReferencedEntity(en);
			}
		}

		dtdattr.setName(attdef.name);

		int attrType = attdef.getDeclaredType();

		if (attrType == AttNode.PEREFERENCE && attdef.type != null) {
			String peName = attdef.type.trim();
			DTDEntity en = (DTDEntity) dtdUtil.getPEPool().get(peName);
			if (en != null) {
				dtdattr.setAttributeTypeReferencedEntity(en);
				setAttrDTDType(dtdattr, getFactory().getDTDBasicType_CDATA()); // hack,
																				// so
																				// we
																				// can
																				// get
																				// back
																				// the
																				// default
																				// value
			}
			else
				// set default type
				setAttrDTDType(dtdattr, getFactory().getDTDBasicType_CDATA());

		}
		else {
			switch (attrType) {
				case AttNode.CDATA :
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_CDATA());
					break;

				case AttNode.ENTITIES :
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_ENTITIES());
					break;

				case AttNode.ENTITY :
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_ENTITY());
					break;

				case AttNode.ID :
					// check for duplicate ID attribute
					if (hasIDAttribute(dtdattr)) {
						String errMsg = DTDCoreMessages._ERROR_DUP_ID_ATTRIBUTE_1; //$NON-NLS-1$
						errMsg += attdef.name + DTDCoreMessages._UI_ERRORPART_DUP_ID_ATTRIBUTE_2; //$NON-NLS-1$
						// dtdattr.getDTDElement().getIElement().setDTDErrorMessage(errMsg);
						// dtdattr.getDTDElement().getDTDFile().setParseError(true);
						parseError = true;
					}
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_ID());
					break;

				case AttNode.IDREF :
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_IDREF());
					break;

				case AttNode.IDREFS :
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_IDREFS());
					break;

				case AttNode.ENUMERATION :
					setAttrDTDType(dtdattr, createDTDEnumeration(dtdattr, attdef, DTDEnumGroupKind.NAME_TOKEN_GROUP));
					break;

				case AttNode.NOTATION :
					setAttrDTDType(dtdattr, createDTDEnumeration(dtdattr, attdef, DTDEnumGroupKind.NOTATION_GROUP));
					break;

				case AttNode.NMTOKEN :
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_NMTOKEN());
					break;

				case AttNode.NMTOKENS :
					setAttrDTDType(dtdattr, getFactory().getDTDBasicType_NMTOKENS());
					break;

				default :
			// System.out.println("DTDATTR '" +attdef.name + "'Unknown
			// type..." + attrType);
			}
		}

		int attrDefault = attdef.getDefaultType();
		int defaultKind = DTDDefaultKind.IMPLIED;
		switch (attrDefault) {
			case AttNode.FIXED :
				defaultKind = DTDDefaultKind.FIXED;
				break;

			case AttNode.IMPLIED :
				defaultKind = DTDDefaultKind.IMPLIED;
				break;

			case AttNode.REQUIRED :
				defaultKind = DTDDefaultKind.REQUIRED;
				break;

			case AttNode.NOFIXED :
				defaultKind = DTDDefaultKind.NOFIXED;
				break;

			default :
		// System.out.println("DTDATTR '" +attdef.name + "' Unknown default
		// type... " + attrDefault);
		}

		DTDDefaultKind defaultKindObj = DTDDefaultKind.get(defaultKind);
		dtdattr.setDefaultKind(defaultKindObj);

		if (parseError) {
			return;
		}

		String defaultValue = attdef.defaultValue;
		if (defaultValue != null) {
			if (attrType == AttNode.ENUMERATION || attrType == AttNode.NOTATION) {
				if (!isDefaultEnumValueValid(attdef, defaultValue)) {
					String typeString = (attrType == AttNode.ENUMERATION ? "enumeration" : "notation"); //$NON-NLS-1$ //$NON-NLS-2$
					String errMsg = DTDCoreMessages._ERROR_INVALID_DEFAULT_ATTR_VALUE_1; //$NON-NLS-1$
					errMsg += typeString + DTDCoreMessages._UI_ERRORPART_INVALID_DEFAULT_ATTR_VALUE_2; //$NON-NLS-1$
					errMsg += attdef.name + "'"; //$NON-NLS-1$

					// dtdattr.getDTDElement().getIElement().setDTDErrorMessage(errMsg);
					// dtdattr.getDTDElement().getDTDFile().setParseError(true);
					return;
				}
			}
			dtdattr.setDefaultValueString(defaultValue);
		}
		// System.out.println("DTDAttr - toMof getDefaultValueString " +
		// getDefaultValueString());
		// System.out.println("DTDAttr - toMof getDefaultValue: " +
		// getDefaultValue());
	}

	public boolean hasIDAttribute(DTDAttribute dtdattr) {
		boolean hasID = false;

		DTDElement element = dtdattr.getDTDElement();
		EList attrs = element.getDTDAttribute();

		Iterator i = attrs.iterator();
		while (i.hasNext()) {
			DTDAttribute attr = (DTDAttribute) i.next();
			DTDType dType = attr.getDTDType();
			if (dType instanceof DTDBasicType) {
				if (((DTDBasicType) dType).getKind().getValue() == DTDBasicTypeKind.ID) {
					hasID = true;
					break;
				}
			}
		}
		return hasID;
	}

	public DTDEnumerationType createDTDEnumeration(DTDAttribute dtdattr, String[] enumValues, int enumKind) {
		DTDEnumerationType enumeration = getFactory().createDTDEnumerationType();
		DTDEnumGroupKind groupKind = DTDEnumGroupKind.get(enumKind);
		enumeration.setKind(groupKind);
		// Enumeration values
		if (enumValues != null) {
			for (int i = 0; i < enumValues.length; i++) {
				EEnumLiteral enumLiteral = createEEnumLiteral();
				// enumVal.setXMIDocument(dtdattr.getXMIDocument());
				// MOF2EMF Port
				// enumLiteral.refSetLiteral(enumValues[i]);
				enumLiteral.setName(enumValues[i]);

				// enumLiteral.setNumber(i);
				enumeration.getEnumLiterals().add(enumLiteral);
			}
		}
		dtdattr.getDTDElement().getDTDFile().getDTDEnumerationType().add(enumeration);
		return enumeration;
	}

	private EEnumLiteral createEEnumLiteral() {
		EcorePackage ePackage = (EcorePackage) EPackage.Registry.INSTANCE.getEPackage(EcorePackage.eNS_URI);
		// MOF2EMF Port
		// return ((EcoreFactory)ePackage.getFactory()).createEEnumLiteral();
		return ePackage.getEcoreFactory().createEEnumLiteral();
	}

	private DTDEnumerationType createDTDEnumeration(DTDAttribute dtdattr, AttNode attdef, int enumKind) {
		DTDEnumerationType enumeration = getFactory().createDTDEnumerationType();
		DTDEnumGroupKind groupKind = DTDEnumGroupKind.get(enumKind);
		enumeration.setKind(groupKind);
		dtdattr.getDTDElement().getDTDFile().getDTDEnumerationType().add(enumeration);

		// Enumeration values
		Enumeration tokenIter = attdef.elements();
		if (tokenIter != null) {
			while (tokenIter.hasMoreElements()) {
				String val = (String) tokenIter.nextElement();
				EEnumLiteral enumLiteral = createEEnumLiteral();
				// enumLiteral.setXMIDocument(dtdattr.getXMIDocument());
				// MOF2EMF Port
				// enumLiteral.refSetLiteral(val);
				enumLiteral.setName(val);


				// enumLiteral.setNumber(i++);
				enumeration.getEnumLiterals().add(enumLiteral);
			}
		}

		return enumeration;
	}

	private boolean isDefaultEnumValueValid(AttNode attdef, String defaultValue) {
		boolean valid = false;
		boolean containsPercent = false;

		// Enumeration values
		Enumeration enumValues = attdef.elements();
		while (enumValues.hasMoreElements()) {
			String val = (String) enumValues.nextElement();
			if (val.equals(defaultValue)) {
				valid = true;
				break;
			}
			if (val.indexOf('%') >= 0) {
				containsPercent = true;
			}
		}
		return valid || containsPercent;
	}

	public void setAttrDTDType(DTDAttribute dtdattr, DTDType type) {
		dtdattr.setDTDType(type);
	}

	protected void addErrorMessage(ErrorMessage errMsg, Object obj) {
		errMsg.setObject(obj);
		dtdUtil.addErrorMessage(errMsg);
	}

	// /**
	// * @generated
	// */
	// protected DTDFactoryImpl getFactoryGen() {
	//
	// return (DTDFactoryImpl)dtdUtil.getFactory();
	// }
	// /**
	// * @generated
	// */
	// protected DTDFile getDTDFileGen() {
	//
	// return dtdFile;
	// }
	// /**
	// * @generated
	// */
	// protected void visitDTDGen(DTD dtd) {
	//
	// super.visitDTD(dtd);
	//
	//
	// // - 2nd pass -
	// // do final processing for Attlists and adding contentModel
	// addAttlistAndContentModel(dtd,dtdFile);
	// }
	// /**
	// * @generated
	// */
	// protected void visitElementDeclGen(ElementDecl element) {
	//
	// // Element might have been added earlier because it is referenced
	// String declName = element.getNodeName() ;
	// // System.out.println("process ElementDecl:" + declName );
	// DTDElement dtdelement = (DTDElement)
	// dtdUtil.getElementPool().get(declName);
	// if (dtdelement == null)
	// {
	// // System.out.println("process ElementDecl - not found - create" );
	// dtdelement = getFactory().createDTDElement();
	// dtdelement.setName(declName);
	// dtdFile.getDTDObject().add(dtdelement);
	// dtdUtil.getElementPool().put(declName,dtdelement);
	// }
	//
	//
	// super.visitElementDecl(element);
	// }
	// /**
	// * @generated
	// */
	// protected void visitNotationDeclGen(NotationDecl notation) {
	//
	// // Notation might have been added earlier because it is referenced
	// // by an entity
	// DTDNotation dtdnot = dtdFile.findNotation( notation.getNodeName() );
	// if (dtdnot == null)
	// {
	// dtdnot = getFactory().createDTDNotation();
	// dtdFile.getDTDObject().add(dtdnot);
	// }
	// dtdnot.setName(notation.getNodeName());
	//
	//
	// if (notation.getSystemId()!= null )
	// dtdnot.setSystemID(notation.getSystemId());
	// if (notation.getPublicId()!= null )
	// dtdnot.setPublicID(notation.getPublicId());
	//
	//
	// if (notation.getComment()!=null)
	// dtdnot.setComment(notation.getComment());
	// if (notation.getErrorMessage()!=null)
	// {
	// addErrorMessage(notation.getErrorMessage(), dtdnot);
	// }
	//
	//
	// super.visitNotationDecl(notation);
	// }
	// /**
	// * @generated
	// */
	// protected void visitParameterEntityReferenceDeclGen(EntityDecl entity)
	// {
	//
	// // This is a parameter entity reference.
	// // Add the link to the real entity that it references
	// DTDParameterEntityReference parmEntRef =
	// getFactory().createDTDParameterEntityReference();
	// dtdFile.getDTDObject().add(parmEntRef);
	//
	//
	// String entityName = entity.getNodeName();
	//
	//
	// // Add the reference to the DTDEntity
	// DTDEntity dtdentity = getDTDFile().findEntity(entityName);
	// if (dtdentity != null)
	// {
	// parmEntRef.setEntity(dtdentity);
	// }
	// if (entity.getErrorMessage()!=null)
	// {
	// addErrorMessage(entity.getErrorMessage(), dtdentity);
	// }
	// // System.out.println("adding PE reference: " + declName);
	//
	//
	// super.visitParameterEntityReferenceDecl(entity);
	// }
	// /**
	// * @generated
	// */
	// protected void visitExternalEntityDeclGen(EntityDecl entity) {
	//
	// DTDEntity dtdEntity = createDTDEntity(entity);
	// // System.out.println("adding entity: " + declName);
	// DTDExternalEntity extEntity = getFactory().createDTDExternalEntity();
	// dtdEntity.setContent(extEntity);
	//
	//
	// finishExternalEntity(extEntity, entity);
	// // System.out.println(" ext entity toMof: " );
	// if (dtdEntity.isParameterEntity())
	// {
	//
	//
	// dtdUtil.getPEPool().put("%"+entity.getNodeName()+";", dtdEntity);
	// }
	//
	//
	// super.visitExternalEntityDecl(entity);
	// }
	// /**
	// * @generated
	// */
	// protected void visitInternalEntityDeclGen(EntityDecl entity) {
	//
	// DTDEntity dtdEntity = createDTDEntity(entity);
	//
	//
	// DTDInternalEntity intEntity = getFactory().createDTDInternalEntity();
	// dtdEntity.setContent(intEntity);
	// intEntity.setValue(entity.getValue());
	// // System.out.println(" int entity toMof: " );
	// if (dtdEntity.isParameterEntity())
	// {
	// dtdUtil.getPEPool().put("%"+entity.getNodeName()+";", dtdEntity);
	// }
	//
	//
	// super.visitInternalEntityDecl(entity);
	// }
	// /**
	// * @generated
	// */
	// protected void addAttlistAndContentModelGen(DTD dtd, DTDFile dFile) {
	//
	// //System.out.println("addAttListAndCotentModel - dtd:" +
	// dtd.getName());
	// Enumeration en = dtd.externalElements();
	// while (en.hasMoreElements())
	// {
	// Object e = en.nextElement();
	// if ( e instanceof ElementDecl )
	// {
	// DTDElement dtdelement = (DTDElement) dtdUtil.getElementPool().get(
	// ((ElementDecl)e).getNodeName() );
	// if (dtdelement == null)
	// {
	// dtdelement = getFactory().createDTDElement();
	// dtdFile.getDTDObject().add(dtdelement);
	// }
	// finishElementDecl(dtdelement, (ElementDecl) e);
	// }
	// else if ( e instanceof Attlist )
	// {
	// processAttList((Attlist) e);
	// }
	// }
	// }
	// /**
	// * @generated
	// */
	// protected void processAttListGen(Attlist attList) {
	//
	// DTDElement e = (DTDElement)
	// dtdUtil.getElementPool().get(attList.getNodeName());
	// if ( e != null )
	// {
	// // Element has been added. Add the attributes
	// //System.out.println(" processAttlist - adding Attlist:" +
	// attList.getNodeName());
	// createAttributes(e, attList);
	// }
	// else
	// {
	// //System.out.println("!!!!!!!!! element is null ");
	// }
	// }
	// /**
	// * @generated
	// */
	// protected void finishExternalEntityGen(DTDExternalEntity extEntity,
	// EntityDecl entityDecl) {
	//
	// updateSystemID(extEntity, entityDecl);
	// extEntity.setPublicID(entityDecl.getPublicId());
	//
	//
	// String notationName = entityDecl.getNotationName();
	// if (notationName != null)
	// {
	// DTDNotation dtdNotation = createOrFindNotation(extEntity,
	// notationName,true);
	// extEntity.setNotation(dtdNotation);
	// }
	// }
	// /**
	// * @generated
	// */
	// protected DTDNotation createOrFindNotationGen(DTDExternalEntity
	// extEntity, String name, boolean create) {
	//
	// DTDNotation aNotation =
	// extEntity.getDTDEntity().getDTDFile().findNotation(name);
	// if (aNotation != null)
	// {
	// return aNotation;
	// }
	//
	//
	// //
	// // Create a notation for the reference
	// //
	// if (create)
	// {
	// aNotation = getFactory().createDTDNotation();
	// dtdFile.getDTDObject().add(aNotation);
	// aNotation.setName(name);
	// }
	// return aNotation;
	// }
	// /**
	// * The SystemID attribute is set to whatever the user enters
	// * e.g. com/ibm/b2b/xmimodels/xxx.dtd.xmi
	// *
	// * In the unparse() method, parse out the DTD file name from
	// * the classpath name.
	// * e.g. returns xxx.dtd
	// */
	// protected void updateSystemIDGen(DTDExternalEntity extEntity,
	// EntityDecl entityDecl) {
	//
	// String systemId = entityDecl.getSystemId();
	// String publicId = entityDecl.getPublicId();
	// if (systemId != null)
	// {
	// IdResolver idResolver = new IdResolverImpl(dtd.getName());
	// String uri = idResolver.resolveId(publicId, systemId);
	// ExternalDTDModel ed = dtdUtil.getExternalDTDModel(resources, uri);
	// if (ed != null)
	// {
	// DTDFile referenceDtdFile = ed.getExternalDTDFile();
	// extEntity.setEntityReferencedFromAnotherFile(referenceDtdFile);
	// extEntity.setSystemID(systemId);
	// }
	// else
	// {
	// if (entityDecl.getErrorMessage() == null)
	// {
	// ErrorMessage dtdError = new ErrorMessage();
	// dtdError.setErrorMessage(DTDCoreMessages.getString("_ERROR_INCL_FILE_LOAD_FAILURE")
	// + " '" + systemId + "'");
	// addErrorMessage(dtdError, extEntity.getDTDEntity());
	// }
	//        
	// if (systemId != null)
	// {
	// extEntity.setSystemID(systemId);
	// }
	// else
	// {
	// extEntity.setSystemID("");
	// }
	// }
	// } // end of if ()
	// else
	// {
	// // set the system id to be ""
	// extEntity.setSystemID("");
	// }
	// }
	// /**
	// * @generated
	// */
	// protected DTDEntity createDTDEntityGen(EntityDecl entity) {
	//
	// // create and do what we can to fill in some basic things
	// DTDEntity dtdEntity = getFactory().createDTDEntity();
	// dtdFile.getDTDObject().add(dtdEntity);
	//
	//
	// dtdEntity.setName(entity.getNodeName());
	// dtdEntity.setParameterEntity(entity.isParameter());
	// if (entity.getComment()!=null)
	// {
	// dtdEntity.setComment(entity.getComment());
	// }
	// if (entity.getErrorMessage()!=null)
	// {
	// addErrorMessage(entity.getErrorMessage(), dtdEntity);
	// }
	//
	//
	// return dtdEntity;
	// }
	// /**
	// * @generated
	// */
	// protected void finishElementDeclGen(DTDElement dtdElement, ElementDecl
	// ed) {
	//
	// dtdElement.setName(ed.getNodeName());
	//
	//
	// CMNode cmNode = ed.getContentModelNode();
	//
	//
	// if (ed.getComment()!=null)
	// {
	// dtdElement.setComment(ed.getComment());
	// }
	// if (ed.getErrorMessage()!=null)
	// {
	// addErrorMessage(ed.getErrorMessage(), dtdElement);
	// }
	//
	//
	// if (cmNode instanceof CMBasicNode)
	// {
	// CMBasicNode bn = (CMBasicNode)cmNode;
	// switch (bn.getType())
	// {
	// case CMNodeType.EMPTY :
	// DTDEmptyContent emptyContent = getFactory().createDTDEmptyContent();
	// dtdElement.setContent(emptyContent);
	// break;
	//
	//
	// case CMNodeType.ANY :
	// DTDAnyContent anyContent = getFactory().createDTDAnyContent();
	// dtdElement.setContent(anyContent);
	// break;
	//
	//
	// case CMNodeType.PCDATA:
	// DTDPCDataContent pcData = getFactory().createDTDPCDataContent();
	// dtdElement.setContent(pcData);
	// }
	//
	//
	// }
	// else if (cmNode instanceof CMReferenceNode)
	// {
	// CMReferenceNode rn = (CMReferenceNode) cmNode;
	// if (rn.getType() == CMNodeType.ENTITY_REFERENCE)
	// {
	// String entityName = rn.getName().trim();
	//
	//
	// DTDEntity anEntity = (DTDEntity) dtdUtil.getPEPool().get(entityName);
	// if (anEntity!=null)
	// {
	// //
	// // Create an DTDEntityReference and set its referenced element
	// //
	// DTDEntityReferenceContent enRef =
	// getFactory().createDTDEntityReferenceContent();
	// enRef.setElementReferencedEntity(anEntity);
	//
	// DTDOccurrenceType occurrenceType =
	// DTDOccurrenceType.get(computeMofOccurrence(rn));
	// enRef.setOccurrence(occurrenceType);
	//
	// dtdElement.setContent(enRef);
	// }
	// else
	// { // create default content
	// DTDEmptyContent emptyContent = getFactory().createDTDEmptyContent();
	// dtdElement.setContent(emptyContent);
	// }
	// }
	// else
	// {
	// //
	// // Find the real element for this element references
	// // If the real element does not yet exist, create it
	// //
	// DTDElement anElement = createOrFindElement(rn.getName(), dtdElement);
	//
	//
	// //
	// // Create an DTDElementReference and set its referenced element
	// //
	// DTDElementReferenceContent elemRef =
	// getFactory().createDTDElementReferenceContent();
	// elemRef.setReferencedElement(anElement);
	//
	// DTDOccurrenceType occurrenceType =
	// DTDOccurrenceType.get(computeMofOccurrence(rn));
	// elemRef.setOccurrence(occurrenceType);
	//
	// // setContent to DTDElementReference
	// dtdElement.setContent(elemRef);
	//
	//
	// }
	// }
	// else if (cmNode instanceof CMGroupNode)
	// {
	// CMGroupNode grpNode = (CMGroupNode)cmNode;
	// DTDGroupContent groupContent = getFactory().createDTDGroupContent();
	// DTDGroupKind groupKind =
	// DTDGroupKind.get(computeMofGroupKind(grpNode.getGroupKind()));
	// groupContent.setGroupKind(groupKind);
	// DTDOccurrenceType occurrenceType =
	// DTDOccurrenceType.get(computeMofOccurrence(grpNode));
	// groupContent.setOccurrence(occurrenceType);
	//
	// // just use the locator for the element as the closest guess
	// processGroupContent(groupContent, grpNode);
	// dtdElement.setContent(groupContent);
	// }
	// else if (cmNode == null)
	// {
	// // bad thing happened here, just create a pcdata
	// DTDEmptyContent emptyContent = getFactory().createDTDEmptyContent();
	// dtdElement.setContent(emptyContent);
	// }
	// }
	// /**
	// * Add a new group to the current group
	// * @param parent - the parent node for this group element
	// * @param op1Node - the group
	// * e.g. (a,b)
	// * @param op2Node - set only if called by processCM1op
	// * e.g. (a,b)+
	// */
	// protected void processGroupContentGen(DTDGroupContent parent,
	// CMGroupNode grpNode) {
	//
	// Enumeration children = grpNode.getChildren().elements();
	// DTDFactory factory = getFactory();
	// while (children.hasMoreElements())
	// {
	// CMNode cnode = (CMNode) children.nextElement();
	//
	//
	// if (cnode instanceof CMGroupNode)
	// {
	// CMGroupNode gNode = (CMGroupNode)cnode;
	// DTDGroupContent groupContent = factory.createDTDGroupContent();
	// DTDGroupKind groupKind =
	// DTDGroupKind.get(computeMofGroupKind(gNode.getGroupKind()));
	// groupContent.setGroupKind(groupKind);
	// DTDOccurrenceType occurrenceType =
	// DTDOccurrenceType.get(computeMofOccurrence(gNode));
	// groupContent.setOccurrence(occurrenceType);
	//
	// parent.getContent().add(groupContent);
	// processGroupContent(groupContent,gNode);
	// }
	// else if (cnode instanceof CMBasicNode)
	// {
	// CMBasicNode n = (CMBasicNode)cnode;
	// if (n.getType() == CMNodeType.PCDATA)
	// {
	// // Create a DTDPCDataContent for a leaf PCData node
	// //
	// DTDPCDataContent pcData = factory.createDTDPCDataContent();
	// // Add #PCDATA to the Group, i.e Mixed content model
	// parent.getContent().add(pcData);
	// }
	// }
	// else if (cnode instanceof CMReferenceNode)
	// {
	// CMReferenceNode rn = (CMReferenceNode)cnode;
	// if (rn.getType()==CMNodeType.ELEMENT_REFERENCE)
	// {
	// // System.out.println("CM Element Ref name: " + rn.getName());
	// //
	// // Create an DTDElementReference and set its referenced element
	// //
	// DTDElementReferenceContent elemRef =
	// factory.createDTDElementReferenceContent();
	//
	//
	// //
	// // Find the real element for this element references
	// // If the real element does not yet exist, create it
	// //
	// DTDElement anElement = createOrFindElement(rn.getName(), elemRef);
	//
	//
	// elemRef.setReferencedElement(anElement);
	// DTDOccurrenceType occurrenceType =
	// DTDOccurrenceType.get(computeMofOccurrence(rn));
	// elemRef.setOccurrence(occurrenceType);
	//
	// // Add DTDElementReference to the Group
	// parent.getContent().add(elemRef);
	// }
	// else // PE Reference
	// {
	// String entityName = rn.getName().trim();
	//
	//
	// // System.out.println("CM PE Ref name: " + entityName);
	// DTDEntity anEntity = (DTDEntity) dtdUtil.getPEPool().get(entityName);
	// if (anEntity!=null)
	// {
	// //
	// // Create an DTDEntityReference and set its referenced element
	// //
	// DTDEntityReferenceContent enRef =
	// factory.createDTDEntityReferenceContent();
	// enRef.setElementReferencedEntity(anEntity);
	//             
	// DTDOccurrenceType occurrenceType =
	// DTDOccurrenceType.get(computeMofOccurrence(rn));
	// enRef.setOccurrence(occurrenceType);
	//
	//
	// // Add DTDEntityReference to the Group
	// parent.getContent().add(enRef);
	//
	//
	// }
	// }
	// }
	// }
	// }
	// /**
	// * Find the real element that is referenced by the current element
	// */
	// protected DTDElement createOrFindElementGen(String name, Object obj) {
	//
	// // DTDElement aElement = getDTDFile().findElement(name);
	//
	//
	// DTDElement aElement = (DTDElement) dtdUtil.getElementPool().get(name);
	//
	//
	// if (aElement != null)
	// {
	// return aElement;
	// }
	//
	//
	// String errorMsg =
	// DTDCoreMessages.getString("_ERROR_UNDECLARED_ELEMENT_1");
	// errorMsg += "\"" + name + "\"";
	// errorMsg +=
	// DTDCoreMessages.getString("_UI_ERRORPART_UNDECLARED_ELEMENT_2");
	//
	//
	// ErrorMessage dtdError = new ErrorMessage();
	//     
	// dtdError.setErrorMessage(errorMsg);
	// addErrorMessage(dtdError, obj);
	// // System.out.println(errorMsg);
	// // setDTDErrorMessage(errorMsg);
	// getDTDFile().setParseError(true);
	//
	//
	// //
	// // Create an empty element for the reference to make it valid
	// //
	//
	//
	// DTDFactory factory = getFactory();
	// DTDElement dtdelement = factory.createDTDElement();
	// dtdelement.setName(name);
	//
	//
	// DTDEmptyContent emptyContent = factory.createDTDEmptyContent();
	// dtdelement.setContent(emptyContent);
	//
	//
	// getDTDFile().getDTDObject().add(dtdelement);
	// dtdUtil.getElementPool().put(name,dtdelement);
	// return dtdelement;
	// }
	// /**
	// * Compute the MOF occurrence from the xml4j occurrence
	// */
	// protected int computeMofOccurrenceGen(CMRepeatableNode rnode) {
	//
	// int occurrence = rnode.getOccurrence();
	// int mofoccur = DTDOccurrenceType.ONE;
	//
	//
	// if (occurrence == CMNodeType.ZERO_OR_MORE)
	// {
	// mofoccur = DTDOccurrenceType.ZERO_OR_MORE;
	// }
	// else if (occurrence == CMNodeType.ONE_OR_MORE)
	// {
	// mofoccur = DTDOccurrenceType.ONE_OR_MORE;
	// }
	// else if (occurrence == CMNodeType.OPTIONAL)
	// {
	// mofoccur = DTDOccurrenceType.OPTIONAL;
	// }
	// return mofoccur;
	// }
	// /**
	// * Compute the MOF model group from the xml4j model group
	// */
	// protected int computeMofGroupKindGen(int type) {
	//
	// if (type == CMNodeType.GROUP_CHOICE)
	// {
	// return DTDGroupKind.CHOICE;
	// }
	// else
	// {
	// return DTDGroupKind.SEQUENCE;
	// }
	// }
	// /**
	// * @generated
	// */
	// protected void createAttributesGen(DTDElement element, Attlist attList)
	// {
	//
	// if (attList.getErrorMessage()!=null)
	// {
	// addErrorMessage(attList.getErrorMessage(), element);
	// }
	//
	//
	// for (int i=0;i<attList.size();i++)
	// {
	// AttNode ad = (AttNode) attList.elementAt(i);
	// // DTDAttributeElement dtdAtt= getDTDAttributeElement(a.getName());
	//
	//
	// // only add the AttDef if it is not added yet
	// // ignore the dup AttDef as documented in the XML 1.0 specs
	// //if( dtdAtt==null)
	// addAttribute(element, ad);
	// }
	// }
	// /**
	// * Create a DTDAttribute from the xml4j attribute
	// */
	// protected void addAttributeGen(DTDElement dtdelement, AttNode ad) {
	//
	// DTDAttribute dtdattr = getFactory().createDTDAttribute();
	// dtdelement.getDTDAttribute().add(dtdattr);
	// finishAttribute(dtdattr, ad);
	// }
	// /**
	// * @generated
	// */
	// protected void finishAttributeGen(DTDAttribute dtdattr, AttNode attdef)
	// {
	//
	// boolean parseError = false;
	//
	//
	// if (attdef.name.startsWith("%"))
	// {
	// String peName = attdef.name.trim();
	// DTDEntity en = (DTDEntity) dtdUtil.getPEPool().get(peName);
	// if (en!=null)
	// {
	// dtdattr.setAttributeNameReferencedEntity(en);
	// }
	// }
	//
	//
	// dtdattr.setName(attdef.name);
	//
	//
	// int attrType = attdef.getDeclaredType();
	//
	//
	// if (attrType==AttNode.PEREFERENCE && attdef.type!=null)
	// {
	// String peName = attdef.type.trim();
	// DTDEntity en = (DTDEntity) dtdUtil.getPEPool().get(peName);
	// if (en!=null)
	// {
	// dtdattr.setAttributeTypeReferencedEntity(en);
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_CDATA()); // hack,
	// so we can get back the default value
	// }
	// else //set default type
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_CDATA());
	//
	//
	// }
	// else
	// {
	// switch (attrType)
	// {
	// case AttNode.CDATA:
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_CDATA());
	// break;
	//
	//
	// case AttNode.ENTITIES:
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_ENTITIES());
	// break;
	//
	//
	// case AttNode.ENTITY:
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_ENTITY());
	// break;
	//
	//
	// case AttNode.ID:
	// // check for duplicate ID attribute
	// if (hasIDAttribute(dtdattr))
	// {
	// String errMsg = DTDCoreMessages.getString("_ERROR_DUP_ID_ATTRIBUTE_1");
	// errMsg += attdef.name +
	// DTDCoreMessages.getString("_UI_ERRORPART_DUP_ID_ATTRIBUTE_2");
	// // dtdattr.getDTDElement().getIElement().setDTDErrorMessage(errMsg);
	// // dtdattr.getDTDElement().getDTDFile().setParseError(true);
	// parseError = true;
	// }
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_ID());
	// break;
	//
	//
	// case AttNode.IDREF:
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_IDREF());
	// break;
	//
	//
	// case AttNode.IDREFS:
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_IDREFS());
	// break;
	//
	//
	// case AttNode.ENUMERATION:
	// setAttrDTDType(dtdattr, createDTDEnumeration(dtdattr, attdef,
	// DTDEnumGroupKind.NAME_TOKEN_GROUP));
	// break;
	//
	//
	// case AttNode.NOTATION:
	// setAttrDTDType(dtdattr, createDTDEnumeration(dtdattr, attdef,
	// DTDEnumGroupKind.NOTATION_GROUP));
	// break;
	//
	//
	// case AttNode.NMTOKEN:
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_NMTOKEN());
	// break;
	//
	//
	// case AttNode.NMTOKENS:
	// setAttrDTDType(dtdattr, getFactory().getDTDBasicType_NMTOKENS());
	// break;
	//
	//
	// default:
	// // System.out.println("DTDATTR '" +attdef.name + "'Unknown type..." +
	// attrType);
	// }
	// }
	//
	//
	// int attrDefault = attdef.getDefaultType();
	// int defaultKind = DTDDefaultKind.IMPLIED;
	// switch (attrDefault)
	// {
	// case AttNode.FIXED:
	// defaultKind = DTDDefaultKind.FIXED;
	// break;
	//
	//
	// case AttNode.IMPLIED:
	// defaultKind = DTDDefaultKind.IMPLIED;
	// break;
	//
	//
	// case AttNode.REQUIRED:
	// defaultKind = DTDDefaultKind.REQUIRED;
	// break;
	//
	//
	// case AttNode.NOFIXED:
	// defaultKind = DTDDefaultKind.NOFIXED;
	// break;
	//
	//
	// default:
	// // System.out.println("DTDATTR '" +attdef.name + "' Unknown default
	// type... " + attrDefault);
	// }
	//
	// DTDDefaultKind defaultKindObj = DTDDefaultKind.get(defaultKind);
	// dtdattr.setDefaultKind(defaultKindObj);
	//
	// if (parseError)
	// {
	// return;
	// }
	//
	//
	// String defaultValue = attdef.defaultValue;
	// if (defaultValue != null)
	// {
	// if (attrType == AttNode.ENUMERATION || attrType == AttNode.NOTATION)
	// {
	// if (! isDefaultEnumValueValid(attdef,defaultValue))
	// {
	// String typeString =
	// (attrType==AttNode.ENUMERATION?"enumeration":"notation");
	// String errMsg =
	// DTDCoreMessages.getString("_ERROR_INVALID_DEFAULT_ATTR_VALUE_1");
	// errMsg += typeString +
	// DTDCoreMessages.getString("_UI_ERRORPART_INVALID_DEFAULT_ATTR_VALUE_2");
	// errMsg += attdef.name + "'";
	//
	//
	// // dtdattr.getDTDElement().getIElement().setDTDErrorMessage(errMsg);
	// // dtdattr.getDTDElement().getDTDFile().setParseError(true);
	// return;
	// }
	// }
	// dtdattr.setDefaultValueString(defaultValue);
	// }
	// // System.out.println("DTDAttr - toMof getDefaultValueString " +
	// getDefaultValueString());
	// // System.out.println("DTDAttr - toMof getDefaultValue: " +
	// getDefaultValue());
	// }
	// /**
	// * @generated
	// */
	// protected boolean hasIDAttributeGen(DTDAttribute dtdattr) {
	//
	// boolean hasID = false;
	//
	//
	// DTDElement element = dtdattr.getDTDElement();
	// EList attrs = element.getDTDAttribute();
	//
	//
	// Iterator i = attrs.iterator();
	// while (i.hasNext())
	// {
	// DTDAttribute attr = (DTDAttribute) i.next();
	// DTDType dType = attr.getDTDType();
	// if (dType instanceof DTDBasicType)
	// {
	// if ( ((DTDBasicType)dType).getKind().getValue() == DTDBasicTypeKind.ID)
	// {
	// hasID = true;
	// break;
	// }
	// }
	// }
	// return hasID;
	// }
	// /**
	// * @generated
	// */
	// protected DTDEnumerationType createDTDEnumerationGen(DTDAttribute
	// dtdattr, String[] enumValues, int enumKind) {
	//
	// DTDEnumerationType enum = getFactory().createDTDEnumerationType();
	// // This is gross, but this is what was done before.
	// DTDAttributeImpl dtdattrimpl = (DTDAttributeImpl) dtdattr;
	// // enum.setID("Enum_" +
	// ((DTDElement)dtdattrimpl.getMOFDomain()).getName() + "_" +
	// dtdattr.getName());
	// DTDEnumGroupKind groupKind = DTDEnumGroupKind.get(enumKind);
	// enum.setKind(groupKind);
	// // Enumeration values
	// if (enumValues!=null)
	// {
	// for(int i=0;i<enumValues.length;i++)
	// {
	// EEnumLiteral enumLiteral = createEEnumLiteral();
	// // enumVal.setXMIDocument(dtdattr.getXMIDocument());
	// enumLiteral.refSetLiteral(enumValues[i]);
	// // enumLiteral.setNumber(i);
	// enum.getEnumLiterals().add(enumLiteral);
	// }
	// }
	// dtdattr.getDTDElement().getDTDFile().getDTDEnumerationType().add(enum);
	// return enum;
	// }
	// /**
	// * @generated
	// */
	// protected EEnumLiteral createEEnumLiteralGen() {
	//
	// EcorePackage ePackage =
	// (EcorePackage)EPackage.Registry.INSTANCE.getEPackage(EcorePackage.eNS_URI);
	// return ((EcoreFactory)ePackage.getFactory()).createEEnumLiteral();
	// }
	// /**
	// * @generated
	// */
	// protected DTDEnumerationType createDTDEnumerationGen(DTDAttribute
	// dtdattr, AttNode attdef, int enumKind) {
	//
	// DTDEnumerationType enum = getFactory().createDTDEnumerationType();
	// // This is gross, but this is what was done before.
	// DTDAttributeImpl dtdattrimpl = (DTDAttributeImpl) dtdattr;
	// // enum.setID("Enum_" +
	// ((DTDElement)dtdattrimpl.getMOFDomain()).getName() + "_" +
	// dtdattr.getName());
	// DTDEnumGroupKind groupKind = DTDEnumGroupKind.get(enumKind);
	// enum.setKind(groupKind);
	// dtdattr.getDTDElement().getDTDFile().getDTDEnumerationType().add(enum);
	//
	//
	// // Enumeration values
	// Enumeration tokenIter = attdef.elements();
	// if (tokenIter != null) {
	// int i=0;
	// while (tokenIter.hasMoreElements())
	// {
	// String val = (String)tokenIter.nextElement();
	// EEnumLiteral enumLiteral = createEEnumLiteral();
	// // enumLiteral.setXMIDocument(dtdattr.getXMIDocument());
	//        
	//
	// enumLiteral.refSetLiteral(val);
	// // enumLiteral.setNumber(i++);
	// enum.getEnumLiterals().add(enumLiteral);
	// }
	// }
	//
	//
	// return enum;
	// }
	// /**
	// * @generated
	// */
	// protected boolean isDefaultEnumValueValidGen(AttNode attdef, String
	// defaultValue) {
	//
	// boolean valid = false;
	// boolean containsPercent = false;
	//
	//
	// // Enumeration values
	// Enumeration enumValues = attdef.elements();
	// while (enumValues.hasMoreElements())
	// {
	// String val = (String)enumValues.nextElement();
	// if (val.equals(defaultValue))
	// {
	// valid = true;
	// break;
	// }
	// if (val.indexOf('%') >= 0)
	// {
	// containsPercent = true;
	// }
	// }
	// return valid || containsPercent;
	// }
	// /**
	// * @generated
	// */
	// protected void setAttrDTDTypeGen(DTDAttribute dtdattr, DTDType type) {
	//
	// dtdattr.setDTDType(type);
	// }
	// /**
	// * @generated
	// */
	// protected void addErrorMessageGen(ErrorMessage errMsg, Object obj) {
	//
	// errMsg.setObject(obj);
	// dtdUtil.addErrorMessage(errMsg);
	// }
}
