public function oauth2_token()
    {
        if (! function_exists('curl_init')) {
            throw new \Exception('To make API requests, the PHP curl extension must be available.');
        }
        if (self::$_oauth_consumer_key == null) {
            throw new \Exception('To obtain a bearer token, the consumer key must be set.');
        }
        $ch  = false;
        $post_fields = array(
            'grant_type' => 'client_credentials'
        );
        $url = self::$_endpoint_oauth . 'oauth2/token';
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cacert.pem');

        curl_setopt($ch, CURLOPT_USERPWD, self::$_oauth_consumer_key . ':' . self::$_oauth_consumer_secret);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Expect:'
        ));
        $reply = curl_exec($ch);

        // certificate validation results
        $validation_result = curl_errno($ch);
        if (in_array(
                $validation_result,
                array(
                    CURLE_SSL_CERTPROBLEM,
                    CURLE_SSL_CACERT,
                    CURLE_SSL_CACERT_BADFILE,
                    CURLE_SSL_CRL_BADFILE,
                    CURLE_SSL_ISSUER_ERROR
                )
            )
        ) {
            throw new \Exception('Error ' . $validation_result . ' while validating the Twitter API certificate.');
        }

        $httpstatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $reply = $this->_parseApiReply('oauth2/token', $reply);
        switch ($this->_return_format) {
            case CODEBIRD_RETURNFORMAT_ARRAY:
                $reply['httpstatus'] = $httpstatus;
                if ($httpstatus == 200) {
                    self::setBearerToken($reply['access_token']);
                }
                break;
            case CODEBIRD_RETURNFORMAT_JSON:
                if ($httpstatus == 200) {
                    $parsed = json_decode($reply);
                    self::setBearerToken($parsed->access_token);
                }
                break;
            case CODEBIRD_RETURNFORMAT_OBJECT:
                $reply->httpstatus = $httpstatus;
                if ($httpstatus == 200) {
                    self::setBearerToken($reply->access_token);
                }
                break;
        }
        return $reply;
    }