# Path: ingenico/connect/sdk/pooled_connection.py
# class PooledConnection(Connection):
#     """
#     Represents a pooled connection to the Ingenico ePayments platform server.
#     Instead of setting up a new HTTP connection for each request, this
#     connection uses a pool of HTTP connections.
#     """
# 
#     def close_idle_connections(self, idle_time):
#         """
#         Closes all HTTP connections that have been idle for the specified time.
#         This should also include all expired HTTP connections.
# 
#         :param idle_time: a datetime.timedelta object indicating the idle time
#         """
#         raise NotImplementedError
# 
#     def close_expired_connections(self):
#         """
#         Closes all expired HTTP connections.
#         """
#         raise NotImplementedError
# 
# Path: ingenico/connect/sdk/request_header.py
# class RequestHeader:
#     """
#     A single request header. Immutable.
#     """
# 
#     def __init__(self, name, value):
#         if name is None or not name.strip():
#             raise ValueError("name is required")
#         self.__name = name
#         self.__value = value
# 
#     @property
#     def name(self):
#         """
#         :return: The header name.
#         """
#         return self.__name
# 
#     @property
#     def value(self):
#         """
#         :return: The un-encoded value.
#         """
#         return self.__value.decode('utf-8') if isinstance(self.__value, bytes) else self.__value
# 
#     def __str__(self):
#         return self.__name + ":" + str(self.__value)
# 
# Path: ingenico/connect/sdk/response_exception.py
# class ResponseException(RuntimeError):
#     """
#     Thrown when a response was received from the Ingenico ePayments platform which
#     indicates an error.
#     """
# 
#     def __init__(self, status, body, headers):
#         super(ResponseException, self).__init__(
#             "the Ingenico ePayments platform returned an error response")
#         self.__status_code = status
#         self.__headers = headers if headers is not None else {}
#         self.__body = body
# 
#     @property
#     def status_code(self):
#         """
#         :return: The HTTP status code that was returned by the Ingenico ePayments
#          platform.
#         """
#         return self.__status_code
# 
#     @property
#     def body(self):
#         """
#         :return: The raw response body that was returned by the Ingenico ePayments
#          platform.
#         """
#         return self.__body
# 
#     @property
#     def headers(self):
#         """
#         :return: The headers that were returned by the Ingenico ePayments platform.
#          Never None.
#         """
#         return self.__headers
# 
#     def get_header(self, header_name):
#         """
#         :return: The header with the given name, or None if there was no such
#          header.
#         """
#         return get_header(self.__headers, header_name)
# 
#     def get_header_value(self, header_name):
#         """
#         :return: The value header with the given name, or None if there was no
#          such header.
#         """
#         return get_header_value(self.__headers, header_name)
# 
#     def __str__(self):
#         string = super(ResponseException, self).__str__()
#         status_code = self.__status_code
#         if status_code > 0:
#             string += "; status_code=" + str(status_code)
#         response_body = self.__body
#         if response_body:
#             string += "; response_body='" + response_body + "'"
#         return str(string)
# 
# Path: ingenico/connect/sdk/response_header.py
# def get_header_value(headers, header_name):
#     """
#     :return: The value of the header with the given name, or None if there
#      was no such header.
#     """
#     if headers is None:
#         return None
#     for name, value in headers.items():
#         if name.lower() == header_name.lower():
#             return value
#     return None


from datetime import datetime
from urllib.parse import quote
from urllib.parse import urlparse
from .communication_exception import CommunicationException
from ingenico.connect.sdk.log.logging_capable import LoggingCapable
from .not_found_exception import NotFoundException
from .pooled_connection import PooledConnection
from .multipart_form_data_object import MultipartFormDataObject
from .multipart_form_data_request import MultipartFormDataRequest
from .request_header import RequestHeader
from .response_exception import ResponseException
from .response_header import get_header_value
            else:
                raise CommunicationException(cause)
        else:
            raise ResponseException(status, body, headers)

    def __is_json(self, headers):
        content_type = get_header_value(headers, "Content-Type")
        return (content_type is None) or (
            "application/json".lower() == content_type) or (
                content_type.lower().startswith("application/json"))

    def close_idle_connections(self, idle_time):
        """
        Utility method that delegates the call to this communicator's session's
        connection if that's an instance of PooledConnection. If not this method
        does nothing.

        :param idle_time: a datetime.timedelta object indicating the idle time
        """
        connection = self.__session.connection
        if isinstance(connection, PooledConnection):
            connection.close_idle_connections(idle_time)

    def close_expired_connections(self):
        """
        Utility method that delegates the call to this communicator's session's
        connection if that's an instance of PooledConnection. If not this method
        does nothing.
        """
        connection = self.__session.connection

# Path: ingenico/connect/sdk/pooled_connection.py
# class PooledConnection(Connection):
#     """
#     Represents a pooled connection to the Ingenico ePayments platform server.
#     Instead of setting up a new HTTP connection for each request, this
#     connection uses a pool of HTTP connections.
#     """
# 
#     def close_idle_connections(self, idle_time):
#         """
#         Closes all HTTP connections that have been idle for the specified time.
#         This should also include all expired HTTP connections.
# 
#         :param idle_time: a datetime.timedelta object indicating the idle time
#         """
#         raise NotImplementedError
# 
#     def close_expired_connections(self):
#         """
#         Closes all expired HTTP connections.
#         """
#         raise NotImplementedError
# 
# Path: ingenico/connect/sdk/request_header.py
# class RequestHeader:
#     """
#     A single request header. Immutable.
#     """
# 
#     def __init__(self, name, value):
#         if name is None or not name.strip():
#             raise ValueError("name is required")
#         self.__name = name
#         self.__value = value
# 
#     @property
#     def name(self):
#         """
#         :return: The header name.
#         """
#         return self.__name
# 
#     @property
#     def value(self):
#         """
#         :return: The un-encoded value.
#         """
#         return self.__value.decode('utf-8') if isinstance(self.__value, bytes) else self.__value
# 
#     def __str__(self):
#         return self.__name + ":" + str(self.__value)
# 
# Path: ingenico/connect/sdk/response_exception.py
# class ResponseException(RuntimeError):
#     """
#     Thrown when a response was received from the Ingenico ePayments platform which
#     indicates an error.
#     """
# 
#     def __init__(self, status, body, headers):
#         super(ResponseException, self).__init__(
#             "the Ingenico ePayments platform returned an error response")
#         self.__status_code = status
#         self.__headers = headers if headers is not None else {}
#         self.__body = body
# 
#     @property
#     def status_code(self):
#         """
#         :return: The HTTP status code that was returned by the Ingenico ePayments
#          platform.
#         """
#         return self.__status_code
# 
#     @property
#     def body(self):
#         """
#         :return: The raw response body that was returned by the Ingenico ePayments
#          platform.
#         """
#         return self.__body
# 
#     @property
#     def headers(self):
#         """
#         :return: The headers that were returned by the Ingenico ePayments platform.
#          Never None.
#         """
#         return self.__headers
# 
#     def get_header(self, header_name):
#         """
#         :return: The header with the given name, or None if there was no such
#          header.
#         """
#         return get_header(self.__headers, header_name)
# 
#     def get_header_value(self, header_name):
#         """
#         :return: The value header with the given name, or None if there was no
#          such header.
#         """
#         return get_header_value(self.__headers, header_name)
# 
#     def __str__(self):
#         string = super(ResponseException, self).__str__()
#         status_code = self.__status_code
#         if status_code > 0:
#             string += "; status_code=" + str(status_code)
#         response_body = self.__body
#         if response_body:
#             string += "; response_body='" + response_body + "'"
#         return str(string)
# 
# Path: ingenico/connect/sdk/response_header.py
# def get_header_value(headers, header_name):
#     """
#     :return: The value of the header with the given name, or None if there
#      was no such header.
#     """
#     if headers is None:
#         return None
#     for name, value in headers.items():
#         if name.lower() == header_name.lower():
#             return value
#     return None


# Path: ingenico/connect/sdk/communicator.py
from datetime import datetime
from urllib.parse import quote
from urllib.parse import urlparse
from .communication_exception import CommunicationException
from ingenico.connect.sdk.log.logging_capable import LoggingCapable
from .not_found_exception import NotFoundException
from .pooled_connection import PooledConnection
from .multipart_form_data_object import MultipartFormDataObject
from .multipart_form_data_request import MultipartFormDataRequest
from .request_header import RequestHeader
from .response_exception import ResponseException
from .response_header import get_header_value

            else:
                raise CommunicationException(cause)
        else:
            raise ResponseException(status, body, headers)

    def __is_json(self, headers):
        content_type = get_header_value(headers, "Content-Type")
        return (content_type is None) or (
            "application/json".lower() == content_type) or (
                content_type.lower().startswith("application/json"))

    def close_idle_connections(self, idle_time):
        """
        Utility method that delegates the call to this communicator's session's
        connection if that's an instance of PooledConnection. If not this method
        does nothing.

        :param idle_time: a datetime.timedelta object indicating the idle time
        """
        connection = self.__session.connection
        if isinstance(connection, PooledConnection):
            connection.close_idle_connections(idle_time)

    def close_expired_connections(self):
        """
        Utility method that delegates the call to this communicator's session's
        connection if that's an instance of PooledConnection. If not this method
        does nothing.
        """
        connection = self.__session.connection

        if isinstance(connection, PooledConnection):