class KPM::BaseInstaller

def install_plugin(plugin_key, raw_kb_version = nil, specified_group_id = nil, specified_artifact_id = nil, specified_packaging = nil, specified_classifier = nil, specified_version = nil, bundles_dir = nil, specified_type = nil, force_download = false, verify_sha1 = true)

def install_plugin(plugin_key, raw_kb_version = nil, specified_group_id = nil, specified_artifact_id = nil, specified_packaging = nil, specified_classifier = nil, specified_version = nil, bundles_dir = nil, specified_type = nil, force_download = false, verify_sha1 = true)
  # plugin_key needs to exist
  raise ArgumentError, 'Aborting installation: User needs to specify a pluginKey' if plugin_key.nil?
  # Lookup artifact and perform validation against input
  looked_up_group_id, looked_up_artifact_id, looked_up_packaging, looked_up_classifier, looked_up_version, looked_up_type = KPM::PluginsDirectory.lookup(plugin_key, true, raw_kb_version)
  validate_installation_arg!(plugin_key, 'group_id', specified_group_id, looked_up_group_id)
  validate_installation_arg!(plugin_key, 'artifact_id', specified_artifact_id, looked_up_artifact_id)
  validate_installation_arg!(plugin_key, 'packaging', specified_packaging, looked_up_packaging)
  validate_installation_arg!(plugin_key, 'type', specified_type, looked_up_type)
  validate_installation_arg!(plugin_key, 'classifier', specified_classifier, looked_up_classifier)
  # If there is no entry in plugins_directory.yml and the group_id is not the killbill default group_id, the key provided must be a user key and must have a namespace
  if looked_up_artifact_id.nil? &&
     specified_group_id != KPM::BaseArtifact::KILLBILL_JAVA_PLUGIN_GROUP_ID &&
     plugin_key.split(':').size == 1
    raise ArgumentError, "Aborting installation: pluginKey = #{plugin_key} does not exist in plugin_directory.yml so format of the key must have a user namespace (e.g namespace:key)"
  end
  # Specified parameters have always precedence except for the artifact_id (to map stripe to stripe-plugin)
  artifact_id = looked_up_artifact_id || specified_artifact_id
  raise ArgumentError, "Aborting installation: unable to lookup plugin #{specified_artifact_id}" if artifact_id.nil?
  bundles_dir = Pathname.new(bundles_dir || DEFAULT_BUNDLES_DIR).expand_path
  plugins_dir = bundles_dir.join('plugins')
  type = specified_type || looked_up_type
  if type.to_s == 'java'
    group_id = specified_group_id || looked_up_group_id || KPM::BaseArtifact::KILLBILL_JAVA_PLUGIN_GROUP_ID
    packaging = specified_packaging || looked_up_packaging || KPM::BaseArtifact::KILLBILL_JAVA_PLUGIN_PACKAGING
    classifier = specified_classifier || looked_up_classifier || KPM::BaseArtifact::KILLBILL_JAVA_PLUGIN_CLASSIFIER
    version = specified_version || looked_up_version || LATEST_VERSION
    destination = plugins_dir.join('java').join(artifact_id).join(version)
  else
    raise ArgumentError, "Aborting installation: plugin type #{type} unsupported"
  end
  sha1_file = "#{bundles_dir}/#{SHA1_FILENAME}"
  plugins_manager = PluginsManager.new(plugins_dir, @logger)
  _, plugin_name = plugins_manager.get_plugin_key_and_name(plugin_key)
  # Before we do the install we verify that the entry we have in the plugin_identifiers.json matches our current request
  coordinate_map = { group_id: group_id, artifact_id: artifact_id, packaging: packaging, classifier: classifier }
  validate_plugin_key!(plugins_dir, plugin_key, coordinate_map)
  @logger.debug("Installing plugin: group_id=#{group_id} artifact_id=#{artifact_id} packaging=#{packaging} classifier=#{classifier} version=#{version} destination=#{destination}")
  artifact_info = KPM::KillbillPluginArtifact.pull(@logger,
                                                   group_id,
                                                   artifact_id,
                                                   packaging,
                                                   classifier,
                                                   version,
                                                   plugin_name,
                                                   destination,
                                                   sha1_file,
                                                   force_download,
                                                   verify_sha1,
                                                   @nexus_config,
                                                   @nexus_ssl_verify)
  # store trace info to be returned as JSON by the KPM::Installer.install method
  @trace_logger.add('plugins', plugin_key,
                    artifact_info.merge('status' => (artifact_info[:skipped] ? 'UP_TO_DATE' : 'INSTALLED'),
                                        :group_id => group_id, :artifact_id => artifact_id, :packaging => packaging, :classifier => classifier))
  # Update with resolved version
  coordinate_map[:version] = artifact_info[:version]
  mark_as_active(plugins_dir, artifact_info, artifact_id)
  update_plugin_identifier(plugins_dir, plugin_key, type.to_s, coordinate_map, artifact_info)
  artifact_info
end