protected function getDefaultPlugins(): array
    {
        // Alters requests, adds base path and authentication.
        $firstPlugins = [
            new BaseUriPlugin($this->getBaseUri(), ['replace' => true]),
            new HeaderDefaultsPlugin($this->getDefaultHeaders()),
        ];

        if ($this->authentication) {
            $firstPlugins[] = new AuthenticationPlugin($this->authentication);
        }

        // Acts based on response data.
        // (Retry plugin should be added here if it will be used.)
        $middlePlugins = [
            new HistoryPlugin($this->journal),
        ];

        if (null !== $this->retryPluginConfig) {
            if (!isset($this->retryPluginConfig['exception_decider'])) {
                $this->retryPluginConfig['exception_decider'] = function (RequestInterface $request, Exception $e) {
                    // When Oauth authentication is in use retry decider should ignore
                    // OauthAuthenticationException.
                    if (!$e instanceof OauthAuthenticationException) {
                        // Do not retry API calls that failed with
                        // client error.
                        if ($e instanceof ApiResponseException && $e->getResponse()->getStatusCode() >= 400 && $e->getResponse()->getStatusCode() < 500) {
                            return false;
                        }

                        return true;
                    }

                    return false;
                };
            }
            $middlePlugins[] = new RetryPlugin($this->retryPluginConfig);
        }

        if ($this->authentication instanceof Oauth) {
            $middlePlugins[] = new RetryOauthAuthenticationPlugin($this->authentication);
        }

        // Alters, analyzes responses.
        $finalPlugins = [
            new ResponseHandlerPlugin($this->errorFormatter),
        ];

        return array_merge($firstPlugins, $middlePlugins, $finalPlugins);
    }