'Validate and parse a given application configuration from flocker\'s
configuration format.
:raises ConfigurationError: if there are validation errors.'

def _parse(self):

    self._validate_configuration_keys()
    for (application_name, config) in self._application_configuration[u'applications'].items():
        self._validate_application_keys(application_name, config)
        image_name = config[u'image']
        try:
            image = DockerImage.from_string(image_name)
        except ValueError as e:
            raise ConfigurationError(u"Application    '{application_name}'    has    a    config    error.    Invalid    Docker    image    name.    {message}".format(application_name=application_name, message=e.message))
        ports = []
        try:
            for port in config.pop(u'ports', []):
                try:
                    internal_port = port.pop(u'internal')
                except KeyError:
                    raise ValueError(u'Missing    internal    port.')
                try:
                    external_port = port.pop(u'external')
                except KeyError:
                    raise ValueError(u'Missing    external    port.')
                if port:
                    raise ValueError(u'Unrecognised    keys:    {keys}.'.format(keys=u',    '.join(sorted(port.keys()))))
                ports.append(Port(internal_port=internal_port, external_port=external_port))
        except ValueError as e:
            raise ConfigurationError(u"Application    '{application_name}'    has    a    config    error.    Invalid    ports    specification.    {message}".format(application_name=application_name, message=e.message))
        links = self._parse_link_configuration(application_name, config.pop(u'links', []))
        volume = None
        if (u'volume' in config):
            try:
                configured_volume = config.pop(u'volume')
                volume = self._parse_volume(configured_volume, application_name)
            except ValueError as e:
                raise ConfigurationError(u"Application    '{application_name}'    has    a    config    error.    Invalid    volume    specification.    {message}".format(application_name=application_name, message=e.message))
        environment = self._parse_environment_config(application_name, config)
        if (u'mem_limit' in config):
            mem_limit = config[u'mem_limit']
            _check_type(value=mem_limit, types=(int,), description=u'mem_limit    must    be    an    integer', application_name=application_name)
        else:
            mem_limit = None
        if (u'cpu_shares' in config):
            cpu_shares = config[u'cpu_shares']
            _check_type(value=cpu_shares, types=(int,), description=u'cpu_shares    must    be    an    integer', application_name=application_name)
        else:
            cpu_shares = None
        attributes = dict(name=application_name, image=image, volume=volume, ports=frozenset(ports), links=links, environment=environment, memory_limit=mem_limit, cpu_shares=cpu_shares)
        if (u'restart_policy' in config):
            attributes[u'restart_policy'] = self._parse_restart_policy(application_name=application_name, config=config.pop(u'restart_policy'))
        self._applications[application_name] = Application(**attributes)
