code: function buildSimplePropsTree(
  	recordTypes, topPropDesc, clause, baseValueExprCtx, propPaths) {
  
  	// create the branching tree top node
  	const topNode = PropertyTreeNode.createTopNode(
  		recordTypes, topPropDesc, baseValueExprCtx, clause);
  
  	// add properties
  	const valuePropsTrees = new Map();
  	const options = {
  		ignoreScopedOrders: true,
  		ignorePresenceTests: (clause !== 'select')
  	};
  	for (let propPath of propPaths)
  		addProperty(topNode, null, propPath, clause, options, valuePropsTrees);
  
  	// make sure there was no value trees
  	if (valuePropsTrees.size > 0)
  		throw new Error(
  			'Internal X2 error: unexpected value trees for ' +
  				Array.from(valuePropsTrees.keys()).join(', ') + '.');
  
  	// return the tree
  	return topNode;
  }
docs: Build possibly branching properties tree assuming no side-value trees are
  involved.
  
  @protected
  @param {module:x2node-records~RecordTypesLibrary} recordTypes Record types
  library.
  @param {module:x2node-records~PropertyDescriptor} topPropDesc Descriptor of
  the top property in the resulting tree. For example, when the tree is being
  built for a query against records of a given record type, this is the
  descriptor of the "records" super-property.
  @param {string} clause Clause for the tree. Every node in the resulting tree
  will be marked as used in this clause.
  @param {module:x2node-dbos~ValueExpressionContext} baseValueExprCtx
  Context for any value expressions used by the properties in the tree. All
  property nodes in the resulting tree will include this context's base path in
  their <code>path</code> property.
  @param {Iterable.<string>} propPaths Paths of properties to include in the
  tree. The paths are relative to (that is do not include) the base value
  expression context's base path.
  @returns {module:x2node-dbos~PropertyTreeNode} The resulting properties tree.
  @throws {module:x2node-common.X2SyntaxError} If the provided paths are invalid.