code: func coalesceValues(c *chart.Chart, v map[string]interface{}) (map[string]interface{}, error) {
  	// If there are no values in the chart, we just return the given values
  	if c.Values == nil || c.Values.Raw == "" {
  		return v, nil
  	}
  
  	nv, err := ReadValues([]byte(c.Values.Raw))
  	if err != nil {
  		// On error, we return just the overridden values.
  		// FIXME: We should log this error. It indicates that the YAML data
  		// did not parse.
  		return v, fmt.Errorf("Error: Reading chart '%s' default values (%s): %s", c.Metadata.Name, c.Values.Raw, err)
  	}
  
  	for key, val := range nv {
  		if value, ok := v[key]; ok {
  			if value == nil {
  				// When the YAML value is null, we remove the value's key.
  				// This allows Helm's various sources of values (value files or --set) to
  				// remove incompatible keys from any previous chart, file, or set values.
  				delete(v, key)
  			} else if dest, ok := value.(map[string]interface{}); ok {
  				// if v[key] is a table, merge nv's val table into v[key].
  				src, ok := val.(map[string]interface{})
  				if !ok {
  					log.Printf("Warning: Building values map for chart '%s'. Skipped value (%+v) for '%s', as it is not a table.", c.Metadata.Name, src, key)
  					continue
  				}
  				// Because v has higher precedence than nv, dest values override src
  				// values.
  				coalesceTables(dest, src, c.Metadata.Name)
  			}
  		} else {
  			// If the key is not in v, copy it from nv.
  			v[key] = val
  		}
  	}
  	return v, nil
  }
docs: // coalesceValues builds up a values map for a particular chart.
  //
  // Values in v will override the values in the chart.