docs: function getPutOperations(putFn, uri, data, locals) {
    // potentially propagate version throughout object
    const cmptOrLayout = splitCascadingData(uri, replacePropagatingVersions(uri, data));
  
    // if locals exist and there are more than one component being put,
    // then we should pass a read-only version to each component so they can't affect each other
    // this operation isn't needed in the common case of putting a single object
    if (!!locals && cmptOrLayout.length > 0) {
      locals = control.setReadOnly(_.cloneDeep(locals));
    }
  
    // run each through the normal put, which may or may not hit custom component logic
    return bluebird.map(cmptOrLayout, ({ key, value }) => putFn(key, value, locals))
      .then(ops => _.filter(_.flattenDeep(ops), _.identity));
  }