@NotNull
 public static IpnbFile parseIpnbFile(
     @NotNull final CharSequence fileText, @NotNull final VirtualFile virtualFile)
     throws IOException {
   final String path = virtualFile.getPath();
   IpnbFileRaw rawFile = gson.fromJson(fileText.toString(), IpnbFileRaw.class);
   if (rawFile == null) {
     int nbformat = isIpythonNewFormat(virtualFile) ? 4 : 3;
     return new IpnbFile(Collections.emptyMap(), nbformat, Lists.newArrayList(), path);
   }
   List<IpnbCell> cells = new ArrayList<IpnbCell>();
   final IpnbWorksheet[] worksheets = rawFile.worksheets;
   if (worksheets == null) {
     for (IpnbCellRaw rawCell : rawFile.cells) {
       cells.add(rawCell.createCell());
     }
   } else {
     for (IpnbWorksheet worksheet : worksheets) {
       final List<IpnbCellRaw> rawCells = worksheet.cells;
       for (IpnbCellRaw rawCell : rawCells) {
         cells.add(rawCell.createCell());
       }
     }
   }
   return new IpnbFile(rawFile.metadata, rawFile.nbformat, cells, path);
 }
 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;
 }