docs: function isCompatibleObjects(objectPropDesc1, objectPropDesc2) {
  
  	const propNames2 = new Set(objectPropDesc2.allPropertyNames);
  	const container1 = objectPropDesc1.nestedProperties;
  	const container2 = objectPropDesc2.nestedProperties;
  	for (let propName of objectPropDesc1.allPropertyNames) {
  		const propDesc1 = container1.getPropertyDesc(propName);
  		if (propDesc1.isView() || propDesc1.isCalculated())
  			continue;
  		if (!propNames2.has(propName)) {
  			if (!propDesc1.optional)
  				return false;
  			continue;
  		}
  		propNames2.delete(propName);
  		const propDesc2 = container2.getPropertyDesc(propName);
  		if (!propDesc1.optional && propDesc2.optional)
  			return false;
  		if ((propDesc1.isArray() && !propDesc2.isArray()) ||
  			(propDesc1.isMap() && !propDesc2.isMap()) ||
  			(propDesc1.isScalar() && !propDesc2.isScalar()))
  			return false;
  		if (propDesc1.scalarValueType !== propDesc2.scalarValueType)
  			return false;
  		if (propDesc1.isRef() && (propDesc1.refTarget !== propDesc2.refTarget))
  			return false;
  		if ((propDesc1.scalarValueType === 'object') &&
  			!isCompatibleObjects(propDesc1, propDesc2))
  			return false;
  	}
  
  	for (let propName of propNames2) {
  		const propDesc2 = container2.getPropertyDesc(propName);
  		if (!propDesc2.isView() && !propDesc2.isCalculated())
  			return false;
  	}
  
  	return true;
  }