public static function createFromObject($object)
    {
        $isFromBase = (static::class === self::class);

        if (!is_object($object)) {
            throw new \Exception('Expecting an object');
        }

        //Test type if it's set
        if (property_exists($object, 'type') && !empty($object->type)) {
            if (array_key_exists($object->type, self::$validatorRegistry)) {
                if (is_object($object->type) || is_array($object->type) || $object->type === null) {
                    throw new \Exception('Expecting string for type');
                }
                $className = self::$validatorRegistry[$object->type];
                $validator = new $className();
            /*} elseif (class_exists(__NAMESPACE__ . '\\' . $object->type)) {
                //if already loaded
                $className = __NAMESPACE__ . '\\' . $object->type;
                $validator = new $className();
            } elseif (class_exists(__NAMESPACE__ . '\\' . $object->type . 'Validator')) {
                //if already loaded
                $className = __NAMESPACE__ . '\\' . $object->type . 'Validator';
                $validator = new $className();*/
            } else {
                $className = $object->type . 'Validator';

                try {
                    //prevent fatal error
                    new \ReflectionClass($className);
                    //attempt to create class
                    $validator = new $className();
                } catch (\Exception $e) {
                    //Wont catch the fatal error
                    throw new \Exception(sprintf(
                        'Incorrect type "%s" from "%s"',
                        $object->type,
                        static::class
                    ));
                }
            }
        } elseif (($validator = static::createFromObjectForAdditional($object)) !== null) {
            return $validator;
        } elseif (!$isFromBase
            || (isset($object->type) && !empty($object->type) && $object->type == static::$type)
        ) {
            $validator = new static();
        } else {
            throw new \Exception(sprintf(
                'Type is required when creating from "%s"',
                self::class
            ));
        }

        //For each Validator's attribute
        foreach (array_merge(
            $validator::getTypeAttributes(),
            $validator::$commonAttributes
        ) as $attribute) {
            //Check if provided object contains this attribute
            if (property_exists($object, $attribute)) {
                if ($attribute == 'properties') {
                    //get properties as array
                    $properties = $object->{$attribute};

                    $createdProperties = new \stdClass();

                    foreach ($properties as $key => $property) {
                        //TODO remove
                        //if (!is_object($property)) {
                        //    throw new \Exception(sprintf(
                        //        'Expected object for property value "%s"',
                        //        $key
                        //    ));
                        //}

                        $createdProperties->{$key} =
                        BaseValidator::createFromObject($property);
                    }
                    //push to class
                    $validator->{$attribute} = $createdProperties;
                } elseif ($attribute == 'items' || $attribute == 'not') {
                    $validator->{$attribute} = BaseValidator::createFromObject(
                        $object->{$attribute}
                    );
                } else {
                    //Use attributes value in Validator object
                    $validator->{$attribute} = $object->{$attribute};
                }
            }
        }

        return $validator;
    }