public static function validate($object, array $values, array $constraints)
    {
        $errors = array();

        // Build a validator and get the entity constraints from the
        // entity object.
        $validatorBuilder = new ValidatorBuilder();
        $validator = $validatorBuilder->getValidator();

        // Loop through all the passed in values. Each $value represents a
        // value of a $property on the object.
        foreach ($values as $property => $value) {
            // Check if we have contraints for this property. If not, test next property.
            if (! isset($constraints[ $property ])) {
                continue;
            }

            // Check if the $value is a map (i.e. an array without a zero index). If so,
            // then we're dealing with a complex object into which we need to recurse into.
            if (is_array($value) and ! isset($value[0])) {
                // We're going to recurise into the sub-object but to get access to it we
                // need to construct it's "getter" method.
                $method = "get".ucfirst($property);

                // Check if the "getter" method exists on the and the property exists in the
                // constraints before calling it. If either doesn't exist we fail silently
                // and skip to the next property.
                if (method_exists($object, $method) and array_key_exists($property, $constraints)) {
                    // The method exists so we can recurse into it. The $value represents an
                    // array of property/value pairs that must be set on the sub-object.
                    $results = static::validate($object->{$method}(), $value, $constraints[ $property ]);

                    // The $results represent the errors that were caused by the validation
                    // of the sub-entity. If we have errors, then apply them to the error
                    // object.
                    if (! empty($results)) {
                        $errors[ $property ] = $results;
                    }
                }
            } else {
                // We're dealing with a simple property. The $value represents the new
                // value that the property must be set to and we grab the contraints
                // based on the property name.
                $results = $validator->validateValue($value, $constraints[ $property ]);

                // A property can have many constraints. E.g. an email address must be
                // a valid email address and cannot be blank. This means that the validation
                // can return multiple errors for a single field. Here we add each individual
                // error for the validated property.
                if ($results->count() > 0) {
                    foreach ($results as $result) {
                        $errors[ $property ][] = $result->getMessage();
                    }
                }
            }
        }

        return $errors;
    }