class NSWTopo::Map

def add(*layers, after: nil, before: nil, replace: nil, overwrite: false, strict: false)

def add(*layers, after: nil, before: nil, replace: nil, overwrite: false, strict: false)
  [%w[before after replace], [before, after, replace]].transpose.select(&:last).each do |option, name|
    next if self.layers.any? { |other| other.name == name }
    raise "no such layer: %s" % name
  end.map(&:first).combination(2).each do |options|
    raise OptionParser::AmbiguousOption,  "can't specify --%s and --%s simultaneously" % options
  end
  strict ||= layers.one?
  layers.inject [self.layers, false, replace || after, []] do |(layers, changed, follow, errors), layer|
    index = layers.index layer unless replace || after || before
    if overwrite || !layer.uptodate?
      layer.create
      log_success "%s layer: %s" % [layer.empty? ? "empty" : "added", layer.name]
    else
      log_neutral "kept existing layer: %s" % layer.name
      next layers, changed, layer.name, errors if index
    end
    layers.delete layer
    case
    when index
    when follow
      index = layers.index { |other| other.name == follow }
      index += 1
    when before
      index = layers.index { |other| other.name == before }
    else
      index = layers.index { |other| (other <=> layer) > 0 } || -1
    end
    next layers.insert(index, layer), true, layer.name, errors
  rescue ArcGIS::Connection::Error => error
    log_warn "couldn't download layer: #{layer.name}"
    next layers, changed, follow, errors << error
  rescue RuntimeError => error
    errors << error
    break layers, changed, follow, errors if strict
    log_warn error.message
    next layers, changed, follow, errors
  end.tap do |ordered_layers, changed, follow, errors|
    if changed
      @layers.replace Hash[ordered_layers.map(&:pair)]
      replace ? delete(replace) : save
    end
    case
    when errors.none?
    when strict
      raise errors.first
    when errors.one?
      raise PartialFailureError, "failed to create layer"
    else
      raise PartialFailureError, "failed to create #{errors.length} layers"
    end
  end
end