/**
   * Appends the index source map to the given buffer.
   *
   * @param out The stream to which the map will be appended.
   * @param name The name of the generated source file that this source map represents.
   * @param sections An ordered list of map sections to include in the index.
   * @throws IOException
   */
  @Override
  public void appendIndexMapTo(Appendable out, String name, List<SourceMapSection> sections)
      throws IOException {
    // Add the header fields.
    out.append("{\n");
    appendFirstField(out, "version", "3");
    appendField(out, "file", escapeString(name));

    // Add the line character maps.
    appendFieldStart(out, "sections");
    out.append("[\n");
    boolean first = true;
    for (SourceMapSection section : sections) {
      if (first) {
        first = false;
      } else {
        out.append(",\n");
      }
      out.append("{\n");
      appendFirstField(out, "offset", offsetValue(section.getLine(), section.getColumn()));
      if (section.getSectionType() == SourceMapSection.SectionType.URL) {
        appendField(out, "url", escapeString(section.getSectionValue()));
      } else if (section.getSectionType() == SourceMapSection.SectionType.MAP) {
        appendField(out, "map", section.getSectionValue());
      } else {
        throw new IOException("Unexpected section type");
      }
      out.append("\n}");
    }

    out.append("\n]");
    appendFieldEnd(out);

    out.append("\n}\n");
  }