    import * as L from '@mapgis/leaflet'
    /* eslint-disable camelcase */
    // save these original methods before they are overwritten
    const proto_initIcon = L.Marker.prototype._initIcon

    const oldIE = L.DomUtil.TRANSFORM === 'msTransform'

    L.Marker.addInitHook(function () {
      // eslint-disable-next-line no-invalid-this
      const iconOptions = this.options.icon && this.options.icon.options
      // eslint-disable-next-line no-invalid-this
      let iconAnchor = iconOptions && this.options.icon.options.iconAnchor
      if (iconAnchor) {
        iconAnchor = `${iconAnchor[0]}px ${iconAnchor[1]}px`
      }
      // eslint-disable-next-line no-invalid-this
      this.options.rotationOrigin =
        this.options.rotationOrigin || iconAnchor || 'center bottom'
      // eslint-disable-next-line no-invalid-this
      this.options.rotationAngle = this.options.rotationAngle || 0

      // Ensure marker keeps rotated during dragging
      // eslint-disable-next-line no-invalid-this
      this.on('drag', function (e) {
        e.target._applyRotation()
      })
    })

    /**
     * L.Marker
     */
    const markerProto = L.extend({}, L.Marker.prototype)

    L.Marker.mergeOptions({
      rotationAngle: 0
    })

    L.Marker.include({
      getEvents() {
        return L.extend(markerProto.getEvents.call(this), { rotate: this.update })
      },

      onAdd(map) {
        markerProto.onAdd.call(this, map)
        map.on('rotate', this.update, this)
      },

      onRemove(map) {
        markerProto.onRemove.call(this, map)
        map.off('rotate', this.update, this)
      },

      _initIcon() {
        proto_initIcon.call(this)
      },

      _setPos(pos) {
        // TODO: use markerProto._setPos
        if (this._map._rotate) {
          pos = this._map.rotatedPointToMapPanePoint(pos)
        }

        // TODO: use markerProto._setPos
        const bearing = this.options.rotationAngle * L.DomUtil.DEG_TO_RAD || 0

        // TODO: use markerProto._setPos
        L.DomUtil.setPositionBearing(this._icon, pos, bearing, pos)

        // TODO: use markerProto._setPos
        if (this._shadow) {
          L.DomUtil.setPositionBearing(this._shadow, pos, bearing, pos)
        }

        this._zIndex = pos.y + this.options.zIndexOffset

        this._resetZIndex()
      },

      _updateZIndex(offset) {
        if (!this._map._rotate) {
          return markerProto._updateZIndex.call(this, offset)
        }
        this._icon.style.zIndex = Math.round(this._zIndex + offset)
      },

      setRotationAngle(angle) {
        this.options.rotationAngle = angle
        this.update()
        return this
      },

      setRotationOrigin(origin) {
        this.options.rotationOrigin = origin
        this.update()
        return this
      },

      setStyle(options) {
        options = options || {}
        const icon = options.icon
        const rotationAngle = options.rotationAngle

        if (icon) {
          this.options.icon = icon

          if (this._map) {
            this._initIcon()
          }

          if (this._popup) {
            this.bindPopup(this._popup, this._popup.options)
          }
        }

        if (rotationAngle) {
          this.options.rotationAngle = rotationAngle
        }

        this.update()
      }
    })