private void pushURL(boolean isPE, String ename, ExternalIdentifiers ids,
            Reader aReader, InputStream aStream, String aEncoding,
            boolean doResolve) throws SAXException, IOException {
        // removed boolean ignoreEncoding -- 2006-02-03 hsivonen
        String systemId;
        InputSource source;
        InputSource scratch = new InputSource();

        if (!isPE) {
            dataBufferFlush();
        }

        scratch.setPublicId(ids.publicId);
        scratch.setSystemId(ids.systemId);

        // See if we should skip or substitute the entity.
        // If we're not skipping, resolving reports startEntity()
        // and updates the (handler's) stack of URIs.
        if (doResolve) {
            // assert (stream == null && reader == null && encoding == null)
            source = handler.resolveEntity(isPE, ename, scratch, ids.baseUri);
            if (source == null) {
                handler.skippedEntity(ename);
                if (isPE) {
                    skippedPE = true;
                }
                return;
            }

            // we might be using alternate IDs/encoding
            systemId = source.getSystemId();
            // The following warning and setting systemId was deleted bcause
            // the application has the option of not setting systemId
            // provided that it has set the characte/byte stream.
            /*
             * if (systemId == null) { handler.warn ("missing system ID, using " +
             * ids.systemId); systemId = ids.systemId; }
             */
        } else {
            // "[document]", or "[dtd]" via getExternalSubset()
            scratch.setCharacterStream(aReader);
            scratch.setByteStream(aStream);
            scratch.setEncoding(aEncoding);
            source = scratch;
            systemId = ids.systemId;
            if (handler.stringInterning) {
                handler.startExternalEntity(ename, systemId,
                        "[document]" == ename);
            } else {
                handler.startExternalEntity(ename, systemId,
                        "[document]".equals(ename));
            }
        }

        // Push the existing status.
        pushInput(ename);

        // Create a new read buffer.
        // (Note the four-character margin)
        readBuffer = new char[READ_BUFFER_MAX + 4];
        readBufferPos = 0;
        readBufferLength = 0;
        readBufferOverflow = -1;
        is = null;
        reader = null;
        line = 0;
        column = 1;
        linePrev = 0;
        columnPrev = 1;
        nextCharOnNewLine = true;
        currentByteCount = 0;

        // If there's an explicit character stream, just
        // ignore encoding declarations.
        if (source.getCharacterStream() != null) {
            sourceType = INPUT_READER;
            this.reader = source.getCharacterStream();
            // swallow UTF-8 BOM -- 2006-02-03 hsivonen
            if ("UTF-8".equalsIgnoreCase(source.getEncoding())) {
                char bom = readCh();
                if (bom != '\uFEFF') {
                    unread(bom);
                }
            }
            tryEncodingDecl(source.getEncoding() == null ? ""
                    : source.getEncoding());
            return;
        }

        // Else we handle the conversion, and need to ensure
        // it's done right.
        if (source.getByteStream() != null) {
            is = source.getByteStream();
        } else {
            // Stop -- 2006-11-10 hsivonen
            fatal("The entity resolver didn't properly resolve the entity.");
        }

        // If we get to here, there must be
        // an InputStream available.
        if (!is.markSupported()) {
            is = new BufferedInputStream(is);
        }

        // Zapped bogus external encoding label code -- 2006-11-10 hsivonen

        // if we got an external encoding label, use it ...
        if (source.getEncoding() != null) {
            draconianInputStreamReader(source.getEncoding(), is, false);
            if ("UTF-8".equalsIgnoreCase(source.getEncoding())) {
                char bom = readCh();
                if (bom != '\uFEFF') {
                    unread(bom);
                }
            }
            tryEncodingDecl(source.getEncoding());
            // ... else autodetect from first bytes.
        } else {
            detectEncoding();
            // Read any XML or text declaration.
            String enc = tryEncodingDecl(null);
            if ((enc == null) && ("UTF-32" == characterEncoding)) {
                fatal("UTF-32 was sniffed from the BOM, but there was no matching encoding declaration. The omission of explicit encoding declaration is only allowed with UTF-8 and UTF-16.");
            }
        }
    }
Push, or skip, a new external input source. The source will be some kind
of parsed entity, such as a PE (including the external DTD subset) or
content for the body.

@param url
           The java.net.URL object for the entity.
@see SAXDriver#resolveEntity
@see #pushString
@see #sourceType
@see #pushInput
@see #detectEncoding
@see #sourceType
@see #readBuffer
src/nu/validator/gnu/xml/aelfred2/XmlParser.java