/**
 * END USER LICENSE AGREEMENT (“EULA”)
 *
 * READ THIS AGREEMENT CAREFULLY (date: 9/13/2011):
 * http://www.akiban.com/licensing/20110913
 *
 * BY INSTALLING OR USING ALL OR ANY PORTION OF THE SOFTWARE, YOU ARE ACCEPTING
 * ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. YOU AGREE THAT THIS
 * AGREEMENT IS ENFORCEABLE LIKE ANY WRITTEN AGREEMENT SIGNED BY YOU.
 *
 * IF YOU HAVE PAID A LICENSE FEE FOR USE OF THE SOFTWARE AND DO NOT AGREE TO
 * THESE TERMS, YOU MAY RETURN THE SOFTWARE FOR A FULL REFUND PROVIDED YOU (A) DO
 * NOT USE THE SOFTWARE AND (B) RETURN THE SOFTWARE WITHIN THIRTY (30) DAYS OF
 * YOUR INITIAL PURCHASE.
 *
 * IF YOU WISH TO USE THE SOFTWARE AS AN EMPLOYEE, CONTRACTOR, OR AGENT OF A
 * CORPORATION, PARTNERSHIP OR SIMILAR ENTITY, THEN YOU MUST BE AUTHORIZED TO SIGN
 * FOR AND BIND THE ENTITY IN ORDER TO ACCEPT THE TERMS OF THIS AGREEMENT. THE
 * LICENSES GRANTED UNDER THIS AGREEMENT ARE EXPRESSLY CONDITIONED UPON ACCEPTANCE
 * BY SUCH AUTHORIZED PERSONNEL.
 *
 * IF YOU HAVE ENTERED INTO A SEPARATE WRITTEN LICENSE AGREEMENT WITH AKIBAN FOR
 * USE OF THE SOFTWARE, THE TERMS AND CONDITIONS OF SUCH OTHER AGREEMENT SHALL
 * PREVAIL OVER ANY CONFLICTING TERMS OR CONDITIONS IN THIS AGREEMENT.
 */

package com.akiban.server.explain.format;

import com.akiban.server.explain.*;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class JsonFormatter
{
    Gson gson;

    public JsonFormatter() {
        gson = new GsonBuilder().setPrettyPrinting().create();
    }

    public String format(Explainer explainer) {
        return gson.toJson(explainer);
    }
}

@@ -1307,41 +1307,222 @@
 ain.
-*;%0A%0Aimport com.google.gson.Gs
+CompoundExplainer;%0Aimport com.akiban.server.explain.Explainer;%0Aimport com.akiban.server.explain.PrimitiveExplainer;%0Aimport com.akiban.server.explain.Label;%0A%0Aimport com.akiban.server.error.AkibanInternalExcepti
 on;%0A
+%0A
 impo
@@ -1544,250 +1544,2001 @@
 son.
-GsonBuilder;%0A%0Apublic class JsonFormatter%0A%7B%0A    Gson gson;%0A%0A    public JsonFormatter() %7B%0A        gson = new GsonBuilder().setPrettyPrinting().create();%0A    %7D%0A%0A    public String format(Explainer explainer) %7B%0A        return gson.toJson(explainer
+stream.JsonWriter;%0A%0Aimport java.util.List;%0Aimport java.util.Map;%0Aimport java.io.IOException;%0Aimport java.io.StringWriter;%0A%0Apublic class JsonFormatter%0A%7B%0A    public String format(Explainer explainer) %7B%0A        StringWriter str = new StringWriter();%0A        JsonWriter writer = new JsonWriter(str);%0A        if (true) %7B%0A            writer.setIndent(%22  %22); // Pretty print%0A        %7D%0A        try %7B%0A            write(writer, explainer);%0A        %7D%0A        catch (IOException ex) %7B%0A            throw new AkibanInternalException(%22Error writing to string%22, ex);%0A        %7D%0A        return str.toString();%0A    %7D%0A%0A    public void write(JsonWriter writer, Explainer explainer) throws IOException %7B%0A        switch (explainer.getType().generalType()) %7B%0A        case SCALAR_VALUE:%0A            writePrimitive(writer, (PrimitiveExplainer)explainer);%0A            break;%0A        default:%0A            writeCompound(writer, (CompoundExplainer)explainer);%0A            break;%0A        %7D%0A    %7D%0A%0A    protected void writePrimitive(JsonWriter writer, PrimitiveExplainer explainer) throws IOException %7B%0A        switch (explainer.getType()) %7B%0A        case STRING:%0A            writer.value((String)explainer.get());%0A            break;%0A        case EXACT_NUMERIC:%0A        case FLOATING_POINT:%0A            writer.value((Number)explainer.get());%0A            break;%0A        default:%0A            writer.value(explainer.get().toString());%0A        %7D%0A    %7D%0A%0A    protected void writeCompound(JsonWriter writer, CompoundExplainer explainer) throws IOException %7B%0A        writer.beginObject();%0A        writer.name(%22type%22);%0A        writer.value(explainer.getType().name().toLowerCase());%0A        for (Map.Entry%3CLabel, List%3CExplainer%3E%3E entry : explainer.get().entrySet()) %7B%0A            writer.name(entry.getKey().name().toLowerCase());%0A            writer.beginArray();%0A            for (Explainer child : entry.getValue()) %7B%0A                write(writer, child);%0A            %7D%0A            writer.endArray();%0A        %7D%0A        writer.endObject(
 );%0A 

Simplify and make formatting nicer.