# Path: ingenico/connect/sdk/defaultimpl/default_marshaller.py
# class DefaultMarshaller(Marshaller):
#     """
#     Marshaller implementation based on json.
#     """
# 
#     @staticmethod
#     def INSTANCE():
#         return _DEFAULT_MARSHALLER_INSTANCE
# 
#     def marshal(self, request_object):
#         if isinstance(request_object, DataObject):
#             dictionary = request_object.to_dictionary()
#             return dumps(dictionary, default=lambda o: o.to_dictionary(),
#                          indent=4)
#         else:
#             return dumps(request_object, default=lambda o: o.__dict__, indent=4)
# 
#     def unmarshal(self, response_json, type_class):
#         if not response_json:
#             return None
#         if issubclass(type_class, DataObject):
#             try:
#                 return type_class().from_dictionary(loads(response_json))
#             except ValueError as e:
#                 raise MarshallerSyntaxException(e)
# 
#         class Object(object):
#             pass
# 
#         def convert_to_object(d):
#             try:
#                 d = dict(d)
#             except (TypeError, ValueError):
#                 return d
#             o = Object()
#             for key, value in d.items():
#                 o.__dict__[key] = convert_to_object(value)
#             return o
# 
#         try:
#             dictionary = loads(response_json)
#             converted_object = convert_to_object(dictionary)
#             return converted_object
#         except ValueError as e:
#             raise MarshallerSyntaxException(e)
# 
# 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)


import platform
import re
from base64 import b64encode
from ingenico.connect.sdk.data_object import DataObject
from ingenico.connect.sdk.defaultimpl.default_marshaller import \
    DefaultMarshaller
from ingenico.connect.sdk.domain.metadata.shopping_cart_extension import ShoppingCartExtension
from .request_header import RequestHeader
                self.sdk_identifier = dictionary['sdkIdentifier']
            if 'sdkCreator' in dictionary:
                self.sdk_creator = dictionary['sdkCreator']
            if 'integrator' in dictionary:
                self.integrator = dictionary['integrator']
            if 'shoppingCartExtension' in dictionary:
                if not isinstance(dictionary['shoppingCartExtension'], dict):
                    raise TypeError('value \'{}\' is not a dictionary'.format(dictionary['shoppingCartExtension']))
                self.shopping_cart_extension = ShoppingCartExtension.create_from_dictionary(dictionary['shoppingCartExtension'])
            return self

    def __init__(self, integrator, shopping_cart_extension=None,
                 additional_request_headers=()):
        MetaDataProvider.__validate_additional_request_headers(
            additional_request_headers)

        def subber(name_or_value):
            return re.sub(r'\r?\n(?:(?![\r\n])\s)*', " ", name_or_value).strip()
        additional_request_headers = [RequestHeader(subber(header.name), subber(header.value))
                                      for header in additional_request_headers]

        server_meta_info = self.ServerMetaInfo()
        server_meta_info.platform_identifier = self._platform_identifier
        server_meta_info.sdk_identifier = self._sdk_identifier
        server_meta_info.sdk_creator = "Ingenico"
        server_meta_info.integrator = integrator
        server_meta_info.shopping_cart_extension = shopping_cart_extension

        server_meta_info_string = DefaultMarshaller.INSTANCE().marshal(
            server_meta_info)

# Path: ingenico/connect/sdk/defaultimpl/default_marshaller.py
# class DefaultMarshaller(Marshaller):
#     """
#     Marshaller implementation based on json.
#     """
# 
#     @staticmethod
#     def INSTANCE():
#         return _DEFAULT_MARSHALLER_INSTANCE
# 
#     def marshal(self, request_object):
#         if isinstance(request_object, DataObject):
#             dictionary = request_object.to_dictionary()
#             return dumps(dictionary, default=lambda o: o.to_dictionary(),
#                          indent=4)
#         else:
#             return dumps(request_object, default=lambda o: o.__dict__, indent=4)
# 
#     def unmarshal(self, response_json, type_class):
#         if not response_json:
#             return None
#         if issubclass(type_class, DataObject):
#             try:
#                 return type_class().from_dictionary(loads(response_json))
#             except ValueError as e:
#                 raise MarshallerSyntaxException(e)
# 
#         class Object(object):
#             pass
# 
#         def convert_to_object(d):
#             try:
#                 d = dict(d)
#             except (TypeError, ValueError):
#                 return d
#             o = Object()
#             for key, value in d.items():
#                 o.__dict__[key] = convert_to_object(value)
#             return o
# 
#         try:
#             dictionary = loads(response_json)
#             converted_object = convert_to_object(dictionary)
#             return converted_object
#         except ValueError as e:
#             raise MarshallerSyntaxException(e)
# 
# 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/meta_data_provider.py
import platform
import re
from base64 import b64encode
from ingenico.connect.sdk.data_object import DataObject
from ingenico.connect.sdk.defaultimpl.default_marshaller import \
    DefaultMarshaller
from ingenico.connect.sdk.domain.metadata.shopping_cart_extension import ShoppingCartExtension
from .request_header import RequestHeader

                self.sdk_identifier = dictionary['sdkIdentifier']
            if 'sdkCreator' in dictionary:
                self.sdk_creator = dictionary['sdkCreator']
            if 'integrator' in dictionary:
                self.integrator = dictionary['integrator']
            if 'shoppingCartExtension' in dictionary:
                if not isinstance(dictionary['shoppingCartExtension'], dict):
                    raise TypeError('value \'{}\' is not a dictionary'.format(dictionary['shoppingCartExtension']))
                self.shopping_cart_extension = ShoppingCartExtension.create_from_dictionary(dictionary['shoppingCartExtension'])
            return self

    def __init__(self, integrator, shopping_cart_extension=None,
                 additional_request_headers=()):
        MetaDataProvider.__validate_additional_request_headers(
            additional_request_headers)

        def subber(name_or_value):
            return re.sub(r'\r?\n(?:(?![\r\n])\s)*', " ", name_or_value).strip()
        additional_request_headers = [RequestHeader(subber(header.name), subber(header.value))
                                      for header in additional_request_headers]

        server_meta_info = self.ServerMetaInfo()
        server_meta_info.platform_identifier = self._platform_identifier
        server_meta_info.sdk_identifier = self._sdk_identifier
        server_meta_info.sdk_creator = "Ingenico"
        server_meta_info.integrator = integrator
        server_meta_info.shopping_cart_extension = shopping_cart_extension

        server_meta_info_string = DefaultMarshaller.INSTANCE().marshal(
            server_meta_info)

        server_meta_info_header = RequestHeader(