    /*
     * call-seq:
     *  create_external_subset(name, external_id, system_id)
     *
     * Create an external subset
     */
    static VALUE create_external_subset(VALUE self, VALUE name, VALUE external_id, VALUE system_id)
    {
      xmlNodePtr node;
      xmlDocPtr doc;
      xmlDtdPtr dtd;

      Data_Get_Struct(self, xmlNode, node);

      doc = node->doc;

      if(doc->extSubset)
        rb_raise(rb_eRuntimeError, "Document already has an external subset");

      dtd = xmlNewDtd(
          doc,
          NIL_P(name)        ? NULL : (const xmlChar *)StringValuePtr(name),
          NIL_P(external_id) ? NULL : (const xmlChar *)StringValuePtr(external_id),
          NIL_P(system_id)   ? NULL : (const xmlChar *)StringValuePtr(system_id)
      );

      if(!dtd) return Qnil;

      return Nokogiri_wrap_xml_node(Qnil, (xmlNodePtr)dtd);
    }