public static function factory() {
		if ( count( func_get_args() ) === 0 ) {
			return new static;
		} else {
			$type = func_get_arg( 0 );
		}

		if ( is_array( $type ) ) {
			$type = (object) $type;
		}

		if ( ! is_string( $type ) && ! is_object( $type ) ) {
			return;
		}

		if ( is_object( $type ) && ! isset( $type->type ) ) {
			$property = new static;
			$property->set_options( $type );

			return $property;
		}

		if ( is_subclass_of( $type, __CLASS__ ) ) {
			return $type;
		}

		$options = null;

		if ( is_object( $type ) ) {
			if ( ! isset( $type->type ) || ! is_string( $type->type ) ) {
				return;
			}

			$options = $type;
			$type    = $type->type;
		}

		// Old types, 'PropertyString' => 'String'.
		$type = preg_replace( '/^Property/', '', $type );

		if ( empty( $type ) ) {
			return;
		}

		$class_name = papi_get_property_class_name( $type );

		if ( ! class_exists( $class_name ) || ! is_subclass_of( $class_name, __CLASS__ ) ) {
			return;
		}

		if ( ! papi()->exists( $class_name ) ) {
			papi()->bind( $class_name, new $class_name() );
		}

		$class = papi()->make( $class_name );

		// @codeCoverageIgnoreStart
		if ( ! is_object( $class ) || $class instanceof Papi_Core_Property === false ) {
			$class = new $class_name();
			papi()->bind( $class_name, $class );
		}
		// @codeCoverageIgnoreEnd

		$property = clone $class;

		if ( is_object( $options ) ) {
			$property->set_options( (array) $options );
		}

		return $property;
	}