JSObject *create(JSContext *cx, HandleObject self, Mode mode, HandleObject owner,
                 HandleObject init_headers) {
  RootedObject headers(cx, create(cx, self, mode, owner));
  if (!headers) {
    return nullptr;
  }

  if (!init_headers) {
    return headers;
  }

  if (!delazify(cx, init_headers)) {
    return nullptr;
  }

  RootedObject headers_map(cx, detail::backing_map(headers));
  RootedObject init_map(cx, detail::backing_map(init_headers));

  RootedValue iterable(cx);
  if (!JS::MapEntries(cx, init_map, &iterable))
    return nullptr;

  JS::ForOfIterator it(cx);
  if (!it.init(iterable))
    return nullptr;

  RootedObject entry(cx);
  RootedValue entry_val(cx);
  RootedValue name_val(cx);
  RootedValue value_val(cx);
  while (true) {
    bool done;
    if (!it.next(&entry_val, &done))
      return nullptr;

    if (done)
      break;

    entry = &entry_val.toObject();
    JS_GetElement(cx, entry, 0, &name_val);
    JS_GetElement(cx, entry, 1, &value_val);

    if (!detail::append_header_value(cx, headers, name_val, value_val, "Headers constructor")) {
      return nullptr;
    }
  }

  return headers;
}
JSObject *create(JSContext *cx, HandleObject self, Mode mode, HandleObject owner,
                 HandleObject init_headers) {
  RootedObject headers(cx, create(cx, self, mode, owner));
  if (!headers) {
    return nullptr;
  }

  if (!init_headers) {
    return headers;
  }

  if (!delazify(cx, init_headers)) {
    return nullptr;
  }

  RootedObject headers_map(cx, detail::backing_map(headers));
  RootedObject init_map(cx, detail::backing_map(init_headers));

  RootedValue iterable(cx);
  if (!JS::MapEntries(cx, init_map, &iterable))
    return nullptr;

  JS::ForOfIterator it(cx);
  if (!it.init(iterable))
    return nullptr;

  RootedObject entry(cx);
  RootedValue entry_val(cx);
  RootedValue name_val(cx);
  RootedValue value_val(cx);
  while (true) {
    bool done;
    if (!it.next(&entry_val, &done))
      return nullptr;

    if (done)
      break;

    entry = &entry_val.toObject();
    JS_GetElement(cx, entry, 0, &name_val);
    JS_GetElement(cx, entry, 1, &value_val);

    if (!detail::append_header_value(cx, headers, name_val, value_val, "Headers constructor")) {
      return nullptr;
    }
  }

  return headers;
}