def _allocate(self, dut_configuration):  # pylint: disable=too-many-branches
        """
        Internal allocation function. Allocates a single resource based on dut_configuration.

        :param dut_configuration: ResourceRequirements object which describes a required resource
        :return: True
        :raises: AllocationError if suitable resource was not found or if the platform was not
        allowed to be used.
        """
        if dut_configuration["type"] == "hardware":
            dut_configuration.set("type", "mbed")
        if dut_configuration["type"] == "mbed":
            if not self._available_devices:
                raise AllocationError("No available devices to allocate from")
            dut_reqs = dut_configuration.get_requirements()
            platforms = None if 'allowed_platforms' not in dut_reqs else dut_reqs[
                'allowed_platforms']
            platform_name = None if 'platform_name' not in dut_reqs else dut_reqs[
                "platform_name"]
            if platform_name is None and platforms:
                platform_name = platforms[0]
            if platform_name and platforms:
                if platform_name not in platforms:
                    raise AllocationError("Platform name not in allowed platforms.")
            # Enumerate through all available devices
            for dev in self._available_devices:
                if platform_name and dev["platform_name"] != platform_name:
                    self.logger.debug("Skipping device %s because of mismatching platform. "
                                      "Required %s but device was %s", dev['target_id'],
                                      platform_name, dev['platform_name'])
                    continue
                if dev['state'] == 'allocated':
                    self.logger.debug("Skipping device %s because it was "
                                      "already allocated", dev['target_id'])
                    continue

                if DutDetection.is_port_usable(dev['serial_port']):
                    dev['state'] = "allocated"
                    dut_reqs['allocated'] = dev
                    self.logger.info("Allocated device %s", dev['target_id'])
                    return True
                else:
                    self.logger.info("Could not open serial port (%s) of "
                                     "allocated device %s", dev['serial_port'], dev['target_id'])
            # Didn't find a matching device to allocate so allocation failed
            raise AllocationError("No suitable local device available")
        elif dut_configuration["type"] == "serial":
            dut_reqs = dut_configuration.get_requirements()
            if not dut_reqs.get("serial_port"):
                raise AllocationError("Serial port not defined for requirement {}".format(dut_reqs))
            if not DutDetection.is_port_usable(dut_reqs['serial_port']):
                raise AllocationError("Serial port {} not usable".format(dut_reqs['serial_port']))
        # Successful allocation, return True

        return True
Internal allocation function. Allocates a single resource based on dut_configuration.

        :param dut_configuration: ResourceRequirements object which describes a required resource
        :return: True
        :raises: AllocationError if suitable resource was not found or if the platform was not
        allowed to be used.