public static Source resolveURI(String href, String baseURI, String documentKey, Controller controller)
            throws XPathException {
        URIResolver resolver = controller.getURIResolver();
        Source source;

        try {
            if (resolver instanceof RelativeURIResolver && documentKey != null) {
                source = ((RelativeURIResolver)resolver).dereference(documentKey);
            } else {
                source = resolver.resolve(href, baseURI);
            }
        } catch (Exception ex) {
            XPathException de = new XPathException("Exception thrown by URIResolver", ex);
            if (controller.getConfiguration().isTraceExternalFunctions()) {
                ex.printStackTrace();
            }
            throw de;
        }

        // if a user URI resolver returns null, try the standard one
        // (Note, the standard URI resolver never returns null)
        if (source==null && !(resolver instanceof NonDelegatingURIResolver)) {
            resolver = controller.getStandardURIResolver();
            try {
                if (resolver instanceof RelativeURIResolver && documentKey != null) {
                    source = ((RelativeURIResolver)resolver).dereference(documentKey);
                } else {
                    source = resolver.resolve(href, baseURI);
                }
            } catch (TransformerException ex) {
                throw XPathException.makeXPathException(ex);
            }
        }
        return source;

    }