code: func NSDetatch(ctx NSContext, el *etree.Element) (*etree.Element, error) {
  	ctx, err := ctx.SubContext(el)
  	if err != nil {
  		return nil, err
  	}
  
  	el = el.Copy()
  
  	// Build a new attribute list
  	attrs := make([]etree.Attr, 0, len(el.Attr))
  
  	// First copy over anything that isn't a namespace declaration
  	for _, attr := range el.Attr {
  		if attr.Space == xmlnsPrefix {
  			continue
  		}
  
  		if attr.Space == defaultPrefix && attr.Key == xmlnsPrefix {
  			continue
  		}
  
  		attrs = append(attrs, attr)
  	}
  
  	// Append all in-context namespace declarations
  	for prefix, namespace := range ctx.prefixes {
  		// Skip the implicit "xml" and "xmlns" prefix declarations
  		if prefix == xmlnsPrefix || prefix == xmlPrefix {
  			continue
  		}
  
  		// Also skip declararing the default namespace as XMLNamespace
  		if prefix == defaultPrefix && namespace == XMLNamespace {
  			continue
  		}
  
  		if prefix != defaultPrefix {
  			attrs = append(attrs, etree.Attr{
  				Space: xmlnsPrefix,
  				Key:   prefix,
  				Value: namespace,
  			})
  		} else {
  			attrs = append(attrs, etree.Attr{
  				Key:   xmlnsPrefix,
  				Value: namespace,
  			})
  		}
  	}
  
  	sort.Sort(SortedAttrs(attrs))
  
  	el.Attr = attrs
  
  	return el, nil
  }
docs: // NSDetatch makes a copy of the passed element, and declares any namespaces in
  // the passed context onto the new element before returning it.