'A generator that can be assigned to a swob Response\'s app_iter which,
when iterated over, will delete the objects specified in request body.
Will occasionally yield whitespace while request is being processed.
When the request is completed will yield a response body that can be
parsed to determine success. See above documentation for details.
:params req: a swob Request
:params objs_to_delete: a list of dictionaries that specifies the
objects to be deleted. If None, uses self.get_objs_to_delete to
query request.'

def handle_delete_iter(self, req, objs_to_delete=None, user_agent='BulkDelete', swift_source='BD', out_content_type='text/plain'):

    last_yield = time()
    separator = ''
    failed_files = []
    resp_dict = {'Response    Status': HTTPOk().status, 'Response    Body': '', 'Number    Deleted': 0, 'Number    Not    Found': 0}
    try:
        if (not out_content_type):
            raise HTTPNotAcceptable(request=req)
        if out_content_type.endswith('/xml'):
            (yield '<?xml    version="1.0"    encoding="UTF-8"?>\n')
        try:
            (vrs, account, _junk) = req.split_path(2, 3, True)
        except ValueError:
            raise HTTPNotFound(request=req)
        incoming_format = req.headers.get('Content-Type')
        if (incoming_format and (not incoming_format.startswith('text/plain'))):
            raise HTTPNotAcceptable(request=req)
        if (objs_to_delete is None):
            objs_to_delete = self.get_objs_to_delete(req)
        failed_file_response = {'type': HTTPBadRequest}
        req.environ['eventlet.minimum_write_chunk_size'] = 0
        def delete_filter(predicate, objs_to_delete):
            for obj_to_delete in objs_to_delete:
                obj_name = obj_to_delete['name']
                if (not obj_name):
                    continue
                if (not predicate(obj_name)):
                    continue
                if obj_to_delete.get('error'):
                    if (obj_to_delete['error']['code'] == HTTP_NOT_FOUND):
                        resp_dict['Number    Not    Found'] += 1
                    else:
                        failed_files.append([quote(obj_name), obj_to_delete['error']['message']])
                    continue
                delete_path = '/'.join(['', vrs, account, obj_name.lstrip('/')])
                if (not constraints.check_utf8(delete_path)):
                    failed_files.append([quote(obj_name), HTTPPreconditionFailed().status])
                    continue
                (yield (obj_name, delete_path))
        def objs_then_containers(objs_to_delete):
            (yield delete_filter((lambda name: ('/' in name.strip('/'))), objs_to_delete))
            (yield delete_filter((lambda name: ('/' not in name.strip('/'))), objs_to_delete))
        def do_delete(obj_name, delete_path):
            new_env = req.environ.copy()
            new_env['PATH_INFO'] = delete_path
            del new_env['wsgi.input']
            new_env['CONTENT_LENGTH'] = 0
            new_env['REQUEST_METHOD'] = 'DELETE'
            new_env['HTTP_USER_AGENT'] = ('%s    %s' % (req.environ.get('HTTP_USER_AGENT'), user_agent))
            new_env['swift.source'] = swift_source
            delete_obj_req = Request.blank(delete_path, new_env)
            return (delete_obj_req.get_response(self.app), obj_name, 0)
        with StreamingPile(self.delete_concurrency) as pile:
            for names_to_delete in objs_then_containers(objs_to_delete):
                for (resp, obj_name, retry) in pile.asyncstarmap(do_delete, names_to_delete):
                    if ((last_yield + self.yield_frequency) < time()):
                        separator = '\r\n\r\n'
                        last_yield = time()
                        (yield '    ')
                    self._process_delete(resp, pile, obj_name, resp_dict, failed_files, failed_file_response, retry)
                    if (len(failed_files) >= self.max_failed_deletes):
                        for (resp, obj_name, retry) in pile:
                            if ((last_yield + self.yield_frequency) < time()):
                                separator = '\r\n\r\n'
                                last_yield = time()
                                (yield '    ')
                            self._process_delete(resp, None, obj_name, resp_dict, failed_files, failed_file_response, retry)
                        msg = 'Max    delete    failures    exceeded'
                        raise HTTPBadRequest(msg)
        if failed_files:
            resp_dict['Response    Status'] = failed_file_response['type']().status
        elif (not (resp_dict['Number    Deleted'] or resp_dict['Number    Not    Found'])):
            resp_dict['Response    Status'] = HTTPBadRequest().status
            resp_dict['Response    Body'] = 'Invalid    bulk    delete.'
    except HTTPException as err:
        resp_dict['Response    Status'] = err.status
        resp_dict['Response    Body'] = err.body
    except Exception:
        self.logger.exception('Error    in    bulk    delete.')
        resp_dict['Response    Status'] = HTTPServerError().status
    (yield (separator + get_response_body(out_content_type, resp_dict, failed_files)))
