code: func TranslateKeys(v map[string]interface{}, dict map[string]string) {
  	// Convert all dict keys for exclusions to lower. so we can match against them
  	// unambiguously with a single lookup.
  	for k, v := range dict {
  		if v == "" {
  			dict[strings.ToLower(k)] = ""
  		}
  	}
  	ck(v, dict, "")
  }
docs: // TranslateKeys recursively translates all keys from m in-place to their
  // canonical form as defined in dict which maps an alias name to the canonical
  // name. If m already has a value for the canonical name then that one is used
  // and the value for the alias name is discarded. Alias names are matched
  // case-insensitive.
  //
  // Example:
  //
  //   m = TranslateKeys(m, map[string]string{"snake_case": "CamelCase"})
  //
  // If the canonical string provided is the empty string, the effect is to stop
  // recursing into any key matching the left hand side. In this case the left
  // hand side must use periods to specify a full path e.g.
  // `connect.proxy.config`. The path must be the canonical key names (i.e.
  // CamelCase) AFTER translation so ExecMode not exec_mode. These are still match
  // in a case-insensitive way.
  //
  // This is needed for example because parts of the Service Definition are
  // "opaque" maps of metadata or config passed to another process or component.
  // If we allow translation to recurse we might mangle the "opaque" keys given
  // where the clash with key names in other parts of the definition (and they do
  // in practice with deprecated managed proxy upstreams) :sob:
  //
  // Example:
  //   m - TranslateKeys(m, map[string]string{
  //     "foo_bar": "FooBar",
  //     "widget.config": "",
  //     // Assume widgets is an array, this will prevent recursing into any
  //     // item's config field
  //     "widgets.config": "",
  //   })