docs: public static void encode (char[] string, int offset, int length,
                                   boolean encodeNewline,
                                   boolean encodeSubsequentBlanksToNbsp,
                                   boolean encodeNonLatin, Writer writer) throws IOException
      {
          if (string == null || length < 0 || offset >= string.length)
          {
              return;
          }
          offset = Math.max(0, offset);
          int realLength = Math.min(length, string.length - offset);
  
          //StringBuilder sb = null;    //create later on demand
          String app;
          char c = ' ';
          char prevC;
          int start = offset;
          
          for (int i = offset; i < offset + realLength; ++i)
          {
              app = null;
              prevC = c;
              c = string[i];
  
              // All characters before letters
              if ((int)c < 0x41)
              {
                  switch (c)
                  {
                      case '"': app = "&quot;"; break;    //"
                      case '&': app = "&amp;"; break;     //&
                      case '<': app = "&lt;"; break;      //<
                      case '>': app = "&gt;"; break;      //>
                      case ' ':
                          if (encodeSubsequentBlanksToNbsp &&
                                  prevC == ' ')
                          {
                              //Space at beginning or after another space
                              app = "&#160;";
                          }
                          break;
                      case '\n':
                          if (encodeNewline)
                          {
                              app = "<br/>";
                          }
                          break;
                      default:
                          break;
                  }
                  // http://www.w3.org/MarkUp/html3/specialchars.html
                  // From C0 extension U+0000-U+001F only U+0009, U+000A and
                  // U+000D are valid control characters
                  if (c <= 0x1F && c != 0x09 && c != 0x0A && c != 0x0D)
                  {
                      // Ignore escape character
                      app = "";
                  }
              }
              else if (encodeNonLatin && (int)c > 0x80)
              {
                   switch(c)
                   {
                      //german umlauts
                      case '\u00E4' : app = "&auml;";  break;
                      case '\u00C4' : app = "&Auml;";  break;
                      case '\u00F6' : app = "&ouml;";  break;
                      case '\u00D6' : app = "&Ouml;";  break;
                      case '\u00FC' : app = "&uuml;";  break;
                      case '\u00DC' : app = "&Uuml;";  break;
                      case '\u00DF' : app = "&szlig;"; break;
  
                      //misc
                      //case 0x80: app = "&euro;"; break;  sometimes euro symbol is ascii 128, should we suport it?
                      case '\u20AC': app = "&euro;";  break;
                      case '\u00AB': app = "&laquo;"; break;
                      case '\u00BB': app = "&raquo;"; break;
                      case '\u00A0': app = "&#160;"; break;
  
                      default :
                          //encode all non basic latin characters
                          app = "&#" + ((int)c) + ";";
                      break;
                  }
              }
              if (app != null)
              {
                  //if (sb == null)
                  //{
                  //    sb = new StringBuilder(realLength*2);
                  //    sb.append(string, offset, i - offset);
                  //}
                  //sb.append(app);
                  if (start < i)
                  {
                      writer.write(string, start, i-start);
                  }
                  start = i+1;
                  writer.write(app);
              }
              /*
              else
              {
                  if (sb != null)
                  {
                      sb.append(c);
                  }
              }*/
          }
  
          //if (sb == null)
          //{
          //    writer.write(string, offset, realLength);
          //}
          //else
          //{
          //    writer.write(sb.toString());
          //}
          if (start == offset)
          {
              writer.write(string, offset, realLength);
          }
          else if (start < offset+realLength)
          {
              writer.write(string,start,offset+realLength-start);
          }
      }