Obtains a range of elements from within an array/string
@param mixed $property
@param int $left_index
@param int $right_index
@param string $type
@throws \InvalidArgumentException
@return string
163557
protected function getRange($property, $left_index, $right_index, $type = null) {
		//verify valid property
		if (!$this->wrappedArg->offsetExists($property))
			throw new \InvalidArgumentException("Unknown property '$property'");
	
		//check if both indexes are empty
		if (empty($left_index) && strlen($right_index) == 0)
			return $this->castParameter($this->wrappedArg->offsetGet($property), $type);
	
		//check if the value is null
		$value = $this->wrappedArg->offsetGet($property);
		if (is_null($value))
			throw new \InvalidArgumentException("Trying to obtain value from NULL parameter on property '$property'");
	
		//check value type
		if (is_array($value)) {
			//get array slice
			$right_index = strlen($right_index) == 0 ? null : intval($right_index);
			return $this->castParameter(array_slice($value, intval($left_index), $right_index), $type);
		}
		//try to convert value to string
		elseif (($value = $this->toString($value)) !== false) {
			if (strlen($right_index) == 0)
				return $this->castParameter(substr($value, intval($left_index)), $type);
	
			return $this->castParameter(substr($value, intval($left_index), intval($right_index)), $type);
		}
			
		throw new \InvalidArgumentException("Cannot obtain indexes from non-array property '$property'");
	}
1338093
public static ExpressionComparator compare(Class<?> type, List<String> properties) {
		ExpressionComparator comparator = ExpressionComparator.create();
		for (String property : properties) {
			comparator.with(leftProperty(type, property), rightProperty(type, property), true);
		}
		return comparator;
	}
350527
public function onLogicalExpression($expressionType, $left, $right)
    {
        $type = $this->unpackExpressionType($expressionType);
        switch ($type) {
            case ExpressionType::AND_LOGICAL:
                return $this->prepareBinaryExpression(self::LOGICAL_AND, $left, $right);
            case ExpressionType::OR_LOGICAL:
                return $this->prepareBinaryExpression(self::LOGICAL_OR, $left, $right);
            default:
                throw new \InvalidArgumentException('onLogicalExpression');
        }
    }
879081
public function setPropertyType($type)
    {
        if (empty($type)) {
            $this->propertyType = null;
            return $this;
        }

        if (!is_string($type)) {
            throw new InvalidArgumentException(
                'Property type must be a string'
            );
        }

        $this->propertyType = $type;

        return $this;
    }
307133
public function getPropertyMetadata($property, $index)
    {
        if ($this->hasPropertyMetadata($property, $index)) {
            return $this->propertyMetadata[$property][$index];
        }

        return false;
    }
762627
@SuppressWarnings("unchecked")
    private static Object getIndexedValue(Object obj, Property property, int index, ObjectWrapper options) {
        if (property == null) {
            throw new IllegalArgumentException("Cannot get the indexed value from 'null' property.");
        }

        Object propertyValue = property.get(obj);

        if (propertyValue == null) {
            throw new NullPointerException("Invalid 'null' value found for indexed '" + property + "' in "
                                                   + obj.getClass().getName() + ".");

        }

        if (propertyValue instanceof List) {
            List list = (List) propertyValue;
            int size = list.size();

            if (size < index) {
                if (options.isOutOfBoundsSafety) {
                    return null;
                } else {
                    throw new IndexOutOfBoundsException("The indexed " + property + " in "
                                                                + obj.getClass().getSimpleName() + " object has only '" + size + "' elements," +
                                                                " but index '" + index + "' requested.");
                }
            }

            return list.get(index);
        } else if (propertyValue.getClass().isArray()) {
            int lenght = Array.getLength(propertyValue);

            if (lenght < index && options.isOutOfBoundsSafety) {
                return null;
            }

            try {
                return Array.get(propertyValue, index);
            } catch (ArrayIndexOutOfBoundsException e) {
                throw new IndexOutOfBoundsException("The indexed " + property + " in "
                                                            + obj.getClass().getSimpleName() + " object has only '" + lenght + "' elements," +
                                                            " but index '" + index + "' requested.");

            }
        } else if (propertyValue instanceof Iterable) {
            Iterable iterable = (Iterable) propertyValue;

            int k = 0;
            for (Object object : iterable) {
                if (k == index) {
                    return object;
                }

                k++;// Hopefully not an infinite iteration
            }

            // Nothing found
            if (options.isOutOfBoundsSafety) {
                return null;
            } else {
                throw new IndexOutOfBoundsException("The indexed " + property + " in "
                                                            + obj.getClass().getSimpleName() + " object has less than '" + index + "'" +
                                                            " elements.");
            }
        } else {
            throw new IllegalArgumentException("Cannot get an indexed value from the not indexed " + property
                                                       + ". Only List, array and Iterable types are supported, but " + property.getType().getSimpleName()
                                                       + " found.");
        }
    }
774922
final public function getObjectsList($objectType, $properties = array(), $objectURI = NULL, $objectId = NULL)
    {

        if (empty($properties)):
            if (!empty($this->propertyModel))
                $properties = array_keys($this->propertyModel);
        endif;

        $query = static::getObjectQuery($properties, "?{$this->valueGroup}property_values", NULL, $objectType, $objectURI, $objectId);

        //echo($this->withConditions) ;
        $query .= "\nGROUP BY o.object_id";
        $query .= $this->getListLookUpConditionsClause();
        $query .= $this->getListOrderByStatement();
        $query .= $this->getLimitClause();

        $total = $this->getObjectsListCount($objectType, $properties, $objectURI, $objectId); //Count first
        $results = $this->database->prepare($query)->execute();
        //Could use SQL_CALC_FOUND here but just the same as just using a second query really;
        //$queries = $this->database->getQueryLog();
        $this->resetListLookUpConditions();
        $this->setListTotal($total);

        return $results;
    }
25544
public function &offsetGet($property)
	{
		$null = null;
		
		if(array_key_exists($property, $this->list))
			return $this->list[$property];
		
		return $null;
	}
949845
private function generateSortByPropertyClosure( $property, $direction = SORT_ASC )
    {

        if( $direction === SORT_DESC ) {
            $aLTb = 1;
            $aGTb = -1;
        } else {
            $aLTb = -1;
            $aGTb = 1;
        }

        $mapper = $this->getPropertyMapper($property);

        return function ( $a, $b ) use ( $mapper, $aLTb, $aGTb ) {
            $propertyA = $mapper->get($a);
            $propertyB = $mapper->get($b);
            if( $propertyA === $propertyB ) {
                return 0;
            }
            return ( $propertyA < $propertyB ) ? $aLTb : $aGTb;
        };

    }
1024245
private function parseValue($value, $types, \ReflectionProperty $property, $object)
    {
        foreach ($types as $type) {
            foreach ($this->context->getParsers() as $parser) {
                if ($parser instanceof ValueParserInterface) {
                    if (is_array($value) && strpos($type, '[]') !== false) {
                        foreach ($value as $key => &$arrayValue) {
                            $arrayValue = $parser->toArrayValue($arrayValue, str_replace('[]', null, $type), $property, $arrayValue);
                        }
                    } else {
                        $value = $parser->toArrayValue($value, $type, $property, $object);
                    }
                } else {
                    throw new \InvalidArgumentException(sprintf('%s is not a valid parser.', get_class($parser)));
                }
            }
        }

        return $value;
    }
259114
public function get($index, $type, $id, $options = [])
    {
        return $this->db->get([$index, $type, $id], $options);
    }
1345004
public function getProperty($property)
    {
        $values = array();
        foreach ($this->columns as $key => $col) {
            if (isset($col[$property])) {
                $values[$key] = $col[$property];
            } else {
                $values[$key] = null;
            }
        }
    }
1051069
public function where($condition, $value = null, $type = null) {
		if (strpos($condition, '||')) {
			$conditions = explode('||', $condition);
			$conditions = array_map('trim', $conditions);
			
			$conditionParts = [];
			
			foreach ($conditions as $condition) {
				list($property, $condition, $valueCond) = $this->_parseCondition($condition);
				if ($valueCond !== '?') {
					$value = is_numeric($valueCond) ? $this->_parseNumeric($valueCond) : $valueCond;
				}

				$conditionParts[] = $this->_buildCondition($property, $condition, $value);
			}
			
			$this->_addCondition([self::MONGO_OR => $conditionParts]);
		} else {
			list($property, $condition, $valueCond) = $this->_parseCondition($condition);
			
			if ($valueCond !== '?') {
				$value = is_numeric($valueCond) ? $this->_parseNumeric($valueCond) : $valueCond;
			}
			
			$mongoCondition = $this->_buildCondition($property, $condition, $value);
			$this->_addCondition($mongoCondition);
		}
		
		return $this;
	}
877794
public function hasPropertyMetadata($property, $index)
    {
        return isset($this->propertyMetadata[$property], $this->propertyMetadata[$property][$index]);
    }
244460
protected function _propertyTypeAllowed($property, $type)
    {
        $definedType = $this->_getPropertyType($property);
        if (!$definedType) {
            return true;
        }
        if (is_object($type) && class_exists($definedType, false)) {
            return ($type instanceof $definedType);
        }
        return gettype($type) == $definedType;
    }
220386
protected function getSubIndex($value, $subindex = null, $type = null) {
		//if no subindex is specified just cast main argument
		if (is_null($subindex))
			return $this->castParameter($value, $type);
	
		//check if the value is null
		if (is_null($value))
			throw new \InvalidArgumentException("Trying to obtain a value from NULL parameter on index $index");
	
		//check whether this value is the first argument
		if (is_array($value) || is_object($value)) {
			$value = ArgumentWrapper::wrap($value);
			//check if the requested property exists
			if (!$value->offsetExists($subindex))
				throw new \InvalidArgumentException("Property '$subindex' not found on given parameter");
				
			if (is_null($type))
				$type = $value->getPropertyType($subindex);
				
			return $this->castParameter($value->offsetGet($subindex), $type);
		}
		elseif (($value = $this->toString($value)) !== false) {
			//check that subindex is numeric
			if (!is_numeric($subindex))
				throw new \InvalidArgumentException("Subindex '$subindex' is not a number");
				
			//convert subindex to a number
			$subindex = intval($subindex);		
			//check string length against index
			if ($subindex < strlen($value) && $subindex >= 0)
				return $this->castParameter($value[$subindex], $type);
	
			throw new \OutOfBoundsException("Index '$subindex' out of bounds for argument $index");
		}
	
		throw new \InvalidArgumentException("Cannot obtain index '$subindex' from a non-array type");
	}
491816
protected function validatePropertyType(string $property, string $type) : bool
    {
        list($type, $arg) = $this->parseType($type);

        switch ($type) {
            case 'any':
            case 'notnull':
            case 'isset':
            case 'set':
                return true;
            case 'string':
                return is_string($this->{$property});
            case 'email':
                return filter_var($this->{$property}, FILTER_VALIDATE_EMAIL) !== false;
            case 'url':
                return filter_var($this->{$property}, FILTER_VALIDATE_URL) !== false;
            case 'int':
                return is_int($this->{$property});
            case 'bool':
            case 'boolean':
                return is_bool($this->{$property});
            case 'array':
                return is_array($this->{$property});
            case 'null':
                return $this->{$property} === null;
            case 'is_a':
                return is_a($this->{$property}, $arg, true);
            case 'is':
                return is_a($this->{$property}, $arg);
            case 'instanceof':
                return $this->{$property} instanceof $arg;
            default:
                throw new \InvalidArgumentException("{$type} is not a recognised type");
        }
    }