/*
 * Copyright (C) 2014 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.squareup.okhttp;

import com.squareup.okhttp.internal.Util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * Fluent API to build <a href="http://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2.1">HTML
 * 2.0</a>-compliant form data.
 */
public final class FormEncodingBuilder {
  private static final MediaType CONTENT_TYPE
      = MediaType.parse("application/x-www-form-urlencoded");

  private final StringBuilder content = new StringBuilder();

  /** Add new key-value pair. */
  public FormEncodingBuilder add(String name, String value) {
    if (content.length() > 0) {
      content.append('&');
    }
    try {
      content.append(URLEncoder.encode(name, "UTF-8"))
          .append('=')
          .append(URLEncoder.encode(value, "UTF-8"));
    } catch (UnsupportedEncodingException e) {
      throw new AssertionError(e);
    }
    return this;
  }

  public RequestBody build() {
    if (content.length() == 0) {
      throw new IllegalStateException("Form encoded body must have at least one part.");
    }

    // Convert to bytes so RequestBody.create() doesn't add a charset to the content-type.
    byte[] contentBytes = content.toString().getBytes(Util.UTF_8);
    return RequestBody.create(CONTENT_TYPE, contentBytes);
  }
}

@@ -635,41 +635,27 @@
 ort 
-com.squareup.okhttp.internal.Util
+java.io.IOException
 ;%0Aim
@@ -724,16 +724,86 @@
 Encoder;
+%0Aimport okio.Buffer;%0Aimport okio.BufferedSink;%0Aimport okio.ByteString;
 %0A%0A/**%0A *
@@ -990,134 +990,18 @@
 ate 
-static final MediaType CONTENT_TYPE%0A      = MediaType.parse(%22application/x-www-form-urlencoded%22);%0A%0A  private final StringBuild
+final Buff
 er c
@@ -1017,19 +1017,12 @@
 new 
-StringBuild
+Buff
 er()
@@ -1135,22 +1135,20 @@
 content.
-length
+size
 () %3E 0) 
@@ -1163,22 +1163,25 @@
 content.
-append
+writeByte
 ('&');%0A 
@@ -1209,22 +1209,25 @@
 content.
-append
+writeUtf8
 (URLEnco
@@ -1256,49 +1256,63 @@
 8%22))
+;
 %0A      
-    .append
+content.writeByte
 ('=')
+;
 %0A      
-    .append
+content.writeUtf8
 (URL
@@ -1505,14 +1505,12 @@
 ent.
-length
+size
 () =
@@ -1615,225 +1615,686 @@
   %7D%0A
-%0A
     
-// Convert to bytes so RequestBody.create() doesn't add a charset to the content-type.%0A    byte%5B%5D contentBytes = content.toString().getBytes(Util.UTF_8);%0A    return RequestBody.create(CONTENT_TYPE, contentBytes);
+return new FormEncodingRequestBody(content.snapshot());%0A  %7D%0A%0A  private static final class FormEncodingRequestBody extends RequestBody %7B%0A    private static final MediaType CONTENT_TYPE =%0A        MediaType.parse(%22application/x-www-form-urlencoded%22);%0A%0A    private final ByteString snapshot;%0A%0A    public FormEncodingRequestBody(ByteString snapshot) %7B%0A      this.snapshot = snapshot;%0A    %7D%0A%0A    @Override public MediaType contentType() %7B%0A      return CONTENT_TYPE;%0A    %7D%0A%0A    @Override public long contentLength() throws IOException %7B%0A      return snapshot.size();%0A    %7D%0A%0A    @Override public void writeTo(BufferedSink sink) throws IOException %7B%0A      sink.write(snapshot);%0A    %7D
 %0A  %7D

Switch Form URL encoding builder and body to use Okio.