Given a Map element and directories object, remove and return a complete
        list of style declarations from any Stylesheet elements found within.

def extract_declarations(map_el, dirs, scale=1, user_styles=[]):
    """ Given a Map element and directories object, remove and return a complete
        list of style declarations from any Stylesheet elements found within.
    """
    styles = []
    
    #
    # First, look at all the stylesheets defined in the map itself.
    #
    for stylesheet in map_el.findall('Stylesheet'):
        map_el.remove(stylesheet)

        content, mss_href = fetch_embedded_or_remote_src(stylesheet, dirs)
        
        if content:
            styles.append((content, mss_href))
    
    #
    # Second, look through the user-supplied styles for override rules.
    #
    for stylesheet in user_styles:
        mss_href = urljoin(dirs.source.rstrip('/')+'/', stylesheet)
        content = urllib.urlopen(mss_href).read().decode(DEFAULT_ENCODING)

        styles.append((content, mss_href))
    
    declarations = []
    
    for (content, mss_href) in styles:
        is_merc = is_merc_projection(map_el.get('srs',''))
        
        for declaration in stylesheet_declarations(content, is_merc, scale):
            #
            # Change the value of each URI relative to the location
            # of the containing stylesheet. We generally just have
            # the one instance of "dirs" around for a full parse cycle,
            # so it's necessary to perform this normalization here
            # instead of later, while mss_href is still available.
            #
            uri_value = declaration.value.value
            
            if uri_value.__class__ is uri:
                uri_value.address = urljoin(mss_href, uri_value.address)

            declarations.append(declaration)

    return declarations