docs: function getAttribute(path, attrNode, context) {
      path.forEach((attributeName, i) => {
          if (!(attrNode.attributes && attrNode.attributes[attributeName])) {
              if (attrNode._origNodes) {
                  let subAttrNode = null;
                  attrNode._origNodes.forEach((origNode, inheritDepth) => {
                      if (!origNode || !origNode.attributes || !origNode.attributes[attributeName]) return;
  
                      let origSubAttrNode = origNode.attributes[attributeName];
  
                      if (subAttrNode) {
                          if (subAttrNode.inherit === 'inherit') {
                              // just add/merge options from sub-resource below
                          } else if (subAttrNode.inherit === 'replace') {
                              return; // just ignore options from sub-resource
                          } else {
                              let attrPath = context.attrPath.join('.');
                              throw new ImplementationError(
                                  `Cannot overwrite attribute "${attributeName}" in "${attrPath}" (maybe use "inherit"?)`
                              );
                          }
                      } else {
                          subAttrNode = {};
                      }
  
                      Object.keys(origSubAttrNode).forEach(optionName => {
                          if (subAttrNode.hasOwnProperty(optionName)) return; // for inherit
  
                          if (optionName === 'attributes') {
                              subAttrNode[optionName] = {};
                          } else if (optionName === 'dataSources') {
                              // DataSources are handled/cloned later in resolveResourceTree():
                              subAttrNode[optionName] = origSubAttrNode[optionName];
                          } else if (typeof origSubAttrNode[optionName] === 'object') {
                              subAttrNode[optionName] = cloneDeep(origSubAttrNode[optionName]);
                          } else {
                              subAttrNode[optionName] = origSubAttrNode[optionName];
                          }
                      });
  
                      // keep the inherit-depth (array length) from parent:
                      subAttrNode._origNodes = subAttrNode._origNodes || Array(attrNode._origNodes.length);
                      subAttrNode._origNodes[inheritDepth] = origSubAttrNode;
  
                      attrNode.attributes[attributeName] = subAttrNode;
                  });
              }
  
              if (!(attrNode.attributes && attrNode.attributes[attributeName])) {
                  throw new RequestError(
                      'Unknown attribute ' + `"${context.attrPath.concat(path.slice(0, i + 1)).join('.')}"`
                  );
              }
          }
  
          attrNode = attrNode.attributes[attributeName];
  
          if (attrNode.resource) {
              const subContext = Object.assign({}, context);
              subContext.attrPath = subContext.attrPath.concat(path.slice(0, i + 1));
              resolveIncludes(attrNode, subContext);
          }
      });
  
      return attrNode;
  }