public IpnbCell createCell() {
   final IpnbCell cell;
   if (cell_type.equals("markdown")) {
     cell = new IpnbMarkdownCell(source, metadata);
   } else if (cell_type.equals("code")) {
     final List<IpnbOutputCell> outputCells = new ArrayList<IpnbOutputCell>();
     for (CellOutputRaw outputRaw : outputs) {
       outputCells.add(outputRaw.createOutput());
     }
     final Integer prompt = prompt_number != null ? prompt_number : execution_count;
     cell =
         new IpnbCodeCell(
             language == null ? "python" : language,
             input == null ? source : input,
             prompt,
             outputCells,
             metadata);
   } else if (cell_type.equals("raw")) {
     cell = new IpnbRawCell(source);
   } else if (cell_type.equals("heading")) {
     cell = new IpnbHeadingCell(source, level, metadata);
   } else {
     cell = null;
   }
   return cell;
 }
 public static IpnbCellRaw fromCell(@NotNull final IpnbCell cell, int nbformat) {
   final IpnbCellRaw raw = new IpnbCellRaw();
   if (cell instanceof IpnbEditableCell) {
     raw.metadata = ((IpnbEditableCell) cell).getMetadata();
   }
   if (cell instanceof IpnbMarkdownCell) {
     raw.cell_type = "markdown";
     raw.source = ((IpnbMarkdownCell) cell).getSource();
   } else if (cell instanceof IpnbCodeCell) {
     raw.cell_type = "code";
     final ArrayList<CellOutputRaw> outputRaws = new ArrayList<CellOutputRaw>();
     for (IpnbOutputCell outputCell : ((IpnbCodeCell) cell).getCellOutputs()) {
       outputRaws.add(CellOutputRaw.fromOutput(outputCell, nbformat));
     }
     raw.outputs = outputRaws;
     final Integer promptNumber = ((IpnbCodeCell) cell).getPromptNumber();
     if (nbformat == 4) {
       raw.execution_count = promptNumber != null && promptNumber >= 0 ? promptNumber : null;
       raw.source = ((IpnbCodeCell) cell).getSource();
     } else {
       raw.prompt_number = promptNumber != null && promptNumber >= 0 ? promptNumber : null;
       raw.language = ((IpnbCodeCell) cell).getLanguage();
       raw.input = ((IpnbCodeCell) cell).getSource();
     }
   } else if (cell instanceof IpnbRawCell) {
     raw.cell_type = "raw";
     raw.source = ((IpnbRawCell) cell).getSource();
   } else if (cell instanceof IpnbHeadingCell) {
     raw.cell_type = "heading";
     raw.source = ((IpnbHeadingCell) cell).getSource();
     raw.level = ((IpnbHeadingCell) cell).getLevel();
   }
   return raw;
 }
    @Override
    public CellOutputRaw deserialize(
        JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {
      final JsonObject object = json.getAsJsonObject();
      final CellOutputRaw cellOutputRaw = new CellOutputRaw();
      final JsonElement ename = object.get("ename");
      if (ename != null) {
        cellOutputRaw.ename = ename.getAsString();
      }
      final JsonElement name = object.get("name");
      if (name != null) {
        cellOutputRaw.name = name.getAsString();
      }
      final JsonElement evalue = object.get("evalue");
      if (evalue != null) {
        cellOutputRaw.evalue = evalue.getAsString();
      }
      final JsonElement data = object.get("data");
      if (data != null) {
        cellOutputRaw.data = gson.fromJson(data, OutputDataRaw.class);
      }

      final JsonElement count = object.get("execution_count");
      if (count != null) {
        cellOutputRaw.execution_count = count.getAsInt();
      }
      final JsonElement outputType = object.get("output_type");
      if (outputType != null) {
        cellOutputRaw.output_type = outputType.getAsString();
      }
      final JsonElement png = object.get("png");
      if (png != null) {
        cellOutputRaw.png = png.getAsString();
      }
      final JsonElement stream = object.get("stream");
      if (stream != null) {
        cellOutputRaw.stream = stream.getAsString();
      }
      final JsonElement jpeg = object.get("jpeg");
      if (jpeg != null) {
        cellOutputRaw.jpeg = jpeg.getAsString();
      }

      cellOutputRaw.html = getStringOrArray("html", object);
      cellOutputRaw.latex = getStringOrArray("latex", object);
      cellOutputRaw.svg = getStringOrArray("svg", object);
      final JsonElement promptNumber = object.get("prompt_number");
      if (promptNumber != null) {
        cellOutputRaw.prompt_number = promptNumber.getAsInt();
      }
      cellOutputRaw.text = getStringOrArray("text", object);
      cellOutputRaw.traceback = getStringOrArray("traceback", object);
      final JsonElement metadata = object.get("metadata");
      if (metadata != null) {
        cellOutputRaw.metadata = gson.fromJson(metadata, Map.class);
      }

      return cellOutputRaw;
    }
    public static CellOutputRaw fromOutput(@NotNull final IpnbOutputCell outputCell, int nbformat) {
      final CellOutputRaw raw = new CellOutputRaw();
      raw.metadata = outputCell.getMetadata();
      if (raw.metadata == null
          && !(outputCell instanceof IpnbStreamOutputCell)
          && !(outputCell instanceof IpnbErrorOutputCell)) {
        raw.metadata = Collections.emptyMap();
      }

      if (outputCell instanceof IpnbPngOutputCell) {
        if (nbformat == 4) {
          final OutputDataRaw dataRaw = new OutputDataRaw();
          dataRaw.png = ((IpnbPngOutputCell) outputCell).getBase64String();
          dataRaw.text = outputCell.getText();
          raw.data = dataRaw;
          raw.execution_count = outputCell.getPromptNumber();
          raw.output_type =
              outputCell.getPromptNumber() != null ? "execute_result" : "display_data";
        } else {
          raw.png = ((IpnbPngOutputCell) outputCell).getBase64String();
          raw.text = outputCell.getText();
        }
      } else if (outputCell instanceof IpnbSvgOutputCell) {
        if (nbformat == 4) {
          final OutputDataRaw dataRaw = new OutputDataRaw();
          dataRaw.text = outputCell.getText();
          dataRaw.svg = ((IpnbSvgOutputCell) outputCell).getSvg();
          raw.data = dataRaw;
          raw.execution_count = outputCell.getPromptNumber();
          raw.output_type =
              outputCell.getPromptNumber() != null ? "execute_result" : "display_data";
        } else {
          raw.svg = ((IpnbSvgOutputCell) outputCell).getSvg();
          raw.text = outputCell.getText();
        }
      } else if (outputCell instanceof IpnbJpegOutputCell) {
        if (nbformat == 4) {
          final OutputDataRaw dataRaw = new OutputDataRaw();
          dataRaw.text = outputCell.getText();
          dataRaw.jpeg = Lists.newArrayList(((IpnbJpegOutputCell) outputCell).getBase64String());
          raw.data = dataRaw;
        } else {
          raw.jpeg = ((IpnbJpegOutputCell) outputCell).getBase64String();
          raw.text = outputCell.getText();
        }
      } else if (outputCell instanceof IpnbLatexOutputCell) {
        if (nbformat == 4) {
          final OutputDataRaw dataRaw = new OutputDataRaw();
          dataRaw.text = outputCell.getText();
          dataRaw.latex = ((IpnbLatexOutputCell) outputCell).getLatex();
          raw.data = dataRaw;
          raw.execution_count = outputCell.getPromptNumber();
          raw.output_type = "execute_result";
        } else {
          raw.latex = ((IpnbLatexOutputCell) outputCell).getLatex();
          raw.text = outputCell.getText();
          raw.prompt_number = outputCell.getPromptNumber();
        }
      } else if (outputCell instanceof IpnbStreamOutputCell) {
        if (nbformat == 4) {
          raw.name = ((IpnbStreamOutputCell) outputCell).getStream();
        } else {
          raw.stream = ((IpnbStreamOutputCell) outputCell).getStream();
        }
        raw.text = outputCell.getText();
        raw.output_type = "stream";
      } else if (outputCell instanceof IpnbHtmlOutputCell) {
        if (nbformat == 4) {
          final OutputDataRaw dataRaw = new OutputDataRaw();
          dataRaw.html = ((IpnbHtmlOutputCell) outputCell).getHtmls();
          dataRaw.text = outputCell.getText();
          raw.data = dataRaw;
          raw.execution_count = outputCell.getPromptNumber();
        } else {
          raw.html = ((IpnbHtmlOutputCell) outputCell).getHtmls();
        }
        raw.output_type = nbformat == 4 ? "execute_result" : "pyout";
      } else if (outputCell instanceof IpnbErrorOutputCell) {
        raw.output_type = nbformat == 4 ? "error" : "pyerr";
        raw.evalue = ((IpnbErrorOutputCell) outputCell).getEvalue();
        raw.ename = ((IpnbErrorOutputCell) outputCell).getEname();
        raw.traceback = outputCell.getText();
      } else if (outputCell instanceof IpnbOutOutputCell) {
        if (nbformat == 4) {
          raw.execution_count = outputCell.getPromptNumber();
          raw.output_type = "execute_result";
          final OutputDataRaw dataRaw = new OutputDataRaw();
          dataRaw.text = outputCell.getText();
          raw.data = dataRaw;
        } else {
          raw.output_type = "pyout";
          raw.prompt_number = outputCell.getPromptNumber();
          raw.text = outputCell.getText();
        }
      } else {
        raw.text = outputCell.getText();
      }
      return raw;
    }