code: function(src, dst, opt_overwriteBehavior) {
      Object.keys(src).forEach(function(key) {
        if (opt_overwriteBehavior === 2 && dst[key] !== undefined) {
          return;
        }
        var value = src[key];
        if (value instanceof Array) {
          var newDst = dst[key];
          if (!newDst) {
            newDst = [];
            dst[name] = newDst;
          }
          copyProperties(value, newDst, opt_overwriteBehavior);
        } else if (value instanceof Object &&
                   !(value instanceof Function) &&
                   !(value instanceof HTMLElement)) {
          var newDst2 = dst[key];
          if (!newDst2) {
            newDst2 = {};
            dst[key] = newDst2;
          }
          copyProperties(value, newDst2, opt_overwriteBehavior);
        } else {
          if (opt_overwriteBehavior === 1 && dst[key] !== undefined) {
            return;
          }
          dst[key] = value;
        }
      });
      return dst;
    }
docs: Copies properties from obj to dst recursively.
  @param {Object} obj Object with new settings.
  @param {Object} dst Object to receive new settings.
  @param {number?} opt_overwriteBehavior
  *   0/falsy = overwrite
  
  src    = {foo:'bar'}
  dst    = {foo:'abc'}
  result = {foo:'bar'}
  
  *   1 = don't overwrite but descend if deeper
  
  src    = {foo:{bar:'moo','abc':def}}
  dst    = {foo:{bar:'ghi'}}
  result = {foo:{bar:'ghi','abc':def}}
  
  'foo' exists but we still go deeper and apply 'abc'
  
  *   2 = don't overwrite don't descend
  
  src    = {foo:{bar:'moo','abc':def}}
  dst    = {foo:{bar:'ghi'}}
  result = {foo:{bar:'ghi'}}
  
  'foo' exists so we don't go any deeper