NAN_METHOD(XmlDocument::ToString)
{
    Nan::HandleScope scope;

    XmlDocument* document = Nan::ObjectWrap::Unwrap<XmlDocument>(info.Holder());
    assert(document);

    int options = 0;

    if (info.Length() > 0) {
    if (info[0]->IsBoolean()) {
        if (Nan::To<v8::Boolean>(info[0]).ToLocalChecked()->Value() == true) {
            options |= XML_SAVE_FORMAT;
        }
    } else if (info[0]->IsObject()) {
        v8::Local<v8::Object> obj = Nan::To<v8::Object>(info[0]).ToLocalChecked();

        // drop the xml declaration
        if (Nan::Get(obj, Nan::New<v8::String>("declaration").ToLocalChecked()).ToLocalChecked()->IsFalse()) {
            options |= XML_SAVE_NO_DECL;
        }

        // format save output
        if (Nan::Get(obj, Nan::New<v8::String>("format").ToLocalChecked()).ToLocalChecked()->IsTrue()) {
            options |= XML_SAVE_FORMAT;
        }

        // no empty tags (only works with XML) ex: <title></title> becomes <title/>
        if (Nan::Get(obj, Nan::New<v8::String>("selfCloseEmpty").ToLocalChecked()).ToLocalChecked()->IsFalse()) {
            options |= XML_SAVE_NO_EMPTY;
        }

        // format with non-significant whitespace
        if (Nan::Get(obj, Nan::New<v8::String>("whitespace").ToLocalChecked()).ToLocalChecked()->IsTrue()) {
            options |= XML_SAVE_WSNONSIG;
        }

        v8::Local<v8::Value> type = Nan::Get(obj, Nan::New<v8::String>("type").ToLocalChecked()).ToLocalChecked();
        if (Nan::Equals(type, Nan::New<v8::String>("XML").ToLocalChecked()).ToChecked() ||
            Nan::Equals(type, Nan::New<v8::String>("xml").ToLocalChecked()).ToChecked()) {
            options |= XML_SAVE_AS_XML;    // force XML serialization on HTML doc
        } else if (Nan::Equals(type, Nan::New<v8::String>("HTML").ToLocalChecked()).ToChecked() ||
                 Nan::Equals(type, Nan::New<v8::String>("html").ToLocalChecked()).ToChecked()) {
            options |= XML_SAVE_AS_HTML;   // force HTML serialization on XML doc
            // if the document is XML and we want formatted HTML output
            // we must use the XHTML serializer because the default HTML
            // serializer only formats node->type = HTML_NODE and not XML_NODEs
            if ((options & XML_SAVE_FORMAT) && (options & XML_SAVE_XHTML) == false) {
              options |= XML_SAVE_XHTML;
            }
        } else if (Nan::Equals(type, Nan::New<v8::String>("XHTML").ToLocalChecked()).ToChecked() ||
                 Nan::Equals(type, Nan::New<v8::String>("xhtml").ToLocalChecked()).ToChecked()) {
                options |= XML_SAVE_XHTML;    // force XHTML serialization
            }
        }
    }

    xmlBuffer* buf = xmlBufferCreate();
    xmlSaveCtxt* savectx = xmlSaveToBuffer(buf, "UTF-8", options);
    xmlSaveTree(savectx, (xmlNode*)document->xml_obj);
    xmlSaveFlush(savectx);
    xmlSaveClose(savectx);
    v8::Local<v8::Value> ret = Nan::Null();
    if (xmlBufferLength(buf) > 0)
        ret = Nan::New<v8::String>((char*)xmlBufferContent(buf), xmlBufferLength(buf)).ToLocalChecked();
    xmlBufferFree(buf);

    return info.GetReturnValue().Set(ret);
}
NAN_METHOD(XmlDocument::ToString)
{
    Nan::HandleScope scope;

    XmlDocument* document = Nan::ObjectWrap::Unwrap<XmlDocument>(info.Holder());
    assert(document);

    int options = 0;

    if (info.Length() > 0) {
    if (info[0]->IsBoolean()) {
        if (Nan::To<v8::Boolean>(info[0]).ToLocalChecked()->Value() == true) {
            options |= XML_SAVE_FORMAT;
        }
    } else if (info[0]->IsObject()) {
        v8::Local<v8::Object> obj = Nan::To<v8::Object>(info[0]).ToLocalChecked();

         
        if (Nan::Get(obj, Nan::New<v8::String>("declaration").ToLocalChecked()).ToLocalChecked()->IsFalse()) {
            options |= XML_SAVE_NO_DECL;
        }

         
        if (Nan::Get(obj, Nan::New<v8::String>("format").ToLocalChecked()).ToLocalChecked()->IsTrue()) {
            options |= XML_SAVE_FORMAT;
        }

         
        if (Nan::Get(obj, Nan::New<v8::String>("selfCloseEmpty").ToLocalChecked()).ToLocalChecked()->IsFalse()) {
            options |= XML_SAVE_NO_EMPTY;
        }

         
        if (Nan::Get(obj, Nan::New<v8::String>("whitespace").ToLocalChecked()).ToLocalChecked()->IsTrue()) {
            options |= XML_SAVE_WSNONSIG;
        }

        v8::Local<v8::Value> type = Nan::Get(obj, Nan::New<v8::String>("type").ToLocalChecked()).ToLocalChecked();
        if (Nan::Equals(type, Nan::New<v8::String>("XML").ToLocalChecked()).ToChecked() ||
            Nan::Equals(type, Nan::New<v8::String>("xml").ToLocalChecked()).ToChecked()) {
            options |= XML_SAVE_AS_XML;     
        } else if (Nan::Equals(type, Nan::New<v8::String>("HTML").ToLocalChecked()).ToChecked() ||
                 Nan::Equals(type, Nan::New<v8::String>("html").ToLocalChecked()).ToChecked()) {
            options |= XML_SAVE_AS_HTML;    
             
             
             
            if ((options & XML_SAVE_FORMAT) && (options & XML_SAVE_XHTML) == false) {
              options |= XML_SAVE_XHTML;
            }
        } else if (Nan::Equals(type, Nan::New<v8::String>("XHTML").ToLocalChecked()).ToChecked() ||
                 Nan::Equals(type, Nan::New<v8::String>("xhtml").ToLocalChecked()).ToChecked()) {
                options |= XML_SAVE_XHTML;     
            }
        }
    }

    xmlBuffer* buf = xmlBufferCreate();
    xmlSaveCtxt* savectx = xmlSaveToBuffer(buf, "UTF-8", options);
    xmlSaveTree(savectx, (xmlNode*)document->xml_obj);
    xmlSaveFlush(savectx);
    xmlSaveClose(savectx);
    v8::Local<v8::Value> ret = Nan::Null();
    if (xmlBufferLength(buf) > 0)
        ret = Nan::New<v8::String>((char*)xmlBufferContent(buf), xmlBufferLength(buf)).ToLocalChecked();
    xmlBufferFree(buf);

    return info.GetReturnValue().Set(ret);
}