public function pushFile($filePath, $mimeType = null, $title = null, $body = null, $altFileName = null)
    {
        self::checkPushable();

        $fullFilePath = realpath($filePath);

        if (!is_readable($fullFilePath)) {
            throw new Exceptions\NotFoundException('File does not exist or is unreadable.');
        }

        if (filesize($fullFilePath) > 25 * 1024 * 1024) {
            throw new Exceptions\FilePushException('File size exceeds 25 MB.');
        }

        $data = [];

        $data['file_name'] = $altFileName === null ? basename($fullFilePath) : $altFileName;

        // Try to guess the MIME type if the argument is NULL
        $data['file_type'] = $mimeType === null ? mime_content_type($fullFilePath) : $mimeType;

        // Request authorization to upload the file
        $response = Connection::sendCurlRequest(Connection::URL_UPLOAD_REQUEST, 'GET', $data, true, $this->apiKey);
        $data['file_url'] = $response->file_url;

        if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
            $response->data->file = new \CURLFile($fullFilePath);
        } else {
            $response->data->file = '@' . $fullFilePath;
        }

        // Upload the file
        Connection::sendCurlRequest($response->upload_url, 'POST', $response->data, false, null);

        $data[$this->recipientType] = $this->recipient;
        $data['type'] = 'file';
        $data['title'] = $title;
        $data['body'] = $body;

        return new Push(
            Connection::sendCurlRequest(Connection::URL_PUSHES, 'POST', $data, true, $this->apiKey),
            $this->apiKey
        );
    }