class ErrorType(object):
    def __init__(self, osm_type):
        if osm_type is None:
            raise ValueError("The passed osm_type is not set")
        self.osm_type = osm_type

    def apply_fix(self, kort_fix):
        pass


class MissingTagErrorType(ErrorType):
    @classmethod
    def handles_error(cls, error):
        return False

    def apply_fix(self, kort_fix):
        osm_tag = kort_fix['osm_tag']
        if osm_tag in self.osm_type['tag']:
            raise ErrorTypeError(
                "Tag %s already exists (%s)"
                % (osm_tag, self.osm_type['tag'][osm_tag])
            )
        self.osm_type['tag'][osm_tag] = kort_fix['answer']
        return (
            self.osm_type,
            "Set tag '%s' to '%s'" % (osm_tag, kort_fix['answer'])
        )


class PoiNameErrorType(MissingTagErrorType):
    @classmethod
    def handles_error(cls, error):
        return error == 'poi_name'


class MissingTrackTypeErrorType(MissingTagErrorType):
    @classmethod
    def handles_error(cls, error):
        return error == 'missing_track_type'


class MissingMaxspeedErrorType(MissingTagErrorType):
    @classmethod
    def handles_error(cls, error):
        return error == 'missing_maxspeed'


class ReligionErrorType(MissingTagErrorType):
    @classmethod
    def handles_error(cls, error):
        return error == 'religion'


class LanguageErrorType(ErrorType):
    @classmethod
    def handles_error(cls, error):
        return error == 'language_unknown'

    def apply_fix(self, kort_fix):
        try:
            orig_tag = kort_fix['osm_tag'].replace(':XX', '')
            new_tag = '%s:%s' % (orig_tag, kort_fix['answer'])

            if self.osm_type['tag'][new_tag] == self.osm_type['tag'][orig_tag]:
                raise ErrorTypeError("The fix has already been applied")

            self.osm_type['tag'][new_tag] = self.osm_type['tag'][orig_tag]
        except KeyError, e:
            raise ErrorTypeError("Tag '%s' not found on osm_type", e)
        return (
            self.osm_type,
            "Set tag '%s' to '%s'" % (new_tag, self.osm_type['tag'][orig_tag])
        )


class WayWoTagsErrorType(ErrorType):
    @classmethod
    def handles_error(cls, error):
        return error == 'way_wo_tags'

    def apply_fix(self, kort_fix):
        raise ErrorTypeError(
            "Errors with type way_wo_tags are considered false positives"
        )


class ErrorTypeError(Exception):
    pass


def itersubclasses(cls, _seen=None):
    """
    itersubclasses(cls)
    Generator over all subclasses of a given class, in depth first order.
    """

    if not isinstance(cls, type):
        raise TypeError('itersubclasses must be called with '
                        'new-style classes, not %.100r' % cls)
    if _seen is None:
        _seen = set()
    try:
        subs = cls.__subclasses__()
    except TypeError:  # fails only when cls is type
        subs = cls.__subclasses__(cls)
    for sub in subs:
        if sub not in _seen:
            _seen.add(sub)
            yield sub
            for sub in itersubclasses(sub, _seen):
                yield sub


def Error(error, osm_type):
    for cls in itersubclasses(ErrorType):
        if cls.handles_error(error):
            return cls(osm_type)
    raise ValueError("No class found to handle error '%s'" % error)

@@ -1668,17 +1668,16 @@
 swer'%5D)%0A
-%0A
         
@@ -1680,18 +1680,28 @@
         
-if
+orig_value =
  self.os
@@ -1718,50 +1718,135 @@
 g'%5D%5B
-new_tag%5D == self.osm_type%5B'tag'%5D%5Borig_tag%5D
+orig_tag%5D%0A%0A            if (new_tag in self.osm_type%5B'tag'%5D and%0A                    self.osm_type%5B'tag'%5D%5Bnew_tag%5D == orig_value)
 :%0A  
@@ -1953,50 +1953,68 @@
 ag'%5D
-%5Bnew_tag%5D = self.osm_type%5B'tag'%5D%5Borig_tag%5D
+.update(%7B%0A                new_tag: orig_value%0A            %7D)
 %0A   

Handle case when tag is not yet set