code: func zeroCmpTwo(a, b interface{}, modCb func() ManifestDiff_Stat) ManifestDiff_Stat {
  	av, bv := reflect.ValueOf(a), reflect.ValueOf(b)
  	t := av.Type()
  	if t != bv.Type() {
  		panic("inconsistent types")
  	}
  	var az, bz bool
  	if t.Kind() == reflect.Slice || t.Kind() == reflect.String {
  		az, bz = av.Len() == 0, bv.Len() == 0
  	} else {
  		z := reflect.Zero(t)
  		az, bz = av == z, bv == z
  	}
  
  	switch {
  	case az && bz:
  		return ManifestDiff_EQUAL
  
  	case az && !bz:
  		return ManifestDiff_ADDED
  
  	case !az && bz:
  		return ManifestDiff_REMOVED
  
  	default:
  		switch t.Kind() {
  		case reflect.String:
  			if av.String() == bv.String() {
  				return ManifestDiff_EQUAL
  			}
  			return ManifestDiff_MODIFIED
  
  		case reflect.Slice:
  			if av.Len() != bv.Len() {
  				return ManifestDiff_MODIFIED
  			}
  		}
  		return modCb()
  	}
  }
docs: // zeroCmpTwo compares two objects of the same type where the objects could be
  // pointers, slices or strings.
  //
  // It generates a Stat value of:
  //   * EQUAL if they're both nil/empty/zero
  //   * ADDED if a is nil and b is not
  //   * REMOVED if b is nil and a is not
  //   * For strings:
  //     * EQUAL/MODIFIED depending on string equality
  //   * For slices:
  //     * MODIFIED if they have differing lengths
  //     * Whatever the callback method returns
  //   * For others
  //     * Whatever the callback method returns
  //
  // The callback method is required for non-string types.