docs: 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)