[122044] "Validate DTD File" action does not detect duplicate Element Type declarations
diff --git a/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationMessages.java b/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationMessages.java
index 8b7fafe..28e3ee0 100644
--- a/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationMessages.java
+++ b/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 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
@@ -19,6 +19,7 @@
  */
 public class DTDValidationMessages extends NLS {
 	public static String _ERROR_REF_ELEMENT_UNDEFINED;
+	public static String _ERROR_DUPLICATE_ELEMENT_DECLARATION;
 
 	private static final String BUNDLE_NAME = "org.eclipse.wst.dtd.core.internal.validation.DTDValidationResources";//$NON-NLS-1$
 
diff --git a/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationResources.properties b/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationResources.properties
index 131e64c..d2a251b 100644
--- a/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationResources.properties
+++ b/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidationResources.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2005, 2006 IBM Corporation and others.
+# Copyright (c) 2005, 2011 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
@@ -12,4 +12,5 @@
 !
 ! Referenced Element Validation
 !
-_ERROR_REF_ELEMENT_UNDEFINED = The element {0} has not been declared.
\ No newline at end of file
+_ERROR_REF_ELEMENT_UNDEFINED = The element {0} has not been declared.
+_ERROR_DUPLICATE_ELEMENT_DECLARATION=The name {0} is used for multiple element declarations.
\ No newline at end of file
diff --git a/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidator.java b/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidator.java
index c2ab0c1..4330ac7 100644
--- a/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidator.java
+++ b/bundles/org.eclipse.wst.dtd.core/src-validation/org/eclipse/wst/dtd/core/internal/validation/DTDValidator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2001, 2006 IBM Corporation and others.
+ * Copyright (c) 2001, 2011 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
@@ -15,9 +15,11 @@
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.List;
-import com.ibm.icu.util.StringTokenizer;
+import java.util.Map;
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
@@ -41,6 +43,8 @@
 import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.helpers.DefaultHandler;
 
+import com.ibm.icu.util.StringTokenizer;
+
 /**
  * DTD validation.
  */
@@ -179,7 +183,7 @@
 
 		private static final String MODEL_DELIMITERS = ",()| "; //$NON-NLS-1$
 
-		private List fElemDecls = new ArrayList();
+		private Map fElemDecls = new HashMap();
 
 		private Hashtable fElemRefs = new Hashtable();
 
@@ -222,8 +226,17 @@
 		 *      java.lang.String)
 		 */
 		public void elementDecl(String name, String model) throws SAXException {
+			// Add each referenced element to the list of referenced elements
+			int line = fLocator.getLineNumber();
+			int column = fLocator.getColumnNumber();
+			String uri = fLocator.getSystemId();			
 			// Add this element to the list of declared elements.
-			fElemDecls.add(name);
+			List locations = (List) fElemDecls.get(name);
+			if (locations == null) {
+				locations = new ArrayList();
+				fElemDecls.put(name, locations);
+			}
+			locations.add(new ElementLocation(column, line, uri));
 
 			// Return if the element model should be ignored. The model should
 			// be
@@ -231,10 +244,6 @@
 			if (fIgnoreElemModel.contains(model)) {
 				return;
 			}
-			// Add each referenced element to the list of referenced elements
-			int line = fLocator.getLineNumber();
-			int column = fLocator.getColumnNumber();
-			String uri = fLocator.getSystemId();
 
 			StringTokenizer strtok = new StringTokenizer(model, MODEL_DELIMITERS);
 			while (strtok.hasMoreTokens()) {
@@ -300,7 +309,7 @@
 		 * 
 		 * @return The list of element declarations.
 		 */
-		public List getElementDeclarations() {
+		public Map getElementDeclarations() {
 			return fElemDecls;
 		}
 
@@ -362,7 +371,20 @@
 		}
 	}
 
-	
+	/**
+	 * Keeps track of element location information
+	 *
+	 */
+	class ElementLocation {
+		int column = -1;
+		int line = -1;
+		String uri;
+		ElementLocation(int column, int line, String uri) {
+			this.column = column;
+			this.line = line;
+			this.uri = uri;
+		}
+	}
 
 	private URIResolver fResolver = null;
 
@@ -403,9 +425,11 @@
 
 			reader.parse(new InputSource(new StringReader(document)));
 
-			List elemDecls = dtdHandler.getElementDeclarations();
+			Map elemDecls = dtdHandler.getElementDeclarations();
 			Hashtable elemRefs = dtdHandler.getElementReferences();
 			validateElementReferences(elemDecls, elemRefs, valinfo);
+
+			validateDuplicateElementDecls(elemDecls, valinfo);
 		}
 		catch (ParserConfigurationException e) {
 
@@ -419,6 +443,21 @@
 		return valinfo;
 	}
 
+	private void validateDuplicateElementDecls(Map elemDecls, ValidationInfo valinfo) {
+		final Iterator it = elemDecls.entrySet().iterator();
+		while (it.hasNext()) {
+			Map.Entry elem = (Map.Entry) it.next();
+			List locations = (List) elem.getValue();
+			if (locations.size() > 1) {
+				final Iterator locationIterator = locations.iterator();
+				while (locationIterator.hasNext()) {
+					ElementLocation elemLoc = (ElementLocation) locationIterator.next();
+					valinfo.addError(NLS.bind(DTDValidationMessages._ERROR_DUPLICATE_ELEMENT_DECLARATION, "'" + elem.getKey() + "'"), elemLoc.line, elemLoc.column, elemLoc.uri); //$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+		}
+	}
+
 	/**
 	 * Validate the element references in the DTD. An element reference is
 	 * <!ELEMENT elem (elementReference)>
@@ -431,12 +470,12 @@
 	 * @param valinfo
 	 *            The validation info object to store validation information.
 	 */
-	private void validateElementReferences(List elemDecls, Hashtable elemRefs, ValidationInfo valinfo) {
+	private void validateElementReferences(Map elemDecls, Hashtable elemRefs, ValidationInfo valinfo) {
 		Enumeration keys = elemRefs.keys();
 		while (keys.hasMoreElements()) {
 			String elemRef = (String) keys.nextElement();
 			// If the element hasn't been declared create an error.
-			if (!elemDecls.contains(elemRef)) {
+			if (!elemDecls.containsKey(elemRef)) {
 				ElementRefLocation elemLoc = (ElementRefLocation) elemRefs.get(elemRef);
 				do {
 					valinfo.addError(NLS.bind(DTDValidationMessages._ERROR_REF_ELEMENT_UNDEFINED, "'" + elemRef + "'"), elemLoc.getLine(), elemLoc.getColumn(), elemLoc.getURI()); //$NON-NLS-1$ //$NON-NLS-2$
@@ -446,4 +485,5 @@
 			}
 		}
 	}
+
 }