diff --git a/doc/migration.xml b/doc/migration.xml
index b0a99e8489858ae86d9f28bf40f76a4787370d8c..5ebc125abfdb864259887fb1a94387c10f971d78 100644
--- a/doc/migration.xml
+++ b/doc/migration.xml
@@ -97,6 +97,7 @@
                   <li>and DOMBuilder/SAX2XMLReader will recognize the feature
                       http://apache.org/xml/features/standard-uri-conformant</li>
                 </ul>
+              <li>Add XMLURL::hasInvalidChar() to indicate if the URL has invalid char as per RFC standard</li>
             </ul>
         </s4>
 
@@ -114,6 +115,7 @@
               a reference as parameter, i.e. QName(const QName&amp; qname).</li>
               <li>To fix [Bug 12232], the QName operator== has been added a const modified.</li>
               <li>Move XMLUri copy constructor and operator = as public.</li>
+              <li>Move XMLUri::isURIString as public.</li>
               <li>For validation purpose, added two more default parameters to
               XMLValidator::validateAttrValue</li>
             </ul>
diff --git a/src/xercesc/internal/DGXMLScanner.cpp b/src/xercesc/internal/DGXMLScanner.cpp
index 80ac479a7064d10c57f563b2a7b00c911cabe8a7..759ebd8f61e76db7da9824fd311d29851149dbb3 100644
--- a/src/xercesc/internal/DGXMLScanner.cpp
+++ b/src/xercesc/internal/DGXMLScanner.cpp
@@ -2270,7 +2270,11 @@ InputSource* DGXMLScanner::resolveSystemId(const XMLCh* const sysId)
                     , XMLExcepts::URL_NoProtocolPresent
                 );
             }
-            srcToFill = new URLInputSource(urlTmp);
+            else {
+                if (fStandardUriConformant && urlTmp.hasInvalidChar())
+                    ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                srcToFill = new URLInputSource(urlTmp);
+            }
         }
         catch(const MalformedURLException& e)
         {
diff --git a/src/xercesc/internal/IGXMLScanner2.cpp b/src/xercesc/internal/IGXMLScanner2.cpp
index 767598fc511dfa385aee08f0e79bbdfe279a097b..842961fad2b8a11722a958f96b8d88cb8266545f 100644
--- a/src/xercesc/internal/IGXMLScanner2.cpp
+++ b/src/xercesc/internal/IGXMLScanner2.cpp
@@ -1270,7 +1270,11 @@ void IGXMLScanner::resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* con
                         , XMLExcepts::URL_NoProtocolPresent
                     );
                 }
-                srcToFill = new URLInputSource(urlTmp);
+                else {
+                    if (fStandardUriConformant && urlTmp.hasInvalidChar())
+                        ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                    srcToFill = new URLInputSource(urlTmp);
+                }
             }
 
             catch(const MalformedURLException& e)
@@ -1423,7 +1427,11 @@ InputSource* IGXMLScanner::resolveSystemId(const XMLCh* const sysId)
                     , XMLExcepts::URL_NoProtocolPresent
                 );
             }
-            srcToFill = new URLInputSource(urlTmp);
+            else {
+                if (fStandardUriConformant && urlTmp.hasInvalidChar())
+                    ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                srcToFill = new URLInputSource(urlTmp);
+            }
         }
         catch(const MalformedURLException& e)
         {
diff --git a/src/xercesc/internal/ReaderMgr.cpp b/src/xercesc/internal/ReaderMgr.cpp
index 45b72a8312c8431e85fb49592d92fe655b6fe839..461994b2f11ac96d8794c8ff74d9b4e8b7e00fb1 100644
--- a/src/xercesc/internal/ReaderMgr.cpp
+++ b/src/xercesc/internal/ReaderMgr.cpp
@@ -547,7 +547,11 @@ XMLReader* ReaderMgr::createReader( const   XMLCh* const        sysId
                     , XMLExcepts::URL_NoProtocolPresent
                 );
             }
-            srcToFill = new URLInputSource(urlTmp);
+            else {
+                if (fStandardUriConformant && urlTmp.hasInvalidChar())
+                    ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                srcToFill = new URLInputSource(urlTmp);
+            }
         }
 
         catch(const MalformedURLException& e)
@@ -653,7 +657,11 @@ XMLReader* ReaderMgr::createReader( const   XMLCh* const        baseURI
                     , XMLExcepts::URL_NoProtocolPresent
                 );
             }
-            srcToFill = new URLInputSource(urlTmp);
+            else {
+                if (fStandardUriConformant && urlTmp.hasInvalidChar())
+                    ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                srcToFill = new URLInputSource(urlTmp);
+            }
         }
 
         catch(const MalformedURLException& e)
diff --git a/src/xercesc/internal/SGXMLScanner.cpp b/src/xercesc/internal/SGXMLScanner.cpp
index 52c21c380ce9fd74cfdcdfa6058cc0f764c027be..417cb4e21a9a48303b2180e39f0339d1cb8950f4 100644
--- a/src/xercesc/internal/SGXMLScanner.cpp
+++ b/src/xercesc/internal/SGXMLScanner.cpp
@@ -2983,7 +2983,11 @@ void SGXMLScanner::resolveSchemaGrammar(const XMLCh* const loc, const XMLCh* con
                         , XMLExcepts::URL_NoProtocolPresent
                     );
                 }
-                srcToFill = new URLInputSource(urlTmp);
+                else {
+                    if (fStandardUriConformant && urlTmp.hasInvalidChar())
+                        ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                    srcToFill = new URLInputSource(urlTmp);
+                }
             }
 
             catch(const MalformedURLException& e)
@@ -3113,7 +3117,11 @@ InputSource* SGXMLScanner::resolveSystemId(const XMLCh* const sysId)
                     , XMLExcepts::URL_NoProtocolPresent
                 );
             }
-            srcToFill = new URLInputSource(urlTmp);
+            else {
+                if (fStandardUriConformant && urlTmp.hasInvalidChar())
+                    ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                srcToFill = new URLInputSource(urlTmp);
+            }
         }
         catch(const MalformedURLException& e)
         {
diff --git a/src/xercesc/internal/WFXMLScanner.cpp b/src/xercesc/internal/WFXMLScanner.cpp
index 28adb340f0e4ed5556b3ff255f15c2650fe70a02..01f6a74dc57f61ad77f4aa44f88795ba87fbb3be 100644
--- a/src/xercesc/internal/WFXMLScanner.cpp
+++ b/src/xercesc/internal/WFXMLScanner.cpp
@@ -1117,6 +1117,8 @@ bool WFXMLScanner::scanStartTagNS(bool& gotData)
     XMLElementDecl* elemDecl = fElementLookup->get(qnameRawBuf);
 
     if (!elemDecl) {
+        if (!XMLString::compareNString(qnameRawBuf, XMLUni::fgXMLNSColonString, 6))
+            emitError(XMLErrs::NoXMLNSAsElementPrefix, qnameRawBuf);
 
         if (fElementIndex < fElements->size()) {
             elemDecl = fElements->elementAt(fElementIndex);
@@ -1314,30 +1316,51 @@ bool WFXMLScanner::scanStartTagNS(bool& gotData)
             }
 
             // Make sure that the name is basically well formed for namespace
-            //
-            // Map prefix to namespace
-            const XMLCh* attPrefix = curAtt->getPrefix();
-            const XMLCh* attLocalName = curAtt->getName();
-            if (attPrefix && *attPrefix) {
-
-                int colonPos = XMLString::indexOf(attLocalName, chColon);
-
-                if (colonPos != -1) {
+            //  enabled rules. It either has no colons, or it has one which
+            //  is neither the first or last char.
+            const int colonFirst = XMLString::indexOf(attNameRawBuf, chColon);
+            if (colonFirst != -1)
+            {
+                const int colonLast = XMLString::lastIndexOf(attNameRawBuf, chColon);
 
-                    curAttListSize = fAttrList->size();
+                if (colonFirst != colonLast)
+                {
                     emitError(XMLErrs::TooManyColonsInName);
                     continue;
                 }
+                else if ((colonFirst == 0)
+                      ||  (colonLast == (int)fAttNameBuf.getLen() - 1))
+                {
+                    emitError(XMLErrs::InvalidColonPos);
+                    continue;
+                }
+            }
+
+            // Map prefix to namespace
+            const XMLCh* attPrefix = curAtt->getPrefix();
+            const XMLCh* attLocalName = curAtt->getName();
+            const XMLCh* namespaceURI = fAttValueBuf.getRawBuffer();
 
+            if (attPrefix && *attPrefix) {
                 if (XMLString::equals(attPrefix, XMLUni::fgXMLString)) {
                     curAtt->setURIId(fXMLNamespaceId);
                 }
                 else if (XMLString::equals(attPrefix, XMLUni::fgXMLNSString)) {
 
+                    if (XMLString::equals(attLocalName, XMLUni::fgXMLNSString))
+                        emitError(XMLErrs::NoUseOfxmlnsAsPrefix);
+                    else if (XMLString::equals(attLocalName, XMLUni::fgXMLString)) {
+                        if (!XMLString::equals(namespaceURI, XMLUni::fgXMLURIName))
+                            emitError(XMLErrs::PrefixXMLNotMatchXMLURI);
+                    }
+
+                    if (!namespaceURI || !*namespaceURI)
+                        emitError(XMLErrs::NoEmptyStrNamespace, attNameRawBuf);
+
                     fElemStack.addPrefix
                     (
                         attLocalName
-                        , fURIStringPool->addOrFind(fAttValueBuf.getRawBuffer())
+                        , fURIStringPool->addOrFind(namespaceURI)
                     );
                     curAtt->setURIId(fXMLNSNamespaceId);
                 }
@@ -1348,10 +1371,15 @@ bool WFXMLScanner::scanStartTagNS(bool& gotData)
             else {
                 if (XMLString::equals(XMLUni::fgXMLNSString, attLocalName)) {
 
+                    if (XMLString::equals(namespaceURI, XMLUni::fgXMLNSURIName))
+                        emitError(XMLErrs::NoUseOfxmlnsURI);
+                    else if (XMLString::equals(namespaceURI, XMLUni::fgXMLURIName))
+                        emitError(XMLErrs::XMLURINotMatchXMLPrefix);
+
                     fElemStack.addPrefix
                     (
                         XMLUni::fgZeroLenString
-                        , fURIStringPool->addOrFind(fAttValueBuf.getRawBuffer())
+                        , fURIStringPool->addOrFind(namespaceURI)
                     );
                 }
             }
diff --git a/src/xercesc/internal/XMLScanner.cpp b/src/xercesc/internal/XMLScanner.cpp
index ae8878221a4e6ff7d2b21bd8128433f9008afbfe..b0a35c1d8943d6522abb94f6fb97cad8884ff2bf 100644
--- a/src/xercesc/internal/XMLScanner.cpp
+++ b/src/xercesc/internal/XMLScanner.cpp
@@ -308,6 +308,17 @@ void XMLScanner::scanDocument(  const   XMLCh* const    systemId)
         }
         else
         {
+            if (fStandardUriConformant && tmpURL.hasInvalidChar()) {
+                MalformedURLException e(__FILE__, __LINE__, XMLExcepts::URL_MalformedURL);
+                fInException = true;
+                emitError
+                (
+                    XMLErrs::XMLException_Fatal
+                    , e.getType()
+                    , e.getMessage()
+                );
+                return;
+            }
             srcToUse = new URLInputSource(tmpURL);
         }
 
@@ -414,6 +425,17 @@ bool XMLScanner::scanFirst( const   XMLCh* const    systemId
         }
         else
         {
+            if (fStandardUriConformant && tmpURL.hasInvalidChar()) {
+                MalformedURLException e(__FILE__, __LINE__, XMLExcepts::URL_MalformedURL);
+                fInException = true;
+                emitError
+                (
+                    XMLErrs::XMLException_Fatal
+                    , e.getType()
+                    , e.getMessage()
+                );
+                return false;
+            }
             srcToUse = new URLInputSource(tmpURL);
         }
     }
@@ -1535,6 +1557,17 @@ Grammar* XMLScanner::loadGrammar(const   XMLCh* const systemId
             }
             else
             {
+                if (fStandardUriConformant && tmpURL.hasInvalidChar()) {
+                    MalformedURLException e(__FILE__, __LINE__, XMLExcepts::URL_MalformedURL);
+                    fInException = true;
+                    emitError
+                    (
+                        XMLErrs::XMLException_Fatal
+                        , e.getType()
+                        , e.getMessage()
+                    );
+                    return 0;
+                }
                 srcToUse = new URLInputSource(tmpURL);
             }
         }
diff --git a/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp b/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp
index d0faeffc7419420092cfab4c0dd8be7f8b801376..a4a50072e9438c26f267259dd1a4f29364e2307b 100644
--- a/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/Win32/Win32PlatformUtils.cpp
@@ -260,6 +260,36 @@ FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
     if (!fileName)
         return 0;
 
+    //
+    //  We have to play a little trick here. If its /x:.....
+    //  style fully qualified path, we have to toss the leading /
+    //  character.
+    //
+    const XMLCh* nameToOpen = fileName;
+    if (*fileName == chForwardSlash)
+    {
+        if (XMLString::stringLen(fileName) > 3)
+        {
+            if (*(fileName + 2) == chColon)
+            {
+                const XMLCh chDrive = *(fileName + 1);
+                if (((chDrive >= chLatin_A) && (chDrive <= chLatin_Z))
+                ||  ((chDrive >= chLatin_a) && (chDrive <= chLatin_z)))
+                {
+                    nameToOpen = fileName + 1;
+                }
+            }
+
+            // Similarly for UNC paths
+            if ( *(fileName + 1) == *(fileName + 2) &&
+                 (*(fileName + 1) == chForwardSlash ||
+                  *(fileName + 1) == chBackSlash) )
+            {
+                nameToOpen = fileName + 1;
+            }
+        }
+    }
+
     //  Ok, this might look stupid but its a semi-expedient way to deal
     //  with a thorny problem. Shift-JIS and some other Asian encodings
     //  are fundamentally broken and map both the backslash and the Yen
@@ -279,9 +309,8 @@ FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
     //   transcode correctly back to 8 bit char * form.
     //
     XMLCh *tmpUName = 0;
-    const XMLCh *nameToOpen = fileName;
 
-    const XMLCh* srcPtr = fileName;
+    const XMLCh* srcPtr = nameToOpen;
     while (*srcPtr)
     {
         if (*srcPtr == chYenSign ||
@@ -296,7 +325,7 @@ FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
     //
     if (*srcPtr)
     {
-        tmpUName = XMLString::replicate(fileName);
+        tmpUName = XMLString::replicate(nameToOpen);
 
         XMLCh* tmpPtr = tmpUName;
         while (*tmpPtr)
diff --git a/src/xercesc/util/XMLURL.cpp b/src/xercesc/util/XMLURL.cpp
index 5e86fa03d7abb503f54a5d8841b67ed6af24885f..ebe13fab221ae734b7d1d27502efbce6c25c9826 100644
--- a/src/xercesc/util/XMLURL.cpp
+++ b/src/xercesc/util/XMLURL.cpp
@@ -72,6 +72,7 @@
 #include <xercesc/util/XMLString.hpp>
 #include <xercesc/util/XMLUniDefs.hpp>
 #include <xercesc/util/XMLUni.hpp>
+#include <xercesc/util/XMLUri.hpp>
 
 XERCES_CPP_NAMESPACE_BEGIN
 
@@ -191,6 +192,7 @@ XMLURL::XMLURL() :
     , fQuery(0)
     , fUser(0)
     , fURLText(0)
+    , fHasInvalidChar(false)
 {
 }
 
@@ -206,6 +208,7 @@ XMLURL::XMLURL(const XMLCh* const    baseURL
     , fQuery(0)
     , fUser(0)
     , fURLText(0)
+    , fHasInvalidChar(false)
 {
 	try
 	{
@@ -230,6 +233,7 @@ XMLURL::XMLURL(const XMLCh* const    baseURL
     , fQuery(0)
     , fUser(0)
     , fURLText(0)
+    , fHasInvalidChar(false)
 {
     XMLCh* tmpRel = XMLString::transcode(relativeURL);
     ArrayJanitor<XMLCh> janRel(tmpRel);
@@ -256,6 +260,7 @@ XMLURL::XMLURL(const XMLURL&         baseURL
     , fQuery(0)
     , fUser(0)
     , fURLText(0)
+    , fHasInvalidChar(false)
 {
 	try
 	{
@@ -280,6 +285,7 @@ XMLURL::XMLURL(const  XMLURL&        baseURL
     , fQuery(0)
     , fUser(0)
     , fURLText(0)
+    , fHasInvalidChar(false)
 {
     XMLCh* tmpRel = XMLString::transcode(relativeURL);
     ArrayJanitor<XMLCh> janRel(tmpRel);
@@ -306,6 +312,7 @@ XMLURL::XMLURL(const XMLCh* const urlText) :
     , fQuery(0)
     , fUser(0)
     , fURLText(0)
+    , fHasInvalidChar(false)
 {
 	try
 	{
@@ -329,6 +336,7 @@ XMLURL::XMLURL(const char* const urlText) :
     , fQuery(0)
     , fUser(0)
     , fURLText(0)
+    , fHasInvalidChar(false)
 {
     XMLCh* tmpText = XMLString::transcode(urlText);
     ArrayJanitor<XMLCh> janRel(tmpText);
@@ -354,6 +362,7 @@ XMLURL::XMLURL(const XMLURL& toCopy) :
     , fQuery(XMLString::replicate(toCopy.fQuery))
     , fUser(XMLString::replicate(toCopy.fUser))
     , fURLText(XMLString::replicate(toCopy.fURLText))
+    , fHasInvalidChar(toCopy.fHasInvalidChar)
 {
 }
 
@@ -503,6 +512,11 @@ bool XMLURL::isRelative() const
 }
 
 
+bool XMLURL::hasInvalidChar() const {
+    return fHasInvalidChar;
+}
+
+
 BinInputStream* XMLURL::makeNewStream() const
 {
     //
@@ -514,38 +528,10 @@ BinInputStream* XMLURL::makeNewStream() const
     {
         if (!fHost || !XMLString::compareIString(fHost, XMLUni::fgLocalHostString))
         {
-            //
-            //  We have to play a little trick here. If its really a Windows
-            //  style fully qualified path, we have to toss the leading /
-            //  character.
-            //
+
             XMLCh* realPath = XMLString::replicate(fPath);
             ArrayJanitor<XMLCh> basePathName(realPath);
 
-            if (*fPath == chForwardSlash)
-            {
-                if (XMLString::stringLen(fPath) > 3)
-                {
-                    if (*(fPath + 2) == chColon)
-                    {
-                        const XMLCh chDrive = *(fPath + 1);
-                        if (((chDrive >= chLatin_A) && (chDrive <= chLatin_Z))
-                        ||  ((chDrive >= chLatin_a) && (chDrive <= chLatin_z)))
-                        {
-                            realPath = fPath + 1;
-                        }
-                    }
-
-                    // Similarly for UNC paths
-                    if ( *(fPath + 1) == *(fPath + 2) &&
-                         (*(fPath + 1) == chForwardSlash ||
-                          *(fPath + 1) == chBackSlash) )
-                    {
-                        realPath = fPath + 1;
-                    }
-                }
-            }
-
             //
             // Need to manually replace any character reference %xx first
             // HTTP protocol will be done automatically by the netaccessor
@@ -835,8 +821,11 @@ bool XMLURL::conglomerateWithBase(const XMLURL& baseURL, bool useExceptions)
     }
 
     // Its a relative path, so weave them together.
-    if (baseURL.fPath)
-        weavePaths(baseURL.fPath);
+    if (baseURL.fPath) {
+        XMLCh* temp = XMLPlatformUtils::weavePaths(baseURL.fPath, fPath);
+        delete [] fPath;
+        fPath = temp;
+    }
 
     // If we had any original path, then we are done
     if (hadPath)
@@ -860,6 +849,12 @@ void XMLURL::parse(const XMLCh* const urlText)
     if (!*urlText)
         ThrowXML(MalformedURLException, XMLExcepts::URL_NoProtocolPresent);
 
+    // Before we start, check if this urlText contains valid uri characters
+    if (!XMLUri::isURIString(urlText))
+        fHasInvalidChar = true;
+    else
+        fHasInvalidChar = false;
+
     //
     //  The first thing we will do is to check for a file name, so that
     //  we don't waste time thinking its a URL. If its in the form x:\
@@ -988,17 +983,17 @@ void XMLURL::parse(const XMLCh* const urlText)
     }
     else
     {
-	    //
-	    // http protocol requires two forward slashes
-	    // we didn't get them, so throw an exception
-	    //
-	if (fProtocol == HTTP) {
-                ThrowXML
+        //
+        // http protocol requires two forward slashes
+        // we didn't get them, so throw an exception
+        //
+        if (fProtocol == HTTP) {
+            ThrowXML
                 (
                     MalformedURLException
                     , XMLExcepts::URL_ExpectingTwoSlashes
                 );
-	}
+        }
     }
 
     //
@@ -1136,117 +1131,5 @@ void XMLURL::parse(const XMLCh* const urlText)
 }
 
 
-void XMLURL::weavePaths(const XMLCh* const basePart)
-{
-    // Watch for stupid stuff
-    if (!basePart)
-        return;
-    if (!*basePart)
-        return;
-
-    //
-    //  Ok, lets start at the end of the base path and work backwards and
-    //  our path part and work forwards. For each leading . we see, we just
-    //  eat it. For each leading .. we see, we eat it and throw away one
-    //  level in the source URL.
-    //
-    //  If the last character in the base part is a forward slash, back
-    //  up one first before we look for the last slash.
-    //
-    const XMLCh* basePtr = basePart + (XMLString::stringLen(basePart) - 1);
-    if (*basePtr == chForwardSlash)
-        basePtr--;
-
-    while ((basePtr >= basePart)
-    &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-    {
-        basePtr--;
-    }
-
-    if (basePtr < basePart)
-        return;
-
-    // Create a buffer as large as both parts
-    XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(fPath)
-                              + XMLString::stringLen(basePart)
-                              + 2];
-    //
-    //  If we have no path part, then copy the base part up to the
-    //  base pointer
-    //
-    if (!fPath)
-    {
-        XMLCh* bufPtr = tmpBuf;
-        const XMLCh* tmpPtr = basePart;
-        while (tmpPtr <= basePtr)
-            *bufPtr++ = *tmpPtr++;
-        *bufPtr = 0;
-
-        fPath = tmpBuf;
-        return;
-    }
-
-    // After this, make sure the buffer gets handled if we exit early
-    ArrayJanitor<XMLCh> janBuf(tmpBuf);
-
-    //
-    //  We have some path part, so we need to check to see if we ahve to
-    //  weave any of the parts together.
-    //
-    XMLCh* pathPtr = fPath;
-    while (true)
-    {
-        // If it does not start with some period, then we are done
-        if (*pathPtr != chPeriod)
-            break;
-
-        unsigned int periodCount = 1;
-        pathPtr++;
-        if (*pathPtr == chPeriod)
-        {
-            pathPtr++;
-            periodCount++;
-        }
-
-        // Has to be followed by a / or \ or the null to mean anything
-        if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
-        &&  *pathPtr)
-        {
-            break;
-        }
-        if (*pathPtr)
-            pathPtr++;
-
-        // If its one period, just eat it, else move backwards in the base
-        if (periodCount == 2)
-        {
-            basePtr--;
-            while ((basePtr >= basePart)
-            &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
-            {
-                basePtr--;
-            }
-
-            // There are not enough levels to handle all the .. parts
-            if (basePtr < basePart)
-                ThrowXML(MalformedURLException, XMLExcepts::URL_BaseUnderflow);
-        }
-    }
-
-    // Copy the base part up to the base pointer
-    XMLCh* bufPtr = tmpBuf;
-    const XMLCh* tmpPtr = basePart;
-    while (tmpPtr <= basePtr)
-        *bufPtr++ = *tmpPtr++;
-
-    // And then copy on the rest of our path
-    XMLString::copyString(bufPtr, pathPtr);
-
-    // Now delete our path and make the new buffer our path
-    delete [] fPath;
-    janBuf.orphan();
-    fPath = tmpBuf;
-}
-
 XERCES_CPP_NAMESPACE_END
 
diff --git a/src/xercesc/util/XMLURL.hpp b/src/xercesc/util/XMLURL.hpp
index 13349b6485f5023b812b1cb9d93c1736f51fa2e4..f59b6824568f79006a845b3c7829d638394f844b 100644
--- a/src/xercesc/util/XMLURL.hpp
+++ b/src/xercesc/util/XMLURL.hpp
@@ -177,6 +177,7 @@ public:
     //  Miscellaneous methods
     // -----------------------------------------------------------------------
     bool isRelative() const;
+    bool hasInvalidChar() const;
     BinInputStream* makeNewStream() const;
     void makeRelativeTo(const XMLCh* const baseURLText);
     void makeRelativeTo(const XMLURL& baseURL);
@@ -193,7 +194,6 @@ private:
     (
         const   XMLCh* const    urlText
     );
-    void weavePaths(const XMLCh* const basePart);
 
 
     // -----------------------------------------------------------------------
@@ -231,6 +231,10 @@ private:
     //      This is a copy of the URL text, after it has been taken apart,
     //      made relative if needed, canonicalized, and then put back
     //      together. Its only created upon demand.
+    //
+    //  fHasInvalidChar
+    //      This indicates if the URL Text contains invalid characters as per
+    //      RFC 2396 standard.
     // -----------------------------------------------------------------------
     XMLCh*          fFragment;
     XMLCh*          fHost;
@@ -241,6 +245,7 @@ private:
     XMLCh*          fQuery;
     XMLCh*          fUser;
     XMLCh*          fURLText;
+    bool            fHasInvalidChar;
 };
 
 
diff --git a/src/xercesc/util/XMLUri.hpp b/src/xercesc/util/XMLUri.hpp
index 9197c732aa266a7226eb3485d2adcbd20f48216f..85b3f1f55ef8e3788c2cc49d4547b8c008281cae 100644
--- a/src/xercesc/util/XMLUri.hpp
+++ b/src/xercesc/util/XMLUri.hpp
@@ -57,6 +57,9 @@
 /*
  * $Id$
  * $Log$
+ * Revision 1.7  2003/01/06 19:43:18  tng
+ * New feature StandardUriConformant to force strict standard uri conformance.
+ *
  * Revision 1.6  2002/11/21 15:42:39  gareth
  * Implemented copy constructor and operator =. Patch by Jennifer Schachter.
  *
@@ -317,6 +320,16 @@ public:
     //  Miscellaneous methods
     // -----------------------------------------------------------------------
 
+    /**
+     * Determine whether a given string contains only URI characters (also
+     * called "uric" in RFC 2396). uric consist of all reserved
+     * characters, unreserved characters and escaped characters.
+     *
+     * @return true if the string is comprised of uric, false otherwise
+     */
+    static bool isURIString(const XMLCh* const uric);
+
+
 private:
 
     static const XMLCh RESERVED_CHARACTERS[];
@@ -360,16 +373,6 @@ private:
      * @return true if the scheme is conformant, false otherwise
      */
     static void isConformantUserInfo(const XMLCh* const userInfo);
-
-    /**
-     * Determine whether a given string contains only URI characters (also
-     * called "uric" in RFC 2396). uric consist of all reserved
-     * characters, unreserved characters and escaped characters.
-     *
-     * @return true if the string is comprised of uric, false otherwise
-     */
-    static bool isURIString(const XMLCh* const uric);
-
     /**
      * Determine whether a string is syntactically capable of representing
      * a valid IPv4 address or the domain name of a network host.
diff --git a/src/xercesc/validators/schema/TraverseSchema.cpp b/src/xercesc/validators/schema/TraverseSchema.cpp
index cefde516f9994a6cffe1c0d97d04048f24710414..fb4f4b9c00b9eb067cdefcf4491507491c2525d2 100644
--- a/src/xercesc/validators/schema/TraverseSchema.cpp
+++ b/src/xercesc/validators/schema/TraverseSchema.cpp
@@ -6130,8 +6130,11 @@ InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc) {
                 ThrowXML(MalformedURLException,
                          XMLExcepts::URL_NoProtocolPresent);
             }
-
-            srcToFill = new URLInputSource(urlTmp);
+            else {
+                if (fScanner->getStandardUriConformant() && urlTmp.hasInvalidChar())
+                    ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
+                srcToFill = new URLInputSource(urlTmp);
+            }
         }
         catch(const MalformedURLException& e) {
             // Its not a URL, so lets assume its a local file name if non-standard URI is allowed