--- temp/jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/mapper/Mapper.java	2005-03-26 14:22:48.000000000 -0700
+++ jakarta-tomcat-5.5.9-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/mapper/Mapper.java	2005-05-08 20:43:40.404904383 -0600
@@ -14,18 +14,19 @@
  *  limitations under the License.
  */
 
 package org.apache.tomcat.util.http.mapper;
 
-import javax.naming.NamingException;
+import java.util.List;
+import java.util.ArrayList;
+
 import javax.naming.directory.DirContext;
+import javax.naming.NamingException;
 
+import org.apache.tomcat.util.buf.Ascii;
 import org.apache.tomcat.util.buf.CharChunk;
 import org.apache.tomcat.util.buf.MessageBytes;
-import org.apache.tomcat.util.buf.Ascii;
-import java.util.List;
-import java.util.ArrayList;
 
 /**
  * Mapper, which implements the servlet API mapping rules (which are derived
  * from the HTTP rules).
  *
@@ -37,29 +38,54 @@
     private static org.apache.commons.logging.Log logger =
         org.apache.commons.logging.LogFactory.getLog(Mapper.class);
     // ----------------------------------------------------- Instance Variables
 
 
+    HostMap hostMap=new HostMap();
+
     /**
-     * Array containing the virtual hosts definitions.
+     * Default number of alias matches for each host.
      */
-    protected Host[] hosts = new Host[0];
+    private int defaultAliasMatches=0;
 
 
     /**
      * Default host name.
      */
     protected String defaultHostName = null;
 
     /**
+     * Default host, already looked up cached to 
+     * eliminate lookup.
+     */
+    protected Host defaultHost=null;
+
+    /**
      * Context associated with this wrapper, used for wrapper mapping.
      */
     protected Context context = new Context();
 
 
     // --------------------------------------------------------- Public Methods
 
+    /**
+     * Set the number of allowed alias matches. If this number is
+     * non-zero, then wild-card host matching is enabled. This 
+     * number limits the number of wild-card host matches in
+     * order to prevent a denial of service attack.
+     */
+    public void setAllowedAliasMatches(final int matches){
+        defaultAliasMatches=matches;
+        hostMap.setEnableWildCardMatching(matches>0);
+    }
+
+    /**
+     * 
+     */
+    public int getAllowedAliasMatches(){
+        return defaultAliasMatches;
+    }
 
     /**
      * Get default host.
      *
      * @return Default host name
@@ -74,75 +100,80 @@
      *
      * @param defaultHostName Default host name
      */
     public void setDefaultHostName(String defaultHostName) {
         this.defaultHostName = defaultHostName;
+        defaultHost=null;
+    }
+
+    /**
+     * Return the default host, or null if the host
+     * has not been set.
+     */
+    private Host getDefaultHost(){
+        if (defaultHost==null && defaultHostName!=null) {
+            defaultHost=hostMap.getHost(defaultHostName);
+        }
+        return defaultHost;
     }
 
     /**
      * Add a new host to the mapper.
      *
      * @param name Virtual host name
      * @param host Host object
      */
     public synchronized void addHost(String name, String[] aliases,
                                      Object host) {
-        Host[] newHosts = new Host[hosts.length + 1];
+
+        // FIXME: This next line comes out in the final version.
+        setAllowedAliasMatches(16);
+
+        HostMap hm=hostMap;
+        if (hm.contains(name)) {
+            return;
+        }
+        hm=new HostMap(hm);
+        
         Host newHost = new Host();
         ContextList contextList = new ContextList();
         newHost.name = name;
         newHost.contextList = contextList;
         newHost.object = host;
-        if (insertMap(hosts, newHosts, newHost)) {
-            hosts = newHosts;
-        }
+        newHost.aliasMatchesRemaining=defaultAliasMatches;
+        hm.addHost(newHost);
         for (int i = 0; i < aliases.length; i++) {
-            newHosts = new Host[hosts.length + 1];
+            if (!hm.contains(aliases[i])) {
             newHost = new Host();
+                newHost.aliasMatchesRemaining=defaultAliasMatches;
             newHost.name = aliases[i];
             newHost.contextList = contextList;
             newHost.object = host;
-            if (insertMap(hosts, newHosts, newHost)) {
-                hosts = newHosts;
+                hm.addHost(newHost);
             }
         }
+        hostMap=hm;
     }
 
 
     /**
      * Remove a host from the mapper.
      *
      * @param name Virtual host name
      */
     public synchronized void removeHost(String name) {
-        // Find and remove the old host
-        int pos = find(hosts, name);
-        if (pos < 0) {
+
+        if (!hostMap.contains(name)) {
             return;
         }
-        Object host = hosts[pos].object;
-        Host[] newHosts = new Host[hosts.length - 1];
-        if (removeMap(hosts, newHosts, name)) {
-            hosts = newHosts;
-        }
-        // Remove all aliases (they will map to the same host object)
-        for (int i = 0; i < newHosts.length; i++) {
-            if (newHosts[i].object == host) {
-                Host[] newHosts2 = new Host[hosts.length - 1];
-                if (removeMap(hosts, newHosts2, newHosts[i].name)) {
-                    hosts = newHosts2;
-                }
-            }
-        }
+        HostMap hm=new HostMap(hostMap);
+        hm.removeHost(name);
+        hostMap=hm;
     }
 
     public String[] getHosts() {
-        String hostN[] = new String[hosts.length];
-        for( int i = 0; i < hosts.length; i++ ) {
-            hostN[i] = hosts[i].name;
-        }
-        return hostN;
+        return hostMap.getHosts();
     }
 
 
     /**
      * Set context, used for wrapper mapping (request dispatcher).
@@ -169,22 +200,15 @@
      */
     public void addContext
         (String hostName, String path, Object context,
          String[] welcomeResources, javax.naming.Context resources) {
 
-        Host[] hosts = this.hosts;
-        int pos = find(hosts, hostName);
-        if( pos <0 ) {
+        Host host=hostMap.getHost(hostName);
+        if (host==null) {
             addHost(hostName, new String[0], "");
-            hosts = this.hosts;
-            pos = find(hosts, hostName);
-        }
-        if (pos < 0) {
-            logger.error("No host found: " + hostName);
+            host=hostMap.getHost(hostName);
         }
-        Host host = hosts[pos];
-        if (host.name.equals(hostName)) {
             int slashCount = slashCount(path);
             synchronized (host) {
                 Context[] contexts = host.contextList.contexts;
                 // Update nesting
                 if (slashCount > host.contextList.nesting) {
@@ -200,27 +224,22 @@
                     host.contextList.contexts = newContexts;
                 }
             }
         }
 
-    }
-
 
     /**
      * Remove a context from an existing host.
      *
      * @param hostName Virtual host name this context belongs to
      * @param path Context path
      */
     public void removeContext(String hostName, String path) {
-        Host[] hosts = this.hosts;
-        int pos = find(hosts, hostName);
-        if (pos < 0) {
+        Host host=hostMap.getHost(hostName);
+        if (host==null) {
             return;
         }
-        Host host = hosts[pos];
-        if (host.name.equals(hostName)) {
             synchronized (host) {
                 Context[] contexts = host.contextList.contexts;
                 if( contexts.length == 0 ){
                     return;
                 }
@@ -235,21 +254,22 @@
                             host.contextList.nesting = slashCount;
                         }
                     }
                 }
             }
-        }
+
     }
 
 
     /**
      * Return all contexts, in //HOST/PATH form
      *
      * @return The context names
      */
     public String[] getContextNames() {
         List list=new ArrayList();
+        Host[] hosts=hostMap.toHostArray();
         for( int i=0; i<hosts.length; i++ ) {
             for( int j=0; j<hosts[i].contextList.contexts.length; j++ ) {
                 String cname=hosts[i].contextList.contexts[j].name;
                 list.add("//" + hosts[i].name +
                         (cname.startsWith("/") ? cname : "/"));
@@ -274,17 +294,14 @@
     }
 
 
     public void addWrapper(String hostName, String contextPath, String path,
                            Object wrapper, boolean jspWildCard) {
-        Host[] hosts = this.hosts;
-        int pos = find(hosts, hostName);
-        if (pos < 0) {
+        Host host=hostMap.getHost(hostName);
+        if (host==null) {
             return;
         }
-        Host host = hosts[pos];
-        if (host.name.equals(hostName)) {
             Context[] contexts = host.contextList.contexts;
             int pos2 = find(contexts, contextPath);
             if( pos2<0 ) {
                 logger.error("No context found: " + contextPath );
                 return;
@@ -292,11 +309,10 @@
             Context context = contexts[pos2];
             if (context.name.equals(contextPath)) {
                 addWrapper(context, path, wrapper, jspWildCard);
             }
         }
-    }
 
 
     /**
      * Add a wrapper to the context associated with this wrapper.
      *
@@ -391,28 +407,24 @@
      * @param contextPath Context path this wrapper belongs to
      * @param path Wrapper mapping
      */
     public void removeWrapper
         (String hostName, String contextPath, String path) {
-        Host[] hosts = this.hosts;
-        int pos = find(hosts, hostName);
-        if (pos < 0) {
+        Host host=hostMap.getHost(hostName);
+        if (host==null) {
             return;
         }
-        Host host = hosts[pos];
-        if (host.name.equals(hostName)) {
             Context[] contexts = host.contextList.contexts;
             int pos2 = find(contexts, contextPath);
             if (pos2 < 0) {
                 return;
             }
             Context context = contexts[pos2];
             if (context.name.equals(contextPath)) {
                 removeWrapper(context, path);
             }
         }
-    }
 
     protected void removeWrapper(Context context, String path) {
         synchronized (context) {
             if (path.endsWith("/*")) {
                 // Wildcard wrapper
@@ -463,22 +475,23 @@
             sb.append(names[i]).append(":");
         }
         return sb.toString();
     }
 
-    public String[] getWrapperNames( String host, String context ) {
+    public String[] getWrapperNames( String hostName, String context ) {
         List list=new ArrayList();
-        if( host==null ) host="";
+        if ( hostName==null ) hostName="";
         if( context==null ) context="";
-        for( int i=0; i<hosts.length; i++ ) {
-            if( ! host.equals( hosts[i].name ))
-                continue;
-            for( int j=0; j<hosts[i].contextList.contexts.length; j++ ) {
-                if( ! context.equals( hosts[i].contextList.contexts[j].name))
+        Host host=hostMap.getHost(hostName);
+        if (host!=null) {
+
+            for ( int j=0; j<host.contextList.contexts.length; j++ ) {
+
+                if ( ! context.equals( host.contextList.contexts[j].name))
                     continue;
                 // found the context
-                Context ctx=hosts[i].contextList.contexts[j];
+                Context ctx=host.contextList.contexts[j];
                 list.add( ctx.defaultWrapper.path);
                 for( int k=0; k<ctx.exactWrappers.length; k++ ) {
                     list.add( ctx.exactWrappers[k].path);
                 }
                 for( int k=0; k<ctx.wildcardWrappers.length; k++ ) {
@@ -549,29 +562,20 @@
         Context context = null;
         int nesting = 0;
 
         // Virtual host mapping
         if (mappingData.host == null) {
-            Host[] hosts = this.hosts;
-            int pos = findIgnoreCase(hosts, host);
-            if ((pos != -1) && (host.equalsIgnoreCase(hosts[pos].name))) {
-                mappingData.host = hosts[pos].object;
-                contexts = hosts[pos].contextList.contexts;
-                nesting = hosts[pos].contextList.nesting;
-            } else {
-                if (defaultHostName == null) {
-                    return;
-                }
-                pos = find(hosts, defaultHostName);
-                if ((pos != -1) && (defaultHostName.equals(hosts[pos].name))) {
-                    mappingData.host = hosts[pos].object;
-                    contexts = hosts[pos].contextList.contexts;
-                    nesting = hosts[pos].contextList.nesting;
-                } else {
+            Host hFound=hostMap.getHost(host);
+            if (hFound==null) {
+                hFound=getDefaultHost();
+                if (hFound==null) {
                     return;
                 }
             }
+            mappingData.host=hFound.object;
+            contexts = hFound.contextList.contexts;
+            nesting = hFound.contextList.nesting;
         }
 
         // Context mapping
         if (mappingData.context == null) {
             int pos = find(contexts, uri);
@@ -1072,11 +1076,12 @@
      */
     private static final int compare(CharChunk name, int start, int end,
                                      String compareTo) {
         int result = 0;
         char[] c = name.getBuffer();
-        int len = compareTo.length();
+        final int compareLen=compareTo.length();
+        int len = compareLen;
         if ((end - start) < len) {
             len = end - start;
         }
         for (int i = 0; (i < len) && (result == 0); i++) {
             if (c[i + start] > compareTo.charAt(i)) {
@@ -1084,13 +1089,13 @@
             } else if (c[i + start] < compareTo.charAt(i)) {
                 result = -1;
             }
         }
         if (result == 0) {
-            if (compareTo.length() > (end - start)) {
+            if (compareLen > (end - start)) {
                 result = -1;
-            } else if (compareTo.length() < (end - start)) {
+            } else if (compareLen < (end - start)) {
                 result = 1;
             }
         }
         return result;
     }
@@ -1102,11 +1107,12 @@
      */
     private static final int compareIgnoreCase(CharChunk name, int start, int end,
                                      String compareTo) {
         int result = 0;
         char[] c = name.getBuffer();
-        int len = compareTo.length();
+        final int compareLen=compareTo.length();
+        int len = compareLen;
         if ((end - start) < len) {
             len = end - start;
         }
         for (int i = 0; (i < len) && (result == 0); i++) {
             if (Ascii.toLower(c[i + start]) > Ascii.toLower(compareTo.charAt(i))) {
@@ -1114,13 +1120,13 @@
             } else if (Ascii.toLower(c[i + start]) < Ascii.toLower(compareTo.charAt(i))) {
                 result = -1;
             }
         }
         if (result == 0) {
-            if (compareTo.length() > (end - start)) {
+            if (compareLen > (end - start)) {
                 result = -1;
-            } else if (compareTo.length() < (end - start)) {
+            } else if (compareLen < (end - start)) {
                 result = 1;
             }
         }
         return result;
     }
@@ -1230,13 +1236,36 @@
 
     // ------------------------------------------------------- Host Inner Class
 
 
     protected static final class Host
-        extends MapElement {
+    extends MapElement implements Comparable {
 
         public ContextList contextList = null;
+        public int hash;
+        /** 
+         * Limiter for host alias matching to prevent DOS. The default
+         * of 0, disables alias matching.
+         */
+        public int aliasMatchesRemaining=0;
+
+        public int compareTo(Object o){
+            int iResult=0;
+            if (o==null) {
+                iResult=1;
+            } else {
+                Host oCompare=(Host)o;
+                if (this.hash>oCompare.hash) {
+                    iResult=1;
+                } else if (this.hash<oCompare.hash) {
+                    iResult=-1;
+                } else {
+                    // iResult is already 0
+                }
+            }
+            return iResult;
+        }
 
     }
 
 
     // ------------------------------------------------ ContextList Inner Class
@@ -1280,87 +1309,234 @@
 
 
     // -------------------------------------------------------- Testing Methods
 
     // FIXME: Externalize this
-    /*
+
     public static void main(String args[]) {
 
         try {
 
         Mapper mapper = new Mapper();
         System.out.println("Start");
 
-        mapper.addHost("sjbjdvwsbvhrb", new String[0], "blah1");
-        mapper.addHost("sjbjdvwsbvhr/", new String[0], "blah1");
-        mapper.addHost("wekhfewuifweuibf", new String[0], "blah2");
-        mapper.addHost("ylwrehirkuewh", new String[0], "blah3");
-        mapper.addHost("iohgeoihro", new String[0], "blah4");
-        mapper.addHost("fwehoihoihwfeo", new String[0], "blah5");
-        mapper.addHost("owefojiwefoi", new String[0], "blah6");
-        mapper.addHost("iowejoiejfoiew", new String[0], "blah7");
-        mapper.addHost("iowejoiejfoiew", new String[0], "blah17");
-        mapper.addHost("ohewoihfewoih", new String[0], "blah8");
-        mapper.addHost("fewohfoweoih", new String[0], "blah9");
-        mapper.addHost("ttthtiuhwoih", new String[0], "blah10");
-        mapper.addHost("lkwefjwojweffewoih", new String[0], "blah11");
-        mapper.addHost("zzzuyopjvewpovewjhfewoih", new String[0], "blah12");
-        mapper.addHost("xxxxgqwiwoih", new String[0], "blah13");
-        mapper.addHost("qwigqwiwoih", new String[0], "blah14");
+            final int TEST_HOST=3;
+
+            String[][][] testHosts={
+                {{"fewohfoweoih"},new String[0], {"blah9"}},
+                {{"fwehoihoihwfeo"},new String[0], {"blah5"}},
+                {{"iohgeoihro"},new String[0], {"blah4"}},
+                {{"iowejoiejfoiew"},{"testalias","*.testdomain.com"}, {"blah7"}},
+                {{"iowejoiejfoiew"},new String[0], {"blah17"}},
+                {{"lkwefjwojweffewoih"},new String[0], {"blah11"}},
+                {{"ohewoihfewoih"},new String[0], {"blah8"}},
+                {{"owefojiwefoi"},new String[0], {"blah6"}},
+                {{"qwigqwiwoih"},new String[0], {"blah14"}},
+                {{"sjbjdvwsbvhr/"},new String[0], {"blah1"}},
+                {{"sjbjdvwsbvhrb"},new String[0], {"blah1"}},
+                {{"ttthtiuhwoih"},new String[0], {"blah10"}},
+                {{"wekhfewuifweuibf"},new String[0], {"blah2"}},
+                {{"xxxxgqwiwoih"},new String[0], {"blah13"}},
+                {{"ylwrehirkuewh"},new String[0], {"blah3"}},
+                {{"zzzuyopjvewpovewjhfewoih"},new String[0], {"blah12"}}
+            };
+
+            for (int i=0; i < testHosts.length; i++) {
+                mapper.addHost(testHosts[i][0][0],testHosts[i][1],testHosts[i][2][0]);
+            }
 
         System.out.println("Map:");
-        for (int i = 0; i < mapper.hosts.length; i++) {
-            System.out.println(mapper.hosts[i].name);
+            String[] hNames=mapper.getHosts();
+
+            if (hNames.length!=(testHosts.length+1)) {
+                // One of the entries was a duplicate, but it also has
+                // two aliases, so the expected
+                // count of hosts is +1
+                System.out.println("***************** FAIL ********** hostCount="+hNames.length+" Expected="+(testHosts.length+1));
         }
 
-        mapper.setDefaultHostName("ylwrehirkuewh");
+            for (int i=0; i < hNames.length; i++ ) {
+                System.out.println(hNames[i]);
+                if (!mapper.hostMap.contains(hNames[i])) {
+                    System.out.println("BIG FAILURE!!!!! Host - "+hNames[i]+" doesnt appear in the hostMap!");
+                }
+            }
+
+            for (int i=0; i < testHosts.length; i++) {
+                if (!mapper.hostMap.contains(testHosts[i][0][0])) {
+                    System.out.println("BIG FAILURE!!!!! HostMapper doesnt appear to contain "+testHosts[i][0][0]+" in the hostMap!");
+                }
+            }
+
+            final String sDefault=testHosts[testHosts.length-2][0][0];
+            mapper.setDefaultHostName(sDefault);
+            if (!sDefault.equals(mapper.getDefaultHostName())) {
+                System.out.println("***************** FAIL ********** getDefaultHostName() returned incorrect value");
+            }
 
         String[] welcomes = new String[2];
         welcomes[0] = "boo/baba";
         welcomes[1] = "bobou";
 
-        mapper.addContext("iowejoiejfoiew", "", "context0", new String[0], null);
-        mapper.addContext("iowejoiejfoiew", "/foo", "context1", new String[0], null);
-        mapper.addContext("iowejoiejfoiew", "/foo/bar", "context2", welcomes, null);
-        mapper.addContext("iowejoiejfoiew", "/foo/bar/bla", "context3", new String[0], null);
-
-        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/fo/*", "wrapper0");
-        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/", "wrapper1");
-        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/blh", "wrapper2");
-        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "*.jsp", "wrapper3");
-        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/blah/bou/*", "wrapper4");
-        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "/blah/bobou/*", "wrapper5");
-        mapper.addWrapper("iowejoiejfoiew", "/foo/bar", "*.htm", "wrapper6");
 
+            /*
+            Columns are
+
+            0   host name
+            1   context path
+            2   Context Name
+            3   Welcome File List
+            */
+            final int CONTEXT_NAME_COL=2;
+            final int CONTEXT_PATH_COL=1;
+            String[][][] contextTestMap={
+                {{testHosts[TEST_HOST][0][0]}, {""}, {"context0"}, new String[0]},
+                {{testHosts[TEST_HOST][0][0]}, {"/foo"}, {"context1"}, new String[0]},
+                {{testHosts[TEST_HOST][0][0]}, {"/foo/bar"}, {"context2"}, welcomes},
+                {{testHosts[TEST_HOST][0][0]}, {"/foo/bar/ble"}, {"context3"}, new String[0]}
+            };
+
+            for (int i=0; i < contextTestMap.length; i++) {
+                mapper.addContext(contextTestMap[i][0][0],
+                                  contextTestMap[i][1][0],
+                                  contextTestMap[i][2][0],
+                                  contextTestMap[i][3],
+                                  null);
+            }
+
+            /*
+            Columns are
+
+                0   java.lang.Integer   Mapping into ContextTestMap
+                1   java.lang.String    URL Mapping
+                2   java.lang.String    Wrapper ID
+                3   java.lang.String    Test URL
+            */
+
+            final int TEST_URI_COL=3;
+            final int WRAPPER_NAME_COL=2;
+            final int WRAPPER_PATH_COL=1;
+            Object[][] testWrappers={
+                {new Integer(0),"","wrapper99","/index.html"},      
+                {new Integer(2),"/fo/*","wrapper0","/foo/bar/fo/xxx.html"},
+                {new Integer(2),"/fuzz/*","wrapper1","/foo/bar/fuzz/test.pdf"},
+                {new Integer(2),"/blh","wrapper2","/foo/bar/blh"},
+                {new Integer(2),"*.jsp","wrapper3","/foo/bar/baz.jsp"},
+                {new Integer(2),"/blah/bou/*","wrapper4","/foo/bar/blah/bou/blech.html"},
+                {new Integer(2),"/bla/blah/bou/*","wrapper4a","/foo/bar/bla/blah/bou/blech.html"},
+                {new Integer(2),"/blah/bobou/*","wrapper5","/foo/bar/blah/bobou/banana.html"},
+                {new Integer(2),"*.html","wrapper6","/foo/bar/farley.html"}
+
+            };
+            for (int i=0; i < testWrappers.length; i++) {
+                mapper.addWrapper(
+                                 contextTestMap[((Integer)testWrappers[i][0]).intValue()][0][0],   // Server
+                                 contextTestMap[((Integer)testWrappers[i][0]).intValue()][1][0],   // Context,
+                                 (String)testWrappers[i][1],
+                                 (String)testWrappers[i][2]
+                                 );
+            }
+            String[] sHost=null;
         MappingData mappingData = new MappingData();
-        MessageBytes host = MessageBytes.newInstance();
-        host.setString("iowejoiejfoiew");
-        MessageBytes uri = MessageBytes.newInstance();
-        uri.setString("/foo/bar/blah/bobou/foo");
+            MessageBytes uri=null ,host=null;
+
+            for (int iOuter=0; iOuter < 2; iOuter++) {
+                if (iOuter==0) {
+                    // First Pass is against the test host
+                    sHost=testHosts[TEST_HOST][0];
+                } else {
+                    // 2nd pass is against an alias
+                    sHost=testHosts[TEST_HOST][1];
+                }
+                host = MessageBytes.newInstance();
+                host.setString(sHost[0]);
+
+                for (int iInner=0; iInner < testWrappers.length; iInner++) {
+
+                    uri = MessageBytes.newInstance();
+
+                    uri.setString((String)testWrappers[iInner][TEST_URI_COL]);
         uri.toChars();
         uri.getCharChunk().setLimit(-1);
 
         mapper.map(host, uri, mappingData);
+                    //  OK, now let's check that the mapper worked.
+                    System.out.println("Host = "+sHost[0]+" URI="+uri.toString());
         System.out.println("MD Host:" + mappingData.host);
         System.out.println("MD Context:" + mappingData.context);
         System.out.println("MD Wrapper:" + mappingData.wrapper);
 
         System.out.println("contextPath:" + mappingData.contextPath);
         System.out.println("wrapperPath:" + mappingData.wrapperPath);
         System.out.println("pathInfo:" + mappingData.pathInfo);
         System.out.println("redirectPath:" + mappingData.redirectPath);
 
+                    // Check the host name - Aliases will come back with the parent host
+                    // name.
+                    if (!testHosts[TEST_HOST][2][0].equals(mappingData.host)) {
+                        System.out.println("******* FAIL host.name="+mappingData.host +" Expected="+testHosts[TEST_HOST][2][0]);
+                    }
+
+                    // Check the context
+                    if (mappingData.context!=null) {
+                        if (!mappingData.context.equals(
+                                                       contextTestMap[((Integer)testWrappers[iInner][0]).intValue()][CONTEXT_NAME_COL][0]
+                                                       )
+                           ) {
+                        }
+                    }
+
+                    if (mappingData.wrapper!=null) {
+                        if (!mappingData.wrapper.equals(testWrappers[iInner][2])
+                           ) {
+                            System.out.println(" Wrappers not equal as expected - mappingData.wrapper="+mappingData.wrapper+" expected="+
+                                               testWrappers[iInner][2]);
+                        }
+                    }
+
+                    if (mappingData.contextPath!=null) {
+                        if (!contextTestMap[((Integer)testWrappers[iInner][0]).intValue()][CONTEXT_PATH_COL][0].equals(mappingData.contextPath.toString()
+
+                                                                                                                      )) {
+                            System.out.println(" Context Path not as expected - mappingData.contextPath="+mappingData.contextPath.toString()+" expected="+
+                                               contextTestMap[((Integer)testWrappers[iInner][0]).intValue()][CONTEXT_PATH_COL][0]);
+                        }
+                    }
+
+                    if (mappingData.wrapperPath.toString()!=null) {
+                        if (!((String)testWrappers[iInner][WRAPPER_PATH_COL]).startsWith(mappingData.wrapperPath.toString())
+                            && 
+                            !((String)testWrappers[iInner][WRAPPER_PATH_COL]).startsWith("*")
+                           ) {
+                            System.out.println("Wrapper Path="+mappingData.wrapperPath + "  Expected="+testWrappers[iInner][WRAPPER_PATH_COL]);
+                        }
+                    }
+
+                    if (mappingData.pathInfo.toString()!=null) {
+                        if (!
+                            ((String)testWrappers[iInner][TEST_URI_COL]).endsWith(mappingData.pathInfo.toString())
+                           ) {
+                            System.out.println(" Mismatch between pathInfo ("+mappingData.pathInfo+" and Test URI ("+
+                                               testWrappers[iInner][TEST_URI_COL]);
+                        }
+                    }
+
+                    // TODO: RedirectPath                           redirectPath:null
+
         mappingData.recycle();
-        mapper.map(host, uri, mappingData);
-        System.out.println("MD Host:" + mappingData.host);
-        System.out.println("MD Context:" + mappingData.context);
-        System.out.println("MD Wrapper:" + mappingData.wrapper);
 
-        System.out.println("contextPath:" + mappingData.contextPath);
-        System.out.println("wrapperPath:" + mappingData.wrapperPath);
-        System.out.println("pathInfo:" + mappingData.pathInfo);
-        System.out.println("redirectPath:" + mappingData.redirectPath);
+                }
+            }
+
+            host = MessageBytes.newInstance();
+            host.setString(testHosts[TEST_HOST][0][0]);
+
+            uri=MessageBytes.newInstance();
+            uri.setString((String)testWrappers[6][TEST_URI_COL]);
+            uri.toChars();
+            uri.getCharChunk().setLimit(-1);
+
 
         for (int i = 0; i < 1000000; i++) {
             mappingData.recycle();
             mapper.map(host, uri, mappingData);
         }
@@ -1368,26 +1544,47 @@
         long time = System.currentTimeMillis();
         for (int i = 0; i < 1000000; i++) {
             mappingData.recycle();
             mapper.map(host, uri, mappingData);
         }
+
         System.out.println("Elapsed:" + (System.currentTimeMillis() - time));
+            System.out.println("Host = "+host.toString()+" URI="+uri.toString());
+            System.out.println("MD Host:" + mappingData.host);
+            System.out.println("MD Context:" + mappingData.context);
+            System.out.println("MD Wrapper:" + mappingData.wrapper);
+
+            System.out.println("contextPath:" + mappingData.contextPath);
+            System.out.println("wrapperPath:" + mappingData.wrapperPath);
+            System.out.println("pathInfo:" + mappingData.pathInfo);
+            System.out.println("redirectPath:" + mappingData.redirectPath);
+
+            System.out.println("Testing virtual host name.");
+
+            host = MessageBytes.newInstance();
+            host.setString("host99.testdomain.com");
+
+            uri=MessageBytes.newInstance();
+            uri.setString((String)testWrappers[6][TEST_URI_COL]);
+            uri.toChars();
+            uri.getCharChunk().setLimit(-1);
+
+            System.out.println("Host = "+host.toString()+" URI="+uri.toString());
+
+            mappingData.recycle();
+            mapper.map(host, uri, mappingData);
 
         System.out.println("MD Host:" + mappingData.host);
         System.out.println("MD Context:" + mappingData.context);
         System.out.println("MD Wrapper:" + mappingData.wrapper);
 
         System.out.println("contextPath:" + mappingData.contextPath);
         System.out.println("wrapperPath:" + mappingData.wrapperPath);
-        System.out.println("requestPath:" + mappingData.requestPath);
         System.out.println("pathInfo:" + mappingData.pathInfo);
         System.out.println("redirectPath:" + mappingData.redirectPath);
 
         } catch (Exception e) {
             e.printStackTrace();
         }
 
     }
-    */
-
-
 }
