public static String decodeXmlString(XmlDoctype doctype, String input, boolean peReferenceAllowedP) {
    { int inputEnd = (peReferenceAllowedP ? (input.length() - 1) : ((int)(Stella.NULL_INTEGER)));
      int referenceStart = (peReferenceAllowedP ? Stella.findReferenceStart(input, 0, inputEnd) : Native.string_position(input, '&', 0));
      String substitution = null;

      if (referenceStart == Stella.NULL_INTEGER) {
        return (input);
      }
      else {
        { OutputStringStream buffer = OutputStringStream.newOutputStringStream();
          int referenceEnd = 0;

          if (!(peReferenceAllowedP)) {
            inputEnd = input.length() - 1;
          }
          while (referenceStart != Stella.NULL_INTEGER) {
            buffer.nativeStream.print(Native.string_subsequence(input, referenceEnd, referenceStart));
            referenceEnd = Native.string_position(input, ';', referenceStart);
            if (!(referenceEnd != Stella.NULL_INTEGER)) {
              System.err.print("Safety violation: Unterminated XML reference");
            }
            referenceEnd = referenceEnd + 1;
            substitution = XmlDoctype.decodeXmlReference(doctype, Native.string_subsequence(input, referenceStart, referenceEnd), peReferenceAllowedP);
            if (substitution == null) {
              { OutputStringStream stream000 = OutputStringStream.newOutputStringStream();

                stream000.nativeStream.print("Unrecognized entity reference: `" + Native.string_subsequence(input, referenceStart, referenceEnd) + "'");
                throw ((BadArgumentException)(BadArgumentException.newBadArgumentException(stream000.theStringReader()).fillInStackTrace()));
              }
            }
            else {
              buffer.nativeStream.print(substitution);
            }
            referenceStart = (peReferenceAllowedP ? Stella.findReferenceStart(input, referenceEnd, inputEnd) : Native.string_position(input, '&', referenceEnd));
          }
          if (!(referenceEnd == inputEnd)) {
            buffer.nativeStream.print(Native.string_subsequence(input, referenceEnd, Stella.NULL_INTEGER));
          }
          return (buffer.theStringReader());
        }
      }
    }
  }