<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _assign_fields(self, identifiers, field_values, assign_positions, assigned_bits=0):
 """For internal use only. Assign lengths & positions to a subset of all potential fields with the supplied field_values. This method will check for any assigned bits of all potential fields but will only assign those fields whose identifiers are provided. Parameters identifiers : iterable of identifiers The identifiers of the fields to assign The values held by various fields (used to access the correct identifiers) assign_positions : bool If False, will only assign lengths to fields whose positions are already known. Otherwise lengths and positions will be assigned to all fields as necessary. assigned_bits : int A bit mask of bits which are already allocated. (Note that this will automatically be extended with any already-assigned potential fields' bits.) Returns ------- int Mask of which bits which are assigned to fields after fields have been assigned. """

        # Calculate a mask of already allocated fields' bits
        for i, f in self.fields.potential_fields(field_values):
            if f.length is not None and f.start_at is not None:
                assigned_bits |= ((1 << f.length) - 1) << f.start_at

        # Allocate all specified fields
        for identifier in identifiers:
            field = self.fields.get_field(identifier, field_values)
            if field.length is not None and field.start_at is not None:
                # Already allocated, do nothing!
                pass
            elif assign_positions or field.start_at is not None:
                assigned_bits |= self._assign_field(assigned_bits,
                                                    identifier,
                                                    field_values)

        return assigned_bits