code: func (s *Struct) FillMap(out map[string]interface{}) {
  	if out == nil {
  		return
  	}
  
  	fields := s.structFields()
  
  	for _, field := range fields {
  		name := field.Name
  		val := s.value.FieldByName(name)
  		isSubStruct := false
  		var finalVal interface{}
  
  		tagName, tagOpts := parseTag(field.Tag.Get(s.TagName))
  		if tagName != "" {
  			name = tagName
  		}
  
  		// if the value is a zero value and the field is marked as omitempty do
  		// not include
  		if tagOpts.Has("omitempty") {
  			zero := reflect.Zero(val.Type()).Interface()
  			current := val.Interface()
  
  			if reflect.DeepEqual(current, zero) {
  				continue
  			}
  		}
  
  		if !tagOpts.Has("omitnested") {
  			finalVal = s.nested(val)
  
  			v := reflect.ValueOf(val.Interface())
  			if v.Kind() == reflect.Ptr {
  				v = v.Elem()
  			}
  
  			switch v.Kind() {
  			case reflect.Map, reflect.Struct:
  				isSubStruct = true
  			}
  		} else {
  			finalVal = val.Interface()
  		}
  
  		if tagOpts.Has("string") {
  			s, ok := val.Interface().(fmt.Stringer)
  			if ok {
  				out[name] = s.String()
  			}
  			continue
  		}
  
  		if isSubStruct && (tagOpts.Has("flatten")) {
  			for k := range finalVal.(map[string]interface{}) {
  				out[k] = finalVal.(map[string]interface{})[k]
  			}
  		} else {
  			out[name] = finalVal
  		}
  	}
  }
docs: // FillMap is the same as Map. Instead of returning the output, it fills the
  // given map.