Given a list of declarations, return a list of output.Rule objects.
        
        Optionally provide an output directory for local copies of image files.

def get_shield_rule_groups(declarations, dirs):
    """ Given a list of declarations, return a list of output.Rule objects.
        
        Optionally provide an output directory for local copies of image files.
    """
    property_map = {'shield-face-name': 'face_name',
                    'shield-fontset': 'fontset',
                    'shield-size': 'size', 
                    'shield-fill': 'fill', 'shield-character-spacing': 'character_spacing',
                    'shield-line-spacing': 'line_spacing',
                    'shield-spacing': 'spacing', 'shield-min-distance': 'minimum_distance',
                    'shield-file': 'file', 'shield-width': 'width', 'shield-height': 'height',
                    'shield-meta-output': 'meta-output', 'shield-meta-writer': 'meta-writer',
                    'shield-text-dx': 'dx', 'shield-text-dy': 'dy'}

    property_names = property_map.keys()
    
    # pull out all the names
    text_names = [dec.selector.elements[1].names[0]
                  for dec in declarations
                  if len(dec.selector.elements) is 2 and len(dec.selector.elements[1].names) is 1]
    
    # a place to put groups
    groups = []
    
    # a separate style element for each text name
    for text_name in set(text_names):
    
        # just the ones we care about here.
        # the complicated conditional means: get all declarations that
        # apply to this text_name specifically, or text in general.
        name_declarations = [dec for dec in declarations
                             if dec.property.name in property_map
                                and (len(dec.selector.elements) == 1
                                     or (len(dec.selector.elements) == 2
                                         and dec.selector.elements[1].names[0] in (text_name, '*')))]
        
        # a place to put rules
        rules = []
        
        for (filter, values) in filtered_property_declarations(name_declarations, property_names):
        
            face_name = values.has_key('shield-face-name') and values['shield-face-name'].value or None
            fontset = values.has_key('shield-fontset') and values['shield-fontset'].value or None
            size = values.has_key('shield-size') and values['shield-size'].value or None
            
            file, filetype, width, height \
                = values.has_key('shield-file') \
                and post_process_symbolizer_image_file(str(values['shield-file'].value), dirs) \
                or (None, None, None, None)
            
            width = values.has_key('shield-width') and values['shield-width'].value or width
            height = values.has_key('shield-height') and values['shield-height'].value or height
            
            color = values.has_key('shield-fill') and values['shield-fill'].value or None
            minimum_distance = values.has_key('shield-min-distance') and values['shield-min-distance'].value or None
            
            character_spacing = values.has_key('shield-character-spacing') and values['shield-character-spacing'].value or None
            line_spacing = values.has_key('shield-line-spacing') and values['shield-line-spacing'].value or None
            label_spacing = values.has_key('shield-spacing') and values['shield-spacing'].value or None
            
            text_dx = values.has_key('shield-text-dx') and values['shield-text-dx'].value or 0
            text_dy = values.has_key('shield-text-dy') and values['shield-text-dy'].value or 0
            
            if file and (face_name or fontset):
                symbolizer = output.ShieldSymbolizer(text_name, face_name, size, file, filetype, 
                                            width, height, color, minimum_distance, character_spacing,
                                            line_spacing, label_spacing, text_dx=text_dx, text_dy=text_dy,
                                            fontset=fontset)
            
                rules.append(make_rule(filter, symbolizer))
        
        groups.append((text_name, rules))
    
    return dict(groups)