public function createHandler(string $id, string $type, int $level, array $config): HandlerInterface
    {
        if (!isset($this->_handlers[$id])) {
            $config = array_replace(
                [
                    'processorIds'          => []
                ],
                $config
            );

            if (!is_array($config['processorIds'])) {
                throw InvalidConfigException::create('processorIds', 'array');
            }

            /** @var HandlerInterface $handler */
            $handler = null;

            switch ($type) {
                case self::HANDLER_TYPE_STREAM:
                    $config = array_replace(
                        [
                            'bubble'            => true,
                            'filePermission'    => null,
                            'useLocking'        => false
                        ],
                        $config
                    );

                    if (!isset($config['stream']) || !is_string($config['stream'])) {
                        throw InvalidConfigException::create('stream', 'string');
                    }

                    $handler = new StreamHandler(
                        $config['stream'],
                        $level,
                        $config['bubble'],
                        $config['filePermission'],
                        $config['useLocking']
                    );

                    $this->setHandler($id, $handler);

                    break;
                case self::HANDLER_TYPE_ERROR_LOG:
                    $config = array_replace(
                        [
                            'messageType'       => ErrorLogHandler::OPERATING_SYSTEM,
                            'bubble'            => true,
                            'expandNewLines'    => false
                        ],
                        $config
                    );
                    $handler = new ErrorLogHandler(
                        $config['messageType'],
                        $level,
                        $config['bubble'],
                        $config['expandNewLines']
                    );

                    $this->setHandler($id, $handler);

                    break;
                case self::HANDLER_TYPE_NULL:
                    $handler = new NullHandler($level);

                    $this->setHandler($id, $handler);

                    break;
                default:
                    throw new \InvalidArgumentException(
                        'Type "'.$type.'" is not handled yet by this component. You can set manually the handler '.
                        'instance using the "setHandler" method.'
                    );
            }

            if ($config['processorIds']) {
                foreach ($config['processorIds'] as $processorId) {
                    if (!isset($this->_processors[$processorId])) {
                        throw InvalidConfigException::create(
                            'processorIds',
                            'array',
                            'Additionally, processor ID "'.$processorId.'" does not exist.'
                        );
                    }

                    $handler->pushProcessor($this->_processors[$processorId]);
                }
            }

            $this->_handlers[$id] = $handler;
        }

        return $this->_handlers[$id];
    }