docs: protected ExtractFromRow createExtractFromRow( final String selectorName,
                                                     final String propertyName,
                                                     QueryContext context,
                                                     Columns columns,
                                                     QuerySources sources,
                                                     TypeFactory<?> defaultType,
                                                     boolean allowMultiValued ) {
          final Name propName = context.getExecutionContext().getValueFactories().getNameFactory().create(propertyName);
          final NodeCache cache = context.getNodeCache(sources.getWorkspaceName());
          // Find the expected property type of the value ...
          assert columns != null;
          final int indexInRow = columns.getSelectorIndex(selectorName);
          if (PseudoColumns.contains(propName, true)) {
              if (PseudoColumns.isScore(propName)) {
                  // This is a special case of obtaining the score from the row ...
                  final TypeFactory<?> typeFactory = context.getTypeSystem().getDoubleFactory();
                  return new PropertyValueExtractor(selectorName, propertyName, typeFactory) {
  
                      @Override
                      public Object getValueInRow( RowAccessor row ) {
                          // We have to convert this to a double, since 'float' is not a valid JCR property type ...
                          return new Double(row.getScore(indexInRow));
                      }
                  };
              }
              if (PseudoColumns.isPath(propName)) {
                  // This is a special case of obtaining the score from the row ...
                  final TypeFactory<?> typeFactory = context.getTypeSystem().getPathFactory();
                  return new PropertyValueExtractor(selectorName, propertyName, typeFactory) {
  
                      @Override
                      public Object getValueInRow( RowAccessor row ) {
                          CachedNode node = row.getNode(indexInRow);
                          if (node == null) return null;
                          return node.getPath(cache);
                      }
                  };
              }
              if (PseudoColumns.isDepth(propName)) {
                  // This is a special case of obtaining the score from the row ...
                  final TypeFactory<?> typeFactory = context.getTypeSystem().getLongFactory();
                  return new PropertyValueExtractor(selectorName, propertyName, typeFactory) {
  
                      @Override
                      public Object getValueInRow( RowAccessor row ) {
                          CachedNode node = row.getNode(indexInRow);
                          if (node == null) return null;
                          return node.getDepth(cache);
                      }
                  };
              }
              if (PseudoColumns.isName(propName)) {
                  // This is a special case of obtaining the score from the row ...
                  final TypeFactory<?> typeFactory = context.getTypeSystem().getNameFactory();
                  return new PropertyValueExtractor(selectorName, propertyName, typeFactory) {
  
                      @Override
                      public Object getValueInRow( RowAccessor row ) {
                          CachedNode node = row.getNode(indexInRow);
                          if (node == null) return null;
                          return node.getName(cache);
                      }
                  };
              }
              if (PseudoColumns.isLocalName(propName)) {
                  // This is a special case of obtaining the score from the row ...
                  final TypeFactory<?> typeFactory = context.getTypeSystem().getStringFactory();
                  return new PropertyValueExtractor(selectorName, propertyName, typeFactory) {
  
                      @Override
                      public Object getValueInRow( RowAccessor row ) {
                          CachedNode node = row.getNode(indexInRow);
                          if (node == null) return null;
                          return node.getName(cache).getLocalName();
                      }
                  };
              }
              if (PseudoColumns.isId(propName)) {
                  // This is a special case of obtaining the identifier from the row ...
                  final TypeFactory<?> typeFactory = context.getTypeSystem().getStringFactory();
                  return new PropertyValueExtractor(selectorName, propertyName, typeFactory) {
  
                      @Override
                      public Object getValueInRow( RowAccessor row ) {
                          CachedNode node = row.getNode(indexInRow);
                          if (node == null) return null;
                          return node.getKey().toString();
                      }
                  };
              }
              if (PseudoColumns.isUuid(propName)) {
                  // This is a special case of obtaining the "jcr:uuid" value from the row, except that the
                  // CachedNode instances don't know about this property ...
                  final TypeFactory<?> typeFactory = context.getTypeSystem().getStringFactory();
                  final NodeTypes nodeTypes = context.getNodeTypes();
                  return new PropertyValueExtractor(selectorName, propertyName, typeFactory) {
  
                      @Override
                      public Object getValueInRow( RowAccessor row ) {
                          CachedNode node = row.getNode(indexInRow);
                          if (node == null) return null;
                          if (nodeTypes.isReferenceable(node.getPrimaryType(cache), node.getMixinTypes(cache))) {
                              // The node is a 'mix:referenceable' node, so return the UUID ...
                              NodeKey key = node.getKey();
                              return key.getIdentifier();
                          }
                          return null;
                      }
                  };
              }
          }
          String expectedType = null;
          try {
              expectedType = columns.getColumnTypeForProperty(selectorName, propertyName);
          } catch (NoSuchElementException e) {
              if (defaultType == null) throw e;
          }
          final TypeFactory<?> typeFactory = expectedType != null ? context.getTypeSystem().getTypeFactory(expectedType) : defaultType;
          if (allowMultiValued) {
              return new ExtractFromRow() {
                  @Override
                  public Object getValueInRow( RowAccessor row ) {
                      CachedNode node = row.getNode(indexInRow);
                      if (node == null) return null;
                      org.modeshape.jcr.value.Property prop = node.getProperty(propName, cache);
                      if (prop == null || prop.isEmpty()) return null;
                      if (prop.isSingle()) {
                          return typeFactory.create(prop.getFirstValue());
                      }
                      assert prop.isMultiple();
                      Object[] result = new Object[prop.size()];
                      int i = -1;
                      for (Object value : prop) {
                          result[++i] = typeFactory.create(value);
                      }
                      return result;
                  }
  
                  @Override
                  public TypeFactory<?> getType() {
                      return typeFactory;
                  }
  
                  @Override
                  public String toString() {
                      return "(" + selectorName + "." + propertyName + ")";
                  }
              };
          }
          return new ExtractFromRow() {
              @Override
              public Object getValueInRow( RowAccessor row ) {
                  CachedNode node = row.getNode(indexInRow);
                  if (node == null) return null;
                  org.modeshape.jcr.value.Property prop = node.getProperty(propName, cache);
                  if (prop == null || prop.isEmpty()) return null;
                  return typeFactory.create(prop.getFirstValue());
              }
  
              @Override
              public TypeFactory<?> getType() {
                  return typeFactory;
              }
  
              @Override
              public String toString() {
                  return "(" + selectorName + "." + propertyName + ")";
              }
          };
      }