func (e ExclusiveCanonicalization) renderAttributes(node *etree.Element,
	prefixesInScope []string, defaultNS string) (newDefaultNS string,
	newPrefixesInScope []string) {

	currentNS := node.SelectAttrValue("xmlns", defaultNS)
	elementAttributes := []etree.Attr{}
	nsListToRender := make(map[string]string)
	attrListToRender := attributes{}

	// load map with for prefix -> uri lookup
	for _, attr := range node.Attr {
		if attr.Space == "xmlns" {
			e.namespaces[attr.Key] = attr.Value
		}
	}

	// handle the namespace of the node itself
	if node.Space != "" {
		if !contains(prefixesInScope, node.Space) {
			nsListToRender["xmlns:"+node.Space] = e.namespaces[node.Space]
			prefixesInScope = append(prefixesInScope, node.Space)
		}
	} else if defaultNS != currentNS {
		newDefaultNS = currentNS
		elementAttributes = append(elementAttributes,
			etree.Attr{Key: "xmlns", Value: currentNS})
	}

	for _, attr := range node.Attr {
		// include the namespaces if they are in the inclusiveNamespacePrefixList
		if attr.Space == "xmlns" {
			if !contains(prefixesInScope, attr.Key) &&
				contains(e.inclusiveNamespacePrefixList, attr.Key) {

				nsListToRender["xmlns:"+attr.Key] = attr.Value
				prefixesInScope = append(prefixesInScope, attr.Key)
			}
		}

		// include namespaces for qualfied attributes
		if attr.Space != "" &&
			attr.Space != "xmlns" &&
			!contains(prefixesInScope, attr.Space) {

			nsListToRender["xmlns:"+attr.Space] = e.namespaces[attr.Space]
			prefixesInScope = append(prefixesInScope, attr.Space)
		}

		// inclued all non-namespace attributes
		if attr.Space != "xmlns" && attr.Key != "xmlns" {
			attrListToRender = append(attrListToRender,
				attribute{
					prefix: attr.Space,
					uri:    e.namespaces[attr.Space],
					key:    attr.Key,
					value:  attr.Value,
				})
		}
	}

	// sort and add the namespace attributes first
	sortedNSList := getSortedNamespaces(nsListToRender)
	elementAttributes = append(elementAttributes, sortedNSList...)
	// then sort and add the non-namespace attributes
	sortedAttributes := getSortedAttributes(attrListToRender)
	elementAttributes = append(elementAttributes, sortedAttributes...)
	// replace the nodes attributes with the sorted copy
	node.Attr = elementAttributes
	return currentNS, prefixesInScope
}