From 90c7fcb682233d2abb82567fdb10fea8be748faa Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Mon, 27 May 2024 09:58:46 +0000
Subject: [PATCH 01/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index b560824b9..0c6f95580 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.17
-build-info-extractor-gradle-version=4.33.16
+build-info-version=2.41.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From 28ac9af610a463aa6700c36a22fc179b566d59a6 Mon Sep 17 00:00:00 2001
From: Yahav Itschak <yahavi@users.noreply.github.com>
Date: Sun, 9 Jun 2024 08:43:47 +0300
Subject: [PATCH 02/36] Remove Guava (#793)

---
 .../client/DeployableArtifactDetail.java      |   2 -
 .../docker/extractor/BuildDockerCreator.java  |  13 +-
 .../docker/extractor/DockerPush.java          |  15 +-
 .../docker/extractor/DockerExtractorTest.java |  22 +--
 .../extractor/go/extractor/GoPublish.java     |  11 +-
 .../go/extractor/GoZipBallStreamer.java       |   6 +-
 .../build/extractor/go/GoDriverTest.java      |   2 +-
 .../go/extractor/GoDependencyTreeTest.java    |   2 +-
 .../go/extractor/GoExtractorTest.java         |   9 +-
 .../extractor/GradleModuleExtractor.java      |  34 ++---
 .../artifactory/task/ArtifactoryTask.java     |   8 +-
 .../artifactory/task/helper/TaskHelper.java   |   6 +-
 .../extractor/npm/extractor/NpmPublish.java   |  17 ++-
 .../npm/extractor/NpmExtractorTest.java       |  27 ++--
 .../build/extractor/ModuleExtractorUtils.java |  60 +-------
 .../clientConfiguration/ArtifactSpecs.java    |   8 +-
 .../ArtifactoryClientConfiguration.java       | 137 ++----------------
 .../artifactory/ArtifactoryManager.java       |   8 +-
 .../artifactory/services/SetProperties.java   |  13 +-
 .../deploy/DeployDetails.java                 |  31 ++--
 .../util/DependenciesDownloaderHelper.java    |  11 +-
 .../util/DeploymentUrlUtils.java              |   4 +-
 .../util/PublishedItemsHelper.java            |  14 +-
 .../spec/SingleSpecDeploymentProducer.java    |  26 ++--
 .../util/spec/SpecDeploymentProducer.java     |   7 +-
 .../util/spec/SpecsHelper.java                |  24 ++-
 .../util/spec/UploadSpecHelper.java           |  16 +-
 .../extractor/executor/CommandExecutor.java   |   3 +-
 .../org/jfrog/build/extractor/scan/Issue.java |   3 +-
 .../extractor/client/ArtifactSpecTest.java    |  46 +++---
 .../client/DeploymentUrlUtilsTest.java        |   5 +-
 .../executor/CommandExecutorTest.java         |   4 +-
 .../util/PublishedItemsHelperTest.java        |  36 ++---
 build-info-parent/pom.xml                     |   6 -
 build.gradle                                  |   4 +-
 35 files changed, 243 insertions(+), 397 deletions(-)

diff --git a/build-info-client/src/main/java/org/jfrog/build/client/DeployableArtifactDetail.java b/build-info-client/src/main/java/org/jfrog/build/client/DeployableArtifactDetail.java
index 2502f15f9..ab9489c5a 100644
--- a/build-info-client/src/main/java/org/jfrog/build/client/DeployableArtifactDetail.java
+++ b/build-info-client/src/main/java/org/jfrog/build/client/DeployableArtifactDetail.java
@@ -1,7 +1,5 @@
 package org.jfrog.build.client;
 
-import com.google.common.collect.ArrayListMultimap;
-
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Map;
diff --git a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java
index 4641f446e..a514fb1cc 100644
--- a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java
+++ b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java
@@ -2,12 +2,13 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.ArrayListMultimap;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.ci.BuildInfo;
 import org.jfrog.build.extractor.ci.Module;
-import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryManagerBuilder;
 import org.jfrog.build.extractor.clientConfiguration.client.artifactory.ArtifactoryManager;
@@ -34,7 +35,7 @@
 import static org.jfrog.build.extractor.packageManager.PackageManagerUtils.createArtifactoryClientConfiguration;
 
 public class BuildDockerCreator extends PackageManagerExtractor {
-    private final ArrayListMultimap<String, String> artifactProperties;
+    private final MultiValuedMap<String, String> artifactProperties;
     private final ArtifactoryManagerBuilder artifactoryManagerBuilder;
     private final ImageFileType imageFileType;
     private final String sourceRepo;
@@ -55,7 +56,7 @@ enum ImageFileType {
      * @param artifactProperties        - Properties to be attached to the docker layers deployed to Artifactory.
      */
     public BuildDockerCreator(ArtifactoryManagerBuilder artifactoryManagerBuilder, String imageFile, ImageFileType imageFileType,
-                              ArrayListMultimap<String, String> artifactProperties, String sourceRepo, Log logger) {
+                              MultiValuedMap<String, String> artifactProperties, String sourceRepo, Log logger) {
         this.artifactoryManagerBuilder = artifactoryManagerBuilder;
         this.artifactProperties = artifactProperties;
         this.sourceRepo = sourceRepo;
@@ -91,7 +92,7 @@ public static void main(String[] ignored) {
             BuildDockerCreator dockerBuildCreate = new BuildDockerCreator(artifactoryManagerBuilder,
                     imageFile,
                     imageFileType,
-                    ArrayListMultimap.create(clientConfiguration.publisher.getMatrixParams().asMultimap()),
+                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
                     clientConfiguration.publisher.getRepoKey(),
                     clientConfiguration.getLog());
 
@@ -136,7 +137,7 @@ public BuildInfo execute() {
     /**
      * Update each layer's properties with artifactProperties.
      */
-    private void setImageLayersProps(DockerLayers layers, ArrayListMultimap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
+    private void setImageLayersProps(DockerLayers layers, MultiValuedMap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
         if (layers == null) {
             return;
         }
diff --git a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java
index dd0268fa3..ebf669c68 100644
--- a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java
+++ b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java
@@ -1,11 +1,12 @@
 package org.jfrog.build.extractor.docker.extractor;
 
-import com.google.common.collect.ArrayListMultimap;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.ci.BuildInfo;
 import org.jfrog.build.extractor.ci.Module;
-import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryManagerBuilder;
 import org.jfrog.build.extractor.clientConfiguration.client.artifactory.ArtifactoryManager;
@@ -21,7 +22,7 @@
 import static org.jfrog.build.extractor.packageManager.PackageManagerUtils.createArtifactoryClientConfiguration;
 
 public class DockerPush extends DockerCommand {
-    private final ArrayListMultimap<String, String> artifactProperties;
+    private final MultiValuedMap<String, String> artifactProperties;
 
 
     /**
@@ -36,7 +37,7 @@ public class DockerPush extends DockerCommand {
      * @param env                       - Environment variables to use during docker push execution.
      */
     public DockerPush(ArtifactoryManagerBuilder artifactoryManagerBuilder,
-                      String imageTag, String host, ArrayListMultimap<String, String> artifactProperties, String targetRepository, String username,
+                      String imageTag, String host, MultiValuedMap<String, String> artifactProperties, String targetRepository, String username,
                       String password, Log logger, Map<String, String> env) {
         super(artifactoryManagerBuilder, imageTag, host, targetRepository, username, password, logger, env);
         this.artifactProperties = artifactProperties;
@@ -58,7 +59,7 @@ public static void main(String[] ignored) {
             DockerPush dockerPush = new DockerPush(artifactoryManagerBuilder,
                     dockerHandler.getImageTag(),
                     dockerHandler.getHost(),
-                    ArrayListMultimap.create(clientConfiguration.publisher.getMatrixParams().asMultimap()),
+                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
                     clientConfiguration.publisher.getRepoKey(),
                     clientConfiguration.publisher.getUsername(),
                     clientConfiguration.publisher.getPassword(),
@@ -85,7 +86,7 @@ public BuildInfo execute() {
             String imageId = DockerJavaWrapper.getImageIdFromTag(imageTag, host, env, logger);
             DockerImage image = new DockerImage(imageId, imageTag, "", targetRepository, artifactoryManagerBuilder, "", "");
             Module module = image.generateBuildInfoModule(logger, DockerUtils.CommandType.Push);
-            if (module.getArtifacts() == null || module.getArtifacts().size() == 0) {
+            if (module.getArtifacts() == null || module.getArtifacts().isEmpty()) {
                 logger.warn("Could not find docker image: " + imageTag + " in Artifactory.");
             } else {
                 setImageLayersProps(image.getLayers(), artifactProperties, artifactoryManagerBuilder);
@@ -104,7 +105,7 @@ public BuildInfo execute() {
     /**
      * Update each layer's properties with artifactProperties.
      */
-    private void setImageLayersProps(DockerLayers layers, ArrayListMultimap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
+    private void setImageLayersProps(DockerLayers layers, MultiValuedMap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
         if (layers == null) {
             return;
         }
diff --git a/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java b/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java
index 88122867b..e31acf8c5 100644
--- a/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java
+++ b/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java
@@ -2,10 +2,9 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
+import org.apache.commons.compress.utils.Sets;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.SystemUtils;
@@ -18,6 +17,7 @@
 import org.testng.SkipException;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
+import org.testng.collections.Lists;
 
 import java.io.File;
 import java.io.IOException;
@@ -43,7 +43,7 @@ public class DockerExtractorTest extends IntegrationTestsBase {
     private static final String SHORT_IMAGE_TAG_VIRTUAL = "3";
     private static final String EXPECTED_REMOTE_PATH_KANIKO = "hello-world/latest";
     private static final String DOCKER_HOST = "BITESTS_ARTIFACTORY_DOCKER_HOST";
-    private final ArrayListMultimap<String, String> artifactProperties = ArrayListMultimap.create();
+    private final MultiValuedMap<String, String> artifactProperties;
     private String pullImageFromVirtual;
     private String virtualDomainName;
     private String host;
@@ -56,12 +56,12 @@ public DockerExtractorTest() {
         localRepo1 = getKeyWithTimestamp(DOCKER_LOCAL_REPO);
         remoteRepo = getKeyWithTimestamp(DOCKER_REMOTE_REPO);
         virtualRepo = getKeyWithTimestamp(DOCKER_VIRTUAL_REPO);
-        artifactProperties.putAll(ImmutableMultimap.<String, String>builder()
-                .put("build.name", "docker-push-test")
-                .put("build.number", "1")
-                .put("build.timestamp", "321")
-                .put("property-key", "property-value")
-                .build());
+        artifactProperties = new ArrayListValuedHashMap<String, String>() {{
+            put("build.name", "docker-push-test");
+            put("build.number", "1");
+            put("build.timestamp", "321");
+            put("property-key", "property-value");
+        }};
     }
 
     @BeforeClass
diff --git a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java
index 57375e1a2..4283ada4a 100644
--- a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java
+++ b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java
@@ -1,7 +1,8 @@
 package org.jfrog.build.extractor.go.extractor;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.ArrayListMultimap;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.compress.archivers.zip.ZipFile;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -46,7 +47,7 @@ public class GoPublish extends GoCommand {
     private static final String PKG_MOD_FILE_EXTENSION = "mod";
     private static final String PKG_INFO_FILE_EXTENSION = "info";
 
-    private final ArrayListMultimap<String, String> properties;
+    private final MultiValuedMap<String, String> properties;
     private final List<Artifact> artifactList = new ArrayList<>();
     private final String deploymentRepo;
     private final String version;
@@ -61,7 +62,7 @@ public class GoPublish extends GoCommand {
      * @param version                   - The package's version.
      * @param logger                    - The logger.
      */
-    public GoPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, ArrayListMultimap<String, String> properties, String repo, Path path, String version, String module, Log logger) throws IOException {
+    public GoPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, MultiValuedMap<String, String> properties, String repo, Path path, String version, String module, Log logger) throws IOException {
         super(artifactoryManagerBuilder, path, module, logger);
         this.goDriver = new GoDriver(GO_CLIENT_CMD, null, path.toFile(), logger);
         this.moduleName = goDriver.getModuleName();
@@ -93,7 +94,7 @@ public static void main(String[] ignored) {
 
             GoPublish goPublish = new GoPublish(
                     artifactoryManagerBuilder,
-                    ArrayListMultimap.create(clientConfiguration.publisher.getMatrixParams().asMultimap()),
+                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
                     clientConfiguration.publisher.getRepoKey(),
                     Paths.get(packageManagerHandler.getPath() != null ? packageManagerHandler.getPath() : ".").toAbsolutePath(),
                     clientConfiguration.goHandler.getGoPublishedVersion(),
@@ -153,7 +154,7 @@ private void createAndDeployInfo(ArtifactoryManager artifactoryManager) throws E
     private File archiveProjectDir() throws IOException {
         File zipFile = File.createTempFile(LOCAL_TMP_PKG_PREFIX + LOCAL_PKG_FILENAME, PKG_ZIP_FILE_EXTENSION, path.toFile());
         try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()));
-            Stream<Path> pathFileTree = Files.walk(path)) {
+             Stream<Path> pathFileTree = Files.walk(path)) {
             List<Path> pathsList = pathFileTree
                     // Remove .git dir content, directories and the temp zip file
                     .filter(p -> !path.relativize(p).startsWith(".git/") && !Files.isDirectory(p) && !p.toFile().getName().equals(zipFile.getName()))
diff --git a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoZipBallStreamer.java b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoZipBallStreamer.java
index 9e92d4ed8..00187b100 100644
--- a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoZipBallStreamer.java
+++ b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoZipBallStreamer.java
@@ -34,7 +34,6 @@
 
 package org.jfrog.build.extractor.go.extractor;
 
-import com.google.common.collect.Sets;
 import org.apache.commons.compress.archivers.ArchiveOutputStream;
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
 import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
@@ -50,6 +49,7 @@
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Set;
 import java.util.zip.ZipEntry;
 
@@ -75,7 +75,7 @@ public GoZipBallStreamer(ZipFile zipFile, String projectName, String version, Lo
         this.projectName = projectName;
         this.version = version;
         this.log = log;
-        excludedDirectories = Sets.newHashSet();
+        excludedDirectories = new HashSet<>();
     }
 
     public void writeDeployableZip(File deployableZip) throws IOException {
@@ -202,7 +202,7 @@ private boolean excludeEntry(String entryName) {
     private void scanEntries() {
         Enumeration<? extends ZipEntry> entries = zipFile.getEntries();
         ZipEntry zipEntry;
-        Set<String> allDirectories = Sets.newHashSet();
+        Set<String> allDirectories = new HashSet<>();
         while (entries.hasMoreElements()) {
             zipEntry = entries.nextElement();
             if (!zipEntry.isDirectory() && isSubModule(zipEntry.getName())) {
diff --git a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/GoDriverTest.java b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/GoDriverTest.java
index eaa77580c..83dae63c5 100644
--- a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/GoDriverTest.java
+++ b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/GoDriverTest.java
@@ -1,6 +1,6 @@
 package org.jfrog.build.extractor.go;
 
-import com.google.common.collect.Sets;
+import org.apache.commons.compress.utils.Sets;
 import org.apache.commons.io.FileUtils;
 import org.jfrog.build.api.util.NullLog;
 import org.jfrog.build.extractor.executor.CommandResults;
diff --git a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoDependencyTreeTest.java b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoDependencyTreeTest.java
index ef1b468d5..062f5be56 100644
--- a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoDependencyTreeTest.java
+++ b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoDependencyTreeTest.java
@@ -1,6 +1,6 @@
 package org.jfrog.build.extractor.go.extractor;
 
-import com.google.common.collect.Sets;
+import org.apache.commons.compress.utils.Sets;
 import org.jfrog.build.api.util.NullLog;
 import org.jfrog.build.extractor.scan.DependencyTree;
 import org.testng.annotations.Test;
diff --git a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java
index aff85663c..a66af038b 100644
--- a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java
+++ b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java
@@ -1,12 +1,11 @@
 package org.jfrog.build.extractor.go.extractor;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Sets;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.jfrog.build.IntegrationTestsBase;
-import org.jfrog.build.extractor.ci.Module;
 import org.jfrog.build.extractor.ci.*;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryManagerBuilder;
 import org.jfrog.build.extractor.clientConfiguration.deploy.DeployDetails;
@@ -66,7 +65,7 @@ private enum Project {
             this.targetDir = targetDir;
             this.name = name;
             this.version = version;
-            this.dependencies = Sets.newHashSet(dependencies);
+            this.dependencies = new HashSet<>(Arrays.asList(dependencies));
         }
 
         private String getDependencyId() {
@@ -176,7 +175,7 @@ public void goRunTest(Project project, String args, ArtifactoryManagerBuilder ar
     @Test
     public void goRunPublishTest() {
         Path projectDir = null;
-        ArrayListMultimap<String, String> properties = ArrayListMultimap.create();
+        MultiValuedMap<String, String> properties = MultiMapUtils.newListValuedHashMap();
         try {
             // Run Go build on project1 locally
             Project project = Project.PROJECT_1;
diff --git a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/extractor/GradleModuleExtractor.java b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/extractor/GradleModuleExtractor.java
index a5a52dd4e..45bba451b 100644
--- a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/extractor/GradleModuleExtractor.java
+++ b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/extractor/GradleModuleExtractor.java
@@ -1,8 +1,6 @@
 package org.jfrog.gradle.plugin.artifactory.extractor;
 
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
+import org.apache.commons.compress.utils.Sets;
 import org.gradle.api.Project;
 import org.gradle.api.artifacts.Configuration;
 import org.gradle.api.artifacts.ModuleVersionIdentifier;
@@ -31,14 +29,11 @@
 import javax.annotation.Nullable;
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 
-import static com.google.common.collect.Lists.newArrayList;
 import static org.jfrog.build.api.util.FileChecksumCalculator.*;
 import static org.jfrog.build.extractor.BuildInfoExtractorUtils.getModuleIdString;
 import static org.jfrog.build.extractor.BuildInfoExtractorUtils.getTypeString;
@@ -48,7 +43,7 @@ public class GradleModuleExtractor implements ModuleExtractor<Project> {
 
     @Override
     public Module extractModule(Project project) {
-        Set<GradleDeployDetails> gradleDeployDetails = Sets.newHashSet();
+        Set<GradleDeployDetails> gradleDeployDetails = new HashSet<>();
         String artifactName = project.getName();
         ArtifactoryTask artifactoryTask = ProjectUtils.getBuildInfoTask(project);
         if (artifactoryTask != null) {
@@ -81,10 +76,10 @@ public Module extractModule(Project project) {
                 Iterable<GradleDeployDetails> deployExcludeDetails;
                 Iterable<GradleDeployDetails> deployIncludeDetails;
                 if (excludeArtifactsFromBuild) {
-                    deployIncludeDetails = Iterables.filter(gradleDeployDetails, new IncludeExcludePredicate(project, patterns, true));
-                    deployExcludeDetails = Iterables.filter(gradleDeployDetails, new IncludeExcludePredicate(project, patterns, false));
+                    deployIncludeDetails = gradleDeployDetails.stream().filter(new IncludeExcludePredicate(project, patterns, true)).collect(Collectors.toSet());
+                    deployExcludeDetails = gradleDeployDetails.stream().filter(new IncludeExcludePredicate(project, patterns, false)).collect(Collectors.toSet());
                 } else {
-                    deployIncludeDetails = Iterables.filter(gradleDeployDetails, new ProjectPredicate(project));
+                    deployIncludeDetails = gradleDeployDetails.stream().filter(new ProjectPredicate(project)).collect(Collectors.toSet());
                     deployExcludeDetails = new ArrayList<>();
                 }
                 builder.artifacts(calculateArtifacts(deployIncludeDetails))
@@ -121,7 +116,7 @@ private List<Dependency> calculateDependencies(Project project, String moduleId)
         Map<String, String[][]> requestedByMap = artifactoryDependencyResolutionListener.getModulesHierarchyMap().get(moduleId);
 
         Set<Configuration> configurationSet = project.getConfigurations();
-        List<Dependency> dependencies = newArrayList();
+        List<Dependency> dependencies = new ArrayList<>();
         for (Configuration configuration : configurationSet) {
             if (configuration.getState() != Configuration.State.RESOLVED) {
                 log.info("Artifacts for configuration '{}' were not all resolved, skipping", configuration.getName());
@@ -171,7 +166,8 @@ private ProjectPredicate(Project project) {
             this.project = project;
         }
 
-        public boolean apply(@Nullable GradleDeployDetails input) {
+        @Override
+        public boolean test(@Nullable GradleDeployDetails input) {
             if (input == null) {
                 return false;
             }
@@ -184,21 +180,21 @@ private static class IncludeExcludePredicate implements Predicate<GradleDeployDe
         private final IncludeExcludePatterns patterns;
         private final boolean include;
 
-        public IncludeExcludePredicate(Project project, IncludeExcludePatterns patterns, boolean isInclude) {
+        public IncludeExcludePredicate(Project project, IncludeExcludePatterns patterns, boolean include) {
             this.project = project;
             this.patterns = patterns;
-            include = isInclude;
+            this.include = include;
         }
 
-        public boolean apply(@Nullable GradleDeployDetails input) {
+        @Override
+        public boolean test(@Nullable GradleDeployDetails input) {
             if (input == null) {
                 return false;
             }
             if (include) {
                 return input.getProject().equals(project) && !PatternMatcher.pathConflicts(input.getDeployDetails().getArtifactPath(), patterns);
-            } else {
-                return input.getProject().equals(project) && PatternMatcher.pathConflicts(input.getDeployDetails().getArtifactPath(), patterns);
             }
+            return input.getProject().equals(project) && PatternMatcher.pathConflicts(input.getDeployDetails().getArtifactPath(), patterns);
         }
     }
 }
diff --git a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java
index 980c88976..8f2f63d3e 100644
--- a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java
+++ b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java
@@ -1,8 +1,8 @@
 package org.jfrog.gradle.plugin.artifactory.task;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
 import groovy.lang.Closure;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.gradle.api.Action;
 import org.gradle.api.DefaultTask;
@@ -162,10 +162,10 @@ public void setCiServerBuild() {
 
     public final Set<GradleDeployDetails> deployDetails = new TreeSet<>();
 
-    private final Multimap<String, CharSequence> properties = ArrayListMultimap.create();
+    private final MultiValuedMap<String, CharSequence> properties = MultiMapUtils.newListValuedHashMap();
 
     @Input
-    public Multimap<String, CharSequence> getProperties() {
+    public MultiValuedMap<String, CharSequence> getProperties() {
         return properties;
     }
 
diff --git a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java
index 7fba2fe54..ff476410e 100644
--- a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java
+++ b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java
@@ -1,6 +1,6 @@
 package org.jfrog.gradle.plugin.artifactory.task.helper;
 
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.gradle.api.Project;
 import org.gradle.api.Task;
@@ -70,12 +70,12 @@ protected Map<String, String> getPropsToAdd(PublishArtifactInfo artifact, String
                         .name(project.getName()).version(project.getVersion().toString())
                         .classifier(artifact.getClassifier())
                         .type(artifact.getType()).build();
-        Multimap<String, CharSequence> artifactSpecsProperties = artifactoryTask.artifactSpecs.getProperties(spec);
+        MultiValuedMap<String, CharSequence> artifactSpecsProperties = artifactoryTask.artifactSpecs.getProperties(spec);
         addProps(propsToAdd, artifactSpecsProperties);
         return propsToAdd;
     }
 
-    private void addProps(Map<String, String> target, Multimap<String, CharSequence> props) {
+    private void addProps(Map<String, String> target, MultiValuedMap<String, CharSequence> props) {
         for (Map.Entry<String, CharSequence> entry : props.entries()) {
             // Make sure all GString are now Java Strings
             String key = entry.getKey();
diff --git a/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java b/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
index 7f670b16f..be1550372 100644
--- a/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
+++ b/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
@@ -1,19 +1,20 @@
 package org.jfrog.build.extractor.npm.extractor;
 
-import com.google.common.collect.ArrayListMultimap;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.jfrog.build.api.builder.ModuleType;
+import org.jfrog.build.api.util.Log;
+import org.jfrog.build.client.ArtifactoryUploadResponse;
 import org.jfrog.build.extractor.builder.ArtifactBuilder;
 import org.jfrog.build.extractor.builder.ModuleBuilder;
 import org.jfrog.build.extractor.ci.Artifact;
 import org.jfrog.build.extractor.ci.BuildInfo;
 import org.jfrog.build.extractor.ci.Module;
-import org.jfrog.build.api.util.Log;
-import org.jfrog.build.client.ArtifactoryUploadResponse;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryManagerBuilder;
 import org.jfrog.build.extractor.clientConfiguration.client.artifactory.ArtifactoryManager;
@@ -38,7 +39,7 @@
  */
 @SuppressWarnings({"unused", "WeakerAccess"})
 public class NpmPublish extends NpmCommand {
-    private final ArrayListMultimap<String, String> properties;
+    private final MultiValuedMap<String, String> properties;
     private Artifact deployedArtifact;
     private boolean tarballProvided;
     private final String module;
@@ -53,7 +54,7 @@ public class NpmPublish extends NpmCommand {
      * @param logger                    - The logger.
      * @param env                       - Environment variables to use during npm execution.
      */
-    public NpmPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, ArrayListMultimap<String, String> properties, Path path, String deploymentRepository, Log logger, Map<String, String> env, String module) {
+    public NpmPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, MultiValuedMap<String, String> properties, Path path, String deploymentRepository, Log logger, Map<String, String> env, String module) {
         super(artifactoryManagerBuilder, deploymentRepository, logger, path, env);
         this.properties = properties;
         this.module = module;
@@ -69,7 +70,7 @@ public static void main(String[] ignored) {
             ArtifactoryManagerBuilder artifactoryManagerBuilder = new ArtifactoryManagerBuilder().setClientConfiguration(clientConfiguration, clientConfiguration.publisher);
             ArtifactoryClientConfiguration.PackageManagerHandler npmHandler = clientConfiguration.packageManagerHandler;
             NpmPublish npmPublish = new NpmPublish(artifactoryManagerBuilder,
-                    ArrayListMultimap.create(clientConfiguration.publisher.getMatrixParams().asMultimap()),
+                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
                     Paths.get(npmHandler.getPath() != null ? npmHandler.getPath() : "."),
                     clientConfiguration.publisher.getRepoKey(),
                     clientConfiguration.getLog(),
@@ -116,9 +117,9 @@ private void readPackageInfoFromTarball() throws IOException {
             throw new IOException("Publish path must be a '.tgz' file or a directory containing package.json");
         }
         try (TarArchiveInputStream inputStream = new TarArchiveInputStream(
-                new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(path.toFile()))))) {
+                new GzipCompressorInputStream(new BufferedInputStream(Files.newInputStream(path.toFile().toPath()))))) {
             TarArchiveEntry entry;
-            while ((entry = inputStream.getNextTarEntry()) != null) {
+            while ((entry = inputStream.getNextEntry()) != null) {
                 Path parent = Paths.get(entry.getName()).getParent();
                 if (parent != null && StringUtils.equals(parent.toString(), "package") && StringUtils.endsWith(entry.getName(), "package.json")) {
                     npmPackageInfo.readPackageInfo(inputStream);
diff --git a/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java b/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java
index 7f548c7ba..a1702849d 100644
--- a/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java
+++ b/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java
@@ -1,7 +1,8 @@
 package org.jfrog.build.extractor.npm.extractor;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableMultimap;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -207,18 +208,26 @@ private void runNpmTest(Project project, Dependency[] expectedDependencies, Stri
     @DataProvider
     private Object[][] npmPublishProvider() {
         return new Object[][]{
-                {Project.A, ArrayListMultimap.create(), Project.A.getTargetPath(), ""},
-                {Project.A, ArrayListMultimap.create(ImmutableMultimap.of("a", "b")), Project.A.getTargetPath(), ""},
-                {Project.B, ArrayListMultimap.create(), Project.B.getTargetPath(), Project.B.getPackedFileName()},
-                {Project.B, ArrayListMultimap.create(ImmutableMultimap.of("a", "b", "c", "d")), Project.B.getTargetPath(), Project.B.getPackedFileName()},
-                {Project.C, ArrayListMultimap.create(), Project.C.getTargetPath(), ""},
-                {Project.C, ArrayListMultimap.create(ImmutableMultimap.of("a", "b", "a", "d")), Project.C.getTargetPath(), ""}
+                {Project.A, MultiMapUtils.emptyMultiValuedMap(), Project.A.getTargetPath(), ""},
+                {Project.A, new ArrayListValuedHashMap<String, String>() {{
+                    put("a", "b");
+                }}, Project.A.getTargetPath(), ""},
+                {Project.B, MultiMapUtils.emptyMultiValuedMap(), Project.B.getTargetPath(), Project.B.getPackedFileName()},
+                {Project.B, new ArrayListValuedHashMap<String, String>() {{
+                    put("a", "b");
+                    put("c", "d");
+                }}, Project.B.getTargetPath(), Project.B.getPackedFileName()},
+                {Project.C, MultiMapUtils.emptyMultiValuedMap(), Project.C.getTargetPath(), ""},
+                {Project.C, new ArrayListValuedHashMap<String, String>() {{
+                    put("a", "b");
+                    put("a", "d");
+                }}, Project.C.getTargetPath(), ""}
         };
     }
 
     @SuppressWarnings("unused")
     @Test(dataProvider = "npmPublishProvider")
-    public void npmPublishTest(Project project, ArrayListMultimap<String, String> props, String targetPath, String packageName) {
+    public void npmPublishTest(Project project, MultiValuedMap<String, String> props, String targetPath, String packageName) {
         Path projectDir = null;
         try {
             // Run npm publish
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/ModuleExtractorUtils.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/ModuleExtractorUtils.java
index de29fd2fa..e6c7e9c80 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/ModuleExtractorUtils.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/ModuleExtractorUtils.java
@@ -1,18 +1,10 @@
 package org.jfrog.build.extractor;
 
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
-import com.google.common.base.Charsets;
-import com.google.common.io.Files;
+import com.fasterxml.jackson.core.type.TypeReference;
 import org.jfrog.build.extractor.ci.Module;
 
 import java.io.File;
 import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
 
 import static org.jfrog.build.extractor.BuildInfoExtractorUtils.createMapper;
 
@@ -20,62 +12,22 @@
  * Utilities for serializing/deserializing Module info as json
  */
 public class ModuleExtractorUtils {
-    private static JsonFactory createJsonFactory() {
-        JsonFactory jsonFactory = new JsonFactory();
-        ObjectMapper mapper = createMapper();
-        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
-        jsonFactory.setCodec(mapper);
-        return jsonFactory;
-    }
-
-    /**
-     * Given a Module object, serialize it as a json string.
-     *
-     * @param module The module to serialize
-     * @return The json string representing the serialized module
-     * @throws IOException
-     */
-    public static String moduleToJsonString(Module module) throws IOException {
-        JsonFactory jsonFactory = createJsonFactory();
-
-        try (StringWriter writer = new StringWriter();
-             JsonGenerator jsonGenerator = jsonFactory.createGenerator(writer)) {
-            jsonGenerator.useDefaultPrettyPrinter();
-            jsonGenerator.writeObject(module);
-
-            return writer.getBuffer().toString();
-        }
-    }
-
-    /**
-     * Given a serialized json module string, deserialize it into a Module object.
-     *
-     * @param json The serialized json module string
-     * @return A Module object deserialized from the provided string
-     * @throws IOException
-     */
-    public static Module jsonStringToModule(String json) throws IOException {
-        JsonFactory jsonFactory = createJsonFactory();
-        JsonParser parser = jsonFactory.createParser(new StringReader(json));
-        return jsonFactory.getCodec().readValue(parser, Module.class);
-    }
 
     /**
      * Given a Module object, serialize it to a json string and write it to the provided file.
      *
      * @param module The module object
      * @param toFile The file to write the serialized module to
-     * @throws IOException
+     * @throws IOException in case of any serialization error.
      */
     public static void saveModuleToFile(Module module, File toFile) throws IOException {
-        String moduleInfoJson = moduleToJsonString(module);
         if (!toFile.getParentFile().exists()) {
             toFile.getParentFile().mkdirs();
         }
         if (!toFile.exists()) {
             toFile.createNewFile();
         }
-        Files.asCharSink(toFile, Charsets.UTF_8).write(moduleInfoJson);
+        createMapper().writeValue(toFile, module);
     }
 
     /**
@@ -83,10 +35,10 @@ public static void saveModuleToFile(Module module, File toFile) throws IOExcepti
      *
      * @param fromFile The file containing a serialized json string
      * @return The Module object deserialized from the content of the file
-     * @throws IOException
+     * @throws IOException in case of any deserialization error.
      */
     public static Module readModuleFromFile(File fromFile) throws IOException {
-        String moduleInfoJson = Files.asCharSource(fromFile, Charsets.UTF_8).read();
-        return jsonStringToModule(moduleInfoJson);
+        return createMapper().readValue(fromFile, new TypeReference<Module>() {
+        });
     }
 }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java
index d8b5e28c2..273e158f9 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java
@@ -1,7 +1,7 @@
 package org.jfrog.build.extractor.clientConfiguration;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.LinkedList;
@@ -41,8 +41,8 @@ public ArtifactSpecs(String specsNotation) {
      * @param spec
      * @return
      */
-    public Multimap<String, CharSequence> getProperties(ArtifactSpec spec) {
-        Multimap<String, CharSequence> props = ArrayListMultimap.create();
+    public MultiValuedMap<String, CharSequence> getProperties(ArtifactSpec spec) {
+        MultiValuedMap<String, CharSequence> props = MultiMapUtils.newListValuedHashMap();
         for (ArtifactSpec matcherSpec : this) {
             if (matcherSpec.matches(spec)) {
                 Map<String, CharSequence> matcherSpecProperties = matcherSpec.getProperties();
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
index 196d3be65..256938efa 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
@@ -1,7 +1,6 @@
 package org.jfrog.build.extractor.clientConfiguration;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableMap;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.jfrog.build.api.util.CommonUtils;
 import org.jfrog.build.api.util.Log;
@@ -14,135 +13,25 @@
 import javax.crypto.BadPaddingException;
 import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.NoSuchPaddingException;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
 import java.net.URLEncoder;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.function.Predicate;
 
 import static org.jfrog.build.extractor.ModuleParallelDeployHelper.DEFAULT_DEPLOYMENT_THREADS;
-import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.ACTIVATE_RECORDER;
-import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.BUILD_INFO_CONFIG_PREFIX;
-import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.ENV_VARS_EXCLUDE_PATTERNS;
-import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.ENV_VARS_INCLUDE_PATTERNS;
-import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.EXPORT_FILE;
-import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.INCLUDE_ENV_VARS;
-import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.PROPERTIES_FILE;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.AGENT_NAME;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.AGENT_VERSION;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.ARTIFACTORY_PLUGIN_VERSION;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BACKWARD_COMPATIBLE_DEPLOYABLE_ARTIFACTS;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_AGENT_NAME;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_AGENT_VERSION;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_NAME;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_NUMBER;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_NUMBERS_NOT_TO_DELETE;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_PARENT_NAME;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_PARENT_NUMBER;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_PROJECT;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_RETENTION_ASYNC;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_RETENTION_COUNT;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_RETENTION_DAYS;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_RETENTION_MINIMUM_DATE;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_ROOT;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_STARTED;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_TIMESTAMP;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.BUILD_URL;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.DELETE_BUILD_ARTIFACTS;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.DEPLOYABLE_ARTIFACTS;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.ENVIRONMENT_PREFIX;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.GENERATED_BUILD_INFO;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.INCREMENTAL;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.MIN_CHECKSUM_DEPLOY_SIZE_KB;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.PRINCIPAL;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.RELEASE_COMMENT;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.RELEASE_ENABLED;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.RUN_PARAMETERS;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.VCS_BRANCH;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.VCS_MESSAGE;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.VCS_REVISION;
-import static org.jfrog.build.extractor.ci.BuildInfoFields.VCS_URL;
+import static org.jfrog.build.extractor.ci.BuildInfoConfigProperties.*;
+import static org.jfrog.build.extractor.ci.BuildInfoFields.*;
 import static org.jfrog.build.extractor.ci.BuildInfoProperties.BUILD_INFO_ISSUES_TRACKER_PREFIX;
 import static org.jfrog.build.extractor.ci.BuildInfoProperties.BUILD_INFO_PREFIX;
-import static org.jfrog.build.extractor.ci.IssuesTrackerFields.AFFECTED_ISSUES;
-import static org.jfrog.build.extractor.ci.IssuesTrackerFields.AGGREGATE_BUILD_ISSUES;
-import static org.jfrog.build.extractor.ci.IssuesTrackerFields.AGGREGATION_BUILD_STATUS;
-import static org.jfrog.build.extractor.ci.IssuesTrackerFields.ISSUES_TRACKER_NAME;
-import static org.jfrog.build.extractor.ci.IssuesTrackerFields.ISSUES_TRACKER_VERSION;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.ADD_DEPLOYABLE_ARTIFACTS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.ARTIFACT_SPECS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.CONTEXT_URL;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.DOCKER_HOST;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.DOCKER_IMAGE_TAG;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.DOTNET_NUGET_PROTOCOL;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.DOTNET_USE_DOTNET_CORE_CLI;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.DOWN_SNAPSHOT_REPO_KEY;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.EVEN_UNSTABLE;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.EXCLUDE_PATTERNS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.FILTER_EXCLUDED_ARTIFACTS_FROM_BUILD;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.GO_PUBLISHED_VERSION;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.HOST;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.INCLUDE_PATTERNS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.IVY;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.IVY_ART_PATTERN;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.IVY_IVY_PATTERN;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.IVY_M2_COMPATIBLE;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.IVY_REPO_DEFINED;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.JIB_IMAGE_FILE;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.KANIKO_IMAGE_FILE;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.MATRIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.MAVEN;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.NAME;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.NO_PROXY;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.NPM_CI_COMMAND;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PACKAGE_MANAGER_ARGS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PACKAGE_MANAGER_MODULE;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PACKAGE_MANAGER_PATH;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PASSWORD;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PIP_ENV_ACTIVATION;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PORT;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PUBLICATIONS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PUBLISH_ARTIFACTS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PUBLISH_BUILD_INFO;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.PUBLISH_FORK_COUNT;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.RECORD_ALL_DEPENDENCIES;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.RELEASE_REPO_KEY;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.REPO_KEY;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.SNAPSHOT_REPO_KEY;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.URL;
-import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.USERNAME;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.DEPRECATED_PROP_DEPLOY_PARAM_PROP_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_CONNECTION_RETRIES;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_CONTEXT_URL;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_DEPLOY_PARAM_PROP_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_DOCKER_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_DOTNET_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_GO_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_HTTPS_PROXY_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_INSECURE_TLS;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_MAX_CO_PER_ROUTE;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_MAX_TOTAL_CO;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_NPM_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_PACKAGE_MANAGER_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_PIP_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_PROXY_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_PUBLISH_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_RESOLVE_PREFIX;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_SO_TIMEOUT;
-import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.PROP_TIMEOUT;
+import static org.jfrog.build.extractor.ci.IssuesTrackerFields.*;
+import static org.jfrog.build.extractor.clientConfiguration.ClientConfigurationFields.*;
+import static org.jfrog.build.extractor.clientConfiguration.ClientProperties.*;
 import static org.jfrog.build.extractor.clientConfiguration.util.encryption.PropertyEncryptor.encryptedPropertiesToStream;
 
 /**
@@ -817,7 +706,7 @@ public void setPassword(String password) {
 
     public abstract class RepositoryConfiguration extends AuthenticationConfiguration {
 
-        private ImmutableMap<String, String> calculatedMatrixParams;
+        private Map<String, String> calculatedMatrixParams;
 
         protected RepositoryConfiguration(String prefix) {
             super(prefix);
@@ -994,24 +883,24 @@ public void addMatrixParams(Map<String, String> vars) {
             }
         }
 
-        public void addMatrixParams(ArrayListMultimap<String, String> vars) {
+        public void addMatrixParams(MultiValuedMap<String, String> vars) {
             for (Map.Entry<String, String> entry : vars.entries()) {
                 addMatrixParam(entry.getKey(), entry.getValue());
             }
         }
 
-        public ImmutableMap<String, String> getMatrixParams() {
+        public Map<String, String> getMatrixParams() {
             if (calculatedMatrixParams != null) {
                 return calculatedMatrixParams;
             }
             // First, get value using deprecated key.
             // This check must be first, otherwise, build.gradle properties will override the CI (e.g Jenkins / teamcity) properties.
             Map<String, String> result = getResolveMatrixParams(getDeprecatedMatrixParamPrefix());
-            if (result.size() == 0) {
+            if (result.isEmpty()) {
                 // Fallback to none deprecated key.
                 result = getResolveMatrixParams(getMatrixParamPrefix());
             }
-            this.calculatedMatrixParams = ImmutableMap.copyOf(result);
+            this.calculatedMatrixParams = Collections.unmodifiableMap(new LinkedHashMap<>(result));
             return calculatedMatrixParams;
         }
 
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java
index 7c1626896..a4ea612cd 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java
@@ -1,7 +1,6 @@
 package org.jfrog.build.extractor.clientConfiguration.client.artifactory;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.Header;
 import org.jfrog.build.api.dependency.BuildPatternArtifacts;
@@ -28,6 +27,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -72,7 +72,7 @@ public void setProperties(String relativePath, String properties, boolean encode
         setPropertiesService.execute(jfrogHttpClient);
     }
 
-    public void setProperties(String relativePath, ArrayListMultimap<String, String> properties, boolean encodeProperties) throws IOException {
+    public void setProperties(String relativePath, MultiValuedMap<String, String> properties, boolean encodeProperties) throws IOException {
         SetProperties setPropertiesService = new SetProperties(relativePath, properties, encodeProperties, log);
         setPropertiesService.execute(jfrogHttpClient);
     }
@@ -309,7 +309,7 @@ public String getLatestBuildNumber(String buildName, String latestType, String p
         if (versionService.execute(jfrogHttpClient).isOSS()) {
             throw new IllegalArgumentException(String.format("%s is not supported in Artifactory OSS.", latestType));
         }
-        List<BuildPatternArtifactsRequest> artifactsRequest = Lists.newArrayList();
+        List<BuildPatternArtifactsRequest> artifactsRequest = new ArrayList<>();
         artifactsRequest.add(new BuildPatternArtifactsRequest(buildName, latestType, project));
         List<BuildPatternArtifacts> artifactsResponses = retrievePatternArtifacts(artifactsRequest);
         // Artifactory returns null if no build was found
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java
index f702def51..d0e648cd4 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java
@@ -1,6 +1,7 @@
 package org.jfrog.build.extractor.clientConfiguration.client.artifactory.services;
 
-import com.google.common.collect.ArrayListMultimap;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.HttpPut;
@@ -18,12 +19,12 @@
 
 public class SetProperties extends VoidJFrogService {
     public static final String SET_PROPERTIES_ENDPOINT = "api/storage/";
-    private final ArrayListMultimap<String, String> propertiesMap;
+    private final MultiValuedMap<String, String> propertiesMap;
     private final boolean encodeProperties;
     private final String relativePath;
     private final String propertiesString;
 
-    private SetProperties(String relativePath, String propertiesString, ArrayListMultimap<String, String> propertiesMap, boolean encodeProperties, Log log) {
+    private SetProperties(String relativePath, String propertiesString, MultiValuedMap<String, String> propertiesMap, boolean encodeProperties, Log log) {
         super(log);
         this.relativePath = relativePath;
         this.propertiesMap = propertiesMap;
@@ -35,7 +36,7 @@ public SetProperties(String relativePath, String propertiesString, boolean encod
         this(relativePath, propertiesString, null, encodeProperties, log);
     }
 
-    public SetProperties(String relativePath, ArrayListMultimap<String, String> propertiesMap, boolean encodeProperties, Log log) {
+    public SetProperties(String relativePath, MultiValuedMap<String, String> propertiesMap, boolean encodeProperties, Log log) {
         this(relativePath, null, propertiesMap, encodeProperties, log);
     }
 
@@ -79,8 +80,8 @@ protected void ensureRequirements(JFrogHttpClient client) throws IOException {
         }
     }
 
-    private ArrayListMultimap<String, String> mapPropsString(String props) {
-        ArrayListMultimap<String, String> propsMap = ArrayListMultimap.create();
+    private MultiValuedMap<String, String> mapPropsString(String props) {
+        MultiValuedMap<String, String> propsMap = MultiMapUtils.newListValuedHashMap();
         String[] propsList = props.split(";");
         for (String prop : propsList) {
             if (isNotEmpty(prop)) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java
index 5ce101632..27af64a9c 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java
@@ -1,9 +1,7 @@
 package org.jfrog.build.extractor.clientConfiguration.deploy;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.jfrog.build.api.BuildFileBean;
 import org.jfrog.build.api.producerConsumer.ProducerConsumerItem;
@@ -47,7 +45,7 @@ public class DeployDetails implements Comparable<DeployDetails>, Serializable, P
     /**
      * Properties to attach to the deployed file as matrix params.
      */
-    ArrayListMultimap<String, String> properties;
+    MultiValuedMap<String, String> properties;
     /**
      * Target deploy repository.
      */
@@ -60,6 +58,7 @@ public class DeployDetails implements Comparable<DeployDetails>, Serializable, P
      * The package type generated this artifact's deploy details.
      */
     private PackageType packageType;
+
     /**
      * @return Return the target deployment repository.
      */
@@ -75,7 +74,7 @@ public File getFile() {
         return file;
     }
 
-    public ArrayListMultimap<String, String> getProperties() {
+    public MultiValuedMap<String, String> getProperties() {
         return properties;
     }
 
@@ -88,11 +87,11 @@ public String getSha256() {
     }
 
     public void setSha256(String sha256) {
-        this.sha256=sha256;
+        this.sha256 = sha256;
     }
 
     public void setArtifactPath(String artifactPath) {
-        this.artifactPath=artifactPath;
+        this.artifactPath = artifactPath;
     }
 
     public Boolean getDeploySucceeded() {
@@ -165,10 +164,8 @@ public DeployDetails build() {
         public Builder bean(BuildFileBean bean) {
             Properties beanProperties = bean.getProperties();
             if (beanProperties != null) {
-                ArrayListMultimap<String, String> multimap = ArrayListMultimap.create();
-                for (Map.Entry<String, String> entry : Maps.fromProperties(beanProperties).entrySet()) {
-                    multimap.put(entry.getKey(), entry.getValue());
-                }
+                MultiValuedMap<String, String> multimap = MultiMapUtils.newListValuedHashMap();
+                beanProperties.forEach((key, value) -> multimap.put((String) key, (String) value));
                 deployDetails.properties = multimap;
             }
             deployDetails.sha1 = bean.getSha1();
@@ -218,7 +215,7 @@ public Builder packageType(PackageType packageType) {
 
         public Builder addProperty(String key, String value) {
             if (deployDetails.properties == null) {
-                deployDetails.properties = ArrayListMultimap.create();
+                deployDetails.properties = MultiMapUtils.newListValuedHashMap();
             }
             deployDetails.properties.put(key, value);
             return this;
@@ -226,16 +223,16 @@ public Builder addProperty(String key, String value) {
 
         public Builder addProperties(Map<String, String> propertiesToAdd) {
             if (deployDetails.properties == null) {
-                deployDetails.properties = ArrayListMultimap.create();
+                deployDetails.properties = MultiMapUtils.newListValuedHashMap();
             }
 
-            deployDetails.properties.putAll(Multimaps.forMap(propertiesToAdd));
+            deployDetails.properties.putAll(propertiesToAdd);
             return this;
         }
 
-        public Builder addProperties(Multimap<String, String> propertiesToAdd) {
+        public Builder addProperties(MultiValuedMap<String, String> propertiesToAdd) {
             if (deployDetails.properties == null) {
-                deployDetails.properties = ArrayListMultimap.create();
+                deployDetails.properties = MultiMapUtils.newListValuedHashMap();
             }
 
             deployDetails.properties.putAll(propertiesToAdd);
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DependenciesDownloaderHelper.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DependenciesDownloaderHelper.java
index f74280baf..22c3501b0 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DependenciesDownloaderHelper.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DependenciesDownloaderHelper.java
@@ -1,6 +1,5 @@
 package org.jfrog.build.extractor.clientConfiguration.util;
 
-import com.google.common.io.Files;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.BooleanUtils;
@@ -22,6 +21,8 @@
 import org.jfrog.filespecs.entities.FilesGroup;
 
 import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.security.NoSuchAlgorithmException;
 import java.util.*;
 import java.util.regex.Pattern;
@@ -245,15 +246,15 @@ protected Map<String, String> downloadFile(String downloadPath, String fileDesti
     protected Map<String, String> downloadFileConcurrently(final String uriWithParams, long fileSize, final String fileDestination, String filePath)
             throws Exception {
         String[] downloadedFilesPaths;
-        File tempDir = Files.createTempDir();
-        String tempPath = tempDir.getPath() + File.separatorChar + filePath;
+        Path tempDir = Files.createTempDirectory("downloadFileConcurrently");
+        Path tempPath = tempDir.resolve(filePath);
         try {
-            downloadedFilesPaths = doConcurrentDownload(fileSize, uriWithParams, tempPath);
+            downloadedFilesPaths = doConcurrentDownload(fileSize, uriWithParams, tempPath.toString());
             try (InputStream inputStream = concatenateFilesToSingleStream(downloadedFilesPaths)) {
                 return downloader.saveDownloadedFile(inputStream, fileDestination);
             }
         } finally {
-            FileUtils.deleteDirectory(tempDir);
+            FileUtils.deleteDirectory(tempDir.toFile());
         }
     }
 
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java
index e4b08a44f..9cf71f1bc 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java
@@ -1,6 +1,6 @@
 package org.jfrog.build.extractor.clientConfiguration.util;
 
-import com.google.common.collect.ArrayListMultimap;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.jfrog.build.api.util.CommonUtils;
 import org.jfrog.build.extractor.UrlUtils;
@@ -66,7 +66,7 @@ public static String encodePath(String unescaped) {
     }
 
 
-    public static String buildMatrixParamsString(ArrayListMultimap<String, String> matrixParams, boolean encodeProperties)
+    public static String buildMatrixParamsString(MultiValuedMap<String, String> matrixParams, boolean encodeProperties)
             throws UnsupportedEncodingException {
         StringBuilder matrix = new StringBuilder();
         if (matrixParams != null && !matrixParams.isEmpty()) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java
index ea78e4474..1ead29be1 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java
@@ -16,8 +16,8 @@
 
 package org.jfrog.build.extractor.clientConfiguration.util;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.jfrog.build.extractor.clientConfiguration.util.spec.UploadSpecHelper;
@@ -45,8 +45,8 @@ public class PublishedItemsHelper {
      *                                    then the value is treated as a source only (target will be "").
      * @return a Map containing the sources as keys and targets as values
      */
-    public static Multimap<String, String> getPublishedItemsPatternPairs(String publishedItemsPropertyValue) {
-        Multimap<String, String> patternPairMap = HashMultimap.create();
+    public static MultiValuedMap<String, String> getPublishedItemsPatternPairs(String publishedItemsPropertyValue) {
+        MultiValuedMap<String, String> patternPairMap = MultiMapUtils.newSetValuedHashMap();
         if (StringUtils.isNotBlank(publishedItemsPropertyValue)) {
 
             List<String> patternPairs = parsePatternsFromProperty(publishedItemsPropertyValue);
@@ -148,9 +148,9 @@ public static String removeDoubleDotsFromPattern(String pattern) {
      * @throws IOException in case of any file system exception
      */
     @Deprecated
-    public static Multimap<String, File> buildPublishingData(File checkoutDir, String pattern, String targetPath)
+    public static MultiValuedMap<String, File> buildPublishingData(File checkoutDir, String pattern, String targetPath)
             throws IOException {
-        final Multimap<String, File> filePathsMap = HashMultimap.create();
+        final MultiValuedMap<String, File> filePathsMap = MultiMapUtils.newSetValuedHashMap();
         File patternAbsolutePath = getAbsolutePath(checkoutDir, pattern);
         if (patternAbsolutePath.isFile()) {
             // The given pattern is an absolute path of just one file, let's add it to our result map
@@ -211,7 +211,7 @@ public static Multimap<String, File> buildPublishingData(File checkoutDir, Strin
      * @return a Multimap containing the targets as keys and the files as values
      */
     @Deprecated
-    public static Multimap<String, File> wildCardBuildPublishingData(
+    public static MultiValuedMap<String, File> wildCardBuildPublishingData(
             File checkoutDir, String pattern, String targetPath, boolean flat, boolean isRecursive, boolean regexp) {
         if (!regexp) {
             pattern = PathsUtils.pathToRegExp(pattern);
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java
index 774a09563..1d63adcbe 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java
@@ -1,6 +1,6 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -20,14 +20,13 @@
 /**
  * Actual FileSpec performer, scans the file-system for matching files and creates the deployment data.
  * Handles a single Spec from the 'files' section of a FileSpec.
- *
  * Created by Bar Belity on 07/03/2018.
  */
 public class SingleSpecDeploymentProducer {
 
     private FilesGroup spec;
     private File workspace;
-    private Multimap<String, String> buildProperties;
+    private MultiValuedMap<String, String> buildProperties;
 
     private Pattern regexpPattern;
     private Pattern regexpExcludePattern;
@@ -43,7 +42,7 @@ public class SingleSpecDeploymentProducer {
     private int separatorsCount;
     private Set<String> symlinkSet = new HashSet<>();
 
-    SingleSpecDeploymentProducer(FilesGroup spec, File workspace, Multimap<String, String> buildProperties) {
+    SingleSpecDeploymentProducer(FilesGroup spec, File workspace, MultiValuedMap<String, String> buildProperties) {
         this.spec = spec;
         this.workspace = workspace;
         this.buildProperties = buildProperties;
@@ -52,6 +51,7 @@ public class SingleSpecDeploymentProducer {
     /**
      * Executes a single FileSpec.
      * Find all files matching the spec, create and publish its DeployDetails.
+     *
      * @param deploymentSet Set containing the DeployDetails to deploy
      */
     public void executeSpec(Set<DeployDetails> deploymentSet, ProducerConsumerExecutor executor)
@@ -136,8 +136,9 @@ private void init() throws FileNotFoundException {
 
     /**
      * Check all file candidates for upload in the provided directory, to specified depth.
-     * @param dir base directory to start search for files
-     * @param depth level of folders to search in
+     *
+     * @param dir           base directory to start search for files
+     * @param depth         level of folders to search in
      * @param deploymentSet Set containing the DeployDetails to deploy
      */
     private void collectFiles(String dir, int depth, Set<DeployDetails> deploymentSet, ProducerConsumerExecutor executor)
@@ -195,7 +196,8 @@ private void collectFiles(String dir, int depth, Set<DeployDetails> deploymentSe
     /**
      * Receives a candidate file to upload, creates DeployDetails for the file in case should upload it.
      * Adds the DeployDetails to the BlockingQueue.
-     * @param file upload candidate
+     *
+     * @param file          upload candidate
      * @param deploymentSet Set containing the DeployDetails to deploy
      */
     private void processDeployCandidate(File file, Set<DeployDetails> deploymentSet, ProducerConsumerExecutor executor)
@@ -223,11 +225,12 @@ private void processDeployCandidate(File file, Set<DeployDetails> deploymentSet,
 
     /**
      * Checks if the provided file path matches spec's patterns
-     * @param filePath to candidate file
-     * @param regexpPattern regexp to matched files
+     *
+     * @param filePath             to candidate file
+     * @param regexpPattern        regexp to matched files
      * @param regexpExcludePattern regexp to excluded files
-     * @param workspaceDir File object that represents the workspace
-     * @param baseDirFile the directory to get files from
+     * @param workspaceDir         File object that represents the workspace
+     * @param baseDirFile          the directory to get files from
      * @return true if the file path matches all terms
      */
     private static boolean isFileMatchPattern(String filePath, Pattern regexpPattern, Pattern regexpExcludePattern,
@@ -250,6 +253,7 @@ private static boolean isFileMatchPattern(String filePath, Pattern regexpPattern
 
     /**
      * Throws exception if more than 1M files to deploy found
+     *
      * @param numberOfFiles the number of artifacts to deploy
      */
     private static void validateUploadLimit(int numberOfFiles) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java
index 501f19571..79948e93a 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java
@@ -1,6 +1,6 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.jfrog.build.extractor.clientConfiguration.deploy.DeployDetails;
 import org.jfrog.build.extractor.producerConsumer.ProducerRunnableBase;
 import org.jfrog.filespecs.FileSpec;
@@ -12,7 +12,6 @@
 
 /**
  * Producer object to use with the ProducerConsumerExecutor during artifact deployment by filespec operation.
- *
  * Created by Bar Belity on 27/03/2018.
  */
 public class SpecDeploymentProducer extends ProducerRunnableBase {
@@ -24,9 +23,9 @@ public class SpecDeploymentProducer extends ProducerRunnableBase {
 
     private FileSpec spec;
     private File workspace;
-    private Multimap<String, String> buildProperties;
+    private MultiValuedMap<String, String> buildProperties;
 
-    SpecDeploymentProducer(FileSpec spec, File workspace, Multimap<String, String> buildProperties) {
+    SpecDeploymentProducer(FileSpec spec, File workspace, MultiValuedMap<String, String> buildProperties) {
         this.spec = spec;
         this.workspace = workspace;
         this.buildProperties = buildProperties;
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java
index 9b9360ae7..ad2b7eba9 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java
@@ -1,13 +1,13 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.builder.ArtifactBuilder;
 import org.jfrog.build.extractor.ci.Artifact;
 import org.jfrog.build.extractor.ci.Dependency;
-import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryManagerBuilder;
 import org.jfrog.build.extractor.clientConfiguration.client.artifactory.ArtifactoryManager;
 import org.jfrog.build.extractor.clientConfiguration.deploy.DeployDetails;
@@ -21,11 +21,7 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 import static org.jfrog.build.api.util.CommonUtils.handleJavaTmpdirProperty;
 import static org.jfrog.build.client.PreemptiveHttpClientBuilder.CONNECTION_POOL_SIZE;
@@ -61,8 +57,8 @@ public List<Artifact> uploadArtifactsBySpec(String uploadSpec, File workspace,
         return uploadArtifactsBySpec(uploadSpec, DEFAULT_NUMBER_OF_THREADS, workspace, createMultiMap(buildProperties), artifactoryManagerBuilder);
     }
 
-    private static <K, V> Multimap<K, V> createMultiMap(Map<K, V> input) {
-        Multimap<K, V> multimap = ArrayListMultimap.create();
+    private static <K, V> MultiValuedMap<K, V> createMultiMap(Map<K, V> input) {
+        MultiValuedMap<K, V> multimap = MultiMapUtils.newListValuedHashMap();
         for (Map.Entry<K, V> entry : input.entrySet()) {
             multimap.put(entry.getKey(), entry.getValue());
         }
@@ -82,7 +78,7 @@ private static <K, V> Multimap<K, V> createMultiMap(Map<K, V> input) {
      *                     checksums or in case of any file system exception
      */
     public List<Artifact> uploadArtifactsBySpec(String uploadSpec, int numberOfThreads, File workspace,
-                                                Multimap<String, String> buildProperties,
+                                                MultiValuedMap<String, String> buildProperties,
                                                 ArtifactoryManagerBuilder artifactoryManagerBuilder) throws Exception {
         FileSpec fileSpec = FileSpec.fromString(uploadSpec);
         FileSpecsValidation.validateUploadFileSpec(fileSpec, this.log);
@@ -157,13 +153,13 @@ public boolean editPropertiesBySpec(String spec, ArtifactoryManager artifactoryM
      * @param props Spec's properties
      * @return created properties map
      */
-    public static ArrayListMultimap<String, String> getPropertiesMap(String props) {
-        ArrayListMultimap<String, String> propertiesMap = ArrayListMultimap.create();
+    public static MultiValuedMap<String, String> getPropertiesMap(String props) {
+        MultiValuedMap<String, String> propertiesMap = MultiMapUtils.newListValuedHashMap();
         fillPropertiesMap(props, propertiesMap);
         return propertiesMap;
     }
 
-    public static void fillPropertiesMap(String props, ArrayListMultimap<String, String> propertiesMap) {
+    public static void fillPropertiesMap(String props, MultiValuedMap<String, String> propertiesMap) {
         if (StringUtils.isBlank(props)) {
             return;
         }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java
index 2091feaed..396b8aae3 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java
@@ -1,7 +1,7 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiValuedMap;
+import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.BooleanUtils;
@@ -18,9 +18,7 @@
 import java.util.Map;
 import java.util.regex.Pattern;
 
-import static org.jfrog.build.api.util.FileChecksumCalculator.MD5_ALGORITHM;
-import static org.jfrog.build.api.util.FileChecksumCalculator.SHA1_ALGORITHM;
-import static org.jfrog.build.api.util.FileChecksumCalculator.SHA256_ALGORITHM;
+import static org.jfrog.build.api.util.FileChecksumCalculator.*;
 import static org.jfrog.build.extractor.clientConfiguration.util.PathsUtils.removeUnescapedChar;
 
 /**
@@ -40,7 +38,7 @@ public class UploadSpecHelper {
      */
     public static DeployDetails buildDeployDetails(String targetPath, File artifactFile,
                                                    String uploadTarget, String explode, String props,
-                                                   Multimap<String, String> buildProperties)
+                                                   MultiValuedMap<String, String> buildProperties)
             throws IOException, NoSuchAlgorithmException {
         String path = UploadSpecHelper.wildcardCalculateTargetPath(targetPath, artifactFile);
         path = StringUtils.replace(path, "//", "/");
@@ -153,9 +151,9 @@ protected static String getUploadPath(File file, Pattern pathPattern, String tar
         return PathsUtils.reformatRegexp(sourcePath, fileTargetPath.replace('\\', '/'), pathPattern);
     }
 
-    public static Multimap<String, File> getUploadPathsMap(List<File> files, File workspaceDir, String targetPath,
-                                                           boolean isFlat, Pattern regexPattern, boolean isAbsolutePath) {
-        Multimap<String, File> filePathsMap = HashMultimap.create();
+    public static MultiValuedMap<String, File> getUploadPathsMap(List<File> files, File workspaceDir, String targetPath,
+                                                                 boolean isFlat, Pattern regexPattern, boolean isAbsolutePath) {
+        MultiValuedMap<String, File> filePathsMap = new HashSetValuedHashMap<>();
         boolean isTargetDirectory = StringUtils.endsWith(targetPath, "/");
 
         for (File file : files) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/executor/CommandExecutor.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/executor/CommandExecutor.java
index 2d5161e8b..f1f907123 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/executor/CommandExecutor.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/executor/CommandExecutor.java
@@ -1,6 +1,5 @@
 package org.jfrog.build.extractor.executor;
 
-import com.google.common.collect.Maps;
 import org.apache.commons.lang3.SystemUtils;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.UrlUtils;
@@ -182,7 +181,7 @@ private CommandResults getCommandResults(boolean terminatedProperly, List<String
 
     private static Process runProcess(File execDir, String executablePath, List<String> args, List<String> credentials, Map<String, String> env, Log logger) throws IOException {
         // Make sure to copy the environment variables map to avoid changing the original map or in case it is immutable.
-        Map<String, String> newEnv = Maps.newHashMap(env);
+        Map<String, String> newEnv = new HashMap<>(env);
 
         args = formatCommand(args, credentials, executablePath, newEnv);
         logCommand(logger, args, credentials);
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/scan/Issue.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/scan/Issue.java
index 82c96d0f2..0246b9790 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/scan/Issue.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/scan/Issue.java
@@ -4,7 +4,6 @@
 import com.fasterxml.jackson.annotation.JsonInclude;
 import org.apache.commons.lang3.StringUtils;
 
-import javax.annotation.Nonnull;
 import java.util.List;
 import java.util.Objects;
 
@@ -96,7 +95,7 @@ public boolean isHigherSeverityThan(Issue o) {
     }
 
     @Override
-    public int compareTo(@Nonnull Issue otherIssue) {
+    public int compareTo(Issue otherIssue) {
         return Integer.compare(hashCode(), Objects.hashCode(otherIssue));
     }
 
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/ArtifactSpecTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/ArtifactSpecTest.java
index afc5a2de5..78c123872 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/ArtifactSpecTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/ArtifactSpecTest.java
@@ -1,9 +1,10 @@
 package org.jfrog.build.extractor.client;
 
-import com.google.common.collect.ImmutableMap;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactSpec;
 import org.testng.annotations.Test;
 
+import java.util.HashMap;
+
 import static org.testng.Assert.*;
 
 
@@ -14,7 +15,7 @@
 public class ArtifactSpecTest {
 
     @Test
-    public void stringConstruction() throws Exception {
+    public void stringConstruction() {
         ArtifactSpec standard = ArtifactSpec.newSpec("conf grp:art:ver:cls@jar k1:v1, k2:v2 , k3:   v3");
         ArtifactSpec noPropSpaces = ArtifactSpec.newSpec("conf grp:art:ver:cls@jar k1:v1,k2:v2,k3:v3");
         ArtifactSpec noConf = ArtifactSpec.newSpec("grp:art:ver:cls@jar k1:v1, k2:v2 , k3:   v3");
@@ -26,41 +27,50 @@ public void stringConstruction() throws Exception {
         assertEquals(standard.getVersion(), "ver");
         assertEquals(standard.getClassifier(), "cls");
         assertEquals(standard.getType(), "jar");
-        assertEquals(standard.getProperties(), ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3"));
-
+        assertEquals(standard.getProperties(), new HashMap<String, String>() {{
+            put("k1", "v1");
+            put("k2", "v2");
+            put("k3", "v3");
+        }});
         assertEquals(noPropSpaces.getConfiguration(), "conf");
         assertEquals(noPropSpaces.getGroup(), "grp");
         assertEquals(noPropSpaces.getName(), "art");
         assertEquals(noPropSpaces.getVersion(), "ver");
         assertEquals(noPropSpaces.getClassifier(), "cls");
         assertEquals(noPropSpaces.getType(), "jar");
-        assertEquals(noPropSpaces.getProperties(), ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3"));
-
+        assertEquals(noPropSpaces.getProperties(), new HashMap<String, String>() {{
+            put("k1", "v1");
+            put("k2", "v2");
+            put("k3", "v3");
+        }});
         assertEquals(noConf.getConfiguration(), "*");
         assertEquals(noConf.getGroup(), "grp");
         assertEquals(noConf.getName(), "art");
         assertEquals(noConf.getVersion(), "ver");
         assertEquals(noConf.getClassifier(), "cls");
         assertEquals(noConf.getType(), "jar");
-        assertEquals(noConf.getProperties(), ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3"));
+        assertEquals(noConf.getProperties(), new HashMap<String, String>() {{
+            put("k1", "v1");
+            put("k2", "v2");
+            put("k3", "v3");
+        }});
 
-        try {
-            ArtifactSpec noProps = ArtifactSpec.newSpec("all grp:art:ver:cls@jar");
-            fail("Artifact spec cannot be constructed from string without a properties notation.");
-        } catch (IllegalArgumentException e) {
-            //Expected
-        }
+        assertThrows(IllegalArgumentException.class, () -> ArtifactSpec.newSpec("all grp:art:ver:cls@jar"));
         assertEquals(allConf.getConfiguration(), "*");
         assertEquals(allConf.getGroup(), "grp");
         assertEquals(allConf.getName(), "art");
         assertEquals(allConf.getVersion(), "ver");
         assertEquals(allConf.getClassifier(), "cls");
         assertEquals(allConf.getType(), "jar");
-        assertEquals(allConf.getProperties(), ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3"));
+        assertEquals(allConf.getProperties(), new HashMap<String, String>() {{
+            put("k1", "v1");
+            put("k2", "v2");
+            put("k3", "v3");
+        }});
     }
 
     @Test
-    public void matches() throws Exception {
+    public void matches() {
         ArtifactSpec spec =
                 ArtifactSpec.builder().configuration("conf").group("grp").name("art").version("ver").classifier("cls")
                         .type("jar").build();
@@ -89,7 +99,7 @@ public void matches() throws Exception {
     }
 
     @Test
-    public void matchesWithNull1() throws Exception {
+    public void matchesWithNull1() {
         ArtifactSpec spec =
                 ArtifactSpec.builder().configuration(null).group("org.jfrog").name("shared")
                         .version("1.0")
@@ -99,9 +109,9 @@ public void matchesWithNull1() throws Exception {
     }
 
     @Test
-    public void matchesWithNull2() throws Exception {
+    public void matchesWithNull2() {
         ArtifactSpec spec = ArtifactSpec.builder().group("org.jfrog").name("shared")
-                        .version("1.0").build();
+                .version("1.0").build();
         someTests(spec);
     }
 
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java
index 6eee87c61..d4eadf916 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java
@@ -1,6 +1,7 @@
 package org.jfrog.build.extractor.client;
 
-import com.google.common.collect.ArrayListMultimap;
+import org.apache.commons.collections4.MultiMapUtils;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.jfrog.build.extractor.clientConfiguration.ClientProperties;
 import org.jfrog.build.extractor.clientConfiguration.util.DeploymentUrlUtils;
 import org.testng.Assert;
@@ -35,7 +36,7 @@ public void getDeploymentUrlWithEncodingNeeded() throws UnsupportedEncodingExcep
 
 
     public void testKeyWithMultiValuesParam() throws UnsupportedEncodingException {
-        ArrayListMultimap<String, String> params = ArrayListMultimap.create();
+        MultiValuedMap<String, String> params = MultiMapUtils.newListValuedHashMap();
         params.put("key", "valueA");
         params.put("key", "valueB");
         params.put("keyA", "valueA");
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/executor/CommandExecutorTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/executor/CommandExecutorTest.java
index c5cd361b2..4bcd113da 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/executor/CommandExecutorTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/executor/CommandExecutorTest.java
@@ -1,6 +1,5 @@
 package org.jfrog.build.extractor.executor;
 
-import com.google.common.collect.Maps;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.SystemUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
@@ -17,6 +16,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -98,7 +98,7 @@ public void testGenerateWindowsEnv() throws IOException {
         }
         File projectDir = Files.createTempDirectory("").toFile();
         try {
-            Map<String, String> env = Maps.newHashMap(System.getenv());
+            Map<String, String> env = new HashMap<>(System.getenv());
             Path execPath = Paths.get("C:\\Program Files\\Go\\bin\\go");
             CommandExecutor.addToWindowsPath(env, execPath);
             assertTrue(env.get("Path").startsWith("C:\\Program Files\\Go\\bin"));
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java
index a02e5cf64..8272d0f16 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java
@@ -1,6 +1,6 @@
 package org.jfrog.build.extractor.util;
 
-import com.google.common.collect.Multimap;
+import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FilenameUtils;
 import org.jfrog.build.extractor.clientConfiguration.util.PublishedItemsHelper;
 import org.testng.annotations.BeforeClass;
@@ -32,9 +32,9 @@ public void setup() {
     }
 
     public void testDoubleDotWithStartWildcard() throws IOException {
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs("../../saas/**/*.xml=>target/xml");
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("../../saas/**/*.xml=>target/xml");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 2, "Expected to find 2 files");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -45,10 +45,10 @@ public void testDoubleDotWithStartWildcard() throws IOException {
     }
 
     public void testAbsolutePath() throws IOException {
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs(
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(
                 absoluteFile.getAbsolutePath() + "=>jaja/gululu");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 1, "Expected to find 1 files");
             assertTrue(buildPublishingData.containsValue(absoluteFile), "Expected to find the absolute file");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
@@ -59,9 +59,9 @@ public void testAbsolutePath() throws IOException {
     }
 
     public void testAbsolutePathSameWorkspace() throws IOException {
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs(checkoutDir.getAbsolutePath() + "/inner/*.gradle" + "=>test/props");
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(checkoutDir.getAbsolutePath() + "/inner/*.gradle" + "=>test/props");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 1, "Expected to find 1 file");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -72,14 +72,14 @@ public void testAbsolutePathSameWorkspace() throws IOException {
 
     public void testMultiPatterns() throws IOException {
         String pattern = "**/multi1/*=>test/multi1, **multi2/*=>test/multi2";
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs(pattern);
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(pattern);
         assertEquals(pairs.keySet().size(), 2, "Expected to find 2 keys");
     }
 
     public void testAllWorkspace() throws IOException {
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs("**");
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("**");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 6, "Expected to find 6 files");
         }
     }
@@ -87,17 +87,17 @@ public void testAllWorkspace() throws IOException {
     public void testAbsolutePathWithDoubleStar() throws IOException {
         File resourceAsFile = getResourceAsFile("/root/workspace");
         String fileAbsolutePath = FilenameUtils.separatorsToUnix(resourceAsFile.getAbsolutePath());
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs(fileAbsolutePath + "/ant/**");
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(fileAbsolutePath + "/ant/**");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 7, "Expected to find 7 files");
         }
     }
 
     public void testAllSpecificFilesFromCheckoutDir() throws IOException {
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs("**/*.blabla=>blabla");
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("**/*.blabla=>blabla");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 2, "Expected to find 2 files");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -107,9 +107,9 @@ public void testAllSpecificFilesFromCheckoutDir() throws IOException {
     }
 
     public void testEmptyTargetPath() throws IOException {
-        Multimap<String, String> pairs = getPublishedItemsPatternPairs("../../**/**/*.xml");
+        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("../../**/**/*.xml");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 2, "Expected to find 2 files");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -118,11 +118,11 @@ public void testEmptyTargetPath() throws IOException {
         }
     }
 
-    private Multimap<String, String> getPublishedItemsPatternPairs(String pattern) {
+    private MultiValuedMap<String, String> getPublishedItemsPatternPairs(String pattern) {
         return PublishedItemsHelper.getPublishedItemsPatternPairs(pattern);
     }
 
-    private Multimap<String, File> getBuildPublishingData(Map.Entry<String, String> entry) throws IOException {
+    private MultiValuedMap<String, File> getBuildPublishingData(Map.Entry<String, String> entry) throws IOException {
         return PublishedItemsHelper.buildPublishingData(checkoutDir, entry.getKey(), entry.getValue());
     }
 
diff --git a/build-info-parent/pom.xml b/build-info-parent/pom.xml
index 370978e34..55e7bd838 100644
--- a/build-info-parent/pom.xml
+++ b/build-info-parent/pom.xml
@@ -46,12 +46,6 @@
 
     <dependencyManagement>
         <dependencies>
-            <dependency>
-                <groupId>com.google.guava</groupId>
-                <artifactId>guava</artifactId>
-                <version>r08</version>
-            </dependency>
-
             <dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-lang3</artifactId>
diff --git a/build.gradle b/build.gradle
index a450cddf0..c54358561 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,6 +9,7 @@ buildscript {
         commonsIoVersion = '2.11.0'
         commonsLang3Version = '3.12.0'
         commonsLoggingVersion = '1.2'
+        commonsCollections4Version = '4.4'
         dockerJavaVersion = '3.3.3'
         easymockclassextensionVersion = '3.2'
         eclipseAetherVersion = '1.1.0'
@@ -18,7 +19,6 @@ buildscript {
         gradleVersionsPluginVersion = '0.42.0'
 
         groovyAllVersion = '3.0.13'
-        guavaVersion = '32.1.3-jre'
         httpClientVersion = '4.5.14'
         httpCoreVersion = '4.4.16'
         ivyVersion = '2.5.2'
@@ -134,6 +134,7 @@ subprojects {
         implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jacksonVersion
         implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion
         implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jacksonVersion
+        implementation group: 'org.apache.commons', name: 'commons-collections4', version: commonsCollections4Version
         implementation group: 'org.apache.commons', name: 'commons-compress', version: commonsCompressVersion
 
         implementation("org.apache.httpcomponents:httpclient:$httpClientVersion") {
@@ -142,7 +143,6 @@ subprojects {
 
         implementation "org.apache.httpcomponents:httpcore:$httpCoreVersion"
         implementation "commons-codec:commons-codec:$commonsCodecVersion"
-        implementation group: 'com.google.guava', name: 'guava', 'version': guavaVersion
         implementation group: 'org.jfrog.filespecs', name: 'file-specs-java', version: fileSpecsJavaVersion
 
         testImplementation group: 'org.testng', name: 'testng', version: testNgVersion

From fc5cd3ba5e826815d8963a12e81b469cf389e88c Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Sun, 9 Jun 2024 05:50:43 +0000
Subject: [PATCH 03/36] [artifactory-release] Release version 2.41.18 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0c6f95580..3ee8aabfd 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.41.18
+build-info-extractor-gradle-version=4.33.17

From 941e78dceedfd596a984bfee2cd611b072dfea77 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Sun, 9 Jun 2024 05:58:06 +0000
Subject: [PATCH 04/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 3ee8aabfd..0c6f95580 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.18
-build-info-extractor-gradle-version=4.33.17
+build-info-version=2.41.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From 7772a09bdc64223b831fe8f5f85314cfbfb89959 Mon Sep 17 00:00:00 2001
From: Yahav Itschak <yahavi@users.noreply.github.com>
Date: Fri, 14 Jun 2024 17:10:56 +0300
Subject: [PATCH 05/36] Bump commons-compress to 1.26.2 (#794)

---
 .../org/jfrog/build/extractor/npm/extractor/NpmPublish.java   | 4 ++--
 build.gradle                                                  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java b/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
index be1550372..44e0c4f25 100644
--- a/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
+++ b/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
@@ -2,7 +2,7 @@
 
 import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
-import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
 import org.apache.commons.lang3.StringUtils;
@@ -118,7 +118,7 @@ private void readPackageInfoFromTarball() throws IOException {
         }
         try (TarArchiveInputStream inputStream = new TarArchiveInputStream(
                 new GzipCompressorInputStream(new BufferedInputStream(Files.newInputStream(path.toFile().toPath()))))) {
-            TarArchiveEntry entry;
+            ArchiveEntry entry;
             while ((entry = inputStream.getNextEntry()) != null) {
                 Path parent = Paths.get(entry.getName()).getParent();
                 if (parent != null && StringUtils.equals(parent.toString(), "package") && StringUtils.endsWith(entry.getName(), "package.json")) {
diff --git a/build.gradle b/build.gradle
index c54358561..ecfd84151 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
         antVersion = '1.10.12'
         buildInfoExtractorVersion = '4.29.4'
         commonsCodecVersion = '1.15'
-        commonsCompressVersion = '1.26.0'
+        commonsCompressVersion = '1.26.2'
         commonsIoVersion = '2.11.0'
         commonsLang3Version = '3.12.0'
         commonsLoggingVersion = '1.2'

From fddaffda863d20d38c0e6a223db9c531748a8689 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Sat, 15 Jun 2024 08:25:28 +0000
Subject: [PATCH 06/36] [artifactory-release] Release version 2.41.19 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0c6f95580..f7db625f7 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.41.19
+build-info-extractor-gradle-version=4.33.18

From 1ac24e5e407ad243901f04540a50d1a4022fb5ca Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Sat, 15 Jun 2024 09:00:05 +0000
Subject: [PATCH 07/36] [artifactory-release] Release version 2.41.20 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index f7db625f7..c87961a0f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.19
-build-info-extractor-gradle-version=4.33.18
+build-info-version=2.41.20
+build-info-extractor-gradle-version=4.33.19

From 6dfb4e921f788b69ec09ad56117ba674687ab845 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Sat, 15 Jun 2024 09:08:21 +0000
Subject: [PATCH 08/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index c87961a0f..0c6f95580 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.20
-build-info-extractor-gradle-version=4.33.19
+build-info-version=2.41.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From 90ef81473361da3ab2743dcd7d8f328c8ab080ef Mon Sep 17 00:00:00 2001
From: Yahav Itschak <yahavi@users.noreply.github.com>
Date: Mon, 17 Jun 2024 08:39:36 +0300
Subject: [PATCH 09/36] Remove commons-collections and add Multimaps (#795)

---
 .github/workflows/integrationTests.yml        |   2 -
 .../main/java/org/jfrog/build/api/Issues.java |   1 -
 .../build/api/multiMap/ListMultimap.java      |  39 +++++
 .../jfrog/build/api/multiMap/Multimap.java    | 163 ++++++++++++++++++
 .../jfrog/build/api/multiMap/SetMultimap.java |  35 ++++
 .../build/api/multiMap/ListMultimapTest.java  |  48 ++++++
 .../build/api/multiMap/MultimapTest.java      | 155 +++++++++++++++++
 .../build/api/multiMap/SetMultimapTest.java   |  47 +++++
 .../docker/extractor/BuildDockerCreator.java  |  12 +-
 .../docker/extractor/DockerPush.java          |  12 +-
 .../docker/extractor/DockerExtractorTest.java |   9 +-
 .../extractor/go/extractor/GoPublish.java     |  10 +-
 .../go/extractor/GoExtractorTest.java         |   6 +-
 .../artifactory/task/ArtifactoryTask.java     |   8 +-
 .../artifactory/task/helper/TaskHelper.java   |   6 +-
 .../extractor/npm/extractor/NpmPublish.java   |  10 +-
 .../npm/extractor/NpmExtractorTest.java       |  19 +-
 .../clientConfiguration/ArtifactSpecs.java    |   8 +-
 .../ArtifactoryClientConfiguration.java       |   4 +-
 .../artifactory/ArtifactoryManager.java       |   4 +-
 .../artifactory/services/SetProperties.java   |  15 +-
 .../deploy/DeployDetails.java                 |  18 +-
 .../util/DeploymentUrlUtils.java              |   4 +-
 .../util/PublishedItemsHelper.java            |  14 +-
 .../spec/SingleSpecDeploymentProducer.java    |   6 +-
 .../util/spec/SpecDeploymentProducer.java     |   6 +-
 .../util/spec/SpecsHelper.java                |  17 +-
 .../util/spec/UploadSpecHelper.java           |  12 +-
 .../client/DeploymentUrlUtilsTest.java        |   6 +-
 .../util/PublishedItemsHelperTest.java        |  36 ++--
 build.gradle                                  |   1 -
 31 files changed, 608 insertions(+), 125 deletions(-)
 create mode 100644 build-info-api/src/main/java/org/jfrog/build/api/multiMap/ListMultimap.java
 create mode 100644 build-info-api/src/main/java/org/jfrog/build/api/multiMap/Multimap.java
 create mode 100644 build-info-api/src/main/java/org/jfrog/build/api/multiMap/SetMultimap.java
 create mode 100644 build-info-api/src/test/java/org/jfrog/build/api/multiMap/ListMultimapTest.java
 create mode 100644 build-info-api/src/test/java/org/jfrog/build/api/multiMap/MultimapTest.java
 create mode 100644 build-info-api/src/test/java/org/jfrog/build/api/multiMap/SetMultimapTest.java

diff --git a/.github/workflows/integrationTests.yml b/.github/workflows/integrationTests.yml
index ccf86093f..564c642f8 100644
--- a/.github/workflows/integrationTests.yml
+++ b/.github/workflows/integrationTests.yml
@@ -1,8 +1,6 @@
 name: Integration Tests
 on:
   push:
-    branches:
-      - master
   # Triggers the workflow on labeled PRs only.
   pull_request_target:
     types: [ labeled ]
diff --git a/build-info-api/src/main/java/org/jfrog/build/api/Issues.java b/build-info-api/src/main/java/org/jfrog/build/api/Issues.java
index cdc873e68..29ec8902f 100644
--- a/build-info-api/src/main/java/org/jfrog/build/api/Issues.java
+++ b/build-info-api/src/main/java/org/jfrog/build/api/Issues.java
@@ -6,7 +6,6 @@
 import java.io.Serializable;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * @author Noam Y. Tenne
diff --git a/build-info-api/src/main/java/org/jfrog/build/api/multiMap/ListMultimap.java b/build-info-api/src/main/java/org/jfrog/build/api/multiMap/ListMultimap.java
new file mode 100644
index 000000000..da1e0ce1a
--- /dev/null
+++ b/build-info-api/src/main/java/org/jfrog/build/api/multiMap/ListMultimap.java
@@ -0,0 +1,39 @@
+package org.jfrog.build.api.multiMap;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Map;
+
+/**
+ * A multimap that uses a {@link LinkedList} to store the values.
+ */
+public class ListMultimap<Key, Value> extends Multimap<Key, Value> {
+
+    /**
+     * Default constructor.
+     */
+    public ListMultimap() {
+        super();
+    }
+
+    /**
+     * Constructor that accepts a map.
+     *
+     * @param map the map
+     */
+    public ListMultimap(Map<Key, Value> map) {
+        super(map);
+    }
+
+    /**
+     * Put a key-value pair into the multimap.
+     *
+     * @param key   the key
+     * @param value the value
+     */
+    public void put(Key key, Value value) {
+        Collection<Value> currentValue = multiMap.getOrDefault(key, new LinkedList<>());
+        currentValue.add(value);
+        multiMap.put(key, currentValue);
+    }
+}
diff --git a/build-info-api/src/main/java/org/jfrog/build/api/multiMap/Multimap.java b/build-info-api/src/main/java/org/jfrog/build/api/multiMap/Multimap.java
new file mode 100644
index 000000000..3f70faa73
--- /dev/null
+++ b/build-info-api/src/main/java/org/jfrog/build/api/multiMap/Multimap.java
@@ -0,0 +1,163 @@
+package org.jfrog.build.api.multiMap;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+import java.io.Serializable;
+import java.util.*;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
+@JsonSubTypes({
+        @JsonSubTypes.Type(value = ListMultimap.class, name = "list"),
+        @JsonSubTypes.Type(value = SetMultimap.class, name = "set"),
+})
+public abstract class Multimap<Key, Value> implements Serializable {
+    private static final long serialVersionUID = 1L;
+    Map<Key, Collection<Value>> multiMap = new HashMap<>();
+
+    /**
+     * Default constructor.
+     */
+    Multimap() {
+    }
+
+    /**
+     * Constructor that accepts a map.
+     *
+     * @param map the map
+     */
+    Multimap(Map<Key, Value> map) {
+        map.forEach(this::put);
+    }
+
+    /**
+     * Put a key-value pair into the multimap.
+     *
+     * @param key   the key
+     * @param value the value
+     */
+    public abstract void put(Key key, Value value);
+
+    /**
+     * Get all values for a key.
+     *
+     * @param key the key
+     * @return a collection of values for the key
+     */
+    public Collection<Value> get(Key key) {
+        return multiMap.get(key);
+    }
+
+    /**
+     * Put all key-value pairs from a map into the multimap.
+     *
+     * @param map the map
+     */
+    public void putAll(Map<Key, Value> map) {
+        for (Map.Entry<Key, Value> entry : map.entrySet()) {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Put all key-value pairs from a multimap into the multimap.
+     *
+     * @param multimap the multimap
+     */
+    public void putAll(Multimap<Key, Value> multimap) {
+        for (Map.Entry<Key, Collection<Value>> entry : multimap.multiMap.entrySet()) {
+            for (Value value : entry.getValue()) {
+                put(entry.getKey(), value);
+            }
+        }
+    }
+
+    /**
+     * Put all values for a key into the multimap.
+     *
+     * @param key    the key
+     * @param values the values
+     */
+    public void putAll(Key key, Collection<Value> values) {
+        for (Value value : values) {
+            put(key, value);
+        }
+    }
+
+    /**
+     * Get all key-value pairs in the multimap.
+     *
+     * @return a set of key-value pairs
+     */
+    public Set<Map.Entry<Key, Value>> entries() {
+        Set<Map.Entry<Key, Value>> entries = new HashSet<>();
+        for (Map.Entry<Key, Collection<Value>> entry : multiMap.entrySet()) {
+            for (Value value : entry.getValue()) {
+                entries.add(new AbstractMap.SimpleEntry<>(entry.getKey(), value));
+            }
+        }
+        return entries;
+    }
+
+    /**
+     * Get the underlying map.
+     *
+     * @return the map
+     */
+    public Map<Key, Collection<Value>> asMap() {
+        return multiMap;
+    }
+
+    /**
+     * Get all keys in the multimap.
+     *
+     * @return a set of keys
+     */
+    public Set<Key> keySet() {
+        return multiMap.keySet();
+    }
+
+    /**
+     * Check if the multimap contains a value.
+     *
+     * @param value the value
+     * @return true if the multimap contains the value
+     */
+    public boolean containsValue(Value value) {
+        for (Collection<Value> values : multiMap.values()) {
+            if (values.contains(value)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the number of key-value pairs in the multimap.
+     *
+     * @return the number of key-value pairs
+     */
+    public int size() {
+        int size = 0;
+        for (Collection<Value> values : multiMap.values()) {
+            size += values.size();
+        }
+        return size;
+    }
+
+    /**
+     * Check if the multimap is empty.
+     *
+     * @return true if the multimap is empty
+     */
+    public boolean isEmpty() {
+        return multiMap.isEmpty();
+    }
+
+    /**
+     * Clear the multimap.
+     */
+    public void clear() {
+        multiMap.clear();
+    }
+}
diff --git a/build-info-api/src/main/java/org/jfrog/build/api/multiMap/SetMultimap.java b/build-info-api/src/main/java/org/jfrog/build/api/multiMap/SetMultimap.java
new file mode 100644
index 000000000..506d2232f
--- /dev/null
+++ b/build-info-api/src/main/java/org/jfrog/build/api/multiMap/SetMultimap.java
@@ -0,0 +1,35 @@
+package org.jfrog.build.api.multiMap;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * A multimap that uses a {@link HashSet} to store the values.
+ */
+public class SetMultimap<Key, Value> extends Multimap<Key, Value> {
+    public SetMultimap() {
+        super();
+    }
+
+    /**
+     * Constructor that accepts a map.
+     *
+     * @param map the map
+     */
+    public SetMultimap(Map<Key, Value> map) {
+        super(map);
+    }
+
+    /**
+     * Put a key-value pair into the multimap.
+     *
+     * @param key   the key
+     * @param value the value
+     */
+    public void put(Key key, Value value) {
+        Collection<Value> currentValue = multiMap.getOrDefault(key, new HashSet<>());
+        currentValue.add(value);
+        multiMap.put(key, currentValue);
+    }
+}
diff --git a/build-info-api/src/test/java/org/jfrog/build/api/multiMap/ListMultimapTest.java b/build-info-api/src/test/java/org/jfrog/build/api/multiMap/ListMultimapTest.java
new file mode 100644
index 000000000..7b2d4f115
--- /dev/null
+++ b/build-info-api/src/test/java/org/jfrog/build/api/multiMap/ListMultimapTest.java
@@ -0,0 +1,48 @@
+package org.jfrog.build.api.multiMap;
+
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class ListMultimapTest {
+
+    public void testDefaultConstructor() {
+        // Create a new multimap
+        Multimap<String, String> multimap = new ListMultimap<>();
+
+        // Assert that the multimap is empty
+        assertEquals(multimap.size(), 0);
+    }
+
+    public void testConstructorWithMap() {
+        // Create a new map
+        Map<String, String> map = new HashMap<>();
+        map.put("key", "value");
+
+        // Create a new multimap with the map
+        Multimap<String, String> multimap = new ListMultimap<>(map);
+
+        // Assert that the multimap contains the value
+        assertTrue(multimap.containsValue("value"));
+    }
+
+    public void testPutDuplicated() {
+        // Populate multimap with duplicated values
+        Multimap<String, String> multimap = new ListMultimap<>();
+        multimap.put("key", "value");
+        multimap.put("key", "value");
+
+        // Convert the collection to an array
+        String[] values = multimap.get("key").toArray(new String[0]);
+
+        // Assert that the values were added
+        assertEquals(values.length, 2);
+        assertEquals(values[0], "value");
+        assertEquals(values[1], "value");
+    }
+}
diff --git a/build-info-api/src/test/java/org/jfrog/build/api/multiMap/MultimapTest.java b/build-info-api/src/test/java/org/jfrog/build/api/multiMap/MultimapTest.java
new file mode 100644
index 000000000..1f74b66c1
--- /dev/null
+++ b/build-info-api/src/test/java/org/jfrog/build/api/multiMap/MultimapTest.java
@@ -0,0 +1,155 @@
+package org.jfrog.build.api.multiMap;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public class MultimapTest {
+
+    @DataProvider
+    private Object[][] testCases() {
+        return new Object[][]{
+                {new ListMultimap<String, String>()},
+                {new SetMultimap<String, String>()}
+        };
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testPut(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        multimap.put("key1", "value1");
+        multimap.put("key2", "value2");
+        multimap.put("key2", "value3");
+
+        // Assert that the values were added
+        assertTrue(multimap.get("key1").contains("value1"));
+        assertTrue(multimap.get("key2").contains("value2"));
+        assertTrue(multimap.get("key2").contains("value3"));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testPutAllMultimap(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        Multimap<String, String> otherMultimap = new ListMultimap<>();
+        otherMultimap.put("key1", "value1");
+        otherMultimap.put("key2", "value2");
+        otherMultimap.put("key2", "value3");
+
+        // Add the values to the multimap
+        multimap.putAll(otherMultimap);
+
+        // Assert that the values were added
+        assertTrue(multimap.get("key1").contains("value1"));
+        assertTrue(multimap.get("key2").contains("value2"));
+        assertTrue(multimap.get("key2").contains("value3"));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testPutAllCollection(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        List<String> otherCollection = new ArrayList<>();
+        otherCollection.add("value1");
+        otherCollection.add("value2");
+
+        // Add the values to the multimap
+        multimap.putAll("key", otherCollection);
+
+        // Assert that the values were added
+        assertTrue(multimap.get("key").contains("value1"));
+        assertTrue(multimap.get("key").contains("value2"));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testPutAllMap(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        Map<String, String> otherMap = new HashMap<>();
+        otherMap.put("key1", "value1");
+        otherMap.put("key2", "value2");
+
+        // Add the values to the multimap
+        multimap.putAll(otherMap);
+
+        // Assert that the values were added
+        assertTrue(multimap.get("key1").contains("value1"));
+        assertTrue(multimap.get("key2").contains("value2"));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testEntries(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        multimap.put("key1", "value1");
+        multimap.put("key2", "value2");
+
+        // Assert that the entries were added
+        assertTrue(multimap.entries().contains(new HashMap.SimpleEntry<>("key1", "value1")));
+        assertTrue(multimap.entries().contains(new HashMap.SimpleEntry<>("key2", "value2")));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testAsMap(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        multimap.put("key1", "value1");
+        multimap.put("key2", "value2");
+
+        // Assert that the map contains the keys
+        assertTrue(multimap.asMap().containsKey("key1"));
+        assertTrue(multimap.asMap().containsKey("key2"));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testKeySet(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        multimap.put("key1", "value1");
+        multimap.put("key2", "value2");
+
+        // Assert that the key set contains the keys
+        assertTrue(multimap.keySet().contains("key1"));
+        assertTrue(multimap.keySet().contains("key2"));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testContainsValue(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        multimap.put("key1", "value1");
+        multimap.put("key2", "value2");
+
+        // Assert that the multimap contains the values
+        assertTrue(multimap.containsValue("value1"));
+        assertTrue(multimap.containsValue("value2"));
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testSize(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        multimap.put("key1", "value1");
+        multimap.put("key2", "value2");
+
+        // Assert that the size is correct
+        assertEquals(multimap.size(), 2);
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testIsEmpty(Multimap<String, String> multimap) {
+        assertTrue(multimap.isEmpty());
+    }
+
+    @Test(dataProvider = "testCases")
+    public void testClear(Multimap<String, String> multimap) {
+        // Populate multimap with values
+        multimap.put("key1", "value1");
+        multimap.put("key2", "value2");
+
+        // Clear the multimap
+        multimap.clear();
+
+        // Assert that the multimap is empty
+        assertTrue(multimap.isEmpty());
+    }
+}
diff --git a/build-info-api/src/test/java/org/jfrog/build/api/multiMap/SetMultimapTest.java b/build-info-api/src/test/java/org/jfrog/build/api/multiMap/SetMultimapTest.java
new file mode 100644
index 000000000..d217e4c35
--- /dev/null
+++ b/build-info-api/src/test/java/org/jfrog/build/api/multiMap/SetMultimapTest.java
@@ -0,0 +1,47 @@
+package org.jfrog.build.api.multiMap;
+
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class SetMultimapTest {
+
+    public void testDefaultConstructor() {
+        // Create a new multimap
+        Multimap<String, String> multimap = new SetMultimap<>();
+
+        // Assert that the multimap is empty
+        assertEquals(multimap.size(), 0);
+    }
+
+    public void testConstructorWithMap() {
+        // Create a new map
+        Map<String, String> map = new HashMap<>();
+        map.put("key", "value");
+
+        // Create a new multimap with the map
+        Multimap<String, String> multimap = new SetMultimap<>(map);
+
+        // Assert that the multimap contains the value
+        assertTrue(multimap.containsValue("value"));
+    }
+
+    public void testPutDuplicated() {
+        // Populate multimap with duplicated values
+        Multimap<String, String> multimap = new SetMultimap<>();
+        multimap.put("key", "value");
+        multimap.put("key", "value");
+
+        // Convert the collection to an array
+        String[] values = multimap.get("key").toArray(new String[0]);
+
+        // Assert that only one values was added
+        assertEquals(values.length, 1);
+        assertEquals(values[0], "value");
+    }
+}
diff --git a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java
index a514fb1cc..243818f08 100644
--- a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java
+++ b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/BuildDockerCreator.java
@@ -2,10 +2,10 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.commons.collections4.MultiValuedMap;
-import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.ci.BuildInfo;
 import org.jfrog.build.extractor.ci.Module;
@@ -35,7 +35,7 @@
 import static org.jfrog.build.extractor.packageManager.PackageManagerUtils.createArtifactoryClientConfiguration;
 
 public class BuildDockerCreator extends PackageManagerExtractor {
-    private final MultiValuedMap<String, String> artifactProperties;
+    private final Multimap<String, String> artifactProperties;
     private final ArtifactoryManagerBuilder artifactoryManagerBuilder;
     private final ImageFileType imageFileType;
     private final String sourceRepo;
@@ -56,7 +56,7 @@ enum ImageFileType {
      * @param artifactProperties        - Properties to be attached to the docker layers deployed to Artifactory.
      */
     public BuildDockerCreator(ArtifactoryManagerBuilder artifactoryManagerBuilder, String imageFile, ImageFileType imageFileType,
-                              MultiValuedMap<String, String> artifactProperties, String sourceRepo, Log logger) {
+                              Multimap<String, String> artifactProperties, String sourceRepo, Log logger) {
         this.artifactoryManagerBuilder = artifactoryManagerBuilder;
         this.artifactProperties = artifactProperties;
         this.sourceRepo = sourceRepo;
@@ -92,7 +92,7 @@ public static void main(String[] ignored) {
             BuildDockerCreator dockerBuildCreate = new BuildDockerCreator(artifactoryManagerBuilder,
                     imageFile,
                     imageFileType,
-                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
+                    new ListMultimap<>(clientConfiguration.publisher.getMatrixParams()),
                     clientConfiguration.publisher.getRepoKey(),
                     clientConfiguration.getLog());
 
@@ -137,7 +137,7 @@ public BuildInfo execute() {
     /**
      * Update each layer's properties with artifactProperties.
      */
-    private void setImageLayersProps(DockerLayers layers, MultiValuedMap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
+    private void setImageLayersProps(DockerLayers layers, Multimap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
         if (layers == null) {
             return;
         }
diff --git a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java
index ebf669c68..05a97728c 100644
--- a/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java
+++ b/build-info-extractor-docker/src/main/java/org/jfrog/build/extractor/docker/extractor/DockerPush.java
@@ -1,9 +1,9 @@
 package org.jfrog.build.extractor.docker.extractor;
 
-import org.apache.commons.collections4.MultiValuedMap;
-import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.ci.BuildInfo;
 import org.jfrog.build.extractor.ci.Module;
@@ -22,7 +22,7 @@
 import static org.jfrog.build.extractor.packageManager.PackageManagerUtils.createArtifactoryClientConfiguration;
 
 public class DockerPush extends DockerCommand {
-    private final MultiValuedMap<String, String> artifactProperties;
+    private final Multimap<String, String> artifactProperties;
 
 
     /**
@@ -37,7 +37,7 @@ public class DockerPush extends DockerCommand {
      * @param env                       - Environment variables to use during docker push execution.
      */
     public DockerPush(ArtifactoryManagerBuilder artifactoryManagerBuilder,
-                      String imageTag, String host, MultiValuedMap<String, String> artifactProperties, String targetRepository, String username,
+                      String imageTag, String host, Multimap<String, String> artifactProperties, String targetRepository, String username,
                       String password, Log logger, Map<String, String> env) {
         super(artifactoryManagerBuilder, imageTag, host, targetRepository, username, password, logger, env);
         this.artifactProperties = artifactProperties;
@@ -59,7 +59,7 @@ public static void main(String[] ignored) {
             DockerPush dockerPush = new DockerPush(artifactoryManagerBuilder,
                     dockerHandler.getImageTag(),
                     dockerHandler.getHost(),
-                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
+                    new ListMultimap<>(clientConfiguration.publisher.getMatrixParams()),
                     clientConfiguration.publisher.getRepoKey(),
                     clientConfiguration.publisher.getUsername(),
                     clientConfiguration.publisher.getPassword(),
@@ -105,7 +105,7 @@ public BuildInfo execute() {
     /**
      * Update each layer's properties with artifactProperties.
      */
-    private void setImageLayersProps(DockerLayers layers, MultiValuedMap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
+    private void setImageLayersProps(DockerLayers layers, Multimap<String, String> artifactProperties, ArtifactoryManagerBuilder artifactoryManagerBuilder) throws IOException {
         if (layers == null) {
             return;
         }
diff --git a/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java b/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java
index e31acf8c5..8591345c3 100644
--- a/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java
+++ b/build-info-extractor-docker/src/test/java/org/jfrog/build/extractor/docker/extractor/DockerExtractorTest.java
@@ -2,14 +2,13 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.apache.commons.collections4.MultiValuedMap;
-import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.compress.utils.Sets;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.SystemUtils;
 import org.jfrog.build.IntegrationTestsBase;
-import org.jfrog.build.extractor.ci.Module;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.ci.*;
 import org.jfrog.build.extractor.docker.DockerJavaWrapper;
 import org.jfrog.build.extractor.executor.CommandExecutor;
@@ -43,7 +42,7 @@ public class DockerExtractorTest extends IntegrationTestsBase {
     private static final String SHORT_IMAGE_TAG_VIRTUAL = "3";
     private static final String EXPECTED_REMOTE_PATH_KANIKO = "hello-world/latest";
     private static final String DOCKER_HOST = "BITESTS_ARTIFACTORY_DOCKER_HOST";
-    private final MultiValuedMap<String, String> artifactProperties;
+    private final Multimap<String, String> artifactProperties;
     private String pullImageFromVirtual;
     private String virtualDomainName;
     private String host;
@@ -56,7 +55,7 @@ public DockerExtractorTest() {
         localRepo1 = getKeyWithTimestamp(DOCKER_LOCAL_REPO);
         remoteRepo = getKeyWithTimestamp(DOCKER_REMOTE_REPO);
         virtualRepo = getKeyWithTimestamp(DOCKER_VIRTUAL_REPO);
-        artifactProperties = new ArrayListValuedHashMap<String, String>() {{
+        artifactProperties = new ListMultimap<String, String>() {{
             put("build.name", "docker-push-test");
             put("build.number", "1");
             put("build.timestamp", "321");
diff --git a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java
index 4283ada4a..cb4efa352 100644
--- a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java
+++ b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoPublish.java
@@ -1,12 +1,12 @@
 package org.jfrog.build.extractor.go.extractor;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.commons.collections4.MultiValuedMap;
-import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.compress.archivers.zip.ZipFile;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.jfrog.build.api.builder.ModuleType;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.util.FileChecksumCalculator;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.client.ArtifactoryUploadResponse;
@@ -47,7 +47,7 @@ public class GoPublish extends GoCommand {
     private static final String PKG_MOD_FILE_EXTENSION = "mod";
     private static final String PKG_INFO_FILE_EXTENSION = "info";
 
-    private final MultiValuedMap<String, String> properties;
+    private final Multimap<String, String> properties;
     private final List<Artifact> artifactList = new ArrayList<>();
     private final String deploymentRepo;
     private final String version;
@@ -62,7 +62,7 @@ public class GoPublish extends GoCommand {
      * @param version                   - The package's version.
      * @param logger                    - The logger.
      */
-    public GoPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, MultiValuedMap<String, String> properties, String repo, Path path, String version, String module, Log logger) throws IOException {
+    public GoPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, Multimap<String, String> properties, String repo, Path path, String version, String module, Log logger) throws IOException {
         super(artifactoryManagerBuilder, path, module, logger);
         this.goDriver = new GoDriver(GO_CLIENT_CMD, null, path.toFile(), logger);
         this.moduleName = goDriver.getModuleName();
@@ -94,7 +94,7 @@ public static void main(String[] ignored) {
 
             GoPublish goPublish = new GoPublish(
                     artifactoryManagerBuilder,
-                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
+                    new ListMultimap<>(clientConfiguration.publisher.getMatrixParams()),
                     clientConfiguration.publisher.getRepoKey(),
                     Paths.get(packageManagerHandler.getPath() != null ? packageManagerHandler.getPath() : ".").toAbsolutePath(),
                     clientConfiguration.goHandler.getGoPublishedVersion(),
diff --git a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java
index a66af038b..850b4a892 100644
--- a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java
+++ b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoExtractorTest.java
@@ -1,11 +1,11 @@
 package org.jfrog.build.extractor.go.extractor;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.jfrog.build.IntegrationTestsBase;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.ci.*;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryManagerBuilder;
 import org.jfrog.build.extractor.clientConfiguration.deploy.DeployDetails;
@@ -175,7 +175,7 @@ public void goRunTest(Project project, String args, ArtifactoryManagerBuilder ar
     @Test
     public void goRunPublishTest() {
         Path projectDir = null;
-        MultiValuedMap<String, String> properties = MultiMapUtils.newListValuedHashMap();
+        Multimap<String, String> properties = new ListMultimap<>();
         try {
             // Run Go build on project1 locally
             Project project = Project.PROJECT_1;
diff --git a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java
index 8f2f63d3e..2e6079ca9 100644
--- a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java
+++ b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/ArtifactoryTask.java
@@ -1,8 +1,6 @@
 package org.jfrog.gradle.plugin.artifactory.task;
 
 import groovy.lang.Closure;
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.gradle.api.Action;
 import org.gradle.api.DefaultTask;
@@ -17,6 +15,8 @@
 import org.gradle.api.tasks.Optional;
 import org.gradle.api.tasks.*;
 import org.gradle.util.ConfigureUtil;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactSpecs;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration;
 import org.jfrog.gradle.plugin.artifactory.ArtifactoryPluginUtil;
@@ -162,10 +162,10 @@ public void setCiServerBuild() {
 
     public final Set<GradleDeployDetails> deployDetails = new TreeSet<>();
 
-    private final MultiValuedMap<String, CharSequence> properties = MultiMapUtils.newListValuedHashMap();
+    private final Multimap<String, CharSequence> properties = new ListMultimap<>();
 
     @Input
-    public MultiValuedMap<String, CharSequence> getProperties() {
+    public Multimap<String, CharSequence> getProperties() {
         return properties;
     }
 
diff --git a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java
index ff476410e..4ef7dbc2a 100644
--- a/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java
+++ b/build-info-extractor-gradle/src/main/groovy/org/jfrog/gradle/plugin/artifactory/task/helper/TaskHelper.java
@@ -1,11 +1,11 @@
 package org.jfrog.gradle.plugin.artifactory.task.helper;
 
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.gradle.api.Project;
 import org.gradle.api.Task;
 import org.gradle.api.logging.Logger;
 import org.gradle.api.logging.Logging;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactSpec;
 import org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration;
 import org.jfrog.gradle.plugin.artifactory.ArtifactoryPluginUtil;
@@ -70,12 +70,12 @@ protected Map<String, String> getPropsToAdd(PublishArtifactInfo artifact, String
                         .name(project.getName()).version(project.getVersion().toString())
                         .classifier(artifact.getClassifier())
                         .type(artifact.getType()).build();
-        MultiValuedMap<String, CharSequence> artifactSpecsProperties = artifactoryTask.artifactSpecs.getProperties(spec);
+        Multimap<String, CharSequence> artifactSpecsProperties = artifactoryTask.artifactSpecs.getProperties(spec);
         addProps(propsToAdd, artifactSpecsProperties);
         return propsToAdd;
     }
 
-    private void addProps(Map<String, String> target, MultiValuedMap<String, CharSequence> props) {
+    private void addProps(Map<String, String> target, Multimap<String, CharSequence> props) {
         for (Map.Entry<String, CharSequence> entry : props.entries()) {
             // Make sure all GString are now Java Strings
             String key = entry.getKey();
diff --git a/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java b/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
index 44e0c4f25..ba21efc22 100644
--- a/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
+++ b/build-info-extractor-npm/src/main/java/org/jfrog/build/extractor/npm/extractor/NpmPublish.java
@@ -1,13 +1,13 @@
 package org.jfrog.build.extractor.npm.extractor;
 
-import org.apache.commons.collections4.MultiValuedMap;
-import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
 import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.jfrog.build.api.builder.ModuleType;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.client.ArtifactoryUploadResponse;
 import org.jfrog.build.extractor.builder.ArtifactBuilder;
@@ -39,7 +39,7 @@
  */
 @SuppressWarnings({"unused", "WeakerAccess"})
 public class NpmPublish extends NpmCommand {
-    private final MultiValuedMap<String, String> properties;
+    private final Multimap<String, String> properties;
     private Artifact deployedArtifact;
     private boolean tarballProvided;
     private final String module;
@@ -54,7 +54,7 @@ public class NpmPublish extends NpmCommand {
      * @param logger                    - The logger.
      * @param env                       - Environment variables to use during npm execution.
      */
-    public NpmPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, MultiValuedMap<String, String> properties, Path path, String deploymentRepository, Log logger, Map<String, String> env, String module) {
+    public NpmPublish(ArtifactoryManagerBuilder artifactoryManagerBuilder, Multimap<String, String> properties, Path path, String deploymentRepository, Log logger, Map<String, String> env, String module) {
         super(artifactoryManagerBuilder, deploymentRepository, logger, path, env);
         this.properties = properties;
         this.module = module;
@@ -70,7 +70,7 @@ public static void main(String[] ignored) {
             ArtifactoryManagerBuilder artifactoryManagerBuilder = new ArtifactoryManagerBuilder().setClientConfiguration(clientConfiguration, clientConfiguration.publisher);
             ArtifactoryClientConfiguration.PackageManagerHandler npmHandler = clientConfiguration.packageManagerHandler;
             NpmPublish npmPublish = new NpmPublish(artifactoryManagerBuilder,
-                    new ArrayListValuedHashMap<>(clientConfiguration.publisher.getMatrixParams()),
+                    new ListMultimap<>(clientConfiguration.publisher.getMatrixParams()),
                     Paths.get(npmHandler.getPath() != null ? npmHandler.getPath() : "."),
                     clientConfiguration.publisher.getRepoKey(),
                     clientConfiguration.getLog(),
diff --git a/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java b/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java
index a1702849d..b0282c8ef 100644
--- a/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java
+++ b/build-info-extractor-npm/src/test/java/org/jfrog/build/extractor/npm/extractor/NpmExtractorTest.java
@@ -1,12 +1,11 @@
 package org.jfrog.build.extractor.npm.extractor;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
-import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.jfrog.build.IntegrationTestsBase;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.builder.DependencyBuilder;
 import org.jfrog.build.extractor.ci.BuildInfo;
 import org.jfrog.build.extractor.ci.Dependency;
@@ -208,17 +207,17 @@ private void runNpmTest(Project project, Dependency[] expectedDependencies, Stri
     @DataProvider
     private Object[][] npmPublishProvider() {
         return new Object[][]{
-                {Project.A, MultiMapUtils.emptyMultiValuedMap(), Project.A.getTargetPath(), ""},
-                {Project.A, new ArrayListValuedHashMap<String, String>() {{
+                {Project.A, new ListMultimap<>(), Project.A.getTargetPath(), ""},
+                {Project.A, new ListMultimap<String, String>() {{
                     put("a", "b");
                 }}, Project.A.getTargetPath(), ""},
-                {Project.B, MultiMapUtils.emptyMultiValuedMap(), Project.B.getTargetPath(), Project.B.getPackedFileName()},
-                {Project.B, new ArrayListValuedHashMap<String, String>() {{
+                {Project.B, new ListMultimap<>(), Project.B.getTargetPath(), Project.B.getPackedFileName()},
+                {Project.B, new ListMultimap<String, String>() {{
                     put("a", "b");
                     put("c", "d");
                 }}, Project.B.getTargetPath(), Project.B.getPackedFileName()},
-                {Project.C, MultiMapUtils.emptyMultiValuedMap(), Project.C.getTargetPath(), ""},
-                {Project.C, new ArrayListValuedHashMap<String, String>() {{
+                {Project.C, new ListMultimap<>(), Project.C.getTargetPath(), ""},
+                {Project.C, new ListMultimap<String, String>() {{
                     put("a", "b");
                     put("a", "d");
                 }}, Project.C.getTargetPath(), ""}
@@ -227,7 +226,7 @@ private Object[][] npmPublishProvider() {
 
     @SuppressWarnings("unused")
     @Test(dataProvider = "npmPublishProvider")
-    public void npmPublishTest(Project project, MultiValuedMap<String, String> props, String targetPath, String packageName) {
+    public void npmPublishTest(Project project, Multimap<String, String> props, String targetPath, String packageName) {
         Path projectDir = null;
         try {
             // Run npm publish
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java
index 273e158f9..06231d65c 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactSpecs.java
@@ -1,8 +1,8 @@
 package org.jfrog.build.extractor.clientConfiguration;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 
 import java.util.LinkedList;
 import java.util.Map;
@@ -41,8 +41,8 @@ public ArtifactSpecs(String specsNotation) {
      * @param spec
      * @return
      */
-    public MultiValuedMap<String, CharSequence> getProperties(ArtifactSpec spec) {
-        MultiValuedMap<String, CharSequence> props = MultiMapUtils.newListValuedHashMap();
+    public Multimap<String, CharSequence> getProperties(ArtifactSpec spec) {
+        Multimap<String, CharSequence> props = new ListMultimap<>();
         for (ArtifactSpec matcherSpec : this) {
             if (matcherSpec.matches(spec)) {
                 Map<String, CharSequence> matcherSpecProperties = matcherSpec.getProperties();
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
index 256938efa..445e066b9 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
@@ -1,7 +1,7 @@
 package org.jfrog.build.extractor.clientConfiguration;
 
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.util.CommonUtils;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.ci.BuildInfo;
@@ -883,7 +883,7 @@ public void addMatrixParams(Map<String, String> vars) {
             }
         }
 
-        public void addMatrixParams(MultiValuedMap<String, String> vars) {
+        public void addMatrixParams(Multimap<String, String> vars) {
             for (Map.Entry<String, String> entry : vars.entries()) {
                 addMatrixParam(entry.getKey(), entry.getValue());
             }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java
index a4ea612cd..9ca6a9d1d 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/ArtifactoryManager.java
@@ -1,12 +1,12 @@
 package org.jfrog.build.extractor.clientConfiguration.client.artifactory;
 
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.Header;
 import org.jfrog.build.api.dependency.BuildPatternArtifacts;
 import org.jfrog.build.api.dependency.BuildPatternArtifactsRequest;
 import org.jfrog.build.api.dependency.PatternResultFileSet;
 import org.jfrog.build.api.dependency.PropertySearchResult;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.release.Distribution;
 import org.jfrog.build.api.release.Promotion;
 import org.jfrog.build.api.search.AqlSearchResult;
@@ -72,7 +72,7 @@ public void setProperties(String relativePath, String properties, boolean encode
         setPropertiesService.execute(jfrogHttpClient);
     }
 
-    public void setProperties(String relativePath, MultiValuedMap<String, String> properties, boolean encodeProperties) throws IOException {
+    public void setProperties(String relativePath, Multimap<String, String> properties, boolean encodeProperties) throws IOException {
         SetProperties setPropertiesService = new SetProperties(relativePath, properties, encodeProperties, log);
         setPropertiesService.execute(jfrogHttpClient);
     }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java
index d0e648cd4..41be473df 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/client/artifactory/services/SetProperties.java
@@ -1,11 +1,12 @@
 package org.jfrog.build.extractor.clientConfiguration.client.artifactory.services;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.HttpPut;
 import org.apache.http.client.methods.HttpRequestBase;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
+import org.jfrog.build.api.multiMap.SetMultimap;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.client.JFrogHttpClient;
 import org.jfrog.build.extractor.clientConfiguration.client.VoidJFrogService;
@@ -19,12 +20,12 @@
 
 public class SetProperties extends VoidJFrogService {
     public static final String SET_PROPERTIES_ENDPOINT = "api/storage/";
-    private final MultiValuedMap<String, String> propertiesMap;
+    private final Multimap<String, String> propertiesMap;
     private final boolean encodeProperties;
     private final String relativePath;
     private final String propertiesString;
 
-    private SetProperties(String relativePath, String propertiesString, MultiValuedMap<String, String> propertiesMap, boolean encodeProperties, Log log) {
+    private SetProperties(String relativePath, String propertiesString, Multimap<String, String> propertiesMap, boolean encodeProperties, Log log) {
         super(log);
         this.relativePath = relativePath;
         this.propertiesMap = propertiesMap;
@@ -36,7 +37,7 @@ public SetProperties(String relativePath, String propertiesString, boolean encod
         this(relativePath, propertiesString, null, encodeProperties, log);
     }
 
-    public SetProperties(String relativePath, MultiValuedMap<String, String> propertiesMap, boolean encodeProperties, Log log) {
+    public SetProperties(String relativePath, Multimap<String, String> propertiesMap, boolean encodeProperties, Log log) {
         this(relativePath, null, propertiesMap, encodeProperties, log);
     }
 
@@ -80,8 +81,8 @@ protected void ensureRequirements(JFrogHttpClient client) throws IOException {
         }
     }
 
-    private MultiValuedMap<String, String> mapPropsString(String props) {
-        MultiValuedMap<String, String> propsMap = MultiMapUtils.newListValuedHashMap();
+    private Multimap<String, String> mapPropsString(String props) {
+        Multimap<String, String> propsMap = new ListMultimap<>();
         String[] propsList = props.split(";");
         for (String prop : propsList) {
             if (isNotEmpty(prop)) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java
index 27af64a9c..ad3b3d45a 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/deploy/DeployDetails.java
@@ -1,9 +1,9 @@
 package org.jfrog.build.extractor.clientConfiguration.deploy;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.jfrog.build.api.BuildFileBean;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.producerConsumer.ProducerConsumerItem;
 
 import java.io.File;
@@ -45,7 +45,7 @@ public class DeployDetails implements Comparable<DeployDetails>, Serializable, P
     /**
      * Properties to attach to the deployed file as matrix params.
      */
-    MultiValuedMap<String, String> properties;
+    Multimap<String, String> properties;
     /**
      * Target deploy repository.
      */
@@ -74,7 +74,7 @@ public File getFile() {
         return file;
     }
 
-    public MultiValuedMap<String, String> getProperties() {
+    public Multimap<String, String> getProperties() {
         return properties;
     }
 
@@ -164,7 +164,7 @@ public DeployDetails build() {
         public Builder bean(BuildFileBean bean) {
             Properties beanProperties = bean.getProperties();
             if (beanProperties != null) {
-                MultiValuedMap<String, String> multimap = MultiMapUtils.newListValuedHashMap();
+                Multimap<String, String> multimap = new ListMultimap<>();
                 beanProperties.forEach((key, value) -> multimap.put((String) key, (String) value));
                 deployDetails.properties = multimap;
             }
@@ -215,7 +215,7 @@ public Builder packageType(PackageType packageType) {
 
         public Builder addProperty(String key, String value) {
             if (deployDetails.properties == null) {
-                deployDetails.properties = MultiMapUtils.newListValuedHashMap();
+                deployDetails.properties = new ListMultimap<>();
             }
             deployDetails.properties.put(key, value);
             return this;
@@ -223,16 +223,16 @@ public Builder addProperty(String key, String value) {
 
         public Builder addProperties(Map<String, String> propertiesToAdd) {
             if (deployDetails.properties == null) {
-                deployDetails.properties = MultiMapUtils.newListValuedHashMap();
+                deployDetails.properties = new ListMultimap<>();
             }
 
             deployDetails.properties.putAll(propertiesToAdd);
             return this;
         }
 
-        public Builder addProperties(MultiValuedMap<String, String> propertiesToAdd) {
+        public Builder addProperties(Multimap<String, String> propertiesToAdd) {
             if (deployDetails.properties == null) {
-                deployDetails.properties = MultiMapUtils.newListValuedHashMap();
+                deployDetails.properties = new ListMultimap<>();
             }
 
             deployDetails.properties.putAll(propertiesToAdd);
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java
index 9cf71f1bc..7cc6b5e25 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/DeploymentUrlUtils.java
@@ -1,7 +1,7 @@
 package org.jfrog.build.extractor.clientConfiguration.util;
 
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.api.util.CommonUtils;
 import org.jfrog.build.extractor.UrlUtils;
 import org.jfrog.build.extractor.clientConfiguration.ClientProperties;
@@ -66,7 +66,7 @@ public static String encodePath(String unescaped) {
     }
 
 
-    public static String buildMatrixParamsString(MultiValuedMap<String, String> matrixParams, boolean encodeProperties)
+    public static String buildMatrixParamsString(Multimap<String, String> matrixParams, boolean encodeProperties)
             throws UnsupportedEncodingException {
         StringBuilder matrix = new StringBuilder();
         if (matrixParams != null && !matrixParams.isEmpty()) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java
index 1ead29be1..b7ab1b71e 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/PublishedItemsHelper.java
@@ -16,10 +16,10 @@
 
 package org.jfrog.build.extractor.clientConfiguration.util;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.multiMap.Multimap;
+import org.jfrog.build.api.multiMap.SetMultimap;
 import org.jfrog.build.extractor.clientConfiguration.util.spec.UploadSpecHelper;
 
 import java.io.File;
@@ -45,8 +45,8 @@ public class PublishedItemsHelper {
      *                                    then the value is treated as a source only (target will be "").
      * @return a Map containing the sources as keys and targets as values
      */
-    public static MultiValuedMap<String, String> getPublishedItemsPatternPairs(String publishedItemsPropertyValue) {
-        MultiValuedMap<String, String> patternPairMap = MultiMapUtils.newSetValuedHashMap();
+    public static Multimap<String, String> getPublishedItemsPatternPairs(String publishedItemsPropertyValue) {
+        Multimap<String, String> patternPairMap = new SetMultimap<>();
         if (StringUtils.isNotBlank(publishedItemsPropertyValue)) {
 
             List<String> patternPairs = parsePatternsFromProperty(publishedItemsPropertyValue);
@@ -148,9 +148,9 @@ public static String removeDoubleDotsFromPattern(String pattern) {
      * @throws IOException in case of any file system exception
      */
     @Deprecated
-    public static MultiValuedMap<String, File> buildPublishingData(File checkoutDir, String pattern, String targetPath)
+    public static Multimap<String, File> buildPublishingData(File checkoutDir, String pattern, String targetPath)
             throws IOException {
-        final MultiValuedMap<String, File> filePathsMap = MultiMapUtils.newSetValuedHashMap();
+        final Multimap<String, File> filePathsMap = new SetMultimap<>();
         File patternAbsolutePath = getAbsolutePath(checkoutDir, pattern);
         if (patternAbsolutePath.isFile()) {
             // The given pattern is an absolute path of just one file, let's add it to our result map
@@ -211,7 +211,7 @@ public static MultiValuedMap<String, File> buildPublishingData(File checkoutDir,
      * @return a Multimap containing the targets as keys and the files as values
      */
     @Deprecated
-    public static MultiValuedMap<String, File> wildCardBuildPublishingData(
+    public static Multimap<String, File> wildCardBuildPublishingData(
             File checkoutDir, String pattern, String targetPath, boolean flat, boolean isRecursive, boolean regexp) {
         if (!regexp) {
             pattern = PathsUtils.pathToRegExp(pattern);
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java
index 1d63adcbe..279100b8d 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SingleSpecDeploymentProducer.java
@@ -1,9 +1,9 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.clientConfiguration.deploy.DeployDetails;
 import org.jfrog.build.extractor.clientConfiguration.util.PathsUtils;
 import org.jfrog.build.extractor.producerConsumer.ProducerConsumerExecutor;
@@ -26,7 +26,7 @@ public class SingleSpecDeploymentProducer {
 
     private FilesGroup spec;
     private File workspace;
-    private MultiValuedMap<String, String> buildProperties;
+    private Multimap<String, String> buildProperties;
 
     private Pattern regexpPattern;
     private Pattern regexpExcludePattern;
@@ -42,7 +42,7 @@ public class SingleSpecDeploymentProducer {
     private int separatorsCount;
     private Set<String> symlinkSet = new HashSet<>();
 
-    SingleSpecDeploymentProducer(FilesGroup spec, File workspace, MultiValuedMap<String, String> buildProperties) {
+    SingleSpecDeploymentProducer(FilesGroup spec, File workspace, Multimap<String, String> buildProperties) {
         this.spec = spec;
         this.workspace = workspace;
         this.buildProperties = buildProperties;
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java
index 79948e93a..f6a04151a 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecDeploymentProducer.java
@@ -1,6 +1,6 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import org.apache.commons.collections4.MultiValuedMap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.clientConfiguration.deploy.DeployDetails;
 import org.jfrog.build.extractor.producerConsumer.ProducerRunnableBase;
 import org.jfrog.filespecs.FileSpec;
@@ -23,9 +23,9 @@ public class SpecDeploymentProducer extends ProducerRunnableBase {
 
     private FileSpec spec;
     private File workspace;
-    private MultiValuedMap<String, String> buildProperties;
+    private Multimap<String, String> buildProperties;
 
-    SpecDeploymentProducer(FileSpec spec, File workspace, MultiValuedMap<String, String> buildProperties) {
+    SpecDeploymentProducer(FileSpec spec, File workspace, Multimap<String, String> buildProperties) {
         this.spec = spec;
         this.workspace = workspace;
         this.buildProperties = buildProperties;
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java
index ad2b7eba9..b50c34776 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/SpecsHelper.java
@@ -1,9 +1,10 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
+import org.jfrog.build.api.multiMap.SetMultimap;
 import org.jfrog.build.api.util.Log;
 import org.jfrog.build.extractor.builder.ArtifactBuilder;
 import org.jfrog.build.extractor.ci.Artifact;
@@ -57,8 +58,8 @@ public List<Artifact> uploadArtifactsBySpec(String uploadSpec, File workspace,
         return uploadArtifactsBySpec(uploadSpec, DEFAULT_NUMBER_OF_THREADS, workspace, createMultiMap(buildProperties), artifactoryManagerBuilder);
     }
 
-    private static <K, V> MultiValuedMap<K, V> createMultiMap(Map<K, V> input) {
-        MultiValuedMap<K, V> multimap = MultiMapUtils.newListValuedHashMap();
+    private static <K, V> Multimap<K, V> createMultiMap(Map<K, V> input) {
+        Multimap<K, V> multimap = new ListMultimap<>();
         for (Map.Entry<K, V> entry : input.entrySet()) {
             multimap.put(entry.getKey(), entry.getValue());
         }
@@ -78,7 +79,7 @@ private static <K, V> MultiValuedMap<K, V> createMultiMap(Map<K, V> input) {
      *                     checksums or in case of any file system exception
      */
     public List<Artifact> uploadArtifactsBySpec(String uploadSpec, int numberOfThreads, File workspace,
-                                                MultiValuedMap<String, String> buildProperties,
+                                                Multimap<String, String> buildProperties,
                                                 ArtifactoryManagerBuilder artifactoryManagerBuilder) throws Exception {
         FileSpec fileSpec = FileSpec.fromString(uploadSpec);
         FileSpecsValidation.validateUploadFileSpec(fileSpec, this.log);
@@ -153,13 +154,13 @@ public boolean editPropertiesBySpec(String spec, ArtifactoryManager artifactoryM
      * @param props Spec's properties
      * @return created properties map
      */
-    public static MultiValuedMap<String, String> getPropertiesMap(String props) {
-        MultiValuedMap<String, String> propertiesMap = MultiMapUtils.newListValuedHashMap();
+    public static Multimap<String, String> getPropertiesMap(String props) {
+        Multimap<String, String> propertiesMap = new ListMultimap<>();
         fillPropertiesMap(props, propertiesMap);
         return propertiesMap;
     }
 
-    public static void fillPropertiesMap(String props, MultiValuedMap<String, String> propertiesMap) {
+    public static void fillPropertiesMap(String props, Multimap<String, String> propertiesMap) {
         if (StringUtils.isBlank(props)) {
             return;
         }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java
index 396b8aae3..ef8f0e32f 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/util/spec/UploadSpecHelper.java
@@ -1,11 +1,11 @@
 package org.jfrog.build.extractor.clientConfiguration.util.spec;
 
-import org.apache.commons.collections4.MultiValuedMap;
-import org.apache.commons.collections4.multimap.HashSetValuedHashMap;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.jfrog.build.api.multiMap.Multimap;
+import org.jfrog.build.api.multiMap.SetMultimap;
 import org.jfrog.build.api.util.FileChecksumCalculator;
 import org.jfrog.build.extractor.clientConfiguration.deploy.DeployDetails;
 import org.jfrog.build.extractor.clientConfiguration.util.PathsUtils;
@@ -38,7 +38,7 @@ public class UploadSpecHelper {
      */
     public static DeployDetails buildDeployDetails(String targetPath, File artifactFile,
                                                    String uploadTarget, String explode, String props,
-                                                   MultiValuedMap<String, String> buildProperties)
+                                                   Multimap<String, String> buildProperties)
             throws IOException, NoSuchAlgorithmException {
         String path = UploadSpecHelper.wildcardCalculateTargetPath(targetPath, artifactFile);
         path = StringUtils.replace(path, "//", "/");
@@ -151,9 +151,9 @@ protected static String getUploadPath(File file, Pattern pathPattern, String tar
         return PathsUtils.reformatRegexp(sourcePath, fileTargetPath.replace('\\', '/'), pathPattern);
     }
 
-    public static MultiValuedMap<String, File> getUploadPathsMap(List<File> files, File workspaceDir, String targetPath,
-                                                                 boolean isFlat, Pattern regexPattern, boolean isAbsolutePath) {
-        MultiValuedMap<String, File> filePathsMap = new HashSetValuedHashMap<>();
+    public static Multimap<String, File> getUploadPathsMap(List<File> files, File workspaceDir, String targetPath,
+                                                           boolean isFlat, Pattern regexPattern, boolean isAbsolutePath) {
+        Multimap<String, File> filePathsMap = new SetMultimap<>();
         boolean isTargetDirectory = StringUtils.endsWith(targetPath, "/");
 
         for (File file : files) {
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java
index d4eadf916..b23f6a831 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/client/DeploymentUrlUtilsTest.java
@@ -1,7 +1,7 @@
 package org.jfrog.build.extractor.client;
 
-import org.apache.commons.collections4.MultiMapUtils;
-import org.apache.commons.collections4.MultiValuedMap;
+import org.jfrog.build.api.multiMap.ListMultimap;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.clientConfiguration.ClientProperties;
 import org.jfrog.build.extractor.clientConfiguration.util.DeploymentUrlUtils;
 import org.testng.Assert;
@@ -36,7 +36,7 @@ public void getDeploymentUrlWithEncodingNeeded() throws UnsupportedEncodingExcep
 
 
     public void testKeyWithMultiValuesParam() throws UnsupportedEncodingException {
-        MultiValuedMap<String, String> params = MultiMapUtils.newListValuedHashMap();
+        Multimap<String, String> params = new ListMultimap<>();
         params.put("key", "valueA");
         params.put("key", "valueB");
         params.put("keyA", "valueA");
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java
index 8272d0f16..7272fb82b 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/util/PublishedItemsHelperTest.java
@@ -1,7 +1,7 @@
 package org.jfrog.build.extractor.util;
 
-import org.apache.commons.collections4.MultiValuedMap;
 import org.apache.commons.io.FilenameUtils;
+import org.jfrog.build.api.multiMap.Multimap;
 import org.jfrog.build.extractor.clientConfiguration.util.PublishedItemsHelper;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -32,9 +32,9 @@ public void setup() {
     }
 
     public void testDoubleDotWithStartWildcard() throws IOException {
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("../../saas/**/*.xml=>target/xml");
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs("../../saas/**/*.xml=>target/xml");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 2, "Expected to find 2 files");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -45,10 +45,10 @@ public void testDoubleDotWithStartWildcard() throws IOException {
     }
 
     public void testAbsolutePath() throws IOException {
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs(
                 absoluteFile.getAbsolutePath() + "=>jaja/gululu");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 1, "Expected to find 1 files");
             assertTrue(buildPublishingData.containsValue(absoluteFile), "Expected to find the absolute file");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
@@ -59,9 +59,9 @@ public void testAbsolutePath() throws IOException {
     }
 
     public void testAbsolutePathSameWorkspace() throws IOException {
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(checkoutDir.getAbsolutePath() + "/inner/*.gradle" + "=>test/props");
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs(checkoutDir.getAbsolutePath() + "/inner/*.gradle" + "=>test/props");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 1, "Expected to find 1 file");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -72,14 +72,14 @@ public void testAbsolutePathSameWorkspace() throws IOException {
 
     public void testMultiPatterns() throws IOException {
         String pattern = "**/multi1/*=>test/multi1, **multi2/*=>test/multi2";
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(pattern);
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs(pattern);
         assertEquals(pairs.keySet().size(), 2, "Expected to find 2 keys");
     }
 
     public void testAllWorkspace() throws IOException {
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("**");
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs("**");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 6, "Expected to find 6 files");
         }
     }
@@ -87,17 +87,17 @@ public void testAllWorkspace() throws IOException {
     public void testAbsolutePathWithDoubleStar() throws IOException {
         File resourceAsFile = getResourceAsFile("/root/workspace");
         String fileAbsolutePath = FilenameUtils.separatorsToUnix(resourceAsFile.getAbsolutePath());
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs(fileAbsolutePath + "/ant/**");
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs(fileAbsolutePath + "/ant/**");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 7, "Expected to find 7 files");
         }
     }
 
     public void testAllSpecificFilesFromCheckoutDir() throws IOException {
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("**/*.blabla=>blabla");
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs("**/*.blabla=>blabla");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 2, "Expected to find 2 files");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -107,9 +107,9 @@ public void testAllSpecificFilesFromCheckoutDir() throws IOException {
     }
 
     public void testEmptyTargetPath() throws IOException {
-        MultiValuedMap<String, String> pairs = getPublishedItemsPatternPairs("../../**/**/*.xml");
+        Multimap<String, String> pairs = getPublishedItemsPatternPairs("../../**/**/*.xml");
         for (final Map.Entry<String, String> entry : pairs.entries()) {
-            MultiValuedMap<String, File> buildPublishingData = getBuildPublishingData(entry);
+            Multimap<String, File> buildPublishingData = getBuildPublishingData(entry);
             assertEquals(buildPublishingData.size(), 2, "Expected to find 2 files");
             for (Map.Entry<String, File> fileEntry : buildPublishingData.entries()) {
                 String targetPath = PublishedItemsHelper.calculateTargetPath(fileEntry.getKey(), fileEntry.getValue());
@@ -118,11 +118,11 @@ public void testEmptyTargetPath() throws IOException {
         }
     }
 
-    private MultiValuedMap<String, String> getPublishedItemsPatternPairs(String pattern) {
+    private Multimap<String, String> getPublishedItemsPatternPairs(String pattern) {
         return PublishedItemsHelper.getPublishedItemsPatternPairs(pattern);
     }
 
-    private MultiValuedMap<String, File> getBuildPublishingData(Map.Entry<String, String> entry) throws IOException {
+    private Multimap<String, File> getBuildPublishingData(Map.Entry<String, String> entry) throws IOException {
         return PublishedItemsHelper.buildPublishingData(checkoutDir, entry.getKey(), entry.getValue());
     }
 
diff --git a/build.gradle b/build.gradle
index ecfd84151..8ab75ceab 100644
--- a/build.gradle
+++ b/build.gradle
@@ -134,7 +134,6 @@ subprojects {
         implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jacksonVersion
         implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion
         implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jacksonVersion
-        implementation group: 'org.apache.commons', name: 'commons-collections4', version: commonsCollections4Version
         implementation group: 'org.apache.commons', name: 'commons-compress', version: commonsCompressVersion
 
         implementation("org.apache.httpcomponents:httpclient:$httpClientVersion") {

From ee35755cf0cb3ecedbee09de528fa9bf7568c850 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Mon, 17 Jun 2024 05:46:24 +0000
Subject: [PATCH 10/36] [artifactory-release] Release version 2.41.21 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0c6f95580..2b733d647 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.41.21
+build-info-extractor-gradle-version=4.33.20

From b82ee0627bd002fc987e85898d3ba48f950a6366 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Mon, 17 Jun 2024 05:53:18 +0000
Subject: [PATCH 11/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 2b733d647..0c6f95580 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.21
-build-info-extractor-gradle-version=4.33.20
+build-info-version=2.41.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From 1f1a914cccc75f558b48deb76d8a8f3bba20981b Mon Sep 17 00:00:00 2001
From: yahavi <yahavi@jfrog.com>
Date: Fri, 9 Aug 2024 14:11:55 +0300
Subject: [PATCH 12/36] Fix Setup Artifactory in the integration tests

---
 .github/workflows/integrationTests.yml | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/integrationTests.yml b/.github/workflows/integrationTests.yml
index 564c642f8..adf82ec03 100644
--- a/.github/workflows/integrationTests.yml
+++ b/.github/workflows/integrationTests.yml
@@ -91,12 +91,9 @@ jobs:
             ${{ runner.os }}-maven-
 
       - name: Setup Artifactory
-        run: |
-          go install github.com/jfrog/jfrog-testing-infra/local-rt-setup@latest
-          ~/go/bin/local-rt-setup
-        env:
-          RTLIC: ${{secrets.RTLIC}}
-          GOPROXY: direct
+        uses: jfrog/.github/actions/install-local-artifactory@main
+        with:
+          RTLIC: ${{ secrets.RTLIC }}
 
       # Run tests
       - name: Run Tests

From 541ae683b9223df6cc316e9f1da8f349916ff6da Mon Sep 17 00:00:00 2001
From: yahavi <yahavi@jfrog.com>
Date: Fri, 9 Aug 2024 14:45:51 +0300
Subject: [PATCH 13/36] Fix Setup Artifactory in the integration tests

---
 .github/workflows/integrationTests.yml | 36 +++++++++-----------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/.github/workflows/integrationTests.yml b/.github/workflows/integrationTests.yml
index adf82ec03..a0a323f46 100644
--- a/.github/workflows/integrationTests.yml
+++ b/.github/workflows/integrationTests.yml
@@ -184,12 +184,9 @@ jobs:
             ${{ runner.os }}-maven-
 
       - name: Setup Artifactory
-        run: |
-          go install github.com/jfrog/jfrog-testing-infra/local-rt-setup@latest
-          ~/go/bin/local-rt-setup
-        env:
-          RTLIC: ${{secrets.RTLIC}}
-          GOPROXY: direct
+        uses: jfrog/.github/actions/install-local-artifactory@main
+        with:
+          RTLIC: ${{ secrets.RTLIC }}
 
       # Run tests
       - name: Run Tests
@@ -306,12 +303,9 @@ jobs:
             ${{ runner.os }}-maven-
 
       - name: Setup Artifactory
-        run: |
-          go install github.com/jfrog/jfrog-testing-infra/local-rt-setup@latest
-          ~/go/bin/local-rt-setup
-        env:
-          RTLIC: ${{secrets.RTLIC}}
-          GOPROXY: direct
+        uses: jfrog/.github/actions/install-local-artifactory@main
+        with:
+          RTLIC: ${{ secrets.RTLIC }}
 
       # Run tests
       - name: Run Tests
@@ -365,12 +359,9 @@ jobs:
             ${{ runner.os }}-maven-
 
       - name: Setup Artifactory
-        run: |
-          go install github.com/jfrog/jfrog-testing-infra/local-rt-setup@latest
-          ~/go/bin/local-rt-setup
-        env:
-          RTLIC: ${{secrets.RTLIC}}
-          GOPROXY: direct
+        uses: jfrog/.github/actions/install-local-artifactory@main
+        with:
+          RTLIC: ${{ secrets.RTLIC }}
 
       # Run tests
       - name: Run Tests
@@ -419,12 +410,9 @@ jobs:
             ${{ runner.os }}-maven-
 
       - name: Setup Artifactory
-        run: |
-          go install github.com/jfrog/jfrog-testing-infra/local-rt-setup@latest
-          ~/go/bin/local-rt-setup
-        env:
-          RTLIC: ${{secrets.RTLIC}}
-          GOPROXY: direct
+        uses: jfrog/.github/actions/install-local-artifactory@main
+        with:
+          RTLIC: ${{ secrets.RTLIC }}
 
       # Run tests
       - name: Run Tests

From 26cff7fc4005ebb1065d9c487f2443c118ea36be Mon Sep 17 00:00:00 2001
From: yahavi <yahavi@jfrog.com>
Date: Fri, 9 Aug 2024 15:14:42 +0300
Subject: [PATCH 14/36] Fix Setup Artifactory in the integration tests

---
 .../src/test/resources/artifactory/Dockerfile                   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/build-info-extractor-docker/src/test/resources/artifactory/Dockerfile b/build-info-extractor-docker/src/test/resources/artifactory/Dockerfile
index c47054915..f386b4d0a 100644
--- a/build-info-extractor-docker/src/test/resources/artifactory/Dockerfile
+++ b/build-info-extractor-docker/src/test/resources/artifactory/Dockerfile
@@ -7,4 +7,4 @@ ENV JFROG_HOME=/jfrog_home
 WORKDIR /jfrog_home
 EXPOSE 8082
 EXPOSE 8081
-CMD ["sh","-c","local-rt-setup; sleep infinity"]
\ No newline at end of file
+CMD ["sh","-c","local-rt-setup --rt-version 7.84.17; sleep infinity"]
\ No newline at end of file

From f36267bea52a4e5c4f31ff06cdebb5787b1bf9e9 Mon Sep 17 00:00:00 2001
From: Yahav Itschak <yahavi@users.noreply.github.com>
Date: Fri, 9 Aug 2024 16:01:08 +0300
Subject: [PATCH 15/36] Support multiple no proxy hosts in Maven (#801)

---
 .../maven/resolver/ArtifactoryResolutionTest.java     | 11 +++++++++++
 .../java/org/jfrog/build/extractor/ProxySelector.java |  4 +++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/build-info-extractor-maven3/src/test/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolutionTest.java b/build-info-extractor-maven3/src/test/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolutionTest.java
index 7018497ac..6682c6854 100644
--- a/build-info-extractor-maven3/src/test/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolutionTest.java
+++ b/build-info-extractor-maven3/src/test/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolutionTest.java
@@ -33,6 +33,7 @@ public class ArtifactoryResolutionTest {
     final int HTTP_PROXY_PORT = 8888;
     final int HTTPS_PROXY_PORT = 8889;
     final String NO_PROXY_PATTERN = "www.http-no-proxy-url.com";
+    final String MULTIPLE_NO_PROXY_PATTERNS = "www.no-proxy-1.com,www.http-no-proxy-url.com";
     ArtifactoryResolution artifactoryResolution;
     ArtifactoryResolution artifactoryResolutionOnlyRelease;
     RemoteRepository snapshotRepository;
@@ -180,6 +181,16 @@ public void TestNullProxyHttps() {
         assertNull(artifactoryResolutionWithNoHttp.createSnapshotRepository().getProxy());
     }
 
+    @Test(description = "In the case of 'http.nonProxyHosts' with multiple hosts that one of them is matching the repository URL, null is returned from getProxy().")
+    public void TestMultipleNoProxy() {
+        // Prepare
+        ProxySelector multipleNoHostsProxySelector = new ProxySelector(HTTP_PROXY_URL, HTTP_PROXY_PORT, HTTP_PROXY_USERNAME, HTTP_PROXY_PASSWORD, HTTPS_PROXY_URL, HTTPS_PROXY_PORT, HTTPS_PROXY_USERNAME, HTTPS_PROXY_PASSWORD, MULTIPLE_NO_PROXY_PATTERNS);
+        // Act
+        ArtifactoryResolution artifactoryResolutionWithNoHttp = new ArtifactoryResolution(HTTP_RELEASE_URL, "https://" + NO_PROXY_PATTERN, USERNAME, PASSWORD, multipleNoHostsProxySelector, new NullPlexusLog());
+        // Assert
+        assertNull(artifactoryResolutionWithNoHttp.createSnapshotRepository().getProxy());
+    }
+
     @Test(description = "HTTP proxy is configured, but HTTPS isn't => a valid proxy return.")
     public void testOnlyHttpProxyConfigured() {
         // Prepare
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/ProxySelector.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/ProxySelector.java
index b19537677..db62b85dd 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/ProxySelector.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/ProxySelector.java
@@ -25,13 +25,15 @@ public class ProxySelector {
     private Proxy httpsProxy;
 
     public ProxySelector(String httpHost, int httpPort, String httpUsername, String httpPassword, String httpsHost, int httpsPort, String httpsUsername, String httpsPassword, String noProxy) {
-        this.noProxy = noProxy;
         if (StringUtils.isNotBlank(httpHost)) {
             this.httpProxy = new Proxy(httpHost, httpPort, httpUsername, httpPassword, false);
         }
         if (StringUtils.isNotBlank(httpsHost)) {
             this.httpsProxy = new Proxy(httpsHost, httpsPort, httpsUsername, httpsPassword, true);
         }
+        // The NO_PROXY environment variable standard uses commas to separate no-proxy hosts.
+        // The Java system property http.nonProxyHosts uses pipes.
+        this.noProxy = StringUtils.replace(noProxy, ",", "|");
     }
 
     public Proxy getProxy(String repositoryUrl) {

From 54cb4a89452fd24e77f1ddbd88b141070105955c Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Wed, 21 Aug 2024 10:41:49 +0000
Subject: [PATCH 16/36] [artifactory-release] Release version 2.41.22 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0c6f95580..cab644b1e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.41.22
+build-info-extractor-gradle-version=4.33.21

From 04fafa63fe3ed9ff40bdc5aca02f7bc1ca8f0a54 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Wed, 21 Aug 2024 10:51:08 +0000
Subject: [PATCH 17/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index cab644b1e..0c6f95580 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.22
-build-info-extractor-gradle-version=4.33.21
+build-info-version=2.41.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From bdb835250abc2d6b071922595ac3a0cd4eafa20d Mon Sep 17 00:00:00 2001
From: Yuval Ohayon <84730882+yuvalojfrog@users.noreply.github.com>
Date: Sun, 8 Sep 2024 17:31:01 +0300
Subject: [PATCH 18/36] Fix VERSION_PATTERN Regex pattern in Go (#805)

---
 .../go/extractor/GoVersionUtils.java          |   5 +-
 .../go/extractor/GoVersionUtilsTest.java      | 178 ++++++++++++++++++
 2 files changed, 182 insertions(+), 1 deletion(-)
 create mode 100644 build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java

diff --git a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java
index bfef3759e..4befb6a41 100644
--- a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java
+++ b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java
@@ -14,7 +14,10 @@ public class GoVersionUtils {
 
     public static final String INCOMPATIBLE = "+incompatible";
     public static final int ZERO_OR_ONE = 0;
-    protected static final Pattern VERSION_PATTERN = Pattern.compile("v(\\d*)\\.(\\d+)\\.(\\d+)");
+    // The regular expression used here is derived from the SemVer specification: https://semver.org/
+    protected static final Pattern VERSION_PATTERN = Pattern.compile(
+            "v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\." +
+                    "(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
 
     /**
      * @param version full version string
diff --git a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java
new file mode 100644
index 000000000..63a1ba69f
--- /dev/null
+++ b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java
@@ -0,0 +1,178 @@
+package org.jfrog.build.extractor.go.extractor;
+
+
+import org.jfrog.build.api.util.Log;
+import org.jfrog.build.api.util.NullLog;
+import org.testng.annotations.Test;
+
+import static org.testng.AssertJUnit.*;
+
+public class GoVersionUtilsTest {
+
+    @Test
+    public void getMajorVersion_ValidVersion_ReturnsMajorVersion() {
+        Log log = new NullLog();
+        assertEquals(GoVersionUtils.getMajorVersion("v0.0.4", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.3", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v2.2.3", log), 2);
+        assertEquals(GoVersionUtils.getMajorVersion("v10.20.30", log), 10);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.1.2-prerelease+meta", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.1.2+meta", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0-alpha", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0-alpha.beta", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0-alpha.1", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0-alpha.0valid", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0-rc.1+build.1", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.3-beta", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v10.2.3-DEV-SNAPSHOT", log), 10);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.3-SNAPSHOT-123", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v2.0.0+build.1848", log), 2);
+        assertEquals(GoVersionUtils.getMajorVersion("v2.0.1-alpha.1227", log), 2);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0-alpha+beta", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.3----RC-SNAPSHOT.12.9.1--.12+788", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.3----R-S.12.9.1--.12+meta", log), 1);
+        assertEquals(GoVersionUtils.getMajorVersion("v2.2.0-beta.1", log), 2);
+    }
+
+    @Test
+    public void getMajorVersion_InvalidVersion_ReturnsZero() {
+        Log log = new NullLog();
+        assertEquals(GoVersionUtils.getMajorVersion("invalid.version", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion(null, log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v01.1.1", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v9.8.7-whatever+meta+meta", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.3.DEV", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.3-0123", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.0.0-alpha_beta", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2-SNAPSHOT", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("v1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788", log), 0);
+    }
+
+    @Test
+    public void getMajorProjectVersion_ValidProject_ReturnsMajorVersion() {
+        Log log = new NullLog();
+        assertEquals(GoVersionUtils.getMajorProjectVersion("github.com/owner/repo/v3", log), 3);
+        assertEquals(GoVersionUtils.getMajorProjectVersion("github.com/owner/repo/v2", log), 2);
+    }
+
+    @Test
+    public void getMajorProjectVersion_InvalidProject_ReturnsZeroOrOne() {
+        Log log = new NullLog();
+        assertEquals(GoVersionUtils.getMajorProjectVersion("github.com/owner/repo", log), 0);
+        assertEquals(GoVersionUtils.getMajorProjectVersion("", log), 0);
+        assertEquals(GoVersionUtils.getMajorProjectVersion(null, log), 0);
+    }
+
+    @Test
+    public void getCleanVersion_WithIncompatible_ReturnsCleanVersion() {
+        assertEquals(GoVersionUtils.getCleanVersion("1.2.3+incompatible"), "1.2.3");
+    }
+
+    @Test
+    public void getCleanVersion_WithoutIncompatible_ReturnsSameVersion() {
+        assertEquals(GoVersionUtils.getCleanVersion("1.2.3"), "1.2.3");
+    }
+
+    @Test
+    public void isCompatibleGoModuleNaming_ValidInputs_ReturnsTrue() {
+        Log log = new NullLog();
+        assertTrue(GoVersionUtils.isCompatibleGoModuleNaming("github.com/owner/repo/v2", "v2.0.5", log));
+        assertTrue(GoVersionUtils.isCompatibleGoModuleNaming("github.com/owner/repo", "v1.0.5", log));
+    }
+
+    @Test
+    public void isCompatibleGoModuleNaming_InvalidInputs_ReturnsFalse() {
+        Log log = new NullLog();
+        assertFalse(GoVersionUtils.isCompatibleGoModuleNaming("github.com/owner/repo", "v2.0.5", log));
+        assertFalse(GoVersionUtils.isCompatibleGoModuleNaming("github.com/owner/repo/v2", "v2.0.5+incompatible", log));
+    }
+
+    @Test
+    public void getSubModule_ValidProjectName_ReturnsSubModule() {
+        assertEquals(GoVersionUtils.getSubModule("github.com/owner/repo/submodule"), "submodule");
+    }
+
+    @Test
+    public void getSubModule_InvalidProjectName_ReturnsEmptyString() {
+        assertEquals(GoVersionUtils.getSubModule("github.com/owner/repo"), "");
+        assertEquals(GoVersionUtils.getSubModule(""), "");
+        assertEquals(GoVersionUtils.getSubModule(null), "");
+    }
+
+    @Test
+    public void getParent_ValidPath_ReturnsParentPath() {
+        assertEquals(GoVersionUtils.getParent("/path/to/file"), "/path/to");
+    }
+
+    @Test
+    public void getParent_InvalidPath_ReturnsEmptyString() {
+        assertEquals(GoVersionUtils.getParent(""), "");
+        assertEquals(GoVersionUtils.getParent(null), "");
+    }
+
+    @Test
+    public void getMajorVersion() {
+        Log log = new NullLog();
+        assertEquals(GoVersionUtils.getMajorVersion("", log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion(null, log), 0);
+        assertEquals(GoVersionUtils.getMajorVersion("vX.1.2", log), 0);
+    }
+
+    @Test
+    public void getMajorProjectVersion_InvalidMajorVersion_LogsErrorAndReturnsZero() {
+        Log log = new NullLog();
+        assertEquals(GoVersionUtils.getMajorProjectVersion("github.com/owner/repo/vX", log), 0);
+    }
+
+    @Test
+    public void getCleanVersion_NullVersion_ReturnsNull() {
+        assertNull(GoVersionUtils.getCleanVersion(null));
+    }
+
+    @Test
+    public void isCompatibleGoModuleNaming_EmptyProjectName_ReturnsFalse() {
+        Log log = new NullLog();
+        assertFalse(GoVersionUtils.isCompatibleGoModuleNaming("", "v2.0.5", log));
+    }
+
+    @Test
+    public void isCompatibleGoModuleNaming_EmptyVersion_ReturnsFalse() {
+        Log log = new NullLog();
+        assertFalse(GoVersionUtils.isCompatibleGoModuleNaming("github.com/owner/repo/v2", "", log));
+    }
+
+    @Test
+    public void isCompatibleGoModuleNaming_NullProjectName_ReturnsFalse() {
+        Log log = new NullLog();
+        assertFalse(GoVersionUtils.isCompatibleGoModuleNaming(null, "v2.0.5", log));
+    }
+
+    @Test
+    public void isCompatibleGoModuleNaming_NullVersion_ReturnsFalse() {
+        Log log = new NullLog();
+        assertFalse(GoVersionUtils.isCompatibleGoModuleNaming("github.com/owner/repo/v2", null, log));
+    }
+
+    @Test
+    public void getSubModule_EmptyProjectName_ReturnsEmptyString() {
+        assertEquals(GoVersionUtils.getSubModule(""), "");
+    }
+
+    @Test
+    public void getSubModule_NullProjectName_ReturnsEmptyString() {
+        assertEquals(GoVersionUtils.getSubModule(null), "");
+    }
+
+    @Test
+    public void getParent_EmptyPath_ReturnsEmptyString() {
+        assertEquals(GoVersionUtils.getParent(""), "");
+    }
+
+    @Test
+    public void getParent_NullPath_ReturnsEmptyString() {
+        assertEquals(GoVersionUtils.getParent(null), "");
+    }
+
+}
\ No newline at end of file

From c54d127ad8c46e4383194494a5e4301300171a13 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Mon, 9 Sep 2024 03:12:00 +0000
Subject: [PATCH 19/36] [artifactory-release] Release version 2.41.23 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0c6f95580..75e431378 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.41.23
+build-info-extractor-gradle-version=4.33.22

From ff71e3208a38aab52e44cf8f0d7ffb08ea0929d8 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Mon, 9 Sep 2024 03:18:53 +0000
Subject: [PATCH 20/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 75e431378..0c6f95580 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.23
-build-info-extractor-gradle-version=4.33.22
+build-info-version=2.41.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From 13afda7849a581797fc88e3e593b286bc278f051 Mon Sep 17 00:00:00 2001
From: Eyal Delarea <eyalde@jfrog.com>
Date: Wed, 20 Nov 2024 11:52:18 +0200
Subject: [PATCH 21/36] Add original deployment repository field (#807)

---
 .../java/org/jfrog/build/api/Artifact.java    | 19 +++++++++++++++++
 .../extractor/builder/ArtifactBuilder.java    | 13 ++++++++++++
 .../jfrog/build/extractor/ci/Artifact.java    | 21 +++++++++++++++++++
 .../build/extractor/ci/ArtifactTest.java      |  7 +++++++
 .../ci/BuildInfoMavenBuilderTest.java         |  9 ++++----
 .../client/AccessManagerTest.java             |  2 +-
 .../org/jfrog/build/IntegrationTestsBase.java | 20 +++++++++++++++---
 7 files changed, 83 insertions(+), 8 deletions(-)

diff --git a/build-info-api/src/main/java/org/jfrog/build/api/Artifact.java b/build-info-api/src/main/java/org/jfrog/build/api/Artifact.java
index 10b9f7102..d053bfd48 100644
--- a/build-info-api/src/main/java/org/jfrog/build/api/Artifact.java
+++ b/build-info-api/src/main/java/org/jfrog/build/api/Artifact.java
@@ -10,6 +10,7 @@
 public class Artifact extends BaseBuildFileBean {
 
     private String name;
+    private String originalDeploymentRepo;
 
     /**
      * Returns the name of the artifact
@@ -29,6 +30,24 @@ public void setName(String name) {
         this.name = name;
     }
 
+    /**
+     * Returns the original deployment repository of the artifact
+     *
+     * @return repository name
+     */
+    public String getOriginalDeploymentRepo() {
+        return originalDeploymentRepo;
+    }
+
+    /**
+     * Sets the original deployment repository of the artifact
+     *
+     * @param originalDeploymentRepo repository name
+     */
+    public void setOriginalDeploymentRepo(String originalDeploymentRepo) {
+        this.originalDeploymentRepo = originalDeploymentRepo;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/builder/ArtifactBuilder.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/builder/ArtifactBuilder.java
index 19e6b4572..1c96e34d5 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/builder/ArtifactBuilder.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/builder/ArtifactBuilder.java
@@ -20,6 +20,7 @@ public class ArtifactBuilder {
     private String md5;
     private String remotePath;
     private Properties properties;
+    private String originalDeploymentRepo;
 
     public ArtifactBuilder(String name) {
         this.name = name;
@@ -43,6 +44,7 @@ public Artifact build() {
         artifact.setRemotePath(remotePath);
         artifact.setLocalPath(localPath);
         artifact.setProperties(properties);
+        artifact.setOriginalDeploymentRepo(originalDeploymentRepo);
         return artifact;
     }
 
@@ -134,6 +136,17 @@ public ArtifactBuilder properties(Properties properties) {
         return this;
     }
 
+    /**
+     * Sets the originalDeploymentRepo of the artifact
+     *
+     * @param originalDeploymentRepo Artifact original deployment repository
+     * @return Builder instance
+     */
+    public ArtifactBuilder originalDeploymentRepo(String originalDeploymentRepo) {
+        this.originalDeploymentRepo = originalDeploymentRepo;
+        return this;
+    }
+
     /**
      * Adds the given property to the properties object
      *
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/ci/Artifact.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/ci/Artifact.java
index 36a1c73f7..242edc2c6 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/ci/Artifact.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/ci/Artifact.java
@@ -8,6 +8,7 @@
 public class Artifact extends BaseBuildFileBean {
 
     private String name;
+    private String originalDeploymentRepo;
 
     /**
      * Returns the name of the artifact
@@ -27,6 +28,24 @@ public void setName(String name) {
         this.name = name;
     }
 
+    /**
+     * Returns the original deployment repository of the artifact
+     *
+     * @return repository name
+     */
+    public String getOriginalDeploymentRepo() {
+        return originalDeploymentRepo;
+    }
+
+    /**
+     * Sets the original deployment repository of the artifact
+     *
+     * @param originalDeploymentRepo repository name
+     */
+    public void setOriginalDeploymentRepo(String originalDeploymentRepo) {
+        this.originalDeploymentRepo = originalDeploymentRepo;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) {
@@ -59,6 +78,7 @@ public org.jfrog.build.api.Artifact ToBuildArtifact() {
         result.setSha1(sha1);
         result.setRemotePath(remotePath);
         result.setProperties(getProperties());
+        result.setOriginalDeploymentRepo(originalDeploymentRepo);
         return result;
     }
 
@@ -71,6 +91,7 @@ public static Artifact ToBuildInfoArtifact(org.jfrog.build.api.Artifact artifact
         result.setSha1(artifact.getSha1());
         result.setRemotePath(artifact.getRemotePath());
         result.setProperties(artifact.getProperties());
+        result.setOriginalDeploymentRepo(artifact.getOriginalDeploymentRepo());
         return result;
     }
 }
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/ArtifactTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/ArtifactTest.java
index 03ee45525..bac857283 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/ArtifactTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/ArtifactTest.java
@@ -30,6 +30,7 @@ public void testEmptyConstructor() {
         assertNull(artifact.getSha1(), "Artifact SHA1 checksum should have not been initialized.");
         assertNull(artifact.getSha256(), "Artifact SHA256 checksum should have not been initialized.");
         assertNull(artifact.getMd5(), "Artifact MD5 checksum should have not been initialized.");
+        assertNull(artifact.getOriginalDeploymentRepo(), "Artifact original deployment repository should have not been initialized.");
     }
 
     /**
@@ -43,6 +44,7 @@ public void testSetters() {
         String md5 = "gog";
         String localPath = "blip";
         String remotePath = "blop";
+        String originalDeploymentRepository = "repo";
         Properties properties = new Properties();
 
         Artifact artifact = new Artifact();
@@ -54,6 +56,7 @@ public void testSetters() {
         artifact.setLocalPath(localPath);
         artifact.setRemotePath(remotePath);
         artifact.setProperties(properties);
+        artifact.setOriginalDeploymentRepo(originalDeploymentRepository);
 
         Assert.assertEquals(artifact.getName(), name, "Unexpected artifact name.");
         Assert.assertEquals(artifact.getType(), type, "Unexpected artifact type.");
@@ -63,6 +66,7 @@ public void testSetters() {
         Assert.assertEquals(artifact.getLocalPath(), localPath, "Unexpected artifact local path.");
         Assert.assertEquals(artifact.getRemotePath(), remotePath, "Unexpected artifact remote path.");
         Assert.assertEquals(artifact.getProperties(), properties, "Unexpected artifact properties.");
+        Assert.assertEquals(artifact.getOriginalDeploymentRepo(),originalDeploymentRepository, "Unexpected artifact original deployment repository.");
     }
 
     public void testEqualsAndHash() {
@@ -75,6 +79,7 @@ public void testEqualsAndHash() {
         artifact1.setSha1("111");
         artifact1.setSha256("11111");
         artifact1.setMd5("1111");
+        artifact1.setOriginalDeploymentRepo("repo");
         artifact1.setProperties(properties);
 
         Artifact artifact2 = new Artifact();
@@ -83,6 +88,7 @@ public void testEqualsAndHash() {
         artifact2.setSha1("111");
         artifact2.setSha256("11111");
         artifact2.setMd5("1111");
+        artifact2.setOriginalDeploymentRepo("repo");
         artifact2.setProperties(properties);
 
         Artifact artifact3 = new Artifact();
@@ -91,6 +97,7 @@ public void testEqualsAndHash() {
         artifact3.setSha1("1113");
         artifact3.setSha256("11133");
         artifact3.setMd5("11113");
+        artifact3.setOriginalDeploymentRepo("diff-repo");
         artifact3.setProperties(properties);
 
         Assert.assertEquals(artifact1, artifact2, "Expected equals == true for equivalent artifacts");
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/BuildInfoMavenBuilderTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/BuildInfoMavenBuilderTest.java
index 2ffa85f80..327b44e85 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/BuildInfoMavenBuilderTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/ci/BuildInfoMavenBuilderTest.java
@@ -34,6 +34,7 @@ public class BuildInfoMavenBuilderTest {
     public static final String SHA1 = "e4e264c711ae7ab54f26542f0dd09a43b93fa12c";
     public static final String SHA2 = "yyyy23029162f3b2dc51f512cb64bce8cb6913ed6e540f23ec567d898f60yyyy";
     public static final String MD5 = "d9303a42c66c2824fd6ba0f75e335294";
+    public static final String DEPLOY_REPO = "repo";
 
     /**
      * Validates the build values when using the defaults
@@ -163,12 +164,12 @@ public void testDuplicateModules() {
      */
     public void testDuplicateModuleArtifacts() {
         ModuleBuilder module1 = new ModuleBuilder().type(ModuleType.MAVEN).id("id");
-        module1.addArtifact(new ArtifactBuilder("artifact1").md5(MD5).sha1(SHA1).sha256(SHA2).build());
-        module1.addArtifact(new ArtifactBuilder("artifact2").md5(MD5).sha1(SHA1).sha256(SHA2).build());
+        module1.addArtifact(new ArtifactBuilder("artifact1").md5(MD5).sha1(SHA1).sha256(SHA2).originalDeploymentRepo(DEPLOY_REPO).build());
+        module1.addArtifact(new ArtifactBuilder("artifact2").md5(MD5).sha1(SHA1).sha256(SHA2).originalDeploymentRepo(DEPLOY_REPO).build());
 
         ModuleBuilder module2 = new ModuleBuilder().type(ModuleType.MAVEN).id("id");
-        module2.addArtifact(new ArtifactBuilder("artifact1").md5(MD5).sha1(SHA1).sha256(SHA2).build());
-        module2.addArtifact(new ArtifactBuilder("artifact2").md5(MD5).sha1(SHA1).sha256(SHA2).build());
+        module2.addArtifact(new ArtifactBuilder("artifact1").md5(MD5).sha1(SHA1).sha256(SHA2).originalDeploymentRepo(DEPLOY_REPO).build());
+        module2.addArtifact(new ArtifactBuilder("artifact2").md5(MD5).sha1(SHA1).sha256(SHA2).originalDeploymentRepo(DEPLOY_REPO).build());
 
         BuildInfoMavenBuilder builder = new BuildInfoMavenBuilder("test").number("4").started("test");
         builder.addModule(module1.build());
diff --git a/build-info-extractor/src/test/java/org/jfrog/build/extractor/clientConfiguration/client/AccessManagerTest.java b/build-info-extractor/src/test/java/org/jfrog/build/extractor/clientConfiguration/client/AccessManagerTest.java
index be51d1cb5..6f8120596 100644
--- a/build-info-extractor/src/test/java/org/jfrog/build/extractor/clientConfiguration/client/AccessManagerTest.java
+++ b/build-info-extractor/src/test/java/org/jfrog/build/extractor/clientConfiguration/client/AccessManagerTest.java
@@ -45,7 +45,7 @@ public class AccessManagerTest extends IntegrationTestsBase {
     @BeforeClass
     @Override
     public void init() throws IOException {
-        super.init();
+        super.init(true);
         String accessUrl = getPlatformUrl() + "access";
         accessManager = new AccessManager(accessUrl, getAdminToken(), getLog());
     }
diff --git a/build-info-extractor/src/testFixtures/java/org/jfrog/build/IntegrationTestsBase.java b/build-info-extractor/src/testFixtures/java/org/jfrog/build/IntegrationTestsBase.java
index 1eaa468a5..e6b321c64 100644
--- a/build-info-extractor/src/testFixtures/java/org/jfrog/build/IntegrationTestsBase.java
+++ b/build-info-extractor/src/testFixtures/java/org/jfrog/build/IntegrationTestsBase.java
@@ -59,8 +59,7 @@ public static Log getLog() {
         return log;
     }
 
-    @BeforeClass
-    public void init() throws IOException {
+    public void init(boolean isAccessTest) throws IOException {
         Properties props = new Properties();
         // This file is not in GitHub. Create your own in src/test/resources or use environment variables.
         InputStream inputStream = this.getClass().getResourceAsStream("/artifactory-bi.properties");
@@ -69,8 +68,13 @@ public void init() throws IOException {
             props.load(inputStream);
             inputStream.close();
         }
+        String testPort = "8081";
+        // Change the port variable only if isAccessTest is true
+        if (isAccessTest) {
+            testPort = "8082";
+        }
 
-        platformUrl = readParam(props, "url", "http://127.0.0.1:8081");
+        platformUrl = readParam(props, "url", "http://127.0.0.1:" + testPort);
         if (!platformUrl.endsWith("/")) {
             platformUrl += "/";
         }
@@ -92,6 +96,16 @@ public void init() throws IOException {
         }
     }
 
+    @BeforeClass
+    public void init() throws IOException {
+        init(false);
+    }
+
+    @BeforeClass
+    public void accessInit() throws IOException {
+        init(true);
+    }
+
     @AfterClass
     protected void terminate() throws IOException {
         // Delete the virtual first.

From 850394c843c12fb8c633ce75895dc3adb8be2cdc Mon Sep 17 00:00:00 2001
From: Robi Nino <robi.nino@gmail.com>
Date: Tue, 26 Nov 2024 12:44:24 +0200
Subject: [PATCH 22/36] Use short version identifier in Pipelines (#811)

---
 release/pipelines.release.yml  | 2 +-
 release/pipelines.snapshot.yml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/release/pipelines.release.yml b/release/pipelines.release.yml
index 543d0a2f9..51fed5f4d 100644
--- a/release/pipelines.release.yml
+++ b/release/pipelines.release.yml
@@ -7,7 +7,7 @@ pipelines:
           auto:
             language: java
             versions:
-              - "8.0.0"
+              - "8"
       environmentVariables:
         readOnly:
           NEXT_VERSION: 2.0.0
diff --git a/release/pipelines.snapshot.yml b/release/pipelines.snapshot.yml
index 9b94f5ccb..a0dd47c0a 100644
--- a/release/pipelines.snapshot.yml
+++ b/release/pipelines.snapshot.yml
@@ -8,7 +8,7 @@ pipelines:
           auto:
             language: java
             versions:
-              - "8.0.0"
+              - "8"
 
     steps:
       - name: Snapshot

From 25f7db6f5f129058aa35a9ca8178bbdc65165fbe Mon Sep 17 00:00:00 2001
From: RobiNino <robin@jfrog.com>
Date: Tue, 26 Nov 2024 16:40:58 +0200
Subject: [PATCH 23/36] Temporarily skip audit

---
 release/pipelines.release.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/release/pipelines.release.yml b/release/pipelines.release.yml
index 51fed5f4d..867dee2d4 100644
--- a/release/pipelines.release.yml
+++ b/release/pipelines.release.yml
@@ -54,7 +54,7 @@ pipelines:
             - jf gradlec --use-wrapper --uses-plugin --repo-resolve ecosys-maven-remote --repo-deploy ecosys-oss-release-local
 
             # Run audit
-            - jf audit --fail=false
+            #- jf audit --fail=false
 
             # Update version
             - sed -i -e "/build-info-version=/ s/=.*/=$NEXT_VERSION/" -e "/build-info-extractor-gradle-version=/ s/=.*/=$NEXT_GRADLE_VERSION/" gradle.properties

From 46bffec43cadba2e5bc5be7211034768b8368fb1 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Tue, 26 Nov 2024 14:46:25 +0000
Subject: [PATCH 24/36] [artifactory-release] Release version 2.41.24 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0c6f95580..704a7552e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.41.24
+build-info-extractor-gradle-version=4.33.23

From 394216517e79aeab505e35c47d800b44016df149 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Tue, 26 Nov 2024 14:55:00 +0000
Subject: [PATCH 25/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 704a7552e..0c6f95580 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.24
-build-info-extractor-gradle-version=4.33.23
+build-info-version=2.41.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From 2a5003da6e1ef9cfe070538227f912dee2215039 Mon Sep 17 00:00:00 2001
From: RobiNino <robin@jfrog.com>
Date: Tue, 26 Nov 2024 16:59:56 +0200
Subject: [PATCH 26/36] Revert Temporarily skip audit

---
 release/pipelines.release.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/release/pipelines.release.yml b/release/pipelines.release.yml
index 867dee2d4..51fed5f4d 100644
--- a/release/pipelines.release.yml
+++ b/release/pipelines.release.yml
@@ -54,7 +54,7 @@ pipelines:
             - jf gradlec --use-wrapper --uses-plugin --repo-resolve ecosys-maven-remote --repo-deploy ecosys-oss-release-local
 
             # Run audit
-            #- jf audit --fail=false
+            - jf audit --fail=false
 
             # Update version
             - sed -i -e "/build-info-version=/ s/=.*/=$NEXT_VERSION/" -e "/build-info-extractor-gradle-version=/ s/=.*/=$NEXT_GRADLE_VERSION/" gradle.properties

From 02686fc18f236aa05db3aafd13c01e9c0dd973c5 Mon Sep 17 00:00:00 2001
From: Eyal Delarea <eyalde@jfrog.com>
Date: Wed, 1 Jan 2025 14:42:56 +0200
Subject: [PATCH 27/36] NuGet - add `allowInsecureConnections` attribute to
 config (#810)

---
 .../extractor/nuget/extractor/NugetRun.java     | 17 +++++++++++------
 .../nuget/extractor/NugetExtractorTest.java     |  7 ++++---
 .../ArtifactoryClientConfiguration.java         |  7 +++++++
 .../clientConfiguration/ClientProperties.java   |  6 ++++++
 4 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/build-info-extractor-nuget/src/main/java/org/jfrog/build/extractor/nuget/extractor/NugetRun.java b/build-info-extractor-nuget/src/main/java/org/jfrog/build/extractor/nuget/extractor/NugetRun.java
index 17b3d5513..afc822dd8 100644
--- a/build-info-extractor-nuget/src/main/java/org/jfrog/build/extractor/nuget/extractor/NugetRun.java
+++ b/build-info-extractor-nuget/src/main/java/org/jfrog/build/extractor/nuget/extractor/NugetRun.java
@@ -35,6 +35,7 @@
 import java.util.stream.Stream;
 
 import static org.jfrog.build.api.util.FileChecksumCalculator.*;
+import static org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration.DEFAULT_NUGET_ALLOW_INSECURE_CONNECTIONS;
 import static org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration.DEFAULT_NUGET_PROTOCOL;
 import static org.jfrog.build.extractor.packageManager.PackageManagerUtils.createArtifactoryClientConfiguration;
 
@@ -47,7 +48,7 @@ public class NugetRun extends PackageManagerExtractor {
     private static final String CONFIG_FILE_FORMAT = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
             "<configuration>\n" +
             "\t<packageSources>\n" +
-            "\t\t<add key=\"JFrogJenkins\" value=\"%s\" protocolVersion=\"%s\" />\n" +
+            "\t\t<add key=\"JFrogJenkins\" value=\"%s\" protocolVersion=\"%s\" allowInsecureConnections=\"%s\"/>\n" +
             "\t</packageSources>\n" +
             "\t<packageSourceCredentials>\n" +
             "\t\t<JFrogJenkins>\n" +
@@ -75,6 +76,7 @@ public class NugetRun extends PackageManagerExtractor {
     private String apiProtocol;
     private String module;
     private String nugetCmdArgs;
+    private boolean allowInsecureConnections;
     private List<String> dependenciesSources;
     private List<Module> modulesList = new ArrayList<>();
 
@@ -91,10 +93,11 @@ public class NugetRun extends PackageManagerExtractor {
      * @param module                    - NuGet module
      * @param username                  - JFrog platform username.
      * @param password                  - JFrog platform password.
+     * @param allowInsecureConnections  - Allow insecure package sources connection, should be used only for developing.
      * @param apiProtocol               - A string indicates which NuGet protocol should be used (V2/V3).
      */
 
-    public NugetRun(ArtifactoryManagerBuilder artifactoryManagerBuilder, String resolutionRepo, boolean useDotnetCli, String nugetCmdArgs, Log logger, Path path, Map<String, String> env, String module, String username, String password, String apiProtocol) {
+    public NugetRun(ArtifactoryManagerBuilder artifactoryManagerBuilder, String resolutionRepo, boolean useDotnetCli, String nugetCmdArgs, Log logger, Path path, Map<String, String> env, String module, String username, String password, String apiProtocol, Boolean allowInsecureConnections) {
         this.artifactoryManagerBuilder = artifactoryManagerBuilder;
         this.toolchainDriver = useDotnetCli ? new DotnetDriver(env, path, logger) : new NugetDriver(env, path, logger);
         this.workingDir = Files.isDirectory(path) ? path : path.toAbsolutePath().getParent();
@@ -106,6 +109,7 @@ public NugetRun(ArtifactoryManagerBuilder artifactoryManagerBuilder, String reso
         this.password = password;
         this.apiProtocol = StringUtils.isBlank(apiProtocol) ? DEFAULT_NUGET_PROTOCOL : apiProtocol;
         this.module = module;
+        this.allowInsecureConnections = allowInsecureConnections == null ? DEFAULT_NUGET_ALLOW_INSECURE_CONNECTIONS : allowInsecureConnections;
     }
 
     private static String removeQuotes(String str) {
@@ -160,7 +164,8 @@ public static void main(String[] ignored) {
                     handler.getModule(),
                     clientConfiguration.resolver.getUsername(),
                     clientConfiguration.resolver.getPassword(),
-                    clientConfiguration.dotnetHandler.apiProtocol());
+                    clientConfiguration.dotnetHandler.apiProtocol(),
+                    clientConfiguration.getNuGetAllowInsecureConnections());
             nugetRun.executeAndSaveBuildInfo(clientConfiguration);
         } catch (RuntimeException e) {
             ExceptionUtils.printRootCauseStackTrace(e, System.out);
@@ -208,7 +213,7 @@ private File prepareConfig(ArtifactoryManager artifactoryManager) throws Excepti
         if (!nugetCmdArgs.contains(toolchainDriver.getFlagSyntax(ToolchainDriverBase.CONFIG_FILE_FLAG)) && !nugetCmdArgs.contains(toolchainDriver.getFlagSyntax(ToolchainDriverBase.SOURCE_FLAG))) {
             configFile = File.createTempFile(NUGET_CONFIG_FILE_PREFIX, null);
             configFile.deleteOnExit();
-            addSourceToConfigFile(configFile.getAbsolutePath(), artifactoryManager, resolutionRepo, username, password, apiProtocol);
+            addSourceToConfigFile(configFile.getAbsolutePath(), artifactoryManager, resolutionRepo, username, password, apiProtocol, allowInsecureConnections);
         }
         return configFile;
     }
@@ -217,10 +222,10 @@ private File prepareConfig(ArtifactoryManager artifactoryManager) throws Excepti
      * We will write a temporary NuGet configuration using a string formater in order to support NuGet v3 protocol.
      * Currently the NuGet configuration utility doesn't allow setting protocolVersion.
      */
-    private void addSourceToConfigFile(String configPath, ArtifactoryManager client, String repo, String username, String password, String apiProtocol) throws Exception {
+    private void addSourceToConfigFile(String configPath, ArtifactoryManager client, String repo, String username, String password, String apiProtocol, boolean allowInsecureConnections) throws Exception {
         String sourceUrl = toolchainDriver.buildNugetSourceUrl(client, repo, apiProtocol);
         String protocolVersion = apiProtocol.substring(apiProtocol.length() - 1);
-        String configFileText = String.format(CONFIG_FILE_FORMAT, sourceUrl, protocolVersion, username, password);
+        String configFileText = String.format(CONFIG_FILE_FORMAT, sourceUrl, protocolVersion, Boolean.toString(allowInsecureConnections), username, password);
         try (PrintWriter out = new PrintWriter(configPath)) {
             out.println(configFileText);
         }
diff --git a/build-info-extractor-nuget/src/test/java/org/jfrog/build/extractor/nuget/extractor/NugetExtractorTest.java b/build-info-extractor-nuget/src/test/java/org/jfrog/build/extractor/nuget/extractor/NugetExtractorTest.java
index 05df5962f..a608ff92b 100644
--- a/build-info-extractor-nuget/src/test/java/org/jfrog/build/extractor/nuget/extractor/NugetExtractorTest.java
+++ b/build-info-extractor-nuget/src/test/java/org/jfrog/build/extractor/nuget/extractor/NugetExtractorTest.java
@@ -31,6 +31,7 @@ public class NugetExtractorTest extends IntegrationTestsBase {
 
     private static final String NUGET_REMOTE_REPO = "build-info-tests-nuget-remote";
     private static final String CUSTOM_MODULE = "custom-module-name";
+    private static final boolean ALLOW_INSECURE_CONNECTIONS_TEST = true;
 
     private static final Path PROJECTS_ROOT = Paths.get(".").toAbsolutePath().normalize().resolve(Paths.get("src", "test", "resources", "org", "jfrog", "build", "extractor"));
 
@@ -95,7 +96,7 @@ public void nugetRunTest(Project project, String args, String moduleName, String
         try {
             // Run nuget restore install
             projectDir = createProjectDir(project);
-            NugetRun nugetRun = new NugetRun(artifactoryManagerBuilder, remoteRepo, false, args, log, projectDir, env, moduleName, getUsername(), getAdminToken(), "v2");
+            NugetRun nugetRun = new NugetRun(artifactoryManagerBuilder, remoteRepo, false, args, log, projectDir, env, moduleName, getUsername(), getAdminToken(), "v2",ALLOW_INSECURE_CONNECTIONS_TEST);
             executeAndAssertBuildInfo(nugetRun, expectedModules, expectedDependencies);
         } catch (Exception e) {
             fail(ExceptionUtils.getStackTrace(e));
@@ -117,7 +118,7 @@ public void dotnetCliRunTest(Project project, String args, String moduleName, St
         try {
             // Run nuget restore install
             projectDir = createProjectDir(project);
-            NugetRun nugetRun = new NugetRun(artifactoryManagerBuilder, remoteRepo, true, args, log, projectDir, env, moduleName, getUsername(), getAdminToken(), "v2");
+            NugetRun nugetRun = new NugetRun(artifactoryManagerBuilder, remoteRepo, true, args, log, projectDir, env, moduleName, getUsername(), getAdminToken(), "v2",ALLOW_INSECURE_CONNECTIONS_TEST);
             executeAndAssertBuildInfo(nugetRun, expectedModules, expectedDependencies);
         } catch (Exception e) {
             fail(ExceptionUtils.getStackTrace(e));
@@ -167,7 +168,7 @@ private Object[][] projectRootProvider() {
     private void getProjectRootTest(String args, String expectedProjectRootFileName) {
         try {
             File rootDir = PROJECTS_ROOT.resolve("projectRootTestDir").toFile();
-            NugetRun nugetRun = new NugetRun(artifactoryManagerBuilder, remoteRepo, false, args, log, rootDir.toPath(), env, null, getUsername(), getAdminToken(), "v2");
+            NugetRun nugetRun = new NugetRun(artifactoryManagerBuilder, remoteRepo, false, args, log, rootDir.toPath(), env, null, getUsername(), getAdminToken(), "v2",ALLOW_INSECURE_CONNECTIONS_TEST);
             File projectRoot = nugetRun.getProjectRootPath();
             assertTrue(projectRoot.getPath().endsWith(expectedProjectRootFileName));
         } catch (Exception e) {
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
index 445e066b9..875079014 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
@@ -41,6 +41,7 @@ public class ArtifactoryClientConfiguration {
     // Try checksum deploy of files greater than 10KB
     public static final transient int DEFAULT_MIN_CHECKSUM_DEPLOY_SIZE_KB = 10;
     public static final String DEFAULT_NUGET_PROTOCOL = "v2";
+    public static final boolean DEFAULT_NUGET_ALLOW_INSECURE_CONNECTIONS = false;
 
     public final ResolverHandler resolver;
     public final PublisherHandler publisher;
@@ -54,6 +55,8 @@ public class ArtifactoryClientConfiguration {
     public final DockerHandler dockerHandler;
     public final GoHandler goHandler;
     public final PrefixPropertyHandler root;
+
+
     /**
      * To configure the props builder itself, so all method of this classes delegated from here
      */
@@ -208,6 +211,10 @@ public boolean getInsecureTls() {
         return root.getBooleanValue(PROP_INSECURE_TLS, false);
     }
 
+    public boolean getNuGetAllowInsecureConnections() {
+        return root.getBooleanValue(PROP_NUGET_ALLOW_INSECURE_CONNECTIONS, false);
+    }
+
     public void setInsecureTls(boolean enabled) {
         root.setBooleanValue(PROP_INSECURE_TLS, enabled);
     }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientProperties.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientProperties.java
index b0324cb89..faee7accc 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientProperties.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientProperties.java
@@ -70,4 +70,10 @@ public interface ClientProperties {
      * Property for whether to use relaxed ssl check and ignore issues with server certificate
      */
     String PROP_INSECURE_TLS = "insecureTls";
+
+    /**
+     * Property to allow NuGet package sources to use insecure connections (HTTP).
+     * This setting is enforced by the NuGet client and is not recommended for production use.
+     */
+    String PROP_NUGET_ALLOW_INSECURE_CONNECTIONS = "nuget.AllowInsecureConnections";
 }
\ No newline at end of file

From e53bf46e1e82dddf9f5c19bd5c1ebb774ec81871 Mon Sep 17 00:00:00 2001
From: Eyal Delarea <eyalde@jfrog.com>
Date: Wed, 1 Jan 2025 15:36:26 +0200
Subject: [PATCH 28/36] Update setup .NET action (#813)

---
 .github/workflows/integrationTests.yml | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/integrationTests.yml b/.github/workflows/integrationTests.yml
index a0a323f46..495b5497f 100644
--- a/.github/workflows/integrationTests.yml
+++ b/.github/workflows/integrationTests.yml
@@ -330,14 +330,16 @@ jobs:
         with:
           ref: ${{ github.event.pull_request.head.sha }}
 
+      - name: Install dotnet
+        uses: actions/setup-dotnet@v4
+        with:
+          dotnet-version: "3.x"
+
       - name: Install NuGet
         uses: nuget/setup-nuget@v2
         with:
           nuget-version: 6.x
-      - name: Install dotnet
-        uses: actions/setup-dotnet@v2
-        with:
-          dotnet-version: "3.x"
+
       - name: Install Java
         uses: actions/setup-java@v3
         with:

From 530dd55dd33a28e2665c05923325aa0f33bcf5b5 Mon Sep 17 00:00:00 2001
From: Eyal Delarea <eyalde@jfrog.com>
Date: Thu, 2 Jan 2025 09:34:56 +0200
Subject: [PATCH 29/36] Tests - Fix .NET ubuntu installation (#814)

---
 .github/workflows/integrationTests.yml | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/integrationTests.yml b/.github/workflows/integrationTests.yml
index 495b5497f..7cfd0d4a9 100644
--- a/.github/workflows/integrationTests.yml
+++ b/.github/workflows/integrationTests.yml
@@ -330,10 +330,26 @@ jobs:
         with:
           ref: ${{ github.event.pull_request.head.sha }}
 
+      # Prepare ubuntu by installing Mono and handle dotnet installation issues.
+      - name: Prepare ubuntu
+        if: matrix.os == 'ubuntu-latest'
+        run: |
+          # Install Mono
+          sudo apt-get update
+          sudo apt-get install -y apt-transport-https dirmngr gnupg ca-certificates
+          sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+          echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
+          sudo apt-get update
+          sudo apt-get install -y mono-complete
+          # Fixes dotnet installation issues, see https://github.com/jfrog/jfrog-cli/pull/2808 for more details.
+          echo "DOTNET_INSTALL_DIR=/usr/share/dotnet" >> $GITHUB_ENV
+          sudo mkdir -p /usr/share/dotnet
+          sudo chmod 777 /usr/share/dotnet
+
       - name: Install dotnet
         uses: actions/setup-dotnet@v4
         with:
-          dotnet-version: "3.x"
+          dotnet-version: "6.x"
 
       - name: Install NuGet
         uses: nuget/setup-nuget@v2

From 9c9bcb534a53dba310216886c3f3702d99a6d916 Mon Sep 17 00:00:00 2001
From: Nadav Yogev <nadavy@jfrog.com>
Date: Tue, 14 Jan 2025 13:42:27 +0200
Subject: [PATCH 30/36] Fix go version extractor to accept valid semver with 2
 dashes (#815)

---
 .../go/extractor/GoVersionUtils.java          | 30 ++++++++-----------
 .../go/extractor/GoVersionUtilsTest.java      |  1 +
 build.gradle                                  |  4 +++
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java
index 4befb6a41..6a302475c 100644
--- a/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java
+++ b/build-info-extractor-go/src/main/java/org/jfrog/build/extractor/go/extractor/GoVersionUtils.java
@@ -1,11 +1,11 @@
 package org.jfrog.build.extractor.go.extractor;
 
+import com.github.zafarkhaja.semver.Version;
 import org.apache.commons.lang3.StringUtils;
 import org.jfrog.build.api.util.Log;
 
 import java.io.File;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Optional;
 
 /**
  * @author BarakH
@@ -14,30 +14,24 @@ public class GoVersionUtils {
 
     public static final String INCOMPATIBLE = "+incompatible";
     public static final int ZERO_OR_ONE = 0;
-    // The regular expression used here is derived from the SemVer specification: https://semver.org/
-    protected static final Pattern VERSION_PATTERN = Pattern.compile(
-            "v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\." +
-                    "(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$");
+
+    private GoVersionUtils() {
+    }
 
     /**
      * @param version full version string
      * @return The major version as an integer or 0 if couldn't parse it
      */
-    public static int getMajorVersion(String version, Log log) {
+    public static long getMajorVersion(String version, Log log) {
         if (StringUtils.isEmpty(version)) {
             return 0;
         }
         version = getCleanVersion(version);
-        Matcher matcher = VERSION_PATTERN.matcher(version);
-        if (matcher.matches()) {
-            String major = matcher.group(1);
-            if (!StringUtils.isEmpty(major)) {
-                try {
-                    return Integer.parseInt(major);
-                } catch (NumberFormatException e) {
-                    log.error("Failed to parse major version of " + version, e);
-                }
-            }
+        Optional<Version> parsedVersion = Version.tryParse(StringUtils.removeStart(version, "v"));
+        if (parsedVersion.isPresent()) {
+            return parsedVersion.get().majorVersion();
+        } else {
+            log.debug("Failed to parse major version of " + version);
         }
         return 0;
     }
@@ -89,7 +83,7 @@ public static boolean isCompatibleGoModuleNaming(String projectName, String vers
         if (StringUtils.isBlank(projectName) || StringUtils.isBlank(version)) {
             return false;
         }
-        int majorVersion = getMajorVersion(version, log);
+        long majorVersion = getMajorVersion(version, log);
         if (majorVersion >= 2) {
             return (projectName.endsWith("/v" + majorVersion) && !version.endsWith(INCOMPATIBLE));
         }
diff --git a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java
index 63a1ba69f..b1410c2ce 100644
--- a/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java
+++ b/build-info-extractor-go/src/test/java/org/jfrog/build/extractor/go/extractor/GoVersionUtilsTest.java
@@ -33,6 +33,7 @@ public void getMajorVersion_ValidVersion_ReturnsMajorVersion() {
         assertEquals(GoVersionUtils.getMajorVersion("v1.2.3----RC-SNAPSHOT.12.9.1--.12+788", log), 1);
         assertEquals(GoVersionUtils.getMajorVersion("v1.2.3----R-S.12.9.1--.12+meta", log), 1);
         assertEquals(GoVersionUtils.getMajorVersion("v2.2.0-beta.1", log), 2);
+        assertEquals(GoVersionUtils.getMajorVersion("v2.0.0-beta-1", log), 2);
     }
 
     @Test
diff --git a/build.gradle b/build.gradle
index 8ab75ceab..f71c1af65 100644
--- a/build.gradle
+++ b/build.gradle
@@ -478,6 +478,10 @@ project('build-info-extractor-docker') {
 
 project('build-info-extractor-go') {
     description = 'JFrog Build-Info Go Extractor'
+
+    dependencies {
+        implementation group: 'com.github.zafarkhaja', name: 'java-semver', version: '0.10.2'
+    }
 }
 
 project('build-info-extractor-pip') {

From 3670f60abddabe6ac3d79b148f309e58ca2930b2 Mon Sep 17 00:00:00 2001
From: Kanishk Gupta <148543773+fluxxBot@users.noreply.github.com>
Date: Wed, 26 Feb 2025 11:40:39 +0530
Subject: [PATCH 31/36] Support disabling Maven Snapshot dependency Resolution
 & Set Update Policy (#818)

---
 .../maven/ArtifactoryProjectBuilder.java      |  5 +++-
 .../ArtifactoryEclipseResolversHelper.java    | 24 ++++++++++++++---
 .../resolver/ArtifactoryPluginResolution.java | 26 ++++++++++++++-----
 .../maven/resolver/ArtifactoryResolution.java | 26 ++++++++++++++-----
 .../maven/resolver/ResolutionHelper.java      |  4 +++
 .../ArtifactoryClientConfiguration.java       |  9 +++++++
 .../ClientConfigurationFields.java            |  2 ++
 build.gradle                                  |  1 +
 8 files changed, 80 insertions(+), 17 deletions(-)

diff --git a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/ArtifactoryProjectBuilder.java b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/ArtifactoryProjectBuilder.java
index ab093c715..fd23059ca 100644
--- a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/ArtifactoryProjectBuilder.java
+++ b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/ArtifactoryProjectBuilder.java
@@ -51,7 +51,10 @@ private List<ArtifactRepository> getRepositories() {
         List<ArtifactRepository> repositories = new ArrayList<>();
         ProxySelector proxySelector = new ProxySelector(resolutionHelper.getHttpProxyHost(), resolutionHelper.getHttpProxyPort(), resolutionHelper.getHttpProxyUsername(), resolutionHelper.getHttpProxyPassword(), resolutionHelper.getHttpsProxyHost(), resolutionHelper.getHttpsProxyPort(), resolutionHelper.getHttpsProxyUsername(), resolutionHelper.getHttpsProxyPassword(), resolutionHelper.getNoProxy());
 
-        ArtifactoryPluginResolution artifactoryResolution = new ArtifactoryPluginResolution(resolutionHelper.getRepoReleaseUrl(), resolutionHelper.getRepoSnapshotUrl(), resolutionHelper.getRepoUsername(), resolutionHelper.getRepoPassword(), proxySelector, resolutionHelper.getLogger());
+        boolean isSnapshotEnabled = !resolutionHelper.isSnapshotDisabled();
+        ArtifactoryPluginResolution artifactoryResolution = new ArtifactoryPluginResolution(resolutionHelper.getRepoReleaseUrl(), resolutionHelper.getRepoSnapshotUrl(), resolutionHelper.getRepoUsername(), resolutionHelper.getRepoPassword(), proxySelector, resolutionHelper.getLogger())
+                .setSnapshotEnabled(isSnapshotEnabled)
+                .setSnapshotUpdatePolicy(resolutionHelper.getSnapshotUpdatePolicy());
         ArtifactRepository snapshotRepository = artifactoryResolution.createSnapshotRepository();
         if (snapshotRepository != null) {
             repositories.add(snapshotRepository);
diff --git a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryEclipseResolversHelper.java b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryEclipseResolversHelper.java
index 007fe7294..179d0863f 100644
--- a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryEclipseResolversHelper.java
+++ b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryEclipseResolversHelper.java
@@ -43,8 +43,7 @@ void initResolutionRepositories(RepositorySystemSession session) {
     List<RemoteRepository> getResolutionRepositories(RepositorySystemSession session) {
         if (resolutionRepositories.isEmpty()) {
             initResolutionHelper(session);
-            org.jfrog.build.extractor.ProxySelector proxySelector = new org.jfrog.build.extractor.ProxySelector(resolutionHelper.getHttpProxyHost(), resolutionHelper.getHttpProxyPort(), resolutionHelper.getHttpProxyUsername(), resolutionHelper.getHttpProxyPassword(), resolutionHelper.getHttpsProxyHost(), resolutionHelper.getHttpsProxyPort(), resolutionHelper.getHttpsProxyUsername(), resolutionHelper.getHttpsProxyPassword(), resolutionHelper.getNoProxy());
-            ArtifactoryResolution artifactoryResolution = new ArtifactoryResolution(resolutionHelper.getRepoReleaseUrl(), resolutionHelper.getRepoSnapshotUrl(), resolutionHelper.getRepoUsername(), resolutionHelper.getRepoPassword(), proxySelector, logger);
+            ArtifactoryResolution artifactoryResolution = getArtifactoryResolution();
             snapshotRepository = artifactoryResolution.createSnapshotRepository();
             if (snapshotRepository != null) {
                 resolutionRepositories.add(snapshotRepository);
@@ -57,6 +56,13 @@ List<RemoteRepository> getResolutionRepositories(RepositorySystemSession session
         return resolutionRepositories;
     }
 
+    private ArtifactoryResolution getArtifactoryResolution() {
+        ProxySelector proxySelector = new ProxySelector(resolutionHelper.getHttpProxyHost(), resolutionHelper.getHttpProxyPort(), resolutionHelper.getHttpProxyUsername(), resolutionHelper.getHttpProxyPassword(), resolutionHelper.getHttpsProxyHost(), resolutionHelper.getHttpsProxyPort(), resolutionHelper.getHttpsProxyUsername(), resolutionHelper.getHttpsProxyPassword(), resolutionHelper.getNoProxy());
+        return new ArtifactoryResolution(resolutionHelper.getRepoReleaseUrl(), resolutionHelper.getRepoSnapshotUrl(), resolutionHelper.getRepoUsername(), resolutionHelper.getRepoPassword(), proxySelector, logger)
+                .setSnapshotEnabled(isSnapshotEnabled())
+                .setSnapshotUpdatePolicy(resolutionHelper.getSnapshotUpdatePolicy());
+    }
+
     private void initResolutionHelper(RepositorySystemSession session) {
         if (resolutionHelper.isInitialized()) {
             return;
@@ -70,8 +76,7 @@ private void initResolutionHelper(RepositorySystemSession session) {
     List<ArtifactRepository> getResolutionPluginRepositories(RepositorySystemSession session) {
         if (resolutionPluginRepositories.isEmpty()) {
             initResolutionHelper(session);
-            ProxySelector proxySelector = new ProxySelector(resolutionHelper.getHttpProxyHost(), resolutionHelper.getHttpProxyPort(), resolutionHelper.getHttpProxyUsername(), resolutionHelper.getHttpProxyPassword(), resolutionHelper.getHttpsProxyHost(), resolutionHelper.getHttpsProxyPort(), resolutionHelper.getHttpsProxyUsername(), resolutionHelper.getHttpsProxyPassword(), resolutionHelper.getNoProxy());
-            ArtifactoryPluginResolution repositoryBuilder = new ArtifactoryPluginResolution(resolutionHelper.getRepoReleaseUrl(), resolutionHelper.getRepoSnapshotUrl(), resolutionHelper.getRepoUsername(), resolutionHelper.getRepoPassword(), proxySelector, logger);
+            ArtifactoryPluginResolution repositoryBuilder = getArtifactoryPluginResolution();
             ArtifactRepository snapshotRepository = repositoryBuilder.createSnapshotRepository();
             if (snapshotRepository != null) {
                 resolutionPluginRepositories.add(snapshotRepository);
@@ -84,6 +89,13 @@ List<ArtifactRepository> getResolutionPluginRepositories(RepositorySystemSession
         return resolutionPluginRepositories;
     }
 
+    private ArtifactoryPluginResolution getArtifactoryPluginResolution() {
+        ProxySelector proxySelector = new ProxySelector(resolutionHelper.getHttpProxyHost(), resolutionHelper.getHttpProxyPort(), resolutionHelper.getHttpProxyUsername(), resolutionHelper.getHttpProxyPassword(), resolutionHelper.getHttpsProxyHost(), resolutionHelper.getHttpsProxyPort(), resolutionHelper.getHttpsProxyUsername(), resolutionHelper.getHttpsProxyPassword(), resolutionHelper.getNoProxy());
+        return new ArtifactoryPluginResolution(resolutionHelper.getRepoReleaseUrl(), resolutionHelper.getRepoSnapshotUrl(), resolutionHelper.getRepoUsername(), resolutionHelper.getRepoPassword(), proxySelector, logger)
+                .setSnapshotEnabled(isSnapshotEnabled())
+                .setSnapshotUpdatePolicy(resolutionHelper.getSnapshotUpdatePolicy());
+    }
+
     RemoteRepository getSnapshotRepository(RepositorySystemSession session) {
         // Init repositories configured in the Artifactory plugin:
         initResolutionRepositories(session);
@@ -99,4 +111,8 @@ RemoteRepository getReleaseRepository(RepositorySystemSession session) {
 
         return releaseRepository;
     }
+
+    private boolean isSnapshotEnabled() {
+        return !resolutionHelper.isSnapshotDisabled();
+    }
 }
diff --git a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryPluginResolution.java b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryPluginResolution.java
index 612178c5e..fae1d9cc1 100644
--- a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryPluginResolution.java
+++ b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryPluginResolution.java
@@ -13,14 +13,18 @@
  * Those repositories will replace the default Maven repositories.
  */
 public class ArtifactoryPluginResolution extends ArtifactoryResolutionRepositoryBase {
+    private boolean isSnapshotEnabled;
+    private String snapshotUpdatePolicy;
 
     public ArtifactoryPluginResolution(String repoReleaseUrl, String snapshotRepoUrl, String repoUsername, String repoPassword, ProxySelector proxySelector, Logger logger) {
         super(repoReleaseUrl, snapshotRepoUrl, repoUsername, repoPassword, proxySelector, logger);
+        this.isSnapshotEnabled = true;
+        this.snapshotUpdatePolicy = ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY;
     }
 
     public ArtifactRepository createSnapshotRepository() {
         if (super.shouldCreateSnapshotRepository()) {
-            return createDefaultRepository(snapshotRepoUrl, "artifactory-snapshot", false, true);
+            return createDefaultRepository(snapshotRepoUrl, "artifactory-snapshot", false, this.isSnapshotEnabled, this.snapshotUpdatePolicy);
         }
         return null;
     }
@@ -28,14 +32,24 @@ public ArtifactRepository createSnapshotRepository() {
     public ArtifactRepository createReleaseRepository() {
         if (super.shouldCreateReleaseRepository()) {
             String repositoryId = snapshotPolicyEnabled() ? "artifactory-release-snapshot" : "artifactory-release";
-            return createDefaultRepository(releaseRepoUrl, repositoryId, true, snapshotPolicyEnabled());
+            return createDefaultRepository(releaseRepoUrl, repositoryId, true, snapshotPolicyEnabled(), this.snapshotUpdatePolicy);
         }
         return null;
     }
 
-    private ArtifactRepository createDefaultRepository(String repoUrl, String repoId, boolean releasePolicy, Boolean snapshotPolicy) {
+    public ArtifactoryPluginResolution setSnapshotEnabled(boolean isSnapshotEnabled) {
+        this.isSnapshotEnabled = isSnapshotEnabled;
+        return this;
+    }
+
+    public ArtifactoryPluginResolution setSnapshotUpdatePolicy(String snapshotUpdatePolicy) {
+        this.snapshotUpdatePolicy = snapshotUpdatePolicy;
+        return this;
+    }
+
+    private ArtifactRepository createDefaultRepository(String repoUrl, String repoId, boolean releasePolicy, Boolean snapshotPolicy, String snapshotUpdatePolicy) {
         ArtifactRepository repository = new MavenArtifactRepository();
-        setPolicy(repository, releasePolicy, snapshotPolicy);
+        setPolicy(repository, releasePolicy, snapshotPolicy, snapshotUpdatePolicy);
         repository.setLayout(new DefaultRepositoryLayout());
         repository.setUrl(repoUrl);
         repository.setId(repoId);
@@ -44,10 +58,10 @@ private ArtifactRepository createDefaultRepository(String repoUrl, String repoId
         return repository;
     }
 
-    private void setPolicy(ArtifactRepository snapshotPluginRepository, boolean releasePolicyEnabled, boolean snapshotPolicyEnabled) {
+    private void setPolicy(ArtifactRepository snapshotPluginRepository, boolean releasePolicyEnabled, boolean snapshotPolicyEnabled, String snapshotUpdatePolicy) {
         ArtifactRepositoryPolicy releasePolicy = new ArtifactRepositoryPolicy(releasePolicyEnabled, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN);
         snapshotPluginRepository.setReleaseUpdatePolicy(releasePolicy);
-        ArtifactRepositoryPolicy snapshotPolicy = new ArtifactRepositoryPolicy(snapshotPolicyEnabled, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN);
+        ArtifactRepositoryPolicy snapshotPolicy = new ArtifactRepositoryPolicy(snapshotPolicyEnabled, snapshotUpdatePolicy, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN);
         snapshotPluginRepository.setSnapshotUpdatePolicy(snapshotPolicy);
     }
 
diff --git a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolution.java b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolution.java
index 21c99f292..e73ae07e5 100644
--- a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolution.java
+++ b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ArtifactoryResolution.java
@@ -13,14 +13,18 @@
  * Those repositories will be used instead of the default maven repositories.
  */
 public class ArtifactoryResolution extends ArtifactoryResolutionRepositoryBase {
+    private boolean isSnapshotEnabled;
+    private String snapshotUpdatePolicy;
 
     public ArtifactoryResolution(String repoReleaseUrl, String snapshotRepoUrl, String repoUsername, String repoPassword, ProxySelector proxySelector, Logger logger) {
         super(repoReleaseUrl, snapshotRepoUrl, repoUsername, repoPassword, proxySelector, logger);
+        this.isSnapshotEnabled = true;
+        this.snapshotUpdatePolicy = RepositoryPolicy.UPDATE_POLICY_DAILY;
     }
 
     public RemoteRepository createSnapshotRepository() {
         if (super.shouldCreateSnapshotRepository()) {
-            return createRepository(snapshotRepoUrl, "artifactory-snapshot", false, true);
+            return createRepository(snapshotRepoUrl, "artifactory-snapshot", false, this.isSnapshotEnabled, this.snapshotUpdatePolicy);
         }
         return null;
     }
@@ -28,16 +32,26 @@ public RemoteRepository createSnapshotRepository() {
     public RemoteRepository createReleaseRepository() {
         if (shouldCreateReleaseRepository()) {
             String repositoryId = snapshotPolicyEnabled() ? "artifactory-release-snapshot" : "artifactory-release";
-            return createRepository(releaseRepoUrl, repositoryId, true, snapshotPolicyEnabled());
+            return createRepository(releaseRepoUrl, repositoryId, true, snapshotPolicyEnabled(), this.snapshotUpdatePolicy);
         }
         return null;
     }
 
-    private RemoteRepository createRepository(String repoUrl, String repoId, boolean releasePolicy, Boolean snapshotPolicy) {
+    public ArtifactoryResolution setSnapshotEnabled(boolean isSnapshotEnabled) {
+        this.isSnapshotEnabled = isSnapshotEnabled;
+        return this;
+    }
+
+    public ArtifactoryResolution setSnapshotUpdatePolicy(String snapshotUpdatePolicy) {
+        this.snapshotUpdatePolicy = snapshotUpdatePolicy;
+        return this;
+    }
+
+    private RemoteRepository createRepository(String repoUrl, String repoId, boolean releasePolicy, Boolean snapshotPolicy, String snapshotUpdatePolicy) {
         RemoteRepository.Builder builder = new RemoteRepository.Builder(repoId, "default", repoUrl);
         setAuthentication(builder);
         setProxy(builder, repoUrl);
-        setPolicy(builder, releasePolicy, snapshotPolicy);
+        setPolicy(builder, releasePolicy, snapshotPolicy, snapshotUpdatePolicy);
         return builder.build();
     }
 
@@ -49,10 +63,10 @@ private void setAuthentication(RemoteRepository.Builder builder) {
         }
     }
 
-    private void setPolicy(RemoteRepository.Builder builder, boolean releasePolicyEnabled, boolean snapshotPolicyEnabled) {
+    private void setPolicy(RemoteRepository.Builder builder, boolean releasePolicyEnabled, boolean snapshotPolicyEnabled, String snapshotUpdatePolicy) {
         RepositoryPolicy releasePolicy = new RepositoryPolicy(releasePolicyEnabled, RepositoryPolicy.UPDATE_POLICY_DAILY, RepositoryPolicy.CHECKSUM_POLICY_WARN);
         builder.setReleasePolicy(releasePolicy);
-        RepositoryPolicy snapshotPolicy = new RepositoryPolicy(snapshotPolicyEnabled, RepositoryPolicy.UPDATE_POLICY_DAILY, RepositoryPolicy.CHECKSUM_POLICY_WARN);
+        RepositoryPolicy snapshotPolicy = new RepositoryPolicy(snapshotPolicyEnabled, snapshotUpdatePolicy, RepositoryPolicy.CHECKSUM_POLICY_WARN);
         builder.setSnapshotPolicy(snapshotPolicy);
     }
 
diff --git a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ResolutionHelper.java b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ResolutionHelper.java
index 396217569..7f56f850e 100644
--- a/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ResolutionHelper.java
+++ b/build-info-extractor-maven3/src/main/java/org/jfrog/build/extractor/maven/resolver/ResolutionHelper.java
@@ -113,6 +113,10 @@ public String getHttpsProxyPassword() {
         return internalConfiguration.httpsProxy.getPassword();
     }
 
+    public boolean isSnapshotDisabled() { return internalConfiguration.resolver.isSnapshotDisabled(); }
+
+    public String getSnapshotUpdatePolicy() { return internalConfiguration.resolver.getSnapshotUpdatePolicy(); }
+
     public Logger getLogger() {
         return logger;
     }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
index 875079014..fc9149aa7 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ArtifactoryClientConfiguration.java
@@ -9,6 +9,7 @@
 import org.jfrog.build.extractor.ci.Issue;
 import org.jfrog.build.extractor.clientConfiguration.util.IssuesTrackerUtils;
 import org.jfrog.build.extractor.clientConfiguration.util.encryption.EncryptionKeyPair;
+import org.eclipse.aether.repository.RepositoryPolicy;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.IllegalBlockSizeException;
@@ -786,6 +787,14 @@ public String getRepoKey() {
             return getStringValue(REPO_KEY);
         }
 
+        public Boolean isSnapshotDisabled() {
+            return getBooleanValue(SNAPSHOTS_DISABLED, false);
+        }
+
+        public String getSnapshotUpdatePolicy() {
+            return getStringValue(SNAPSHOT_UPDATE_POLICY, RepositoryPolicy.UPDATE_POLICY_DAILY);
+        }
+
         public void setRepoKey(String repoKey) {
             setStringValue(REPO_KEY, repoKey);
         }
diff --git a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientConfigurationFields.java b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientConfigurationFields.java
index f5020406a..20376ea72 100644
--- a/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientConfigurationFields.java
+++ b/build-info-extractor/src/main/java/org/jfrog/build/extractor/clientConfiguration/ClientConfigurationFields.java
@@ -30,6 +30,8 @@ public interface ClientConfigurationFields {
     String DOCKER_HOST = "docker.host";
     String URL = "url";
     String REPO_KEY = "repoKey";
+    String SNAPSHOTS_DISABLED = "snapshots.disabled";
+    String SNAPSHOT_UPDATE_POLICY = "snapshots.updatePolicy";
     String DOWN_SNAPSHOT_REPO_KEY = "downSnapshotRepoKey";
     // Publish fields
     String PUBLISH_ARTIFACTS = "artifacts";
diff --git a/build.gradle b/build.gradle
index f71c1af65..935285696 100644
--- a/build.gradle
+++ b/build.gradle
@@ -334,6 +334,7 @@ project('build-info-extractor') {
     dependencies {
         implementation project(':build-info-client')
         implementation project(':build-info-api')
+        implementation "org.eclipse.aether:aether-api:$eclipseAetherVersion"
 
         testImplementation "org.easymock:easymockclassextension:$easymockclassextensionVersion"
         testImplementation('org.mock-server:mockserver-netty:5.15.0') {

From 77f59c4f67e0474fb3205e2b7da7816032d5e4a7 Mon Sep 17 00:00:00 2001
From: Kanishk Gupta <148543773+fluxxBot@users.noreply.github.com>
Date: Wed, 26 Feb 2025 12:36:52 +0530
Subject: [PATCH 32/36] Added conditional statement to skip audit while
 releasing (#819)

---
 release/pipelines.release.yml | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/release/pipelines.release.yml b/release/pipelines.release.yml
index 51fed5f4d..26b31a3f3 100644
--- a/release/pipelines.release.yml
+++ b/release/pipelines.release.yml
@@ -14,6 +14,7 @@ pipelines:
           NEXT_DEVELOPMENT_VERSION: 2.0.x-SNAPSHOT
           NEXT_GRADLE_VERSION: 4.0.0
           NEXT_GRADLE_DEVELOPMENT_VERSION: 4.0.x-SNAPSHOT
+          SKIP_AUDIT_CHECK: "false"
 
     steps:
       - name: Release
@@ -54,7 +55,14 @@ pipelines:
             - jf gradlec --use-wrapper --uses-plugin --repo-resolve ecosys-maven-remote --repo-deploy ecosys-oss-release-local
 
             # Run audit
-            - jf audit --fail=false
+            - |
+              if [[ $SKIP_AUDIT_CHECK == "true" ]]; then
+                echo "Skipping audit check"
+              else
+                echo "Running audit check"
+                jf audit --fail=false
+              fi
+
 
             # Update version
             - sed -i -e "/build-info-version=/ s/=.*/=$NEXT_VERSION/" -e "/build-info-extractor-gradle-version=/ s/=.*/=$NEXT_GRADLE_VERSION/" gradle.properties

From c75961b0dedbf90e4cc9725f85ed9e235793b25a Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Wed, 26 Feb 2025 07:19:14 +0000
Subject: [PATCH 33/36] [artifactory-release] Release version 2.42.0 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0c6f95580..a13937abe 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.41.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.42.0
+build-info-extractor-gradle-version=4.33.24

From 5d00f3b3de8b249ae099e39603d9b0a3884e4892 Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Wed, 26 Feb 2025 07:26:31 +0000
Subject: [PATCH 34/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index a13937abe..0037f2466 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.42.0
-build-info-extractor-gradle-version=4.33.24
+build-info-version=2.42.x-SNAPSHOT
+build-info-extractor-gradle-version=4.33.x-SNAPSHOT

From 6f936295da0507ab5c345a7ee3ddf139828336ce Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Wed, 26 Feb 2025 07:40:27 +0000
Subject: [PATCH 35/36] [artifactory-release] Release version 2.42.1 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index 0037f2466..fa40839a2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.42.x-SNAPSHOT
-build-info-extractor-gradle-version=4.33.x-SNAPSHOT
+build-info-version=2.42.1
+build-info-extractor-gradle-version=4.34.1

From e246e9e77a6745ffa3a76f4b40be6d08e0930a3d Mon Sep 17 00:00:00 2001
From: JFrog Pipelines Step <build@pipelines.jfrog.com>
Date: Wed, 26 Feb 2025 07:48:35 +0000
Subject: [PATCH 36/36] [artifactory-release] Next development version
 [skipRun]

---
 gradle.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index fa40839a2..ebebe4e45 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,2 +1,2 @@
-build-info-version=2.42.1
-build-info-extractor-gradle-version=4.34.1
+build-info-version=2.42.x-SNAPSHOT
+build-info-extractor-gradle-version=4.34.x-SNAPSHOT