 
 public extension String {
     public init(xmlDocumentRoot root: Element, version: Version = Version(major: 1), encoding: DocumentEncoding = .utf8, options: SerializationOptions = []) {
-      let versionAttribute = "version=\"" + version.versionString().escaped(content: .attribute(quotes: .double)) + "\""
-      let encodingAttribute = "encoding=\"" + encoding.attributeValue.escaped(content: .attribute(quotes: .double)) + "\""
+      let versionAttribute = "version=" + options.quotes.quoted(attributeString: version.versionString())
+      let encodingAttribute = "encoding=" + options.quotes.quoted(attributeString: encoding.attributeValue)
       self = "<?xml \(versionAttribute) \(encodingAttribute)?>"
          + options.lineSeparator
          + String(xml: root)
-         + options.lineSeparator
    }
    
    public init(xml: Element, options: SerializationOptions = []) {
       let attributes = xml.attributes.isEmpty ? "" : " " + xml.attributes.map {
-         $0.key + "=\"" + $0.value.escaped(content: .attribute(quotes: .double)) + "\""
+         $0.key + "=" + options.quotes.quoted(attributeString: $0.value)
       }.joined(separator: " ")
       let start = "<\(xml.name)\(attributes)"
       let end = "</\(xml.name)>"

   }
}

public enum EscapableContent: Equatable {
   fileprivate typealias Replacement = (unescaped: String, escaped: String)
   
   public enum Quotes: Equatable {
      case single
      case double
   }
   
   // See: https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents
   case attribute(quotes: Quotes)
   case comment
   case text
   case cdata
   case processingInstruction
   
   // See: https://en.wikipedia.org/wiki/XML#Escaping
   fileprivate var replacements: [Replacement] {

         case .double:
            return [ampersandReplacement, doubleQuoteReplacement, lessThanReplacement]
         }
      case .text:
         return [ampersandReplacement, lessThanReplacement]
      case .cdata:
         return []
      case .comment:
         return []
      case .processingInstruction:
         return []
