public function validate(array $data, $rules = [])
    {
        $this->clearErrors();
        $this->clearFieldAliases();

        $data = $this->extractFieldAliases($data);

        // If the rules array is empty, then it means we are
        // receiving the rules directly with the input, so we need
        // to extract the information.
        if (empty($rules)) {
            $rules = $this->extractRules($data);
            $data  = $this->extractInput($data);
        }

        $this->input = $data;

        // Loop through all of the before callbacks and execute them.
        foreach ($this->before as $before) {
            call_user_func_array($before, [ $this ]);
        }

        foreach ($data as $field => $value) {
            $fieldRules = explode('|', $rules[$field]);

            foreach ($fieldRules as $rule) {
                $continue = $this->validateAgainstRule(
                    $field,
                    $value,
                    $this->getRuleName($rule),
                    $this->getRuleArgs($rule)
                );

                // If the rule hasn't passed and it isn't skippable, then we
                // don't need to validate the rest of the rules in the current
                // field.
                if (! $continue) {
                    break;
                }
            }
        }

        return $this;
    }