'Set the values of the field specified by ``name``. Returns the set of all book ids that were affected by the change.
:param book_id_to_val_map: Mapping of book_ids to values that should be applied.
:param allow_case_change: If True, the case of many-one or many-many fields will be changed.
For example, if a  book has the tag ``tag1`` and you set the tag for another book to ``Tag1``
then the both books will have the tag ``Tag1`` if allow_case_change is True, otherwise they will
both have the tag ``tag1``.
:param do_path_update: Used internally, you should never change it.'

@write_api
def set_field(self, name, book_id_to_val_map, allow_case_change=True, do_path_update=True):

    f = self.fields[name]
    is_series = (f.metadata[u'datatype'] == u'series')
    update_path = (name in {u'title', u'authors'})
    if (update_path and iswindows):
        paths = (x for x in (self._field_for(u'path', book_id) for book_id in book_id_to_val_map) if x)
        self.backend.windows_check_if_files_in_use(paths)
    if is_series:
        (bimap, simap) = ({}, {})
        sfield = self.fields[(name + u'_index')]
        for (k, v) in book_id_to_val_map.iteritems():
            if isinstance(v, basestring):
                (v, sid) = get_series_values(v)
            else:
                v = sid = None
            if ((sid is None) and name.startswith(u'#')):
                extra = self._fast_field_for(sfield, k)
                sid = (extra or 1.0)
            bimap[k] = v
            if (sid is not None):
                simap[k] = sid
        book_id_to_val_map = bimap
    dirtied = f.writer.set_books(book_id_to_val_map, self.backend, allow_case_change=allow_case_change)
    if (is_series and simap):
        sf = self.fields[(f.name + u'_index')]
        dirtied |= sf.writer.set_books(simap, self.backend, allow_case_change=False)
    if (dirtied and update_path and do_path_update):
        self._update_path(dirtied, mark_as_dirtied=False)
    self._mark_as_dirty(dirtied)
    return dirtied
