ExternalEntityRefHandlerImpl(XMLParser *parser,
                                     char *context,
                                     char *baseUri,
                                     char *systemId,
                                     char *publicId)
        {
            int result = (int)XMLStatus.OK;

            GCHandle parserHandle = (GCHandle)LibExpat.XMLGetUserData(parser);
            X        expatParser  = (X)parserHandle.Target;

            E      newEntityContext = expatParser.freeEntityContext; // should always be != null
            string encoding;

            try {
                if (!newEntityContext.Open(context, baseUri, systemId, publicId, out encoding))
                {
                    return(result);
                }
            }
            catch (Exception e) {
                expatParser.error = e;
                result            = (int)XMLStatus.ERROR;
                return(result);
            }

            expatParser.PushChildEntityParseContext(parser, context, encoding);

            ParseStatus status = ExpatUtils.Parse(
                newEntityContext.XmlParser, newEntityContext.Read, out newEntityContext.error);

            switch (status)
            {
            case ParseStatus.Finished:
                expatParser.PopChildEntityParseContext();
                break;

            case ParseStatus.Suspended:
                // must suspend parent parser as well - don't check return value
                LibExpat.XMLStopParser(parser, XMLBool.TRUE);
                break;

            case ParseStatus.FatalError:
                result = (int)XMLStatus.ERROR;
                break;

            case ParseStatus.Aborted:
                // must abort parent parser as well - don't check return value
                LibExpat.XMLStopParser(parser, XMLBool.FALSE);
                break;
            }
            return(result);
        }