'Replace the fields in the model and return a new instance
Examples::
# Returns a track with a new name
Track(name=\'foo\').replace(name=\'bar\')
# Return an album with a new number of tracks
Album(num_tracks=2).replace(num_tracks=5)
Note that internally we memoize heavily to keep memory usage down given
our overly repetitive data structures. So you might get an existing
instance if it contains the same values.
:param kwargs: kwargs to set as fields on the object
:type kwargs: any
:rtype: instance of the model with replaced fields'

def replace(self, **kwargs):

    if (not kwargs):
        return self
    other = super(ValidatedImmutableObject, self).replace(**kwargs)
    if hasattr(self, u'_hash'):
        object.__delattr__(other, u'_hash')
    return self._instances.setdefault(weakref.ref(other), other)
