docs: function isValidObjectValue(recordTypes, val, objectPropDesc, forUpdate) {
  
  	const container = objectPropDesc.nestedProperties;
  	for (let propName of container.allPropertyNames) {
  		const propDesc = container.getPropertyDesc(propName);
  		if (propDesc.isView() || propDesc.isCalculated())
  			continue;
  		const propVal = val[propName];
  		if ((propVal === undefined) || (propVal === null)) {
  			if (!propDesc.optional && (!forUpdate || !propDesc.isGenerated()))
  				return false;
  		} else if (propDesc.isArray()) {
  			if (!Array.isArray(propVal))
  				return false;
  			if (!propDesc.optional && (propVal.length === 0))
  				return false;
  			if (propVal.some(
  				v => isInvalidScalarValueType(
  					recordTypes, v, propDesc, forUpdate)))
  				return false;
  		} else if (propDesc.isMap()) {
  			if ((typeof propVal) !== 'object')
  				return false;
  			const keys = Object.keys(propVal);
  			if (!propDesc.optional && (keys.length === 0))
  				return false;
  			if (keys.some(
  				k => isInvalidScalarValueType(
  					recordTypes, propVal[k], propDesc, forUpdate)))
  				return false;
  		} else {
  			if (isInvalidScalarValueType(
  				recordTypes, propVal, propDesc, forUpdate))
  				return false;
  		}
  	}
  
  	return true;
  }