/**
  * {@inheritdoc}
  */
 public function validate($value, $constraints = null, $groups = null)
 {
     $groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
     $previousValue = $this->context->getValue();
     $previousObject = $this->context->getObject();
     $previousMetadata = $this->context->getMetadata();
     $previousPath = $this->context->getPropertyPath();
     $previousGroup = $this->context->getGroup();
     // If explicit constraints are passed, validate the value against
     // those constraints
     if (null !== $constraints) {
         // You can pass a single constraint or an array of constraints
         // Make sure to deal with an array in the rest of the code
         if (!is_array($constraints)) {
             $constraints = array($constraints);
         }
         $metadata = new GenericMetadata();
         $metadata->addConstraints($constraints);
         $this->validateGenericNode($value, null, is_object($value) ? spl_object_hash($value) : null, $metadata, $this->defaultPropertyPath, $groups, null, TraversalStrategy::IMPLICIT, $this->context);
         $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
         $this->context->setGroup($previousGroup);
         return $this;
     }
     // If an object is passed without explicit constraints, validate that
     // object against the constraints defined for the object's class
     if (is_object($value)) {
         $this->validateObject($value, $this->defaultPropertyPath, $groups, TraversalStrategy::IMPLICIT, $this->context);
         $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
         $this->context->setGroup($previousGroup);
         return $this;
     }
     // If an array is passed without explicit constraints, validate each
     // object in the array
     if (is_array($value)) {
         $this->validateEachObjectIn($value, $this->defaultPropertyPath, $groups, true, $this->context);
         $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
         $this->context->setGroup($previousGroup);
         return $this;
     }
     throw new RuntimeException(sprintf('Cannot validate values of type "%s" automatically. Please ' . 'provide a constraint.', gettype($value)));
 }