class GraphTypeAdapter extends WriteTypeAdapter<Graph> {

        private final TypeAdapter<Node> nodeTypeAdapter;
        private final TypeAdapter<Edge> edgeTypeAdapter;

        public GraphTypeAdapter(Gson gson) {
            nodeTypeAdapter = gson.getAdapter(Node.class);
            edgeTypeAdapter = gson.getAdapter(Edge.class);
        }

        @Override
        public void write(JsonWriter out, Graph graph) throws IOException {
            out.beginObject();

            // Attributes
            writeAttributes(out);

            // Options
            writeOptions(out, graph);

            // Nodes
            out.name("nodes");
            out.beginArray();
            for (Node node : graph.getNodes()) {
                if (!cancel) {
                    nodeTypeAdapter.write(out, node);
                }
            }
            out.endArray();

            // Edges
            out.name("edges");
            out.beginArray();
            for (Edge edge : graph.getEdges()) {
                if (!cancel) {
                    edgeTypeAdapter.write(out, edge);
                }
            }
            out.endArray();
            out.endObject();
        }

        protected void writeOptions(JsonWriter out, Graph graph) throws IOException {<FILL_FUNCTION_BODY>}

        protected void writeAttributes(JsonWriter out) throws IOException {
            if (exportMeta) {
                out.name("attributes");
                out.beginObject();
                out.name("creator");
                out.value(VersionUtils.getGephiVersion());
                if (exportDynamic) {
                    Configuration graphConfig = graph.getModel().getConfiguration();
                    TimeFormat timeFormat = graph.getModel().getTimeFormat();
                    out.name("timeformat");
                    out.value(timeFormat.toString().toLowerCase());
                    out.name("timerepresentation");
                    out.value(graphConfig.getTimeRepresentation().toString().toLowerCase());
                    out.name("timezone");
                    out.value(graph.getModel().getTimeZone().getID());
                }
                out.endObject();
            }
        }
    }

            out.name("options");
            out.beginObject();
            out.name("multi");
            out.value(graph.getModel().getEdgeTypeLabels(false).length > 1);
            out.name("allowSelfLoops");
            out.value(true);
            out.name("type");
            out.value(
                    graph.getModel().isUndirected() ? "undirected" : graph.getModel().isMixed() ? "mixed" : "directed");
            out.endObject();
        
<no_super_class>