public function toArray()
    {
        $object = [];

        if (static::$type) {
            $object['type'] = static::$type;
        }

        $attributes = array_merge(
            static::getTypeAttributes(),
            static::$commonAttributes
        );

        foreach ($attributes as $attribute) {
            $value = $this->{$attribute};

            if ($value !== null) {
                $toCopy = $value;

                //Clone object to prevent original object to be changed
                if (is_object($value)) {
                    $toCopy = clone $value;
                }

                $object[$attribute] = $toCopy;
            }

            if (static::$type == 'object' && $attribute == 'properties') {
                foreach ($object[$attribute] as $key => $property) {
                    if ($property instanceof BaseValidator) {
                        $object[$attribute]->{$key} = $property->toArray();
                    }
                }
                //fix type to array
                $object[$attribute] = (array)$object[$attribute];
            } elseif (in_array($attribute, ['allOf', 'anyOf', 'oneOf'])) {
                if (isset($object[$attribute]) && $object[$attribute] !== null) {
                    foreach ($object[$attribute] as $key => $property) {
                        if ($property instanceof BaseValidator) {
                            $object[$attribute][$key] = $property->toArray();
                        }
                    }
                }
            } elseif (in_array($attribute, ['items', 'not'])) {
                if (isset($object[$attribute])
                    && $object[$attribute]
                    && $object[$attribute] instanceof BaseValidator
                ) {
                    $object[$attribute] = $object[$attribute]->toArray();
                }
            }
        }

        return $object;
    }