docs: def formfields_for_xmlobject(model, fields=None, exclude=None, widgets=None, options=None,
          declared_subforms=None, max_num=None, extra=None):
      """
      Returns three sorted dictionaries (:class:`django.utils.datastructures.SortedDict`).
       * The first is a dictionary of form fields based on the
         :class:`~eulxml.xmlmap.XmlObject` class fields and their types.
       * The second is a sorted dictionary of subform classes for any fields of type
         :class:`~eulxml.xmlmap.fields.NodeField` on the model.
       * The third is a sorted dictionary of formsets for any fields of type
         :class:`~eulxml.xmlmap.fields.NodeListField` on the model.
  
      Default sorting (within each dictionary) is by XmlObject field creation order.
  
      Used by :class:`XmlObjectFormType` to set up a new :class:`XmlObjectForm`
      class.
  
      :param fields: optional list of field names; if specified, only the named fields
                  will be returned, in the specified order
      :param exclude: optional list of field names that should not be included on
                  the form; if a field is listed in both ``fields`` and ``exclude``,
                  it will be excluded
      :param widgets: optional dictionary of widget options to be passed to form
                  field constructor, keyed on field name
      :param options: optional :class:`~django.forms.models.ModelFormOptions`.
                  if specified then fields, exclude, and widgets will default
                  to its values.
      :param declared_subforms: optional dictionary of field names and form classes;
                  if specified, the specified form class will be used to initialize
                  the corresponding subform (for a :class:`~eulxml.xmlmap.fields.NodeField`)
                  or a formset (for a :class:`~eulxml.xmlmap.fields.NodeListField`)
      :param max_num: optional value for the maximum number of times a fieldset should repeat.
      :param max_num: optional value for the number of extra forms to provide.
      """
  
      # first collect fields and excludes for the form and all subforms. base
      # these on the specified options object unless overridden in args.
      fieldlist = getattr(options, 'parsed_fields', None)
      if isinstance(fields, ParsedFieldList):
          fieldlist = fields
      elif fields is not None:
          fieldlist = _parse_field_list(fields, include_parents=True)
  
      excludelist = getattr(options, 'parsed_exclude', None)
      if isinstance(fields, ParsedFieldList):
          fieldlist = fields
      elif exclude is not None:
          excludelist = _parse_field_list(exclude, include_parents=False)
  
      if widgets is None and options is not None:
          widgets = options.widgets
  
      if max_num is None and options is not None:
          max_num = options.max_num
  
      # collect the fields (unordered for now) that we're going to be returning
      formfields = {}
      subforms = {}
      formsets = {}
      field_order = {}
      subform_labels = {}
  
      for name, field in six.iteritems(model._fields):
          if fieldlist and not name in fieldlist.fields:
              # if specific fields have been requested and this is not one of them, skip it
              continue
          if excludelist and name in excludelist.fields:
              # if exclude has been specified and this field is listed, skip it
              continue
          if widgets and name in widgets:
              # if a widget has been specified for this field, pass as option to form field init
              kwargs = {'widget': widgets[name] }
          else:
              kwargs = {}
          # get apppropriate form widget based on xmlmap field type
          field_type = None
  
          # if the xmlmap field knows whether or not it is required, use for form
          if field.required is not None:
              kwargs['required'] = field.required
          if field.verbose_name is not None:
              kwargs['label'] = field.verbose_name
          if field.help_text is not None:
              kwargs['help_text'] = field.help_text
  
          if hasattr(field, 'choices') and field.choices:
              # if a field has choices defined, use a choice field (no matter what base type)
              field_type = ChoiceField
              kwargs['choices'] = [(val, val) for val in field.choices]
              # FIXME: how to properly do non-required choice field?
              # if field is optional, add a blank choice at the beginning of the list
              if field.required == False and '' not in field.choices:
                  # TODO: add an empty_label option (like django ModelChoiceField)
                  # to xmlobjectform and pass it in to make this easier to customize
                  kwargs['choices'].insert(0, ('', ''))
          elif isinstance(field, xmlmap.fields.StringField):
              field_type = CharField
          elif isinstance(field, xmlmap.fields.IntegerField):
              field_type = IntegerField
          elif isinstance(field, xmlmap.fields.DateField):
              field_type = DateField
          elif isinstance(field, xmlmap.fields.SimpleBooleanField):
              # by default, fields are required - for a boolean, required means it must be checked
              # since that seems nonsensical and not useful for a boolean,
              # setting required to False to allow True or False values
              kwargs['required'] = False
              field_type = BooleanField
  
          # datefield ? - not yet well-supported; leaving out for now
          # ... should probably distinguish between date and datetime field
  
          elif isinstance(field, xmlmap.fields.NodeField) or \
              isinstance(field, xmlmap.fields.NodeListField):
              form_label = kwargs['label'] if 'label' in kwargs else fieldname_to_label(name)
              # store subform label in case we can't set on subform/formset
              subform_labels[name] = form_label
  
               # if a subform class was declared, use that class exactly as is
              if name in declared_subforms:
              	subform = declared_subforms[name]
  
              # otherwise, define a new xmlobject form for the nodefield or
              # nodelistfield class, using any options passed in for fields under this one
              else:
                  subform_opts = {
                      'fields': fieldlist.subfields[name] if fieldlist and name in fieldlist.subfields else None,
                      'exclude': excludelist.subfields[name] if excludelist and name in excludelist.subfields else None,
                      'widgets': widgets[name] if widgets and name in widgets else None,
                      'label': form_label,
                  }
  
                  # create the subform class
                  subform = xmlobjectform_factory(field.node_class, **subform_opts)
  
              # store subform or generate and store formset, depending on field type
              if isinstance(field, xmlmap.fields.NodeField):
                  subforms[name] = subform
              elif isinstance(field, xmlmap.fields.NodeListField):
                  # formset_factory is from django core and we link into it here.
                  formsets[name] = formset_factory(subform, formset=BaseXmlObjectFormSet,
                      max_num=subform._meta.max_num, can_delete=subform._meta.can_delete,
                      extra=subform._meta.extra, can_order=subform._meta.can_order)
  
                  formsets[name].form_label = form_label
  
          elif isinstance(field, xmlmap.fields.StringListField) or \
  	    isinstance(field, xmlmap.fields.IntegerListField):
              form_label = kwargs['label'] if 'label' in kwargs else fieldname_to_label(name)
  
              if isinstance(field, xmlmap.fields.IntegerListField):
              	listform = IntegerListFieldForm
              else:
              	listform = ListFieldForm
  
              # generate a listfield formset
              formsets[name] = formset_factory(listform, formset=BaseXmlObjectListFieldFormSet)
              # don't need can_delete: since each form is a single field, empty implies delete
              # todo: extra, max_num ? widget?
              formsets[name].form_label = form_label
  
          # TODO: other list variants
  
  
          else:
              # raise exception for unsupported fields
              # currently doesn't handle list fields
              raise Exception('Error on field "%s": XmlObjectForm does not yet support auto form field generation for %s.' \
              	% (name, field.__class__))
  
          if field_type is not None:
              if 'label' not in kwargs:
                  kwargs['label'] = fieldname_to_label(name)
              formfields[name] = field_type(**kwargs)
  
          # create a dictionary indexed by field creation order, for default field ordering
          field_order[field.creation_counter] = name
  
      # if fields were explicitly specified, return them in that order
      if fieldlist:
          ordered_fields = SortedDict((name, formfields[name])
                                      for name in fieldlist.fields
                                      if name in formfields)
          ordered_subforms = SortedDict((name, subforms[name])
                                        for name in fieldlist.fields
                                        if name in subforms)
          ordered_formsets = SortedDict((name, formsets[name])
                                        for name in fieldlist.fields
                                        if name in formsets)
      else:
          # sort on field creation counter and generate a django sorted dictionary
          ordered_fields = SortedDict(
              [(field_order[key], formfields[field_order[key]]) for key in sorted(field_order.keys())
                                                  if field_order[key] in formfields ]
          )
          ordered_subforms = SortedDict(
              [(field_order[key], subforms[field_order[key]]) for key in sorted(field_order.keys())
                                                  if field_order[key] in subforms ]
          )
          ordered_formsets = SortedDict(
              [(field_order[key], formsets[field_order[key]]) for key in sorted(field_order.keys())
                                                  if field_order[key] in formsets ]
          )
      return ordered_fields, ordered_subforms, ordered_formsets, subform_labels