code: func collectsDiff(i1, i2 interface{}, fieldPath string) map[string][]interface{} {
  	diff := make(map[string][]interface{})
  	t := reflect.TypeOf(i1)
  	if t.Kind() != reflect.Struct {
  		if reflect.DeepEqual(i1, i2) {
  			return diff
  		}
  		diff[fieldPath] = []interface{}{i1, i2}
  		return diff
  	}
  
  	v1 := reflect.ValueOf(i1)
  	v2 := reflect.ValueOf(i2)
  	for i := 0; i < v1.NumField(); i++ {
  		p := t.Field(i).Name
  		if fieldPath != "" {
  			p = fieldPath + "." + p
  		}
  		m := collectsDiff(v1.Field(i).Interface(), v2.Field(i).Interface(), p)
  		for k, v := range m {
  			diff[k] = v
  		}
  	}
  	return diff
  }
docs: // collectsDiff collects different config items.
  // map[string][]string -> map[field path][]{new value, old value}