code: private final AbstractJcrProperty createJcrProperty( Property property,
                                                           Name primaryTypeName,
                                                           Set<Name> mixinTypeNames ) throws ConstraintViolationException {
          NodeTypes nodeTypes = session.nodeTypes();
          JcrPropertyDefinition defn = propertyDefinitionFor(property, primaryTypeName, mixinTypeNames, nodeTypes);
          int jcrPropertyType = defn.getRequiredType();
          jcrPropertyType = determineBestPropertyTypeIfUndefined(jcrPropertyType, property);
          AbstractJcrProperty prop = null;
          if (defn.isMultiple()) {
              prop = new JcrMultiValueProperty(this, property.getName(), jcrPropertyType);
          } else {
              prop = new JcrSingleValueProperty(this, property.getName(), jcrPropertyType);
          }
          prop.setPropertyDefinitionId(defn.getId(), nodeTypes.getVersion());
          return prop;
      }
docs: Create a new JCR Property instance given the supplied information. Note that this does not alter the node in any way, since
  it does not store a reference to this property (the caller must do that if needed).
  
  @param property the cached node property; may not be null
  @param primaryTypeName the name of the node's primary type; may not be null
  @param mixinTypeNames the names of the node's mixin types; may be null or empty
  @return the JCR Property instance, or null if the property could not be represented with a valid property definition given
  the primary type and mixin types
  @throws ConstraintViolationException if the property has no valid property definition