code: def clone_with_new_elements(
              self,
              new_elements,
              drop_keywords=set([]),
              rename_dict={},
              extra_kwargs={}):
          
          kwargs = dict(
              elements=new_elements,
              distinct=self.distinct,
              sort_key=self.sort_key,
              sources=self.sources)
          for name in drop_keywords:
              kwargs.pop(name)
          for old_name, new_name in rename_dict.items():
              kwargs[new_name] = kwargs.pop(old_name)
          kwargs.update(extra_kwargs)
          return self.__class__(**kwargs)
docs: Create another Collection of the same class and with same state but
          possibly different entries. Extra parameters to control which keyword
          arguments get passed to the initializer are necessary since derived
          classes have different constructors than the base class.