private void writeString(Object object) throws IOException {
    out.write("\"");

    String str = object.toString();
    if (str == null) {
      throw new IllegalArgumentException("Non-null object of type '"
          + object.getClass() + "' returned 'null' toString() representation");
    }

    int sz = str.length();

    for (int i = 0; i < sz; i++) {
      char ch = str.charAt(i);

      // handle unicode
      if (ch > 0xfff) {
        out.write("\\u" + hex(ch));
      } else if (ch > 0xff) {
        out.write("\\u0" + hex(ch));
      } else if (ch > 0x7f) {
        out.write("\\u00" + hex(ch));
      } else if (ch < 32) {
        switch (ch) {
          case '\b':
            out.write('\\');
            out.write('b');
            break;
          case '\n':
            out.write('\\');
            out.write('n');
            break;
          case '\t':
            out.write('\\');
            out.write('t');
            break;
          case '\f':
            out.write('\\');
            out.write('f');
            break;
          case '\r':
            out.write('\\');
            out.write('r');
            break;
          default:
            if (ch > 0xf) {
              out.write("\\u00" + hex(ch));
            } else {
              out.write("\\u000" + hex(ch));
            }
            break;
        }
      } else {
        switch (ch) {
          case '"':
            out.write('\\');
            out.write('"');
            break;
          case '\\':
            out.write('\\');
            out.write('\\');
            break;
          case '/':
            out.write('\\');
            out.write('/');
            break;
          default:
            out.write(ch);
            break;
        }
      }
    }

    out.write("\"");
  }
Note: The {@link #writeString} and {@link #hex} methods
are based on code from class {@code StringEscapeUtils} in Commons Lang 2.6.
spock-core/src/main/java/org/spockframework/util/JsonWriter.java