Index: tika-core/src/test/resources/org/apache/tika/mime/duplicate-mimetypes.xml
===================================================================
--- tika-core/src/test/resources/org/apache/tika/mime/duplicate-mimetypes.xml	(revision 0)
+++ tika-core/src/test/resources/org/apache/tika/mime/duplicate-mimetypes.xml	(working copy)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<mime-info>
+
+  <mime-type type="image/hello.word">
+    <acronym>HELLO</acronym>
+    <glob pattern="*.dib"/> <!-- Same as BMP -->
+  </mime-type>
+  
+  <mime-type type="image/hello.mundo">
+    <_comment>kaixo</_comment>
+    <glob pattern="*.mundo"/> 
+  </mime-type>
+  
+  <mime-type type="text/hello.word">
+    <_comment>a text dib</_comment>
+    <glob pattern="*.dib"/> <!-- Same as BMP -->
+  </mime-type>
+  
+
+</mime-info>
Index: tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java
===================================================================
--- tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java	(revision 1403575)
+++ tika-core/src/test/java/org/apache/tika/mime/MimeTypesReaderTest.java	(working copy)
@@ -17,15 +17,18 @@
 package org.apache.tika.mime;
 
 import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
-import java.util.SortedSet;
+import java.util.Map;
 
 import junit.framework.TestCase;
 
 import org.apache.tika.config.TikaConfig;
 import org.apache.tika.metadata.Metadata;
+import org.xml.sax.SAXException;
 
 /**
  * These tests try to ensure that the MimeTypesReader
@@ -170,4 +173,49 @@
         assertEquals(".ppt",mt.getExtensions().get(0));
     }
 
+    
+    public void testCustomErrorHandling() throws Exception {
+      CollectingMimeTypesReaderErrorHandler errors = new CollectingMimeTypesReaderErrorHandler();
+      
+      List<InputStream> streams = new ArrayList<InputStream>(3);
+      try {
+        streams.add( MimeTypesReader.class.getResource("tika-mimetypes.xml").openStream() );
+        streams.add( MimeTypesReader.class.getResource("duplicate-mimetypes.xml").openStream() );
+        
+        MimeTypes types = MimeTypesFactory.create(streams, errors);
+        assertEquals("kaixo", types.forName("image/hello.mundo").getDescription());
+        
+        List<String> duplicates = errors.globErrors.get("*.dib");
+        assertEquals(2, duplicates.size());
+        System.out.println("DUPLICATE: "+errors.globErrors );
+      }
+      finally {
+        for(InputStream s : streams) {
+          if(s!=null) {
+            s.close();
+          }
+        }
+      }
+    }
+    
+    static class CollectingMimeTypesReaderErrorHandler extends MimeTypesReaderErrorHandler {
+
+      public List<String> mimeTypeErrors = new ArrayList<String>();
+      public Map<String,List<String>> globErrors = new HashMap<String, List<String>>();
+      
+      @Override
+      public void onMimeTypeError(String name, MimeTypes types, MimeTypeException e) throws SAXException {
+        mimeTypeErrors.add(name);
+      }
+
+      @Override
+      public void onGlobError(MimeType type, String pattern, boolean isRegex, MimeTypes types, MimeTypeException ex) throws SAXException {
+        List<String> errors = globErrors.get(pattern);
+        if(errors==null) {
+          errors = new ArrayList<String>();
+          globErrors.put(pattern, errors);
+        }
+        errors.add(type.toString());
+      }
+    }
 }
Index: tika-core/src/main/java/org/apache/tika/mime/MimeTypesFactory.java
===================================================================
--- tika-core/src/main/java/org/apache/tika/mime/MimeTypesFactory.java	(revision 1403575)
+++ tika-core/src/main/java/org/apache/tika/mime/MimeTypesFactory.java	(working copy)
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -56,10 +57,10 @@
      * @throws IOException if the stream can not be read
      * @throws MimeTypeException if the type configuration is invalid
      */
-    public static MimeTypes create(InputStream... inputStreams)
+    public static MimeTypes create(Iterable<InputStream> inputStreams, MimeTypesReaderErrorHandler errors)
             throws IOException, MimeTypeException {
         MimeTypes mimeTypes = new MimeTypes();
-        MimeTypesReader reader = new MimeTypesReader(mimeTypes);
+        MimeTypesReader reader = new MimeTypesReader(mimeTypes, errors);
         for(InputStream inputStream : inputStreams) {
            reader.read(inputStream);
         }
@@ -67,10 +68,21 @@
         return mimeTypes;
     }
 
+    /**
+     * Creates and returns a MimeTypes instance from the specified input stream.
+     * Does not close the input stream(s).
+     * @throws IOException if the stream can not be read
+     * @throws MimeTypeException if the type configuration is invalid
+     */
+    public static MimeTypes create(InputStream... inputStreams)
+            throws IOException, MimeTypeException {
+        return create(Arrays.asList(inputStreams), null);
+    }
+
     /** @see #create(InputStream...) */
     public static MimeTypes create(InputStream stream)
             throws IOException, MimeTypeException {
-        return create(new InputStream[] { stream });
+        return create(Arrays.asList(stream),null);
     }
 
     /**
@@ -84,16 +96,16 @@
      */
     public static MimeTypes create(URL... urls)
             throws IOException, MimeTypeException {
-        InputStream[] streams = new InputStream[urls.length];
-        for(int i=0; i<streams.length; i++) {
-           streams[i] = urls[i].openStream();
-        }
-
+        List<InputStream> streams = new ArrayList<InputStream>(urls.length);
+        
         try {
-            return create(streams);
+            for(URL url : urls) {
+              streams.add(url.openStream());
+            }
+            return create(streams, null);
         } finally {
             for(InputStream stream : streams) {
-               stream.close();
+                stream.close();
             }
         }
     }
Index: tika-core/src/main/java/org/apache/tika/mime/MimeTypesReaderErrorHandler.java
===================================================================
--- tika-core/src/main/java/org/apache/tika/mime/MimeTypesReaderErrorHandler.java	(revision 0)
+++ tika-core/src/main/java/org/apache/tika/mime/MimeTypesReaderErrorHandler.java	(working copy)
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.mime;
+
+import org.xml.sax.SAXException;
+
+public class MimeTypesReaderErrorHandler {
+
+  public void onMimeTypeError(String name, MimeTypes types, MimeTypeException e) throws SAXException {
+    throw new SAXException(e);
+  }
+  
+  public void onGlobError(MimeType type, String pattern, boolean isRegex, MimeTypes types, MimeTypeException ex) throws SAXException {
+    throw new SAXException(ex);
+  }
+}
Index: tika-core/src/main/java/org/apache/tika/mime/MimeTypesReader.java
===================================================================
--- tika-core/src/main/java/org/apache/tika/mime/MimeTypesReader.java	(revision 1403575)
+++ tika-core/src/main/java/org/apache/tika/mime/MimeTypesReader.java	(working copy)
@@ -21,7 +21,6 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 
 import javax.xml.parsers.ParserConfigurationException;
@@ -102,9 +101,17 @@
     private int priority;
 
     private StringBuilder characters = null;
+    
+    private final MimeTypesReaderErrorHandler errorHandler;
 
     MimeTypesReader(MimeTypes types) {
+        this(types,null);
+    }
+
+    MimeTypesReader(MimeTypes types, MimeTypesReaderErrorHandler errors) {
         this.types = types;
+        this.errorHandler = (errors==null)
+           ? new MimeTypesReaderErrorHandler() : errors;
     }
 
     void read(InputStream stream) throws IOException, MimeTypeException {
@@ -145,7 +152,7 @@
                 try {
                     type = types.forName(name);
                 } catch (MimeTypeException e) {
-                    throw new SAXException(e);
+                    errorHandler.onMimeTypeError(name, types, e);
                 }
             }
         } else if (ALIAS_TAG.equals(qName)) {
@@ -163,7 +170,7 @@
                 try {
                     types.addPattern(type, pattern, Boolean.valueOf(isRegex));
                 } catch (MimeTypeException e) {
-                    throw new SAXException(e);
+                    errorHandler.onGlobError(type, pattern, Boolean.valueOf(isRegex), types, e);
                 }
             }
         } else if (ROOT_XML_TAG.equals(qName)) {
@@ -257,7 +264,5 @@
         public List<Clause> getClauses() {
             return subclauses;
         }
-
     }
-
 }
