private void dump(OutputStream outputStream, EncodingRule encodingRule, boolean use3ByteBOMifUTF8)
      throws CoreException, IOException {
    getCurrentEncodingMemento();
    String javaEncodingName = null;
    if (encodingRule == EncodingRule.CONTENT_BASED) {
      if (fCurrentEncodingMemento.isValid()) {
        javaEncodingName = fCurrentEncodingMemento.getJavaCharsetName();
      } else {
        throw new UnsupportedCharsetExceptionWithDetail(fCurrentEncodingMemento);
      }
    } else if (encodingRule == EncodingRule.IGNORE_CONVERSION_ERROR)
      javaEncodingName = fCurrentEncodingMemento.getJavaCharsetName();
    else if (encodingRule == EncodingRule.FORCE_DEFAULT)
      javaEncodingName = fCurrentEncodingMemento.getAppropriateDefault();
    // write appropriate "header" unicode BOM bytes
    // Note: Java seems to write appropriate header for
    // UTF-16, but not
    // UTF-8 nor UTF-16BE. This
    // may vary by JRE version, so need to test well.
    // Note: javaEncodingName can be null in invalid
    // cases, so we no hard
    // to skip whole check if that's the case.
    if (javaEncodingName != null) {
      if ((javaEncodingName.equals(UTF_8_CHARSET_NAME) && use3ByteBOMifUTF8)
          || (javaEncodingName.equals(UTF_8_CHARSET_NAME)
              && fCurrentEncodingMemento.isUTF83ByteBOMUsed())) {
        outputStream.write(UTF3BYTEBOM);
      } else if (javaEncodingName.equals(UTF_16LE_CHARSET_NAME)) {
        outputStream.write(UTF16LEBOM);
      } else if (javaEncodingName.equals(UTF_16BE_CHARSET_NAME)) {
        outputStream.write(UTF16BEBOM);
      }
    }
    // TODO add back in line delimiter handling the
    // "right" way (updating
    // markers, not requiring string, etc. .. may need
    // to move to document
    // level)
    // allTextBuffer =
    // handleLineDelimiter(allTextBuffer, document);
    Reader reader = getResettableReader();
    // be sure to test large "readers" ... we'll need
    // to make sure they all
    // can reset to initial position (StringReader,
    // CharArrayReader, and
    // DocumentReader should all work ok).
    reader.reset();
    // There must be cleaner logic somehow, but the
    // idea is that
    // javaEncodingName can be null
    // if original detected encoding is not valid (and
    // if FORCE_DEFAULT was
    // not specified). Hence, we WANT the first
    // Charset.forName to
    // throw appropriate exception.
    Charset charset = null;

    // this call checks "override" properties file
    javaEncodingName = CodedIO.getAppropriateJavaCharset(javaEncodingName);

    if (javaEncodingName == null) {
      charset = Charset.forName(fCurrentEncodingMemento.getDetectedCharsetName());
    } else {
      charset = Charset.forName(javaEncodingName);
    }
    CharsetEncoder charsetEncoder = charset.newEncoder();
    if (!(encodingRule == EncodingRule.IGNORE_CONVERSION_ERROR)) {
      charsetEncoder.onMalformedInput(CodingErrorAction.REPORT);
      charsetEncoder.onUnmappableCharacter(CodingErrorAction.REPORT);
    } else {
      charsetEncoder.onMalformedInput(CodingErrorAction.REPLACE);
      charsetEncoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
    }
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, charsetEncoder);
    // TODO: this may no longer be needed (and is at
    // least wrong spot for
    // it).
    //		if (checkConversion && (!(encodingRule ==
    // EncodingRule.IGNORE_CONVERSION_ERROR))) {
    //			checkConversion(fCurrentEncodingMemento,
    // encodingRule);
    //		}
    char[] charbuf = new char[CodedIO.MAX_BUF_SIZE];
    int nRead = 0;
    try {
      while (nRead != -1) {
        nRead = reader.read(charbuf, 0, MAX_BUF_SIZE);
        if (nRead > 0) {
          outputStreamWriter.flush();
          outputStreamWriter.write(charbuf, 0, nRead);
        }
      }
    } catch (UnmappableCharacterException e) {
      checkConversion(fCurrentEncodingMemento, encodingRule);
    } finally {
      // since we don't own the original output stream, we
      // won't close it ours.
      // the caller who passed it to us must close original one
      // when appropriate.
      // (but we do flush to be sure all up-to-date)
      outputStreamWriter.flush();
    }
  }