diff --git a/aws-lambda/lambda/pom.xml b/aws-lambda/lambda/pom.xml
index 2d903aabc5..1f446e04c0 100644
--- a/aws-lambda/lambda/pom.xml
+++ b/aws-lambda/lambda/pom.xml
@@ -89,7 +89,6 @@
 
     
         1.1.1
-        2.5
         1.3.0
         1.2.0
         2.8.2
diff --git a/blade/pom.xml b/blade/pom.xml
index 178d1afb52..458ec40051 100644
--- a/blade/pom.xml
+++ b/blade/pom.xml
@@ -154,7 +154,6 @@
     
         2.0.14.RELEASE
         4.2.1
-        3.8.1
         1.18.4
         4.5.6
         4.5.6
diff --git a/core-java-modules/core-java-11-2/README.md b/core-java-modules/core-java-11-2/README.md
index 834f310fce..c87936b07d 100644
--- a/core-java-modules/core-java-11-2/README.md
+++ b/core-java-modules/core-java-11-2/README.md
@@ -6,3 +6,4 @@ This module contains articles about Java 11 core features
 - [Guide to Java 8 Optional](https://www.baeldung.com/java-optional)
 - [Guide to Java Reflection](http://www.baeldung.com/java-reflection)
 - [Guide to Java 8’s Collectors](https://www.baeldung.com/java-8-collectors)
+- [New Features in Java 11](https://www.baeldung.com/java-11-new-features)
diff --git a/core-java-modules/core-java-11-2/pom.xml b/core-java-modules/core-java-11-2/pom.xml
index e2b129ae00..b92963a5c8 100644
--- a/core-java-modules/core-java-11-2/pom.xml
+++ b/core-java-modules/core-java-11-2/pom.xml
@@ -28,6 +28,29 @@
             ${assertj.version}
             test
         
+        
+            org.mock-server
+            mockserver-junit-jupiter
+            ${mockserver.version}
+        
+        
+            org.junit.jupiter
+            junit-jupiter-engine
+            ${junit.jupiter.version}
+            test
+        
+        
+            org.junit.jupiter
+            junit-jupiter-params
+            ${junit.jupiter.version}
+            test
+        
+        
+            org.junit.jupiter
+            junit-jupiter-api
+            ${junit.jupiter.version}
+            test
+        
     
 
     
@@ -48,7 +71,9 @@
         11
         11
         29.0-jre
+        5.7.0
         3.17.2
+        5.11.1
     
 
 
diff --git a/core-java-modules/core-java-11-2/src/main/java/com/baeldung/features/MainClass.java b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/features/MainClass.java
new file mode 100644
index 0000000000..b00c56fcd7
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/main/java/com/baeldung/features/MainClass.java
@@ -0,0 +1,17 @@
+package com.baeldung.features;
+
+public class MainClass {
+
+    private static boolean mainPrivateMethod() {
+        return true;
+    }
+
+    public static class NestedClass {
+
+        boolean nestedPublicMethod() {
+            return mainPrivateMethod();
+        }
+
+    }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/HttpClientIntegrationTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/HttpClientIntegrationTest.java
new file mode 100644
index 0000000000..1d49f5dbd1
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/HttpClientIntegrationTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockserver.integration.ClientAndServer;
+import org.mockserver.model.HttpStatusCode;
+import org.mockserver.socket.PortFactory;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.time.Duration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockserver.integration.ClientAndServer.startClientAndServer;
+
+class HttpClientIntegrationTest {
+
+    private static ClientAndServer mockServer;
+    private static int port;
+
+    @BeforeAll
+    static void startServer() {
+        port = PortFactory.findFreePort();
+        mockServer = startClientAndServer(port);
+        mockServer.when(new org.mockserver.model.HttpRequest().withMethod("GET"))
+          .respond(new org.mockserver.model.HttpResponse()
+            .withStatusCode(HttpStatusCode.OK_200.code())
+            .withBody("Hello from the server!"));
+    }
+
+    @AfterAll
+    static void stopServer() {
+        mockServer.stop();
+    }
+
+    @Test
+    void givenSampleHttpRequest_whenRequestIsSent_thenServerResponseIsReceived() throws IOException, InterruptedException {
+        HttpClient httpClient = HttpClient.newBuilder()
+          .version(HttpClient.Version.HTTP_2)
+          .connectTimeout(Duration.ofSeconds(20))
+          .build();
+        HttpRequest httpRequest = HttpRequest.newBuilder()
+          .GET()
+          .uri(URI.create("http://localhost:" + port))
+          .build();
+        HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
+        assertThat(httpResponse.body()).isEqualTo("Hello from the server!");
+    }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/JavaElevenFeaturesUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/JavaElevenFeaturesUnitTest.java
new file mode 100644
index 0000000000..61ce9c7c13
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/JavaElevenFeaturesUnitTest.java
@@ -0,0 +1,61 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import javax.annotation.Nonnull;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class JavaElevenFeaturesUnitTest {
+
+    @Test
+    void givenMultilineString_whenExtractingNonBlankStrippedLines_thenLinesAreReturned() {
+        String multilineString = "Baeldung helps \n \n developers \n explore Java.";
+        List lines = multilineString.lines()
+          .filter(line -> !line.isBlank())
+          .map(String::strip)
+          .collect(Collectors.toList());
+        assertThat(lines).containsExactly("Baeldung helps", "developers", "explore Java.");
+    }
+
+    @Test
+    void givenTemporaryFile_whenReadingStringContent_thenContentIsReturned(@TempDir Path tempDir) throws IOException {
+        Path filePath = Files.writeString(Files.createTempFile(tempDir, "demo", ".txt"), "Sample text");
+        String fileContent = Files.readString(filePath);
+        assertThat(fileContent).isEqualTo("Sample text");
+    }
+
+    @Test
+    void givenSampleList_whenConvertingToArray_thenItemsRemainUnchanged() {
+        List sampleList = Arrays.asList("Java", "Kotlin");
+        String[] sampleArray = sampleList.toArray(String[]::new);
+        assertThat(sampleArray).containsExactly("Java", "Kotlin");
+    }
+
+    @Test
+    void givenSampleList_whenConvertingToUppercaseString_thenUppercaseIsReturned() {
+        List sampleList = Arrays.asList("Java", "Kotlin");
+        String resultString = sampleList.stream()
+          .map((@Nonnull var x) -> x.toUpperCase())
+          .collect(Collectors.joining(", "));
+        assertThat(resultString).isEqualTo("JAVA, KOTLIN");
+    }
+
+    @Test
+    void givenSampleList_whenExtractingNonBlankValues_thenOnlyNonBlanksAreReturned() {
+        List sampleList = Arrays.asList("Java", "\n \n", "Kotlin", " ");
+        List withoutBlanks = sampleList.stream()
+          .filter(Predicate.not(String::isBlank))
+          .collect(Collectors.toList());
+        assertThat(withoutBlanks).containsExactly("Java", "Kotlin");
+    }
+
+}
diff --git a/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/NestedClassesUnitTest.java b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/NestedClassesUnitTest.java
new file mode 100644
index 0000000000..902ad9c6f8
--- /dev/null
+++ b/core-java-modules/core-java-11-2/src/test/java/com/baeldung/features/NestedClassesUnitTest.java
@@ -0,0 +1,37 @@
+package com.baeldung.features;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class NestedClassesUnitTest {
+
+    @Test
+    public void giveNestedClass_whenCallingMainClassPrivateMethod_thenNoExceptionIsThrown() {
+        MainClass.NestedClass nestedInstance = new MainClass.NestedClass();
+        assertThat(nestedInstance.nestedPublicMethod()).isTrue();
+    }
+
+    @Test
+    public void giveNestedClass_whenCheckingNestmate_thenNestedClassIsReturned() {
+        assertThat(MainClass.class.isNestmateOf(MainClass.NestedClass.class)).isTrue();
+    }
+
+    @Test
+    public void giveNestedClass_whenCheckingNestHost_thenMainClassIsReturned() {
+        assertThat(MainClass.NestedClass.class.getNestHost()).isEqualTo(MainClass.class);
+    }
+
+    @Test
+    public void giveNestedClass_whenCheckingNestMembers_thenNestMembersAreReturned() {
+        Set nestedMembers = Arrays.stream(MainClass.NestedClass.class.getNestMembers())
+          .map(Class::getName)
+          .collect(Collectors.toSet());
+        assertThat(nestedMembers).contains(MainClass.class.getName(), MainClass.NestedClass.class.getName());
+    }
+
+}
diff --git a/core-java-modules/core-java-12/README.md b/core-java-modules/core-java-12/README.md
index 6c603e4dea..c28df26c6f 100644
--- a/core-java-modules/core-java-12/README.md
+++ b/core-java-modules/core-java-12/README.md
@@ -2,3 +2,4 @@
 
 
 - [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)
+- [Java 12 New Features](https://www.baeldung.com/java-12-new-features)
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/CompactNumbersUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/CompactNumbersUnitTest.java
new file mode 100644
index 0000000000..08a6d58d72
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/CompactNumbersUnitTest.java
@@ -0,0 +1,21 @@
+package java.com.baeldung.newfeatures;
+
+import org.junit.Test;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+import static org.junit.Assert.assertEquals;
+
+public class CompactNumbersUnitTest {
+
+    @Test
+    public void givenNumber_thenCompactValues() {
+        NumberFormat likesShort = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.SHORT);
+        likesShort.setMaximumFractionDigits(2);
+        assertEquals("2.59K", likesShort.format(2592));
+        NumberFormat likesLong = NumberFormat.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.LONG);
+        likesLong.setMaximumFractionDigits(2);
+        assertEquals("2.59 thousand", likesShort.format(2592));
+    }
+}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/FileMismatchUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/FileMismatchUnitTest.java
new file mode 100644
index 0000000000..7f081fe399
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/FileMismatchUnitTest.java
@@ -0,0 +1,32 @@
+package java.com.baeldung.newfeatures;
+
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.Assert.assertEquals;
+
+public class FileMismatchUnitTest {
+
+    @Test
+    public void givenIdenticalFiles_thenShouldNotFindMismatch() throws IOException {
+        Path filePath1 = Files.createTempFile("file1", ".txt");
+        Path filePath2 = Files.createTempFile("file2", ".txt");
+        Files.writeString(filePath1, "Java 12 Article");
+        Files.writeString(filePath2, "Java 12 Article");
+        long mismatch = Files.mismatch(filePath1, filePath2);
+        assertEquals(-1, mismatch);
+    }
+
+    @Test
+    public void givenDifferentFiles_thenShouldFindMismatch() throws IOException {
+        Path filePath3 = Files.createTempFile("file3", ".txt");
+        Path filePath4 = Files.createTempFile("file4", ".txt");
+        Files.writeString(filePath3, "Java 12 Article");
+        Files.writeString(filePath4, "Java 12 Tutorial");
+        long mismatch = Files.mismatch(filePath3, filePath4);
+        assertEquals(8, mismatch);
+    }
+}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/StringUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/StringUnitTest.java
new file mode 100644
index 0000000000..5ae51bd960
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/StringUnitTest.java
@@ -0,0 +1,15 @@
+package java.com.baeldung.newfeatures;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class StringUnitTest {
+
+    @Test
+    public void givenString_thenRevertValue() {
+        String text = "Baeldung";
+        String transformed = text.transform(value -> new StringBuilder(value).reverse().toString());
+        assertEquals("gnudleaB", transformed);
+    }
+}
diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/TeeingCollectorUnitTest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/TeeingCollectorUnitTest.java
new file mode 100644
index 0000000000..30a5cb40a7
--- /dev/null
+++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/newfeatures/TeeingCollectorUnitTest.java
@@ -0,0 +1,18 @@
+package java.com.baeldung.newfeatures;
+
+import org.junit.Test;
+
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+
+public class TeeingCollectorUnitTest {
+
+    @Test
+    public void givenSetOfNumbers_thenCalculateAverage() {
+        double mean = Stream.of(1, 2, 3, 4, 5)
+          .collect(Collectors.teeing(Collectors.summingDouble(i -> i), Collectors.counting(), (sum, count) -> sum / count));
+        assertEquals(3.0, mean);
+    }
+}
diff --git a/core-java-modules/core-java-15/pom.xml b/core-java-modules/core-java-15/pom.xml
index df8aeafca9..3b0d324d10 100644
--- a/core-java-modules/core-java-15/pom.xml
+++ b/core-java-modules/core-java-15/pom.xml
@@ -20,7 +20,7 @@
         
             org.apache.commons
             commons-lang3
-            ${apache-commons-lang3.version}
+            ${commons-lang3.version}
         
         
             org.assertj
@@ -68,7 +68,6 @@
 
     
         15
-        3.11
         3.17.2
         3.8.1
         3.0.0-M3
diff --git a/core-java-modules/core-java-9/pom.xml b/core-java-modules/core-java-9/pom.xml
index d7894934b1..001faf88cb 100644
--- a/core-java-modules/core-java-9/pom.xml
+++ b/core-java-modules/core-java-9/pom.xml
@@ -47,12 +47,12 @@
         
             org.apache.commons
             commons-lang3
-            3.11
+            ${commons-lang3.version}
         
         
             commons-io
             commons-io
-            2.7
+            ${commons-io.version}
         
     
 
diff --git a/core-java-modules/core-java-arrays-operations-advanced/pom.xml b/core-java-modules/core-java-arrays-operations-advanced/pom.xml
index d73fdcee28..c7ea09c616 100644
--- a/core-java-modules/core-java-arrays-operations-advanced/pom.xml
+++ b/core-java-modules/core-java-arrays-operations-advanced/pom.xml
@@ -29,8 +29,6 @@
     
 
     
-        3.9
-
         3.10.0
     
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-arrays-operations-basic/pom.xml b/core-java-modules/core-java-arrays-operations-basic/pom.xml
index 64856d9b39..dcee6547a0 100644
--- a/core-java-modules/core-java-arrays-operations-basic/pom.xml
+++ b/core-java-modules/core-java-arrays-operations-basic/pom.xml
@@ -68,11 +68,7 @@
 
     
         3.2.0
-
-        3.9
-
         1.19
-
         3.10.0
     
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-arrays-sorting/pom.xml b/core-java-modules/core-java-arrays-sorting/pom.xml
index 9b307870a1..9b900c3de6 100644
--- a/core-java-modules/core-java-arrays-sorting/pom.xml
+++ b/core-java-modules/core-java-arrays-sorting/pom.xml
@@ -76,12 +76,8 @@
 
     
         3.2.0
-
-        3.9
         28.2-jre
-
         1.19
-
         3.10.0
     
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-char/README.md b/core-java-modules/core-java-char/README.md
index 71f8e943aa..fd79da15ab 100644
--- a/core-java-modules/core-java-char/README.md
+++ b/core-java-modules/core-java-char/README.md
@@ -3,4 +3,4 @@
 This module contains articles about Java Character Class
 
 ### Relevant Articles: 
-- Character#isAlphabetic vs Character#isLetter
+- [Character#isAlphabetic vs Character#isLetter](https://www.baeldung.com/java-character-isletter-isalphabetic)
diff --git a/core-java-modules/core-java-collections-3/pom.xml b/core-java-modules/core-java-collections-3/pom.xml
index a9a05f5092..602fcf60f4 100644
--- a/core-java-modules/core-java-collections-3/pom.xml
+++ b/core-java-modules/core-java-collections-3/pom.xml
@@ -35,7 +35,7 @@
         
             org.apache.commons
             commons-lang3
-            3.10
+            ${commons-lang3.version}
         
     
 
diff --git a/core-java-modules/core-java-collections-list/pom.xml b/core-java-modules/core-java-collections-list/pom.xml
index 509f58ea61..76ca66fe70 100644
--- a/core-java-modules/core-java-collections-list/pom.xml
+++ b/core-java-modules/core-java-collections-list/pom.xml
@@ -36,7 +36,6 @@
 
     
         4.1
-        3.8.1
         3.11.1
     
 
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressManualTest.java
similarity index 74%
rename from core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java
rename to core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressManualTest.java
index 6c76505347..0e6b41d1e9 100644
--- a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressUnitTest.java
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterJCStressManualTest.java
@@ -10,11 +10,17 @@ import org.openjdk.jcstress.annotations.Outcome;
 import org.openjdk.jcstress.annotations.State;
 import org.openjdk.jcstress.infra.results.I_Result;
 
+/**
+ * This is defined as a manual test because it tries to simulate the race conditions
+ * in a concurrent program that is poorly designed and hence may fail nondeterministically.
+ * This will help the CI jobs to ignore these tests and a developer to run them manually.
+ *
+ */
 @JCStressTest
 @Outcome(id = "1", expect = ACCEPTABLE_INTERESTING, desc = "One update lost.")
 @Outcome(id = "2", expect = ACCEPTABLE, desc = "Both updates.")
 @State
-public class MyCounterJCStressUnitTest {
+public class MyCounterJCStressManualTest {
 
     private MyCounter counter;
 
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCManualTest.java
similarity index 59%
rename from core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
rename to core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCManualTest.java
index 8a0bedf6c2..985e316635 100644
--- a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCUnitTest.java
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterMultithreadedTCManualTest.java
@@ -1,12 +1,17 @@
 package com.baeldung.concurrent;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 import edu.umd.cs.mtc.MultithreadedTestCase;
 import edu.umd.cs.mtc.TestFramework;
 
-public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
+/**
+ * This is defined as a manual test because it tries to simulate the race conditions
+ * in a concurrent program that is poorly designed and hence may fail nondeterministically.
+ * This will help the CI jobs to ignore these tests and a developer to run them manually.
+ *
+ */
+public class MyCounterMultithreadedTCManualTest extends MultithreadedTestCase {
 
     private MyCounter counter;
 
@@ -29,9 +34,8 @@ public class MyCounterMultithreadedTCUnitTest extends MultithreadedTestCase {
     	assertEquals(2, counter.getCount());
     }
 
-    @Ignore
     @Test
     public void testCounter() throws Throwable {
-        TestFramework.runManyTimes(new MyCounterMultithreadedTCUnitTest(), 1000);
+        TestFramework.runManyTimes(new MyCounterMultithreadedTCManualTest(), 1000);
     }
 }
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleManualTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleManualTest.java
new file mode 100644
index 0000000000..cba30da34b
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleManualTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.junit.Test;
+
+/**
+ * This is defined as a manual test because it tries to simulate the race conditions
+ * in a concurrent program that is poorly designed and hence may fail nondeterministically.
+ * This will help the CI jobs to ignore these tests and a developer to run them manually.
+ *
+ */
+public class MyCounterSimpleManualTest {
+
+	@Test
+	public void testCounter() {
+		MyCounter counter = new MyCounter();
+		for (int i = 0; i < 500; i++)
+			counter.increment();
+		assertEquals(500, counter.getCount());
+	}
+
+	@Test
+	public void testCounterWithConcurrency() throws InterruptedException {
+		int numberOfThreads = 100;
+		ExecutorService service = Executors.newFixedThreadPool(10);
+		CountDownLatch latch = new CountDownLatch(numberOfThreads);
+		MyCounter counter = new MyCounter();
+		for (int i = 0; i < numberOfThreads; i++) {
+			service.execute(() -> {
+				counter.increment();
+				latch.countDown();
+			});
+		}
+		latch.await();
+		assertEquals(numberOfThreads, counter.getCount());
+	}
+
+	@Test
+	public void testSummationWithConcurrencyAndWait() throws InterruptedException {
+		int numberOfThreads = 2;
+		ExecutorService service = Executors.newFixedThreadPool(10);
+		CountDownLatch latch = new CountDownLatch(numberOfThreads);
+		MyCounter counter = new MyCounter();
+		for (int i = 0; i < numberOfThreads; i++) {
+			service.submit(() -> {
+				try {
+					counter.incrementWithWait();
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+				latch.countDown();
+			});
+		}
+		latch.await();
+		assertEquals(numberOfThreads, counter.getCount());
+	}
+
+}
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
deleted file mode 100644
index 9a405e7e24..0000000000
--- a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterSimpleUnitTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.baeldung.concurrent;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class MyCounterSimpleUnitTest {
-
-    @Test
-    public void testCounter() {
-        MyCounter counter = new MyCounter();
-        for (int i = 0; i < 500; i++)
-            counter.increment();
-        assertEquals(500, counter.getCount());
-    }
-
-    @Ignore
-    @Test
-    public void testCounterWithConcurrency() throws InterruptedException {
-        int numberOfThreads = 100;
-        ExecutorService service = Executors.newFixedThreadPool(10);
-        CountDownLatch latch = new CountDownLatch(numberOfThreads);
-        MyCounter counter = new MyCounter();
-        for (int i = 0; i < numberOfThreads; i++) {
-            service.execute(() -> {
-                counter.increment();
-                latch.countDown();
-            });
-        }
-        latch.await();
-        assertEquals(numberOfThreads, counter.getCount());
-    }
-
-    @Ignore
-    @Test
-    public void testSummationWithConcurrencyAndWait() throws InterruptedException {
-        int numberOfThreads = 2;
-        ExecutorService service = Executors.newFixedThreadPool(10);
-        CountDownLatch latch = new CountDownLatch(numberOfThreads);
-        MyCounter counter = new MyCounter();
-        for (int i = 0; i < numberOfThreads; i++) {
-            service.submit(() -> {
-                try {
-                    counter.incrementWithWait();
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                }
-                latch.countDown();
-            });
-        }
-        latch.await();
-        assertEquals(numberOfThreads, counter.getCount());
-    }
-
-}
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitManualTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitManualTest.java
new file mode 100644
index 0000000000..a4ac643f7e
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitManualTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.AfterClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.code.tempusfugit.concurrency.ConcurrentRule;
+import com.google.code.tempusfugit.concurrency.RepeatingRule;
+import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
+import com.google.code.tempusfugit.concurrency.annotations.Repeating;
+
+/**
+ * This is defined as a manual test because it tries to simulate the race conditions
+ * in a concurrent program that is poorly designed and hence may fail nondeterministically.
+ * This will help the CI jobs to ignore these tests and a developer to run them manually.
+ *
+ */
+public class MyCounterTempusFugitManualTest {
+
+	@Rule
+	public ConcurrentRule concurrently = new ConcurrentRule();
+	@Rule
+	public RepeatingRule rule = new RepeatingRule();
+
+	private static MyCounter counter = new MyCounter();
+
+	@Test
+	@Concurrent(count = 2)
+	@Repeating(repetition = 10)
+	public void runsMultipleTimes() {
+		counter.increment();
+	}
+
+	@AfterClass
+	public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
+		assertEquals(counter.getCount(), 20);
+	}
+
+}
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
deleted file mode 100644
index 36a2031e78..0000000000
--- a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterTempusFugitUnitTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.baeldung.concurrent;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.AfterClass;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-
-import com.google.code.tempusfugit.concurrency.ConcurrentRule;
-import com.google.code.tempusfugit.concurrency.RepeatingRule;
-import com.google.code.tempusfugit.concurrency.annotations.Concurrent;
-import com.google.code.tempusfugit.concurrency.annotations.Repeating;
-
-public class MyCounterTempusFugitUnitTest {
-
-    @Rule
-    public ConcurrentRule concurrently = new ConcurrentRule();
-    @Rule
-    public RepeatingRule rule = new RepeatingRule();
-
-    private static MyCounter counter = new MyCounter();
-
-    @Ignore
-    @Test
-    @Concurrent(count = 2)
-    @Repeating(repetition = 10)
-    public void runsMultipleTimes() {
-        counter.increment();
-    }
-
-    @AfterClass
-    public static void annotatedTestRunsMultipleTimes() throws InterruptedException {
-        assertEquals(counter.getCount(), 20);
-    }
-
-}
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverManualTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverManualTest.java
new file mode 100644
index 0000000000..2acfc4ee71
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverManualTest.java
@@ -0,0 +1,48 @@
+package com.baeldung.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.google.testing.threadtester.AnnotatedTestRunner;
+import com.google.testing.threadtester.ThreadedAfter;
+import com.google.testing.threadtester.ThreadedBefore;
+import com.google.testing.threadtester.ThreadedMain;
+import com.google.testing.threadtester.ThreadedSecondary;
+
+/**
+ * This is defined as a manual test because it tries to simulate the race conditions
+ * in a concurrent program that is poorly designed and hence may fail nondeterministically.
+ * This will help the CI jobs to ignore these tests and a developer to run them manually.
+ *
+ */
+public class MyCounterThreadWeaverManualTest {
+
+	private MyCounter counter;
+
+	@ThreadedBefore
+	public void before() {
+		counter = new MyCounter();
+	}
+
+	@ThreadedMain
+	public void mainThread() {
+		counter.increment();
+	}
+
+	@ThreadedSecondary
+	public void secondThread() {
+		counter.increment();
+	}
+
+	@ThreadedAfter
+	public void after() {
+		assertEquals(2, counter.getCount());
+	}
+
+	@Test
+	public void testCounter() {
+		new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
+	}
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java b/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
deleted file mode 100644
index e65a963584..0000000000
--- a/core-java-modules/core-java-concurrency-2/src/test/java/com/baeldung/concurrent/MyCounterThreadWeaverUnitTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.baeldung.concurrent;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-import com.google.testing.threadtester.AnnotatedTestRunner;
-import com.google.testing.threadtester.ThreadedAfter;
-import com.google.testing.threadtester.ThreadedBefore;
-import com.google.testing.threadtester.ThreadedMain;
-import com.google.testing.threadtester.ThreadedSecondary;
-
-public class MyCounterThreadWeaverUnitTest {
-
-    private MyCounter counter;
-
-    @ThreadedBefore
-    public void before() {
-        counter = new MyCounter();
-    }
-
-    @ThreadedMain
-    public void mainThread() {
-        counter.increment();
-    }
-
-    @ThreadedSecondary
-    public void secondThread() {
-        counter.increment();
-    }
-
-    @ThreadedAfter
-    public void after() {
-        assertEquals(2, counter.getCount());
-    }
-
-    @Ignore
-    @Test
-    public void testCounter() {
-        new AnnotatedTestRunner().runTests(this.getClass(), MyCounter.class);
-    }
-
-}
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-advanced-4/README.md b/core-java-modules/core-java-concurrency-advanced-4/README.md
new file mode 100644
index 0000000000..98f2894515
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-4/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Binary Semaphore vs Reentrant Lock](https://www.baeldung.com/java-binary-semaphore-vs-reentrant-lock)
diff --git a/core-java-modules/core-java-concurrency-advanced-4/pom.xml b/core-java-modules/core-java-concurrency-advanced-4/pom.xml
new file mode 100644
index 0000000000..eb9ed3adc1
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-4/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+    4.0.0
+    core-java-concurrency-advanced-4
+    0.1.0-SNAPSHOT
+    core-java-concurrency-advanced-4
+    jar
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+        ../
+    
+
+    
+    
+
+    
+        core-java-concurrency-advanced-4
+        
+            
+                org.apache.maven.plugins
+                maven-compiler-plugin
+                
+                    ${maven.compiler.source}
+                    ${maven.compiler.target}
+                
+            
+        
+        
+            
+                src/main/resources
+                true
+            
+        
+    
+
+    
+        1.8
+        1.8
+    
+
+
diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/AnimalBadPractice.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/AnimalBadPractice.java
new file mode 100644
index 0000000000..ca6b7db765
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/AnimalBadPractice.java
@@ -0,0 +1,35 @@
+package com.baeldung.synchronizationbadpractices;
+
+public class AnimalBadPractice {
+    
+    private String name;
+    private String owner;
+    
+    public String getName() {
+        return name;
+    }
+
+    public String getOwner() {
+        return owner;
+    }
+
+    public synchronized void setName(String name) {
+        this.name = name;
+    }
+    
+    public void setOwner(String owner) {
+        synchronized(this) {
+            this.owner = owner;
+        }
+    }
+    
+    public AnimalBadPractice() {
+        
+    }
+    
+    public AnimalBadPractice(String name, String owner) {
+        this.name = name;
+        this.owner = owner;
+    }
+    
+}
diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/AnimalSolution.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/AnimalSolution.java
new file mode 100644
index 0000000000..b49cfa05d4
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/AnimalSolution.java
@@ -0,0 +1,42 @@
+package com.baeldung.synchronizationbadpractices;
+
+public class AnimalSolution { 
+    
+    private final Object objLock1 = new Object();
+    private final Object objLock2 = new Object();
+    
+    private String name;
+    private String owner;
+    
+    public String getName() {
+        return name;
+    }
+
+    public String getOwner() {
+        return owner;
+    }
+    
+    
+    public void setName(String name) {
+        synchronized(objLock1) {
+            this.name = name;
+        }
+    }
+     
+    public void setOwner(String owner) {
+        synchronized(objLock2) {
+            this.owner = owner;
+        }
+    }
+    
+    public AnimalSolution() {
+        
+    }
+    
+    public AnimalSolution(String name, String owner) {
+        this.name = name;
+        this.owner = owner;
+    }
+    
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/SynchronizationBadPracticeExample.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/SynchronizationBadPracticeExample.java
new file mode 100644
index 0000000000..84d2e1cbb6
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/SynchronizationBadPracticeExample.java
@@ -0,0 +1,51 @@
+package com.baeldung.synchronizationbadpractices;
+
+public class SynchronizationBadPracticeExample {
+
+    public void stringBadPractice1() { 
+        String stringLock = "LOCK_STRING"; 
+        synchronized (stringLock) { 
+            // ... 
+        }
+    }
+
+    private final String stringLock = "LOCK_STRING"; 
+    public void stringBadPractice2() { 
+        synchronized (stringLock) { 
+            // ... 
+        }
+    }
+
+    private final String internedStringLock = new String("LOCK_STRING").intern(); 
+    public void stringBadPractice3() { 
+        synchronized (internedStringLock) { 
+            // ... 
+        }
+    }
+
+    private final Boolean booleanLock = Boolean.FALSE; 
+    public void booleanBadPractice() { 
+        synchronized (booleanLock) { 
+            // ...
+        }
+    }
+
+    private int count = 0; 
+    private final Integer intLock = count; 
+    public void boxedPrimitiveBadPractice() { 
+        synchronized (intLock) { 
+            count++; 
+            // ...
+        }
+    }
+
+    public void classBadPractice() throws InterruptedException {
+        AnimalBadPractice animalObj = new AnimalBadPractice("Tommy", "John");
+        synchronized(animalObj) {
+            while (true) {
+                Thread.sleep(Integer.MAX_VALUE);
+            }
+        } 
+    }
+
+}
diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/SynchronizationSolutionExample.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/SynchronizationSolutionExample.java
new file mode 100644
index 0000000000..a3ab8a2cee
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/synchronizationbadpractices/SynchronizationSolutionExample.java
@@ -0,0 +1,30 @@
+package com.baeldung.synchronizationbadpractices;
+
+public class SynchronizationSolutionExample {
+
+    private final String stringLock = new String("LOCK_STRING"); 
+    public void stringSolution() { 
+        synchronized (stringLock) { 
+            // ... 
+        }
+    }
+
+    private int count = 0;
+    private final Integer intLock = new Integer(count);
+    public void boxedPrimitiveSolution() {
+        synchronized(intLock) {
+            count++; 
+            // ... 
+        } 
+    }
+
+    private static int staticCount = 0;
+    private static final Object staticObjLock = new Object();
+    public void staticVariableSolution() {
+        synchronized(staticObjLock) {
+            staticCount++; 
+            // ... 
+        } 
+    }
+
+}
diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/binarysemaphorereentrantlock/BinarySemaphoreVsReentrantLockUnitTest.java b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/binarysemaphorereentrantlock/BinarySemaphoreVsReentrantLockUnitTest.java
new file mode 100644
index 0000000000..f456e82f39
--- /dev/null
+++ b/core-java-modules/core-java-concurrency-advanced-4/src/test/java/com/baeldung/binarysemaphorereentrantlock/BinarySemaphoreVsReentrantLockUnitTest.java
@@ -0,0 +1,58 @@
+package com.baeldung.binarysemaphorereentrantlock;
+
+import static org.junit.Assert.assertEquals;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.junit.Test;
+
+public class BinarySemaphoreVsReentrantLockUnitTest {
+
+    @Test
+    public void givenBinarySemaphore_whenAcquireAndRelease_thenCheckAvailablePermits() throws InterruptedException {
+        Semaphore binarySemaphore = new Semaphore(1); 
+        try { 
+            binarySemaphore.acquire(); 
+            assertEquals(0, binarySemaphore.availablePermits());
+        } catch (InterruptedException e) { 
+            e.printStackTrace(); 
+        } finally { 
+            binarySemaphore.release(); 
+            assertEquals(1, binarySemaphore.availablePermits()); 
+        }
+    }
+
+    @Test
+    public void givenReentrantLock_whenLockAndUnlock_thenCheckHoldCountAndIsLocked() throws InterruptedException {
+        ReentrantLock reentrantLock = new ReentrantLock(); 
+        try { 
+            reentrantLock.lock(); 
+            assertEquals(1, reentrantLock.getHoldCount()); 
+            assertEquals(true, reentrantLock.isLocked()); 
+        } finally { 
+            reentrantLock.unlock(); 
+            assertEquals(0, reentrantLock.getHoldCount()); 
+            assertEquals(false, reentrantLock.isLocked());
+        }
+    }
+    
+    @Test
+    public void givenReentrantLock_whenLockMultipleTimes_thenUnlockMultipleTimesToRelease() throws InterruptedException {
+        ReentrantLock reentrantLock = new ReentrantLock(); 
+        try { 
+            reentrantLock.lock(); 
+            reentrantLock.lock();
+            assertEquals(2, reentrantLock.getHoldCount()); 
+            assertEquals(true, reentrantLock.isLocked()); 
+        } finally { 
+            reentrantLock.unlock(); 
+            assertEquals(1, reentrantLock.getHoldCount()); 
+            assertEquals(true, reentrantLock.isLocked());
+            
+            reentrantLock.unlock(); 
+            assertEquals(0, reentrantLock.getHoldCount()); 
+            assertEquals(false, reentrantLock.isLocked());
+        }
+    }
+    
+}
diff --git a/core-java-modules/core-java-io-4/.gitignore b/core-java-modules/core-java-io-4/.gitignore
new file mode 100644
index 0000000000..0c0cd871c5
--- /dev/null
+++ b/core-java-modules/core-java-io-4/.gitignore
@@ -0,0 +1,2 @@
+test-link*
+0.*
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-4/README.md b/core-java-modules/core-java-io-4/README.md
new file mode 100644
index 0000000000..c837e2bffc
--- /dev/null
+++ b/core-java-modules/core-java-io-4/README.md
@@ -0,0 +1,8 @@
+## Core Java IO
+
+This module contains articles about core Java input and output (IO)
+
+### Relevant Articles: 
+
+- [Java File Separator vs File Path Separator](https://www.baeldung.com/java-file-vs-file-path-separator)
+- [[<-- Prev]](/core-java-modules/core-java-io-3)
diff --git a/core-java-modules/core-java-io-4/pom.xml b/core-java-modules/core-java-io-4/pom.xml
new file mode 100644
index 0000000000..ee31b35ba9
--- /dev/null
+++ b/core-java-modules/core-java-io-4/pom.xml
@@ -0,0 +1,52 @@
+
+
+    4.0.0
+    core-java-io-4
+    0.1.0-SNAPSHOT
+    core-java-io-4
+    jar
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+        ../
+    
+
+    
+        
+        
+            commons-io
+            commons-io
+            ${commons-io.version}
+        
+        
+        
+            log4j
+            log4j
+            ${log4j.version}
+        
+         
+            org.slf4j
+            log4j-over-slf4j
+            ${org.slf4j.version}
+        
+        
+        
+            org.assertj
+            assertj-core
+            ${assertj.version}
+            test
+        
+    
+
+    
+    
+
+    
+        3.6.1
+    
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/fileseparator/FilePathSeparatorUnitTest.java b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/fileseparator/FilePathSeparatorUnitTest.java
new file mode 100644
index 0000000000..959aae8aff
--- /dev/null
+++ b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/fileseparator/FilePathSeparatorUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.fileseparator;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.StringJoiner;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+public class FilePathSeparatorUnitTest {
+
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void whenCheckPathSeparator_thenResultIsAsExpectedOnWindows() throws IOException {
+        assertEquals(";", File.pathSeparator);
+        assertEquals(';', File.pathSeparatorChar);
+    }
+    
+    @Test
+    @EnabledOnOs({ OS.LINUX, OS.MAC })
+    public void whenCheckPathSeparator_thenResultIsAsExpected() throws IOException {
+        assertEquals(":", File.pathSeparator);
+        assertEquals(':', File.pathSeparatorChar);
+    }
+    
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void whenBuildPathUsingString_thenResultIsAsExpectedOnWindows() throws IOException {
+        String[] pathNames = { "path1", "path2", "path3" };
+        String path = String.join(File.pathSeparator, pathNames);
+        assertEquals("path1;path2;path3",path);
+    }
+
+    @Test
+    @EnabledOnOs({ OS.LINUX, OS.MAC })
+    public void whenBuildPathUsingString_thenResultIsAsExpected() throws IOException {
+        String[] pathNames = { "path1", "path2", "path3" };
+        String path = String.join(File.pathSeparator, pathNames);
+        assertEquals("path1:path2:path3", path);
+    }
+
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void whenbuildPathUsingStringJoiner_thenResultIsAsExpectedOnWindows() throws IOException {
+        assertEquals("path1;path2", buildPathUsingStringJoiner("path1", "path2"));
+    }
+
+    @Test
+    @EnabledOnOs({ OS.LINUX, OS.MAC })
+    public void whenbuildPathUsingStringJoiner_thenResultIsAsExpected() throws IOException {
+        assertEquals("path1:path2", buildPathUsingStringJoiner("path1", "path2"));
+    }
+    
+    private String buildPathUsingStringJoiner(String path1, String path2) {
+        StringJoiner joiner = new StringJoiner(File.pathSeparator);
+        joiner.add(path1);
+        joiner.add(path2);
+        return joiner.toString();
+    }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-4/src/test/java/com/baeldung/fileseparator/FileSeparatorUnitTest.java b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/fileseparator/FileSeparatorUnitTest.java
new file mode 100644
index 0000000000..f908dcc9bb
--- /dev/null
+++ b/core-java-modules/core-java-io-4/src/test/java/com/baeldung/fileseparator/FileSeparatorUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.fileseparator;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.File;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+public class FileSeparatorUnitTest {
+
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void whenCheckFileSeparator_thenCorrectOnWindows() {
+        assertEquals("\\", File.separator);
+        assertEquals('\\', File.separatorChar);
+        
+        String fileSeparator = FileSystems.getDefault().getSeparator();
+        assertEquals("\\",fileSeparator);
+    }
+    
+    @Test
+    @EnabledOnOs({ OS.LINUX, OS.MAC })
+    public void whenCheckFileSeparator_thenCorrect() {
+        assertEquals("/", File.separator);
+        assertEquals('/', File.separatorChar);
+        
+        String fileSeparator = FileSystems.getDefault().getSeparator();
+        assertEquals("/",fileSeparator);
+    }
+    
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void whenBuildFilePathUsingPathsClass_thenCorrectOnWindows() {
+        Path path = Paths.get("dir1", "dir2");
+        assertEquals("dir1\\dir2", path.toString());
+    }
+
+    @Test
+    @EnabledOnOs({ OS.LINUX, OS.MAC })
+    public void whenBuildFilePathUsingPathsClass_thenCorrect() {
+        Path path = Paths.get("dir1", "dir2");
+        assertEquals("dir1/dir2", path.toString());
+    }
+
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void whenBuildFilePathUsingFileClass_thenOutputIsAsExpectedOnWindows() {
+        File file = new File("file1", "file2");
+        assertEquals("file1\\file2", file.toString());
+    }
+
+    @Test
+    @EnabledOnOs({ OS.LINUX, OS.MAC })
+    public void whenBuildFilePathUsingFileClass_thenOutputIsAsExpected() {
+        File file = new File("file1", "file2");
+        assertEquals("file1/file2", file.toString());
+    }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/constantpool/ConstantPool.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/constantpool/ConstantPool.java
new file mode 100644
index 0000000000..b9aea05272
--- /dev/null
+++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/constantpool/ConstantPool.java
@@ -0,0 +1,8 @@
+package com.baeldung.constantpool;
+
+public class ConstantPool {
+    
+    public void sayHello() {
+        System.out.println("Hello World");
+    }
+}
diff --git a/core-java-modules/core-java-lang-2/pom.xml b/core-java-modules/core-java-lang-2/pom.xml
index 5f2d4ec901..d395e8efb1 100644
--- a/core-java-modules/core-java-lang-2/pom.xml
+++ b/core-java-modules/core-java-lang-2/pom.xml
@@ -69,7 +69,6 @@
         1.19
         3.12.2
         1.9.4
-        3.10
         29.0-jre
     
 
diff --git a/core-java-modules/core-java-lang-math-2/README.md b/core-java-modules/core-java-lang-math-2/README.md
index a98ff863ac..5e1dc5af0e 100644
--- a/core-java-modules/core-java-lang-math-2/README.md
+++ b/core-java-modules/core-java-lang-math-2/README.md
@@ -14,4 +14,4 @@
 - [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging)
 - [Matrix Multiplication in Java](https://www.baeldung.com/java-matrix-multiplication)
 - [Largest Power of 2 That Is Less Than the Given Number with Java](https://www.baeldung.com/java-largest-power-of-2-less-than-number)
-- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math)
+- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math)[[Next -->]](/core-java-modules/core-java-lang-math-3)
diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md
new file mode 100644
index 0000000000..dda3013407
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-3/README.md
@@ -0,0 +1,9 @@
+=========
+
+## Core Java 8 Cookbooks and Examples - Part 3
+
+### Relevant articles:
+
+- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
+- [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string)
+- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
diff --git a/core-java-modules/core-java-lang-math-3/pom.xml b/core-java-modules/core-java-lang-math-3/pom.xml
new file mode 100644
index 0000000000..27c2372ab6
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-3/pom.xml
@@ -0,0 +1,35 @@
+
+
+    4.0.0
+    core-java-lang-math-3
+    0.0.1-SNAPSHOT
+    core-java-lang-math-3
+    
+        com.baeldung.core-java-modules
+        core-java-modules
+        0.0.1-SNAPSHOT
+        ../
+    
+
+    
+        
+            net.objecthunter
+            exp4j
+            0.4.8
+        
+
+        
+            com.fathzer
+            javaluator
+            3.0.3
+        
+    
+
+
+    
+
+    
+
+
diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/evaluate/EvalauteMathExpressionsUnitTest.java b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/evaluate/EvalauteMathExpressionsUnitTest.java
new file mode 100644
index 0000000000..a251e8d545
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/evaluate/EvalauteMathExpressionsUnitTest.java
@@ -0,0 +1,91 @@
+package com.baeldung.math.evaluate;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import com.fathzer.soft.javaluator.DoubleEvaluator;
+import com.fathzer.soft.javaluator.StaticVariableSet;
+
+import net.objecthunter.exp4j.Expression;
+import net.objecthunter.exp4j.ExpressionBuilder;
+
+public class EvalauteMathExpressionsUnitTest {
+
+    @Test
+    public void givenSimpleExpression_whenCallEvaluateMethod_thenSuccess() {
+        Expression expression = new ExpressionBuilder("3+2").build();
+        double result = expression.evaluate();
+        Assertions.assertEquals(5, result);
+    }
+
+    @Test
+    public void givenTwoVariables_whenCallEvaluateMethod_thenSuccess() {
+        Expression expression = new ExpressionBuilder("3x+2y").variables("x", "y")
+          .build()
+          .setVariable("x", 2)
+          .setVariable("y", 3);
+        double result = expression.evaluate();
+        Assertions.assertEquals(12, result);
+    }
+    
+    @Test
+    public void givenMathFunctions_whenCallEvaluateMethod_thenSuccess() {
+        Expression expression = new ExpressionBuilder("sin(x)*sin(x)+cos(x)*cos(x)").variables("x")
+          .build()
+          .setVariable("x", 0.5);
+        double result = expression.evaluate();
+        Assertions.assertEquals(1, result);
+    }
+
+    @Test
+    public void givenExpression_whenCallEvaluateMethod_thenSuccess() {
+        String expression = "3+2";
+        DoubleEvaluator eval = new DoubleEvaluator();
+        Double result = eval.evaluate(expression);
+        Assertions.assertEquals(5, result);
+    } 
+    
+    @Test
+    public void givenVariables_whenCallEvaluateMethod_thenSuccess() {
+        String expression = "3*x+2*y";
+        DoubleEvaluator eval = new DoubleEvaluator();
+        StaticVariableSet variables = new StaticVariableSet();
+        variables.set("x", 2.0);
+        variables.set("y", 3.0);
+        Double result = eval.evaluate(expression, variables);
+        Assertions.assertEquals(12, result);
+    }
+
+    @Test
+    public void givenMathFunction_whenCallEvaluateMethod_thenSuccess() {
+        String expression = "sin(x)*sin(x)+cos(x)*cos(x)";
+        DoubleEvaluator eval = new DoubleEvaluator();
+        StaticVariableSet variables = new StaticVariableSet();
+        variables.set("x", 0.5);
+        Double result = eval.evaluate(expression, variables);
+        Assertions.assertEquals(1, result);
+    }
+
+    @Test
+    public void givenJavaScriptingApiAndSimpleExpression_whenCallEvalMethod_thenSuccess() throws ScriptException {
+        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
+        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
+        String expression = "3+2";
+        Integer result = (Integer) scriptEngine.eval(expression);
+        Assertions.assertEquals(5, result);
+    }
+    
+    @Test
+    public void givenJavaScriptingApi_whenCallEvalMethod_thenSuccess() throws ScriptException {
+        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
+        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
+        String expression = "x=2; y=3; 3*x+2*y;";
+        Double result = (Double) scriptEngine.eval(expression);
+        Assertions.assertEquals(12, result);
+    }
+    
+}
diff --git a/core-java-modules/core-java-lang-oop-generics/pom.xml b/core-java-modules/core-java-lang-oop-generics/pom.xml
index 65a0aeac59..1a538edac9 100644
--- a/core-java-modules/core-java-lang-oop-generics/pom.xml
+++ b/core-java-modules/core-java-lang-oop-generics/pom.xml
@@ -13,4 +13,32 @@
     core-java-lang-oop-generics
     jar
 
+    
+        
+            
+                src/main/resources
+                true
+            
+        
+
+        
+            
+                org.apache.maven.plugins
+                maven-compiler-plugin
+                ${maven-compiler-plugin.version}
+                
+                    ${maven.compiler.source}
+                    ${maven.compiler.target}
+                    
+                        
+                    
+                
+            
+        
+    
+    
+        1.8
+        1.8
+    
+
 
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/uncheckedconversion/UncheckedConversion.java b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/uncheckedconversion/UncheckedConversion.java
new file mode 100644
index 0000000000..9ad4a92077
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-generics/src/main/java/com/baeldung/uncheckedconversion/UncheckedConversion.java
@@ -0,0 +1,45 @@
+package com.baeldung.uncheckedconversion;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+public class UncheckedConversion {
+    public static List getRawList() {
+        List result = new ArrayList();
+        result.add("I am the 1st String.");
+        result.add("I am the 2nd String.");
+        result.add("I am the 3rd String.");
+        return result;
+    }
+
+    public static List getRawListWithMixedTypes() {
+        List result = new ArrayList();
+        result.add("I am the 1st String.");
+        result.add("I am the 2nd String.");
+        result.add("I am the 3rd String.");
+        result.add(new Date());
+        return result;
+    }
+
+    public static  List castList(Class extends T> clazz, Collection> rawCollection) {
+        List result = new ArrayList<>(rawCollection.size());
+        for (Object o : rawCollection) {
+            try {
+                result.add(clazz.cast(o));
+            } catch (ClassCastException e) {
+                // log the exception or other error handling
+            }
+        }
+        return result;
+    }
+
+    public static  List castList2(Class extends T> clazz, Collection> rawCollection) throws ClassCastException {
+        List result = new ArrayList<>(rawCollection.size());
+        for (Object o : rawCollection) {
+            result.add(clazz.cast(o));
+        }
+        return result;
+    }
+}
diff --git a/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/uncheckedconversion/UncheckedConversionUnitTest.java b/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/uncheckedconversion/UncheckedConversionUnitTest.java
new file mode 100644
index 0000000000..37b9a878d3
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-generics/src/test/java/com/baeldung/uncheckedconversion/UncheckedConversionUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.uncheckedconversion;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+public class UncheckedConversionUnitTest {
+
+    @Test
+    public void givenRawList_whenAssignToTypedList_shouldHaveCompilerWarning() {
+        List fromRawList = UncheckedConversion.getRawList();
+        Assert.assertEquals(3, fromRawList.size());
+        Assert.assertEquals("I am the 1st String.", fromRawList.get(0));
+    }
+
+    @Test(expected = ClassCastException.class)
+    public void givenRawList_whenListHasMixedType_shouldThrowClassCastException() {
+        List fromRawList = UncheckedConversion.getRawListWithMixedTypes();
+        Assert.assertEquals(4, fromRawList.size());
+        Assert.assertFalse(fromRawList.get(3).endsWith("String."));
+    }
+
+    @Test
+    public void givenRawList_whenAssignToTypedListAfterCallingCastList_shouldOnlyHaveElementsWithExpectedType() {
+        List rawList = UncheckedConversion.getRawListWithMixedTypes();
+        List strList = UncheckedConversion.castList(String.class, rawList);
+        Assert.assertEquals(4, rawList.size());
+        Assert.assertEquals("One element with the wrong type has been filtered out.", 3, strList.size());
+        Assert.assertTrue(strList.stream().allMatch(el -> el.endsWith("String.")));
+    }
+
+    @Test(expected = ClassCastException.class)
+    public void givenRawListWithWrongType_whenAssignToTypedListAfterCallingCastList2_shouldThrowException() {
+        List rawList = UncheckedConversion.getRawListWithMixedTypes();
+        UncheckedConversion.castList2(String.class, rawList);
+    }
+
+}
diff --git a/core-java-modules/core-java-os/src/main/java/com/baeldung/java9/process/OutputStreamExample.java b/core-java-modules/core-java-os/src/main/java/com/baeldung/java9/process/OutputStreamExample.java
index 37378f9d6c..fc6d907bfd 100644
--- a/core-java-modules/core-java-os/src/main/java/com/baeldung/java9/process/OutputStreamExample.java
+++ b/core-java-modules/core-java-os/src/main/java/com/baeldung/java9/process/OutputStreamExample.java
@@ -6,8 +6,7 @@ import java.util.logging.Logger;
 public class OutputStreamExample {
 
     public static void main(String[] args) {
-        Logger log = Logger.getLogger(OutputStreamExample.class.getName());
-        log.log(Level.INFO, Integer.toString(sum(1,2)));
+        System.out.println(sum(1,2));
     }
 
     public static int sum(int a, int b) {
diff --git a/core-java-modules/core-java-os/src/test/java/com/baeldung/java9/process/ProcessUnderstandingUnitTest.java b/core-java-modules/core-java-os/src/test/java/com/baeldung/java9/process/ProcessUnderstandingUnitTest.java
index c8932efb4f..69b65852cc 100644
--- a/core-java-modules/core-java-os/src/test/java/com/baeldung/java9/process/ProcessUnderstandingUnitTest.java
+++ b/core-java-modules/core-java-os/src/test/java/com/baeldung/java9/process/ProcessUnderstandingUnitTest.java
@@ -5,10 +5,10 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.jupiter.api.Assertions.*;
 
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.lang.String;
-import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.lang.Integer;
 
@@ -88,4 +88,21 @@ class ProcessUnderstandingUnitTest {
             .filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000))
             .count()) > 0);
     }
+
+    @Test
+    public void givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3() throws IOException {
+
+        Runtime.getRuntime()
+                .exec("javac -cp src src/main/java/com/baeldung/java9/process/OutputStreamExample.java"
+                        .replace("/", File.separator));
+
+        Process process = Runtime.getRuntime()
+                .exec("java -cp src/main/java com.baeldung.java9.process.OutputStreamExample"
+                .replace("/", File.separator));
+
+        BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
+        int value = Integer.parseInt(output.readLine());
+
+        assertEquals(3, value);
+    }
 }
diff --git a/core-java-modules/core-java-os/src/test/java/com/baeldung/screenshot/ScreenshotUnitTest.java b/core-java-modules/core-java-os/src/test/java/com/baeldung/screenshot/ScreenshotUnitTest.java
index ac358b4e71..bf271ef2cc 100644
--- a/core-java-modules/core-java-os/src/test/java/com/baeldung/screenshot/ScreenshotUnitTest.java
+++ b/core-java-modules/core-java-os/src/test/java/com/baeldung/screenshot/ScreenshotUnitTest.java
@@ -9,11 +9,13 @@ import java.awt.Robot;
 import java.awt.Toolkit;
 import java.awt.image.BufferedImage;
 import java.io.File;
+
+import org.junit.Ignore;
 import org.junit.Test;
-import org.junit.jupiter.api.Disabled;
 
 import static org.junit.Assert.assertTrue;
 
+@Ignore
 public class ScreenshotUnitTest {
 
     @Test
@@ -43,7 +45,6 @@ public class ScreenshotUnitTest {
 
     // This methods needs a component as a parameter and can only be run from an application with a GUI
     @Test
-    @Disabled
     public void givenComponent_whenTakeScreenshot_thenSaveToFile(Component component) throws Exception {
         Rectangle componentRect = component.getBounds();
         BufferedImage bufferedImage = new BufferedImage(componentRect.width, componentRect.height, BufferedImage.TYPE_INT_ARGB);
diff --git a/core-java-modules/core-java-string-algorithms-2/pom.xml b/core-java-modules/core-java-string-algorithms-2/pom.xml
index a635cd8022..2a84cebb4c 100644
--- a/core-java-modules/core-java-string-algorithms-2/pom.xml
+++ b/core-java-modules/core-java-string-algorithms-2/pom.xml
@@ -61,7 +61,6 @@
     
 
     
-        3.8.1
         3.6.1
         1.2
     
diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml
index 2725ba84c6..610956588e 100644
--- a/core-java-modules/core-java-string-algorithms-3/pom.xml
+++ b/core-java-modules/core-java-string-algorithms-3/pom.xml
@@ -59,7 +59,6 @@
     
 
     
-        3.8.1
         3.6.1
         28.1-jre
     
diff --git a/core-java-modules/core-java-string-algorithms/pom.xml b/core-java-modules/core-java-string-algorithms/pom.xml
index 85879d74e2..6ba9ae7bb3 100644
--- a/core-java-modules/core-java-string-algorithms/pom.xml
+++ b/core-java-modules/core-java-string-algorithms/pom.xml
@@ -65,7 +65,6 @@
     
 
     
-        3.8.1
         27.0.1-jre
         0.4.0
         3.6.1
diff --git a/core-java-modules/core-java-string-operations-2/pom.xml b/core-java-modules/core-java-string-operations-2/pom.xml
index db32bf97a1..5865d9a776 100644
--- a/core-java-modules/core-java-string-operations-2/pom.xml
+++ b/core-java-modules/core-java-string-operations-2/pom.xml
@@ -112,7 +112,6 @@
     
         3.6.1
         2.0.0.Final
-        3.8.1
         28.2-jre
         6.0.2.Final
         3.0.0
diff --git a/core-java-modules/core-java-string-operations/pom.xml b/core-java-modules/core-java-string-operations/pom.xml
index c5791e929e..9632988392 100644
--- a/core-java-modules/core-java-string-operations/pom.xml
+++ b/core-java-modules/core-java-string-operations/pom.xml
@@ -60,7 +60,6 @@
     
 
     
-        3.9
         3.6.1
         1.10
     
diff --git a/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java b/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java
index 1611a3002f..52dc9ba1c6 100644
--- a/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java
+++ b/core-java-modules/core-java-time-measurements/src/test/java/com/baeldung/time/LocalDateTimeUnitTest.java
@@ -18,15 +18,6 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic;
 @PrepareForTest({ LocalDateTime.class })
 public class LocalDateTimeUnitTest {
 
-    @Test
-    public void givenLocalDateTimeMock_whenNow_thenGetFixedLocalDateTime() {
-        Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
-        String dateTimeExpected = "2014-12-22T10:15:30";
-        LocalDateTime now = LocalDateTime.now(clock);
-
-        assertThat(now).isEqualTo(dateTimeExpected);
-    }
-
     @Test
     public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
         Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml
index 0a9e818156..2d342c4216 100644
--- a/core-java-modules/pom.xml
+++ b/core-java-modules/pom.xml
@@ -47,6 +47,7 @@
         core-java-concurrency-advanced
         core-java-concurrency-advanced-2
         core-java-concurrency-advanced-3
+        core-java-concurrency-advanced-4
         core-java-concurrency-basic
         core-java-concurrency-basic-2
         core-java-concurrency-collections
@@ -67,6 +68,7 @@
         core-java-io
         core-java-io-2
         core-java-io-3
+		core-java-io-4
         core-java-io-apis
         core-java-io-conversions
         core-java-io-conversions-2
@@ -82,6 +84,7 @@
         core-java-lang-3
         core-java-lang-math
         core-java-lang-math-2
+        core-java-lang-math-3
         core-java-lang-oop-constructors
         core-java-lang-oop-patterns
         core-java-lang-oop-generics
diff --git a/guest/core-kotlin/README.md b/guest/core-kotlin/README.md
new file mode 100644
index 0000000000..c211773f27
--- /dev/null
+++ b/guest/core-kotlin/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Kotlin vs Java](https://www.baeldung.com/kotlin/kotlin-vs-java)
diff --git a/jackson-modules/jackson-conversions-2/README.md b/jackson-modules/jackson-conversions-2/README.md
index 71c5578525..9986fe75b5 100644
--- a/jackson-modules/jackson-conversions-2/README.md
+++ b/jackson-modules/jackson-conversions-2/README.md
@@ -9,4 +9,5 @@ This module contains articles about Jackson conversions.
 - [Converting JSON to CSV in Java](https://www.baeldung.com/java-converting-json-to-csv)
 - [How to Process YAML with Jackson](https://www.baeldung.com/jackson-yaml)
 - [Jackson Streaming API](https://www.baeldung.com/jackson-streaming-api)
+- [Jackson: java.util.LinkedHashMap cannot be cast to X](https://www.baeldung.com/jackson-linkedhashmap-cannot-be-cast)
 - More articles: [[<-- prev]](../jackson-conversions)
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/tocollection/Book.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/tocollection/Book.java
new file mode 100644
index 0000000000..e9cb1343e9
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/tocollection/Book.java
@@ -0,0 +1,70 @@
+package com.baeldung.jackson.tocollection;
+
+
+import java.util.Objects;
+
+public class Book {
+    private Integer bookId;
+    private String title;
+    private String author;
+
+    public Book() {}
+
+    public Book(Integer bookId, String title, String author) {
+        this.bookId = bookId;
+        this.title = title;
+        this.author = author;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof Book)) {
+            return false;
+        }
+
+        Book book = (Book) o;
+
+        if (!Objects.equals(bookId, book.bookId)) {
+            return false;
+        }
+        if (!Objects.equals(title, book.title)) {
+            return false;
+        }
+        return Objects.equals(author, book.author);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = bookId != null ? bookId.hashCode() : 0;
+        result = 31 * result + (title != null ? title.hashCode() : 0);
+        result = 31 * result + (author != null ? author.hashCode() : 0);
+        return result;
+    }
+
+    public Integer getBookId() {
+        return bookId;
+    }
+
+    public void setBookId(Integer bookId) {
+        this.bookId = bookId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getAuthor() {
+        return author;
+    }
+
+    public void setAuthor(String author) {
+        this.author = author;
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/tocollection/JsonToCollectionUtil.java b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/tocollection/JsonToCollectionUtil.java
new file mode 100644
index 0000000000..83e2de2c3b
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/java/com/baeldung/jackson/tocollection/JsonToCollectionUtil.java
@@ -0,0 +1,24 @@
+package com.baeldung.jackson.tocollection;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JsonToCollectionUtil {
+
+    private JsonToCollectionUtil(){}
+
+    public static  List jsonArrayToList(String json, Class elementClass) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, elementClass);
+        return objectMapper.readValue(json, listType);
+    }
+
+    public static  List jsonArrayToList2(String json, Class elementClass) throws IOException {
+        return new ObjectMapper().readValue(json, new TypeReference>() {});
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json
new file mode 100644
index 0000000000..6daf426736
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.json
@@ -0,0 +1,13 @@
+[ {
+    "bookId" : 1,
+    "title" : "A Song of Ice and Fire",
+    "author" : "George R. R. Martin"
+}, {
+    "bookId" : 2,
+    "title" : "The Hitchhiker's Guide to the Galaxy",
+    "author" : "Douglas Adams"
+}, {
+    "bookId" : 3,
+    "title" : "Hackers And Painters",
+    "author" : "Paul Graham"
+} ]
diff --git a/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml
new file mode 100644
index 0000000000..b2f951315b
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/main/resources/to-java-collection/books.xml
@@ -0,0 +1,17 @@
+
+    - 
+        1
+        A Song of Ice and Fire
+        George R. R. Martin
+    +
- 
+        2
+        The Hitchhiker's Guide to the Galaxy
+        Douglas Adams
+    +
- 
+        3
+        Hackers And Painters
+        Paul Graham
+    +
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java
new file mode 100644
index 0000000000..8ddcc2d69a
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/tocollection/DeserializeToJavaCollectionUnitTest.java
@@ -0,0 +1,130 @@
+package com.baeldung.jackson.tocollection;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+public class DeserializeToJavaCollectionUnitTest {
+    private ObjectMapper objectMapper;
+    private XmlMapper xmlMapper;
+    private List expectedBookList;
+
+
+    @BeforeEach
+    void setup() {
+        objectMapper = new ObjectMapper();
+        xmlMapper = new XmlMapper();
+        expectedBookList = Lists.newArrayList(
+          new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
+          new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
+          new Book(3, "Hackers And Painters", "Paul Graham"));
+    }
+
+    private String readFile(String path) {
+        try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
+            return scanner.useDelimiter("\\A").next();
+        }
+    }
+
+    /*====================
+     * JSON tests
+     *====================
+     */
+    @Test
+    void givenJsonString_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
+        String jsonString = readFile("/to-java-collection/books.json");
+        List bookList = objectMapper.readValue(jsonString, ArrayList.class);
+        assertThat(bookList).size().isEqualTo(3);
+        assertThatExceptionOfType(ClassCastException.class)
+          .isThrownBy(() -> bookList.get(0).getBookId())
+          .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
+    }
+
+    @Test
+    void givenJsonString_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
+        String jsonString = readFile("/to-java-collection/books.json");
+        List bookList = objectMapper.readValue(jsonString, new TypeReference
>() {});
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+
+    @Test
+    void givenJsonString_whenDeserializingWithJavaType_thenGetExpectedList() throws JsonProcessingException {
+        String jsonString = readFile("/to-java-collection/books.json");
+        CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class);
+        List bookList = objectMapper.readValue(jsonString, listType);
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+
+    @Test
+    void givenJsonString_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
+        String jsonString = readFile("/to-java-collection/books.json");
+        JsonNode jsonNode = objectMapper.readTree(jsonString);
+        List bookList = objectMapper.convertValue(jsonNode, new TypeReference>() {});
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+
+    @Test
+    void givenJsonString_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
+        String jsonString = readFile("/to-java-collection/books.json");
+        JsonNode jsonNode = objectMapper.readTree(jsonString);
+        List bookList = objectMapper.convertValue(jsonNode, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+
+    /*====================
+     * XML tests
+     *====================
+     */
+    @Test
+    void givenXml_whenDeserializingToList_thenThrowingClassCastException() throws JsonProcessingException {
+        String xml = readFile("/to-java-collection/books.xml");
+        List bookList = xmlMapper.readValue(xml, ArrayList.class);
+        assertThat(bookList).size().isEqualTo(3);
+        assertThatExceptionOfType(ClassCastException.class)
+          .isThrownBy(() -> bookList.get(0).getBookId())
+          .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
+    }
+
+    @Test
+    void givenXml_whenDeserializingWithTypeReference_thenGetExpectedList() throws JsonProcessingException {
+        String xml = readFile("/to-java-collection/books.xml");
+        List bookList = xmlMapper.readValue(xml, new TypeReference>() {});
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+
+    @Test
+    void givenXml_whenDeserializingWithConvertValueAndTypeReference_thenGetExpectedList() throws JsonProcessingException {
+        String xml = readFile("/to-java-collection/books.xml");
+        List node = xmlMapper.readValue(xml, List.class);
+        List bookList = xmlMapper.convertValue(node, new TypeReference>() {});
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+
+    @Test
+    void givenXml_whenDeserializingWithConvertValueAndJavaType_thenGetExpectedList() throws JsonProcessingException {
+        String xml = readFile("/to-java-collection/books.xml");
+        List node = xmlMapper.readValue(xml, List.class);
+        List bookList = xmlMapper.convertValue(node, objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, Book.class));
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+}
diff --git a/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/tocollection/JsonToCollectionUtilUnitTest.java b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/tocollection/JsonToCollectionUtilUnitTest.java
new file mode 100644
index 0000000000..a08e48e069
--- /dev/null
+++ b/jackson-modules/jackson-conversions-2/src/test/java/com/baeldung/jackson/tocollection/JsonToCollectionUtilUnitTest.java
@@ -0,0 +1,51 @@
+package com.baeldung.jackson.tocollection;
+
+import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Scanner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+class JsonToCollectionUtilUnitTest {
+
+    private List expectedBookList;
+
+
+    @BeforeEach
+    void setup() {
+        expectedBookList = Lists.newArrayList(
+          new Book(1, "A Song of Ice and Fire", "George R. R. Martin"),
+          new Book(2, "The Hitchhiker's Guide to the Galaxy", "Douglas Adams"),
+          new Book(3, "Hackers And Painters", "Paul Graham"));
+    }
+
+    private String readFile(String path) {
+        try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path), "UTF-8")) {
+            return scanner.useDelimiter("\\A").next();
+        }
+    }
+
+    @Test
+    void givenJsonString_whenCalljsonArrayToList_thenGetExpectedList() throws IOException {
+        String jsonString = readFile("/to-java-collection/books.json");
+        List bookList = JsonToCollectionUtil.jsonArrayToList(jsonString, Book.class);
+        assertThat(bookList.get(0)).isInstanceOf(Book.class);
+        assertThat(bookList).isEqualTo(expectedBookList);
+    }
+
+    @Test
+    void givenJsonString_whenCalljsonArrayToList2_thenGetException() throws IOException {
+        String jsonString = readFile("/to-java-collection/books.json");
+        List bookList = JsonToCollectionUtil.jsonArrayToList2(jsonString, Book.class);
+        assertThat(bookList).size().isEqualTo(3);
+        assertThatExceptionOfType(ClassCastException.class)
+          .isThrownBy(() -> bookList.get(0).getBookId())
+          .withMessageMatching(".*java.util.LinkedHashMap cannot be cast to .*com.baeldung.jackson.tocollection.Book.*");
+    }
+
+}
diff --git a/java-collections-maps-3/README.md b/java-collections-maps-3/README.md
index 4da8547824..39ac8575fa 100644
--- a/java-collections-maps-3/README.md
+++ b/java-collections-maps-3/README.md
@@ -1,3 +1,4 @@
 ### Relevant Articles:
 
 - [Java Map With Case-Insensitive Keys](https://www.baeldung.com/java-map-with-case-insensitive-keys)
+- [Using a Byte Array as Map Key in Java](https://www.baeldung.com/java-map-key-byte-array)
diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/entry/Book.java b/java-collections-maps-3/src/main/java/com/baeldung/map/entry/Book.java
new file mode 100644
index 0000000000..7e47e22908
--- /dev/null
+++ b/java-collections-maps-3/src/main/java/com/baeldung/map/entry/Book.java
@@ -0,0 +1,35 @@
+package com.baeldung.map.entry;
+
+public class Book {
+    private String title;
+    private String author;
+
+    public Book(String title, String author) {
+        this.title = title;
+        this.author = author;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getAuthor() {
+        return author;
+    }
+
+    public void setAuthor(String author) {
+        this.author = author;
+    }
+
+    @Override
+    public String toString() {
+        return "Book{" +
+                "title='" + title + '\'' +
+                ", author='" + author + '\'' +
+                '}';
+    }
+}
diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryEfficiencyExample.java b/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryEfficiencyExample.java
new file mode 100644
index 0000000000..d64bcb38df
--- /dev/null
+++ b/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryEfficiencyExample.java
@@ -0,0 +1,34 @@
+package com.baeldung.map.entry;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MapEntryEfficiencyExample {
+
+    public static void main(String[] args) {
+        MapEntryEfficiencyExample mapEntryEfficiencyExample = new MapEntryEfficiencyExample();
+        Map map = new HashMap<>();
+
+        map.put("Robert C. Martin", "Clean Code");
+        map.put("Joshua Bloch", "Effective Java");
+
+        System.out.println("Iterating Using Map.KeySet - 2 operations");
+        mapEntryEfficiencyExample.usingKeySet(map);
+
+        System.out.println("Iterating Using Map.Entry - 1 operation");
+        mapEntryEfficiencyExample.usingEntrySet(map);
+
+    }
+
+    public void usingKeySet(Map bookMap) {
+        for (String key : bookMap.keySet()) {
+            System.out.println("key: " + key + " value: " + bookMap.get(key));
+        }
+    }
+
+    public void usingEntrySet(Map bookMap) {
+        for (Map.Entry book: bookMap.entrySet()) {
+            System.out.println("key: " + book.getKey() + " value: " + book.getValue());
+        }
+    }
+}
diff --git a/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryTupleExample.java b/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryTupleExample.java
new file mode 100644
index 0000000000..edcbd263fe
--- /dev/null
+++ b/java-collections-maps-3/src/main/java/com/baeldung/map/entry/MapEntryTupleExample.java
@@ -0,0 +1,25 @@
+package com.baeldung.map.entry;
+
+import java.util.*;
+
+public class MapEntryTupleExample {
+
+    public static void main(String[] args) {
+        Map.Entry tuple1;
+        Map.Entry tuple2;
+        Map.Entry tuple3;
+
+        tuple1 = new AbstractMap.SimpleEntry<>("9780134685991", new Book("Effective Java 3d Edition", "Joshua Bloch"));
+        tuple2 = new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin"));
+        tuple3 = new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin"));
+
+        List> orderedTuples = new ArrayList<>();
+        orderedTuples.add(tuple1);
+        orderedTuples.add(tuple2);
+        orderedTuples.add(tuple3);
+
+        for (Map.Entry tuple : orderedTuples) {
+            System.out.println("key: " + tuple.getKey() + " value: " + tuple.getValue());
+        }
+    }
+}
diff --git a/java-collections-maps-3/src/test/java/com/baeldung/map/entry/MapEntryUnitTest.java b/java-collections-maps-3/src/test/java/com/baeldung/map/entry/MapEntryUnitTest.java
new file mode 100644
index 0000000000..7340558023
--- /dev/null
+++ b/java-collections-maps-3/src/test/java/com/baeldung/map/entry/MapEntryUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.map.entry;
+
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+
+public class MapEntryUnitTest {
+
+    @Test
+    public void givenSimpleEntryList_whenAddDuplicateKey_thenDoesNotOverwriteExistingKey() {
+        List> orderedTuples = new ArrayList<>();
+        orderedTuples.add(new AbstractMap.SimpleEntry<>("9780134685991", new Book("Effective Java 3d Edition", "Joshua Bloch")));
+        orderedTuples.add(new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin")));
+        orderedTuples.add(new AbstractMap.SimpleEntry<>("9780132350884", new Book("Clean Code", "Robert C Martin")));
+
+        assertEquals(3, orderedTuples.size());
+        assertEquals("9780134685991", orderedTuples.get(0).getKey());
+        assertEquals("9780132350884", orderedTuples.get(1).getKey());
+        assertEquals("9780132350884", orderedTuples.get(2).getKey());
+    }
+
+    @Test
+    public void givenRegularMap_whenAddDuplicateKey_thenOverwritesExistingKey() {
+        Map entries = new HashMap<>();
+        entries.put("9780134685991", new Book("Effective Java 3d Edition", "Joshua Bloch"));
+        entries.put("9780132350884", new Book("Clean Code", "Robert C Martin"));
+        entries.put("9780132350884", new Book("Clean Code", "Robert C Martin"));
+
+        assertEquals(2, entries.size());
+    }
+}
diff --git a/java-numbers-3/pom.xml b/java-numbers-3/pom.xml
index 495618885a..62225a898f 100644
--- a/java-numbers-3/pom.xml
+++ b/java-numbers-3/pom.xml
@@ -27,7 +27,7 @@
         
             org.apache.commons
             commons-lang3
-            ${commons.version}
+            ${commons-lang3.version}
             test
         
         
@@ -51,7 +51,6 @@
     
         2.6.0
         0.10.2
-        3.9
         3.6.1
     
 
diff --git a/java-numbers-4/README.md b/java-numbers-4/README.md
index 7db25b283c..cdd53692e0 100644
--- a/java-numbers-4/README.md
+++ b/java-numbers-4/README.md
@@ -2,3 +2,4 @@
 
 - [Probability in Java](https://www.baeldung.com/java-probability)
 - [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff)
+- [Determine if an Integer’s Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer)
diff --git a/java-numbers-4/pom.xml b/java-numbers-4/pom.xml
index e1722fb039..f4b0e23bd7 100644
--- a/java-numbers-4/pom.xml
+++ b/java-numbers-4/pom.xml
@@ -22,7 +22,7 @@
         
             org.apache.commons
             commons-lang3
-            ${commons.version}
+            ${commons-lang3.version}
             test
         
         
@@ -45,7 +45,6 @@
 
     
         0.10.2
-        3.9
         3.6.1
     
 
diff --git a/javax-servlets/pom.xml b/javax-servlets/pom.xml
index 5fc9fef24a..700b823a6e 100644
--- a/javax-servlets/pom.xml
+++ b/javax-servlets/pom.xml
@@ -59,7 +59,6 @@
         4.5.3
         2.8.2
         3.9.1
-        1.3.3
         4.0.1
     
diff --git a/jhipster/jhipster-microservice/car-app/pom.xml b/jhipster/jhipster-microservice/car-app/pom.xml
index c53ea8358e..477192438f 100644
--- a/jhipster/jhipster-microservice/car-app/pom.xml
+++ b/jhipster/jhipster-microservice/car-app/pom.xml
@@ -21,8 +21,6 @@
         -Djava.security.egd=file:/dev/./urandom -Xmx256m
         3.6.2
         2.0.0
-        2.5
-        3.5
         0.4.13
         1.2
         5.2.8.Final
@@ -267,7 +265,7 @@
         
             org.apache.commons
             commons-lang3
-            ${commons-lang.version}
+            ${commons-lang3.version}
         
         
             org.assertj
diff --git a/jhipster/jhipster-microservice/dealer-app/pom.xml b/jhipster/jhipster-microservice/dealer-app/pom.xml
index a0bcc73e31..59df7d3b69 100644
--- a/jhipster/jhipster-microservice/dealer-app/pom.xml
+++ b/jhipster/jhipster-microservice/dealer-app/pom.xml
@@ -20,8 +20,6 @@
         -Djava.security.egd=file:/dev/./urandom -Xmx256m
         3.6.2
         2.0.0
-        2.5
-        3.5
         0.4.13
         1.2
         5.2.8.Final
@@ -266,7 +264,7 @@
         
             org.apache.commons
             commons-lang3
-            ${commons-lang.version}
+            ${commons-lang3.version}
         
         
             org.assertj
diff --git a/jhipster/jhipster-microservice/gateway-app/pom.xml b/jhipster/jhipster-microservice/gateway-app/pom.xml
index c6dcbb3f3e..a50c2bbdd1 100644
--- a/jhipster/jhipster-microservice/gateway-app/pom.xml
+++ b/jhipster/jhipster-microservice/gateway-app/pom.xml
@@ -22,8 +22,6 @@
         2.0.0
         3.6.0
         1.10
-        2.5
-        3.5
         0.4.13
         1.3
         1.2
@@ -299,7 +297,7 @@
         
             org.apache.commons
             commons-lang3
-            ${commons-lang.version}
+            ${commons-lang3.version}
         
         
             org.assertj
diff --git a/jhipster/jhipster-monolithic/pom.xml b/jhipster/jhipster-monolithic/pom.xml
index 04f790faf5..97f2b85b2f 100644
--- a/jhipster/jhipster-monolithic/pom.xml
+++ b/jhipster/jhipster-monolithic/pom.xml
@@ -171,7 +171,7 @@
         
             org.apache.commons
             commons-lang3
-            ${commons-lang.version}
+            ${commons-lang3.version}
         
         
             org.assertj
@@ -887,8 +887,6 @@
         -Djava.security.egd=file:/dev/./urandom -Xmx256m
         3.6.2
         2.0.0
-        2.5
-        3.5
         0.4.13
         1.3
         2.2.1
diff --git a/json-2/pom.xml b/json-2/pom.xml
index 0bdede3b1a..e27d1c83f6 100644
--- a/json-2/pom.xml
+++ b/json-2/pom.xml
@@ -114,7 +114,6 @@
         0.9.23
         3.11.1
         1.9.2
-        3.9
     
     
     	
diff --git a/libraries-6/pom.xml b/libraries-6/pom.xml
index 0f129c27c9..caaebbb922 100644
--- a/libraries-6/pom.xml
+++ b/libraries-6/pom.xml
@@ -94,7 +94,7 @@
         
             commons-io
             commons-io
-            ${commonsio.version}
+            ${commons-io.version}
             test
         
         
@@ -157,7 +157,6 @@
         1.15
         3.6
         3.6.2
-        2.6
         RELEASE
         3.0
         1.8.1
diff --git a/libraries-apache-commons/pom.xml b/libraries-apache-commons/pom.xml
index 74adddabcf..08dddac880 100644
--- a/libraries-apache-commons/pom.xml
+++ b/libraries-apache-commons/pom.xml
@@ -65,7 +65,6 @@
     
 
     
-        3.6
         1.1
         1.9.3
         1.2
diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml
index 95d771ce4e..5adb490e96 100644
--- a/libraries-data/pom.xml
+++ b/libraries-data/pom.xml
@@ -80,7 +80,7 @@
         
             commons-io
             commons-io
-            ${commons.io.version}
+            ${commons-io.version}
             provided
         
         
@@ -165,7 +165,6 @@
     
         2.3
         1.2
-        2.1
         3.0.1
         1.2.2
         1.0.0
diff --git a/maven-modules/versions-maven-plugin/original/pom.xml b/maven-modules/versions-maven-plugin/original/pom.xml
index f705dae5c5..c36a5913c2 100644
--- a/maven-modules/versions-maven-plugin/original/pom.xml
+++ b/maven-modules/versions-maven-plugin/original/pom.xml
@@ -74,7 +74,6 @@
         1.15
         2.3
         4.0
-        3.0
         1.9.1
         2.7
     
diff --git a/maven-modules/versions-maven-plugin/pom.xml b/maven-modules/versions-maven-plugin/pom.xml
index 3a9134ff40..ff49811430 100644
--- a/maven-modules/versions-maven-plugin/pom.xml
+++ b/maven-modules/versions-maven-plugin/pom.xml
@@ -74,8 +74,8 @@
         2.3
         2.7
         1.9.1
-        3.0
         4.0
+        3.11
     
 
 
\ No newline at end of file
diff --git a/parent-java/pom.xml b/parent-java/pom.xml
index d251adcdd3..9170f45bbe 100644
--- a/parent-java/pom.xml
+++ b/parent-java/pom.xml
@@ -27,7 +27,7 @@
         
             commons-io
             commons-io
-            ${commons.io.version}
+            ${commons-io.version}
         
         
             org.openjdk.jmh
@@ -43,7 +43,6 @@
 
     
         29.0-jre
-        2.6
         1.19
         2.3.7
         2.2
diff --git a/patterns/clean-architecture/README.md b/patterns/clean-architecture/README.md
new file mode 100644
index 0000000000..aad8608447
--- /dev/null
+++ b/patterns/clean-architecture/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Clean Architecture with Spring Boot](https://www.baeldung.com/spring-boot-clean-architecture)
diff --git a/patterns/clean-architecture/pom.xml b/patterns/clean-architecture/pom.xml
new file mode 100644
index 0000000000..6e7de78751
--- /dev/null
+++ b/patterns/clean-architecture/pom.xml
@@ -0,0 +1,87 @@
+
+
+    4.0.0
+    clean-architecture
+    1.0
+    clean-architecture
+    Project for clean architecture in java
+
+    
+        com.baeldung
+        parent-boot-2
+        0.0.1-SNAPSHOT
+        ../../parent-boot-2
+    
+
+    
+        1.8
+    
+
+    
+        
+            com.h2database
+            h2
+            runtime
+        
+        
+            org.springframework.boot
+            spring-boot-starter-web
+        
+        
+            org.springframework.boot
+            spring-boot-starter-data-jpa
+        
+        
+            org.junit.jupiter
+            junit-jupiter-engine
+            test
+        
+        
+            org.springframework.boot
+            spring-boot-starter-test
+            test
+            
+                
+                    org.junit.vintage
+                    junit-vintage-engine
+                
+            
+        
+        
+            org.mockito
+            mockito-core
+            test
+        
+        
+            org.junit.platform
+            junit-platform-engine
+        
+        
+            org.junit.jupiter
+            junit-jupiter-engine
+        
+        
+            org.junit.jupiter
+            junit-jupiter-api
+        
+        
+            org.junit.platform
+            junit-platform-runner
+            test
+        
+    
+
+
+    
+        
+
+            
+                org.springframework.boot
+                spring-boot-maven-plugin
+            
+        
+    
+
+
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/CleanArchitectureApplication.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/CleanArchitectureApplication.java
new file mode 100644
index 0000000000..ebac2bacf3
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/CleanArchitectureApplication.java
@@ -0,0 +1,40 @@
+package com.baeldung.pattern.cleanarchitecture;
+
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+
+@SpringBootApplication
+public class CleanArchitectureApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(CleanArchitectureApplication.class);
+    }
+
+    @Bean
+    BeanFactoryPostProcessor beanFactoryPostProcessor(ApplicationContext beanRegistry) {
+        return beanFactory -> {
+            genericApplicationContext((BeanDefinitionRegistry) ((AnnotationConfigServletWebServerApplicationContext) beanRegistry).getBeanFactory());
+        };
+    }
+
+    void genericApplicationContext(BeanDefinitionRegistry beanRegistry) {
+        ClassPathBeanDefinitionScanner beanDefinitionScanner = new ClassPathBeanDefinitionScanner(beanRegistry);
+        beanDefinitionScanner.addIncludeFilter(removeModelAndEntitiesFilter());
+        beanDefinitionScanner.scan("com.baeldung.pattern.cleanarchitecture");
+    }
+
+    static TypeFilter removeModelAndEntitiesFilter() {
+        return (MetadataReader mr, MetadataReaderFactory mrf) -> !mr.getClassMetadata()
+            .getClassName()
+            .endsWith("Model");
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/CommonUser.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/CommonUser.java
new file mode 100644
index 0000000000..c4f105fad5
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/CommonUser.java
@@ -0,0 +1,30 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+class CommonUser implements User {
+
+    String name;
+    String password;
+
+    CommonUser(String name, String password) {
+        this.name = name;
+        this.password = password;
+    }
+
+    CommonUser() {
+    }
+
+    @Override
+    public boolean passwordIsValid() {
+        return password != null && password.length() > 5;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getPassword() {
+        return password;
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/CommonUserFactory.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/CommonUserFactory.java
new file mode 100644
index 0000000000..a2b851da94
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/CommonUserFactory.java
@@ -0,0 +1,8 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+class CommonUserFactory implements UserFactory {
+    @Override
+    public User create(String name, String password) {
+        return new CommonUser(name, password);
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/JpaUser.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/JpaUser.java
new file mode 100644
index 0000000000..20751f282a
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/JpaUser.java
@@ -0,0 +1,21 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+class JpaUser implements UserRegisterDsGateway {
+
+    final JpaUserRepository repository;
+
+    JpaUser(JpaUserRepository repository) {
+        this.repository = repository;
+    }
+
+    @Override
+    public boolean existsByName(String name) {
+        return repository.existsById(name);
+    }
+
+    @Override
+    public void save(UserDsRequestModel requestModel) {
+        UserDataMapper accountDataMapper = new UserDataMapper(requestModel.getName(), requestModel.getPassword(), requestModel.getCreationTime());
+        repository.save(accountDataMapper);
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/JpaUserRepository.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/JpaUserRepository.java
new file mode 100644
index 0000000000..8565ed7965
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/JpaUserRepository.java
@@ -0,0 +1,8 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+interface JpaUserRepository extends JpaRepository {
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/User.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/User.java
new file mode 100644
index 0000000000..aab652f2a1
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/User.java
@@ -0,0 +1,9 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+interface User {
+    boolean passwordIsValid();
+
+    String getName();
+
+    String getPassword();
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserDataMapper.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserDataMapper.java
new file mode 100644
index 0000000000..44112de8a9
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserDataMapper.java
@@ -0,0 +1,53 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import java.time.LocalDateTime;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "user")
+class UserDataMapper {
+
+    @Id
+    String name;
+
+    String password;
+
+    LocalDateTime creationTime;
+
+    public UserDataMapper() {
+    }
+
+    public UserDataMapper(String name, String password, LocalDateTime creationTime) {
+        super();
+        this.name = name;
+        this.password = password;
+        this.creationTime = creationTime;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public LocalDateTime getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(LocalDateTime creationTime) {
+        this.creationTime = creationTime;
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserDsRequestModel.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserDsRequestModel.java
new file mode 100644
index 0000000000..aa0f0b56d1
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserDsRequestModel.java
@@ -0,0 +1,41 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import java.time.LocalDateTime;
+
+class UserDsRequestModel {
+
+    String name;
+    String password;
+    LocalDateTime creationTime;
+
+    public UserDsRequestModel(String name, String password, LocalDateTime creationTime) {
+        this.name = name;
+        this.password = password;
+        this.creationTime = creationTime;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public LocalDateTime getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(LocalDateTime creationTime) {
+        this.creationTime = creationTime;
+    }
+
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserFactory.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserFactory.java
new file mode 100644
index 0000000000..1ff29709be
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserFactory.java
@@ -0,0 +1,5 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+interface UserFactory {
+    User create(String name, String password);
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserInputBoundary.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserInputBoundary.java
new file mode 100644
index 0000000000..e72c30f13c
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserInputBoundary.java
@@ -0,0 +1,5 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+public interface UserInputBoundary {
+    UserResponseModel create(UserRequestModel requestModel);
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserPresenter.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserPresenter.java
new file mode 100644
index 0000000000..45d202643e
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserPresenter.java
@@ -0,0 +1,7 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+interface UserPresenter {
+    UserResponseModel prepareSuccessView(UserResponseModel user);
+
+    UserResponseModel prepareFailView(String error);
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterController.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterController.java
new file mode 100644
index 0000000000..039dc12910
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterController.java
@@ -0,0 +1,20 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+class UserRegisterController {
+
+    final UserInputBoundary userInput;
+
+    UserRegisterController(UserInputBoundary accountGateway) {
+        this.userInput = accountGateway;
+    }
+
+    @PostMapping("/user")
+    UserResponseModel create(@RequestBody UserRequestModel requestModel) {
+        return userInput.create(requestModel);
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterDsGateway.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterDsGateway.java
new file mode 100644
index 0000000000..89c1b7e774
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterDsGateway.java
@@ -0,0 +1,7 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+interface UserRegisterDsGateway {
+    boolean existsByName(String identifier);
+
+    void save(UserDsRequestModel requestModel);
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterInteractor.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterInteractor.java
new file mode 100644
index 0000000000..5137593dc3
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRegisterInteractor.java
@@ -0,0 +1,35 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import java.time.LocalDateTime;
+
+class UserRegisterInteractor implements UserInputBoundary {
+
+    final UserRegisterDsGateway userDsGateway;
+    final UserPresenter userPresenter;
+    final UserFactory userFactory;
+
+    UserRegisterInteractor(UserRegisterDsGateway userRegisterDfGateway, UserPresenter userPresenter,
+        UserFactory userFactory) {
+        this.userDsGateway = userRegisterDfGateway;
+        this.userPresenter = userPresenter;
+        this.userFactory = userFactory;
+    }
+
+    @Override
+    public UserResponseModel create(UserRequestModel requestModel) {
+        if (userDsGateway.existsByName(requestModel.getName())) {
+            return userPresenter.prepareFailView("User already exists.");
+        }
+        User user = userFactory.create(requestModel.getName(), requestModel.getPassword());
+        if (!user.passwordIsValid()) {
+            return userPresenter.prepareFailView("User password must have more than 5 characters.");
+        }
+        LocalDateTime now = LocalDateTime.now();
+        UserDsRequestModel userDsModel = new UserDsRequestModel(user.getName(), user.getPassword(), now);
+
+        userDsGateway.save(userDsModel);
+
+        UserResponseModel accountResponseModel = new UserResponseModel(user.getName(), now.toString());
+        return userPresenter.prepareSuccessView(accountResponseModel);
+    }
+}
\ No newline at end of file
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRequestModel.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRequestModel.java
new file mode 100644
index 0000000000..8317665c31
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserRequestModel.java
@@ -0,0 +1,33 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+class UserRequestModel {
+
+    String name;
+    String password;
+
+    public UserRequestModel() {
+        super();
+    }
+
+    UserRequestModel(String name, String password) {
+        super();
+        this.name = name;
+        this.password = password;
+    }
+
+    String getName() {
+        return name;
+    }
+
+    void setName(String name) {
+        this.name = name;
+    }
+
+    String getPassword() {
+        return password;
+    }
+
+    void setPassword(String password) {
+        this.password = password;
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseFormatter.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseFormatter.java
new file mode 100644
index 0000000000..4842d44e22
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseFormatter.java
@@ -0,0 +1,22 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.server.ResponseStatusException;
+
+class UserResponseFormatter implements UserPresenter {
+
+    @Override
+    public UserResponseModel prepareSuccessView(UserResponseModel response) {
+        LocalDateTime responseTime = LocalDateTime.parse(response.getCreationTime());
+        response.setCreationTime(responseTime.format(DateTimeFormatter.ofPattern("hh:mm:ss")));
+        return response;
+    }
+
+    @Override
+    public UserResponseModel prepareFailView(String error) {
+        throw new ResponseStatusException(HttpStatus.CONFLICT, error);
+    }
+}
diff --git a/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseModel.java b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseModel.java
new file mode 100644
index 0000000000..73a3d8fb10
--- /dev/null
+++ b/patterns/clean-architecture/src/main/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseModel.java
@@ -0,0 +1,29 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+public class UserResponseModel {
+
+    String login;
+    String creationTime;
+
+    public UserResponseModel(String login, String creationTime) {
+        this.login = login;
+        this.creationTime = creationTime;
+    }
+
+    public String getLogin() {
+        return login;
+    }
+
+    public void setLogin(String login) {
+        this.login = login;
+    }
+
+    public String getCreationTime() {
+        return creationTime;
+    }
+
+    public void setCreationTime(String creationTime) {
+        this.creationTime = creationTime;
+    }
+
+}
diff --git a/patterns/clean-architecture/src/main/resources/application.properties b/patterns/clean-architecture/src/main/resources/application.properties
new file mode 100644
index 0000000000..a5a02bb49d
--- /dev/null
+++ b/patterns/clean-architecture/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+server.port=8080
+server.error.include-message=always
\ No newline at end of file
diff --git a/patterns/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseFormatterUnitTest.java b/patterns/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseFormatterUnitTest.java
new file mode 100644
index 0000000000..e394cbbf94
--- /dev/null
+++ b/patterns/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserResponseFormatterUnitTest.java
@@ -0,0 +1,29 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.web.server.ResponseStatusException;
+
+import com.baeldung.pattern.cleanarchitecture.usercreation.UserResponseFormatter;
+import com.baeldung.pattern.cleanarchitecture.usercreation.UserResponseModel;
+
+class UserResponseFormatterUnitTest {
+
+    UserResponseFormatter userResponseFormatter = new UserResponseFormatter();
+
+    @Test
+    void givenDateAnd3HourTime_whenPrepareSuccessView_thenReturnOnly3HourTime() {
+        UserResponseModel modelResponse = new UserResponseModel("baeldung", "2020-12-20T03:00:00.000");
+        UserResponseModel formattedResponse = userResponseFormatter.prepareSuccessView(modelResponse);
+
+        assertThat(formattedResponse.getCreationTime()).isEqualTo("03:00:00");
+    }
+
+    @Test
+    void whenPrepareFailView_thenThrowHttpConflictException() {
+        assertThatThrownBy(() -> userResponseFormatter.prepareFailView("Invalid password"))
+            .isInstanceOf(ResponseStatusException.class);
+    }
+}
diff --git a/patterns/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserUnitTest.java b/patterns/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserUnitTest.java
new file mode 100644
index 0000000000..505ea47e3f
--- /dev/null
+++ b/patterns/clean-architecture/src/test/java/com/baeldung/pattern/cleanarchitecture/usercreation/UserUnitTest.java
@@ -0,0 +1,15 @@
+package com.baeldung.pattern.cleanarchitecture.usercreation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class UserUnitTest {
+
+    @Test
+    void given123Password_whenPasswordIsNotValid_thenIsFalse() {
+        User user = new CommonUser("Baeldung", "123");
+
+        assertThat(user.passwordIsValid()).isFalse();
+    }
+}
diff --git a/patterns/pom.xml b/patterns/pom.xml
index a179d75ffe..112eecb606 100644
--- a/patterns/pom.xml
+++ b/patterns/pom.xml
@@ -24,6 +24,7 @@
         hexagonal-architecture
         intercepting-filter
         solid
+        clean-architecture
     
     
         
diff --git a/performance-tests/README.md b/performance-tests/README.md
index 27c0363010..09bf6dba1f 100644
--- a/performance-tests/README.md
+++ b/performance-tests/README.md
@@ -6,6 +6,7 @@ This module contains articles about performance testing.
 
 - [Performance of Java Mapping Frameworks](https://www.baeldung.com/java-performance-mapping-frameworks)
 - [Performance Effects of Exceptions in Java](https://www.baeldung.com/java-exceptions-performance)
+- [Is Java a Compiled or Interpreted Language?](https://www.baeldung.com/java-compiled-interpreted)
 
 ### Running
 
diff --git a/performance-tests/src/main/external/Fibonacci.cpp b/performance-tests/src/main/external/Fibonacci.cpp
new file mode 100644
index 0000000000..d23603c2ea
--- /dev/null
+++ b/performance-tests/src/main/external/Fibonacci.cpp
@@ -0,0 +1,19 @@
+#include  
+#include  
+
+using namespace std;
+
+int fibonacci(int n) {
+    if (n <= 1)
+        return n;
+    return fibonacci(n - 1) + fibonacci(n - 2);
+}
+
+int main() {
+    for (int i = 0; i < 100; i++) {
+        auto startTime = chrono::high_resolution_clock::now().time_since_epoch();
+        int result = fibonacci(12);
+        auto totalTime = chrono::high_resolution_clock::now().time_since_epoch() - startTime;
+        cout << totalTime << "\n";
+    } 
+}
\ No newline at end of file
diff --git a/performance-tests/src/main/external/Fibonacci.js b/performance-tests/src/main/external/Fibonacci.js
new file mode 100644
index 0000000000..ba41bf3ab9
--- /dev/null
+++ b/performance-tests/src/main/external/Fibonacci.js
@@ -0,0 +1,14 @@
+function fibonacci(index) {
+	if (index <= 1)
+		return index;
+	return fibonacci(index-1) + fibonacci(index-2);
+}
+
+for (var i=0; i<100; i++) {
+	var startTime = process.hrtime.bigint();
+	var result = fibonacci(12);
+	var totalTime = process.hrtime.bigint() - startTime;
+	console.log(totalTime);
+}
+
+    
\ No newline at end of file
diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/jit/Fibonacci.java b/performance-tests/src/main/java/com/baeldung/performancetests/jit/Fibonacci.java
new file mode 100644
index 0000000000..c980093128
--- /dev/null
+++ b/performance-tests/src/main/java/com/baeldung/performancetests/jit/Fibonacci.java
@@ -0,0 +1,20 @@
+package com.baeldung.performancetests.jit;
+
+public class Fibonacci {
+
+    public static void main(String[] args) {
+        for (int i=0; i<100; i++) {
+            long startTime = System.nanoTime();
+            int result = fibonacci(12);
+            long totalTime = System.nanoTime() - startTime;
+            System.out.println(totalTime);
+        }
+    }
+
+    private static int fibonacci(int index) {
+        if (index <= 1)
+            return index;
+        return fibonacci(index-1) + fibonacci(index-2);
+    }
+
+}
diff --git a/performance-tests/src/main/resources/FibonacciPerformancesResults.csv b/performance-tests/src/main/resources/FibonacciPerformancesResults.csv
new file mode 100644
index 0000000000..01a1f3dd90
--- /dev/null
+++ b/performance-tests/src/main/resources/FibonacciPerformancesResults.csv
@@ -0,0 +1,103 @@
+Runs;Java using JIT;Java without JIT;C++ without O2;C++ with O2;JavaScript
+1;21900;10572;8684;2643;35115
+2;60790;10572;8306;2643;20389
+3;1888;24543;7551;2265;20390
+4;4153;25675;8307;2265;19256
+5;1888;26053;8307;2265;19257
+6;5664;25675;8307;1887;35115
+7;1510;25676;29829;2266;20012
+8;1510;26053;7929;2643;35493
+9;1511;23787;7929;1888;40023
+10;3776;26431;26053;3776;20012
+11;1510;25676;7929;2265;35115
+12;1510;10195;7552;3775;19256
+13;17746;10572;7552;1888;40024
+14;26431;10194;7552;2265;19257
+15;1133;10195;8685;2265;18501
+16;1133;10572;7929;2265;18879
+17;1133;10572;7929;1888;53995
+18;756;10195;7929;1888;35115
+19;1133;10195;7930;2266;19634
+20;756;10573;7552;2266;37003
+21;1133;9817;7552;1888;35115
+22;1133;10194;7930;2266;32472
+23;1133;10195;7929;2266;18879
+24;755;10195;8307;3776;19257
+25;755;10195;7551;1888;34738
+26;1510;10194;7551;2265;18501
+27;3776;10194;7929;2266;33227
+28;1888;37758;9440;1888;19634
+29;1133;10573;8306;1888;32472
+30;1133;26430;7929;2265;32849
+31;1133;24165;8306;4153;32850
+32;755;24166;7929;2643;18879
+33;1133;10572;24920;4153;32850
+34;755;23788;10194;2643;19257
+35;756;23788;12837;4154;18501
+36;755;11328;8307;2643;33227
+37;1132;29829;8307;7174;1000211
+38;755;36625;8307;4531;39646
+39;1133;10950;7929;2643;34360
+40;1133;10950;7929;4531;3021
+41;1133;10573;7929;2643;2643
+42;755;29829;15104;2643;2643
+43;755;29829;13971;2643;3398
+44;1133;10950;8685;5664;3021
+45;1133;10950;9817;3020;3398
+46;1133;10950;8684;3776;3020
+47;1888;30962;7930;3020;3021
+48;1132;10950;8307;2643;3399
+49;1133;29451;7929;2265;2266
+50;1133;29452;8307;23033;2265
+51;755;10950;7929;2643;2266
+52;755;10950;7930;2643;2643
+53;755;11327;7929;4908;2265
+54;755;11328;7929;2265;2643
+55;1133;10572;7929;18879;16236
+56;756;36248;7929;2643;2643
+57;755;10572;7929;2265;2643
+58;755;10950;9818;2644;2643
+59;1132;10950;7929;2266;2643
+60;20012;30206;7929;2266;3021
+61;1133;30206;7929;2266;16613
+62;1511;30206;7552;2266;2643
+63;3021;30207;8307;1888;2643
+64;1510;10950;7929;1888;2266
+65;1510;30207;7929;2266;2644
+66;1888;30207;8307;2265;2643
+67;1511;29829;7929;2266;2643
+68;1888;10950;7930;2265;2266
+69;1510;29829;7929;21145;3020
+70;1511;29829;7929;1888;16613
+71;1510;30206;7929;2643;2265
+72;1510;10950;7929;2266;2644
+73;1888;10573;24921;18124;2266
+74;1888;10573;9062;6797;2644
+75;1888;10950;7929;2265;2643
+76;1133;10950;7929;2266;2644
+77;1133;29829;12460;2266;3020
+78;755;11328;8307;2643;2266
+79;755;11327;8684;2266;2643
+80;1133;30206;8307;2266;2643
+81;1133;29829;7929;2266;2266
+82;1888;30206;7929;2266;16236
+83;1510;11327;8307;2266;16613
+84;1888;11327;7929;2265;2643
+85;1133;10573;8307;6042;2266
+86;1133;10950;7929;2643;2266
+87;1133;10950;9817;2265;2265
+88;755;10950;24165;2643;2643
+89;755;11328;7929;3399;2643
+90;755;10950;8307;4909;3020
+91;755;10572;7552;23787;3020
+92;1133;10572;7929;2643;3021
+93;1132;10572;8307;2643;2643
+94;1132;10950;7551;2266;3398
+95;755;10950;23788;2265;2644
+96;755;10573;7551;1888;2265
+97;755;29829;12460;2266;2643
+98;1132;30207;7929;2266;2265
+99;1133;30206;7929;2265;2266
+100;755;10572;7929;2265;2643
+;;;;;
+;;;;;
diff --git a/persistence-modules/hibernate-annotations/pom.xml b/persistence-modules/hibernate-annotations/pom.xml
index 5367921f31..d3b786d6c8 100644
--- a/persistence-modules/hibernate-annotations/pom.xml
+++ b/persistence-modules/hibernate-annotations/pom.xml
@@ -30,7 +30,7 @@
         
         	org.apache.commons
         	commons-lang3
-        	${commons.lang3.version}
+        	${commons-lang3.version}
         
         
         
@@ -44,31 +44,15 @@
             hibernate-spatial
             ${hibernate-core.version}
         
-        
-            org.opengeo
-            geodb
-            ${geodb.version}
-        
     
     
-    
-        
-            geodb-repo
-            GeoDB repository
-            http://repo.boundlessgeo.com/main/
-        
-    
-
     
         5.4.7.Final
         1.4.200
-        3.8.1
         true
         2.1.7.RELEASE
         5.4.7.Final
         1.4.200
-        3.8.1
-        0.9
     
 
 
diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml
index 4eabc5d298..ebc854a621 100644
--- a/persistence-modules/hibernate-mapping/pom.xml
+++ b/persistence-modules/hibernate-mapping/pom.xml
@@ -71,8 +71,6 @@
         3.0.1-b11        
         1.0.3
         1.3
-        3.9
-        2.6
     
 
 
diff --git a/persistence-modules/hibernate-queries/pom.xml b/persistence-modules/hibernate-queries/pom.xml
index 06f7f42088..4374c833c2 100644
--- a/persistence-modules/hibernate-queries/pom.xml
+++ b/persistence-modules/hibernate-queries/pom.xml
@@ -35,11 +35,6 @@
             hibernate-spatial
             ${hibernate.version}
         
-        
-            org.opengeo
-            geodb
-            ${geodb.version}
-        
         
             mysql
             mysql-connector-java
@@ -62,19 +57,10 @@
         
     
 
-    
-        
-            geodb-repo
-            GeoDB repository
-            http://repo.boundlessgeo.com/main/
-        
-    
-
     
         6.0.6
         2.2.3
         3.8.0
-        0.9
         1.21
     
 
diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml
index 7f04abc09f..3feffc98fd 100644
--- a/persistence-modules/hibernate5/pom.xml
+++ b/persistence-modules/hibernate5/pom.xml
@@ -35,11 +35,6 @@
             hibernate-spatial
             ${hibernate.version}
         
-        
-            org.opengeo
-            geodb
-            ${geodb.version}
-        
         
             mysql
             mysql-connector-java
@@ -68,21 +63,12 @@
         
     
 
-    
-        
-            geodb-repo
-            GeoDB repository
-            http://repo.boundlessgeo.com/main/
-        
-    
-
     
         5.4.12.Final
         6.0.6
         2.2.3
         3.8.0
         1.21
-        0.9
     
 
 
diff --git a/persistence-modules/java-jpa-3/README.md b/persistence-modules/java-jpa-3/README.md
index 1949207364..9c9e040825 100644
--- a/persistence-modules/java-jpa-3/README.md
+++ b/persistence-modules/java-jpa-3/README.md
@@ -9,3 +9,4 @@ This module contains articles about the Java Persistence API (JPA) in Java.
 - [Defining Indexes in JPA](https://www.baeldung.com/jpa-indexes)
 - [JPA CascadeType.REMOVE vs orphanRemoval](https://www.baeldung.com/jpa-cascade-remove-vs-orphanremoval)
 - [A Guide to MultipleBagFetchException in Hibernate](https://www.baeldung.com/java-hibernate-multiplebagfetchexception)
+- [How to Convert a Hibernate Proxy to a Real Entity Object](https://www.baeldung.com/hibernate-proxy-to-real-entity-object)
diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/CreditCardPayment.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/CreditCardPayment.java
new file mode 100644
index 0000000000..6eb41f7ccc
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/CreditCardPayment.java
@@ -0,0 +1,20 @@
+package com.baeldung.jpa.hibernateunproxy;
+
+import javax.persistence.Entity;
+import java.math.BigDecimal;
+
+@Entity
+public class CreditCardPayment extends Payment {
+
+    private String cardNumber;
+
+    CreditCardPayment(BigDecimal amount, WebUser webUser, String cardNumber) {
+        this.amount = amount;
+        this.webUser = webUser;
+        this.cardNumber = cardNumber;
+    }
+
+    protected CreditCardPayment() {
+    }
+
+}
diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/Payment.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/Payment.java
new file mode 100644
index 0000000000..9e70da5f65
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/Payment.java
@@ -0,0 +1,47 @@
+package com.baeldung.jpa.hibernateunproxy;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+import java.math.BigDecimal;
+import java.util.Objects;
+
+@Entity
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public abstract class Payment {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    protected WebUser webUser;
+
+    protected BigDecimal amount;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        Payment payment = (Payment) o;
+
+        return Objects.equals(id, payment.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return id != null ? id.hashCode() : 0;
+    }
+
+    protected Payment() {
+    }
+
+}
diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/PaymentReceipt.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/PaymentReceipt.java
new file mode 100644
index 0000000000..530839eef4
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/PaymentReceipt.java
@@ -0,0 +1,53 @@
+package com.baeldung.jpa.hibernateunproxy;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import java.util.Objects;
+import java.util.UUID;
+
+@Entity
+public class PaymentReceipt {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    private Payment payment;
+
+    private String transactionNumber;
+
+    PaymentReceipt(Payment payment) {
+        this.payment = payment;
+        this.transactionNumber = UUID.randomUUID().toString();
+    }
+
+    public Payment getPayment() {
+        return payment;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        PaymentReceipt that = (PaymentReceipt) o;
+
+        return Objects.equals(id, that.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return id != null ? id.hashCode() : 0;
+    }
+
+    protected PaymentReceipt() {
+    }
+
+}
diff --git a/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/WebUser.java b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/WebUser.java
new file mode 100644
index 0000000000..d3f82bacd4
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/main/java/com/baeldung/jpa/hibernateunproxy/WebUser.java
@@ -0,0 +1,42 @@
+package com.baeldung.jpa.hibernateunproxy;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import java.util.Objects;
+
+@Entity
+public class WebUser {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+
+    private String name;
+
+    WebUser(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        WebUser webUser = (WebUser) o;
+
+        return Objects.equals(id, webUser.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return id != null ? id.hashCode() : 0;
+    }
+
+    protected WebUser() {
+    }
+
+}
diff --git a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml
index f428fea07b..19ecae8491 100644
--- a/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml
+++ b/persistence-modules/java-jpa-3/src/main/resources/META-INF/persistence.xml
@@ -77,4 +77,24 @@
             
         
     
+    
+        org.hibernate.jpa.HibernatePersistenceProvider
+        com.baeldung.jpa.hibernateunproxy.Payment
+        com.baeldung.jpa.hibernateunproxy.CreditCardPayment
+        com.baeldung.jpa.hibernateunproxy.PaymentReceipt
+        com.baeldung.jpa.hibernateunproxy.WebUser
+        true
+        
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+        
+    
 
diff --git a/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/hibernateunproxy/HibernateProxyIntegrationTest.java b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/hibernateunproxy/HibernateProxyIntegrationTest.java
new file mode 100644
index 0000000000..717745bb13
--- /dev/null
+++ b/persistence-modules/java-jpa-3/src/test/java/com/baeldung/jpa/hibernateunproxy/HibernateProxyIntegrationTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.jpa.hibernateunproxy;
+
+import org.hibernate.Hibernate;
+import org.hibernate.proxy.HibernateProxy;
+import org.junit.Assert;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import java.math.BigDecimal;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class HibernateProxyIntegrationTest {
+
+    private static EntityManager entityManager;
+
+    @BeforeAll
+    public static void setup() {
+        EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-h2-hibernate-unproxy");
+        entityManager = factory.createEntityManager();
+        populateH2DB();
+    }
+
+    @Test
+    public void givenPaymentReceipt_whenAccessingPayment_thenVerifyType() {
+        PaymentReceipt paymentReceipt = entityManager.find(PaymentReceipt.class, 3L);
+        Assert.assertTrue(paymentReceipt.getPayment() instanceof HibernateProxy);
+    }
+
+    @Test
+    public void givenWebUserProxy_whenCreatingPayment_thenExecuteSingleStatement() {
+        entityManager.getTransaction().begin();
+
+        WebUser webUser = entityManager.getReference(WebUser.class, 1L);
+        Payment payment = new CreditCardPayment(new BigDecimal(100), webUser, "CN-1234");
+        entityManager.persist(payment);
+
+        entityManager.getTransaction().commit();
+        Assert.assertTrue(webUser instanceof HibernateProxy);
+    }
+
+    @Test
+    public void givenPaymentReceipt_whenCastingPaymentToConcreteClass_thenThrowClassCastException() {
+        PaymentReceipt paymentReceipt = entityManager.find(PaymentReceipt.class, 3L);
+        assertThrows(ClassCastException.class, () -> {
+            CreditCardPayment creditCardPayment = (CreditCardPayment) paymentReceipt.getPayment();
+        });
+    }
+
+    @Test
+    public void givenPaymentReceipt_whenPaymentIsUnproxied_thenReturnRealEntityObject() {
+        PaymentReceipt paymentReceipt = entityManager.find(PaymentReceipt.class, 3L);
+        Assert.assertTrue(Hibernate.unproxy(paymentReceipt.getPayment()) instanceof CreditCardPayment);
+    }
+
+    private static void populateH2DB() {
+        entityManager.getTransaction().begin();
+
+        WebUser webUser = new WebUser("name");
+        entityManager.persist(webUser);
+
+        Payment payment = new CreditCardPayment(new BigDecimal(100), webUser, "CN-1234");
+        entityManager.persist(payment);
+
+        PaymentReceipt receipt = new PaymentReceipt(payment);
+        entityManager.persist(receipt);
+
+        entityManager.getTransaction().commit();
+        entityManager.clear();
+    }
+
+}
diff --git a/persistence-modules/jnosql/pom.xml b/persistence-modules/jnosql/pom.xml
index fb7ac72b05..81c62ee562 100644
--- a/persistence-modules/jnosql/pom.xml
+++ b/persistence-modules/jnosql/pom.xml
@@ -21,7 +21,7 @@
     
 
     
-        0.0.5
+        0.0.6
     
 
 
diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml
index c7905a178d..8789a8473b 100644
--- a/persistence-modules/pom.xml
+++ b/persistence-modules/pom.xml
@@ -86,6 +86,7 @@
         spring-jpa
         spring-jpa-2
         spring-jdbc
+        spring-jooq
          
         spring-persistence-simple
     
diff --git a/persistence-modules/spring-boot-persistence-mongodb/README.md b/persistence-modules/spring-boot-persistence-mongodb/README.md
index f277ef66ca..97241ad464 100644
--- a/persistence-modules/spring-boot-persistence-mongodb/README.md
+++ b/persistence-modules/spring-boot-persistence-mongodb/README.md
@@ -3,3 +3,6 @@
 - [Auto-Generated Field for MongoDB using Spring Boot](https://www.baeldung.com/spring-boot-mongodb-auto-generated-field)
 - [Spring Boot Integration Testing with Embedded MongoDB](http://www.baeldung.com/spring-boot-embedded-mongodb)
 - [Upload and Retrieve Files Using MongoDB and Spring Boot](https://www.baeldung.com/spring-boot-mongodb-upload-file)
+- [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs)
+- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
+
diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/config/MongoConfig.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/config/MongoConfig.java
new file mode 100644
index 0000000000..3cfefa099c
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/config/MongoConfig.java
@@ -0,0 +1,53 @@
+package com.baeldung.zoneddatetime.config;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
+import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+import com.baeldung.zoneddatetime.converter.ZonedDateTimeReadConverter;
+import com.baeldung.zoneddatetime.converter.ZonedDateTimeWriteConverter;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+
+@Configuration
+@EnableMongoRepositories(basePackages = { "com.baeldung" })
+public class MongoConfig extends AbstractMongoClientConfiguration {
+
+    private final List> converters = new ArrayList>();
+
+    @Override
+    protected String getDatabaseName() {
+        return "test";
+    }
+
+    @Override
+    public MongoClient mongoClient() {
+        final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
+        final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
+            .applyConnectionString(connectionString)
+            .build();
+        return MongoClients.create(mongoClientSettings);
+    }
+
+    @Override
+    public Collection getMappingBasePackages() {
+        return Collections.singleton("com.baeldung");
+    }
+
+    @Override
+    public MongoCustomConversions customConversions() {
+        converters.add(new ZonedDateTimeReadConverter());
+        converters.add(new ZonedDateTimeWriteConverter());
+        return new MongoCustomConversions(converters);
+    }
+
+}
diff --git a/persistence-modules/spring-data-mongodb/src/main/java/converter/ZonedDateTimeReadConverter.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/converter/ZonedDateTimeReadConverter.java
similarity index 88%
rename from persistence-modules/spring-data-mongodb/src/main/java/converter/ZonedDateTimeReadConverter.java
rename to persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/converter/ZonedDateTimeReadConverter.java
index a2d847957b..f4a4c2d040 100644
--- a/persistence-modules/spring-data-mongodb/src/main/java/converter/ZonedDateTimeReadConverter.java
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/converter/ZonedDateTimeReadConverter.java
@@ -1,4 +1,4 @@
-package converter;
+package com.baeldung.zoneddatetime.converter;
 
 import org.springframework.core.convert.converter.Converter;
 
diff --git a/persistence-modules/spring-data-mongodb/src/main/java/converter/ZonedDateTimeWriteConverter.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/converter/ZonedDateTimeWriteConverter.java
similarity index 87%
rename from persistence-modules/spring-data-mongodb/src/main/java/converter/ZonedDateTimeWriteConverter.java
rename to persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/converter/ZonedDateTimeWriteConverter.java
index e13ac2d130..2244a1460a 100644
--- a/persistence-modules/spring-data-mongodb/src/main/java/converter/ZonedDateTimeWriteConverter.java
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/converter/ZonedDateTimeWriteConverter.java
@@ -1,4 +1,4 @@
-package converter;
+package com.baeldung.zoneddatetime.converter;
 
 import org.springframework.core.convert.converter.Converter;
 
diff --git a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/model/Action.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/model/Action.java
similarity index 96%
rename from persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/model/Action.java
rename to persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/model/Action.java
index aa480dbdf7..06202fe465 100644
--- a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/model/Action.java
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/model/Action.java
@@ -1,4 +1,4 @@
-package com.baeldung.model;
+package com.baeldung.zoneddatetime.model;
 
 import org.springframework.data.annotation.Id;
 import org.springframework.data.mongodb.core.mapping.Document;
diff --git a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/repository/ActionRepository.java b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/repository/ActionRepository.java
similarity index 55%
rename from persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/repository/ActionRepository.java
rename to persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/repository/ActionRepository.java
index bdca490fe6..e214c4b3c4 100644
--- a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/repository/ActionRepository.java
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/java/com/baeldung/zoneddatetime/repository/ActionRepository.java
@@ -1,6 +1,7 @@
-package com.baeldung.repository;
+package com.baeldung.zoneddatetime.repository;
 
-import com.baeldung.model.Action;
 import org.springframework.data.mongodb.repository.MongoRepository;
 
+import com.baeldung.zoneddatetime.model.Action;
+
 public interface ActionRepository extends MongoRepository { }
\ No newline at end of file
diff --git a/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/mongoConfig.xml b/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/mongoConfig.xml
new file mode 100644
index 0000000000..c5b9068de3
--- /dev/null
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/mongoConfig.xml
@@ -0,0 +1,31 @@
+
+
+    
+
+    
+
+    
+
+    
+        
+        
+    
+
+    
+        
+        
+    
+
+    
+        
+    
+
+
\ No newline at end of file
diff --git a/persistence-modules/spring-data-mongodb/src/main/resources/test.png b/persistence-modules/spring-boot-persistence-mongodb/src/main/resources/test.png
similarity index 100%
rename from persistence-modules/spring-data-mongodb/src/main/resources/test.png
rename to persistence-modules/spring-boot-persistence-mongodb/src/main/resources/test.png
diff --git a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java
similarity index 100%
rename from persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java
rename to persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/gridfs/GridFSLiveTest.java
diff --git a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/repository/ActionRepositoryLiveTest.java b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/zoneddatetime/ActionRepositoryLiveTest.java
similarity index 87%
rename from persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/repository/ActionRepositoryLiveTest.java
rename to persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/zoneddatetime/ActionRepositoryLiveTest.java
index 79648f1a20..3a241418ca 100644
--- a/persistence-modules/spring-data-mongodb/src/test/java/com/baeldung/repository/ActionRepositoryLiveTest.java
+++ b/persistence-modules/spring-boot-persistence-mongodb/src/test/java/com/baeldung/zoneddatetime/ActionRepositoryLiveTest.java
@@ -1,7 +1,5 @@
-package com.baeldung.repository;
+package com.baeldung.zoneddatetime;
 
-import com.baeldung.config.MongoConfig;
-import com.baeldung.model.Action;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -12,6 +10,10 @@ import org.springframework.data.mongodb.core.MongoOperations;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
+import com.baeldung.zoneddatetime.config.MongoConfig;
+import com.baeldung.zoneddatetime.model.Action;
+import com.baeldung.zoneddatetime.repository.ActionRepository;
+
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 
diff --git a/persistence-modules/spring-data-jpa-annotations/README.md b/persistence-modules/spring-data-jpa-annotations/README.md
index 5f1c8dbc27..1ee579cf6c 100644
--- a/persistence-modules/spring-data-jpa-annotations/README.md
+++ b/persistence-modules/spring-data-jpa-annotations/README.md
@@ -4,7 +4,6 @@ This module contains articles about annotations used in Spring Data JPA
 
 ### Relevant articles
 
-- [Spring Data Annotations](https://www.baeldung.com/spring-data-annotations)
 - [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd)
 - [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable)
 - [Spring Data JPA @Modifying Annotation](https://www.baeldung.com/spring-data-jpa-modifying-annotation)
diff --git a/persistence-modules/spring-data-mongodb/README.md b/persistence-modules/spring-data-mongodb/README.md
index 381bf83fa8..acc978c68e 100644
--- a/persistence-modules/spring-data-mongodb/README.md
+++ b/persistence-modules/spring-data-mongodb/README.md
@@ -7,13 +7,10 @@
 - [A Guide to Queries in Spring Data MongoDB](http://www.baeldung.com/queries-in-spring-data-mongodb)
 - [Spring Data MongoDB – Indexes, Annotations and Converters](http://www.baeldung.com/spring-data-mongodb-index-annotations-converter)
 - [Custom Cascading in Spring Data MongoDB](http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb)
-- [GridFS in Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-gridfs)
 - [Introduction to Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-tutorial)
 - [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations)
 - [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
-- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions )
-- [ZonedDateTime with Spring Data MongoDB](https://www.baeldung.com/spring-data-mongodb-zoneddatetime)
-
+- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions)
 
 ## Spring Data MongoDB Live Testing
 
diff --git a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java
index 8036bbbca2..90b1268133 100644
--- a/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java
+++ b/persistence-modules/spring-data-mongodb/src/main/java/com/baeldung/config/MongoConfig.java
@@ -5,16 +5,13 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.data.mongodb.MongoDatabaseFactory;
 import org.springframework.data.mongodb.MongoTransactionManager;
 import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
-import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
 import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
-import org.springframework.data.mongodb.gridfs.GridFsTemplate;
 import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
 
 import com.baeldung.converter.UserWriterConverter;
@@ -25,18 +22,12 @@ import com.mongodb.MongoClientSettings;
 import com.mongodb.client.MongoClient;
 import com.mongodb.client.MongoClients;
 
-import converter.ZonedDateTimeReadConverter;
-import converter.ZonedDateTimeWriteConverter;
-
 @Configuration
 @EnableMongoRepositories(basePackages = "com.baeldung.repository")
 public class MongoConfig extends AbstractMongoClientConfiguration {
 
     private final List> converters = new ArrayList>();
 
-    @Autowired
-    private MappingMongoConverter mongoConverter;
-
     @Override
     protected String getDatabaseName() {
         return "test";
@@ -69,16 +60,9 @@ public class MongoConfig extends AbstractMongoClientConfiguration {
     @Override
     public MongoCustomConversions customConversions() {
         converters.add(new UserWriterConverter());
-        converters.add(new ZonedDateTimeReadConverter());
-        converters.add(new ZonedDateTimeWriteConverter());
         return new MongoCustomConversions(converters);
     }
 
-    @Bean
-    public GridFsTemplate gridFsTemplate() throws Exception {
-        return new GridFsTemplate(mongoDbFactory(), mongoConverter);
-    }
-
     @Bean
     MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
         return new MongoTransactionManager(dbFactory);
diff --git a/persistence-modules/spring-data-mongodb/src/main/resources/mongoConfig.xml b/persistence-modules/spring-data-mongodb/src/main/resources/mongoConfig.xml
index 074a203b1a..5067bec78e 100644
--- a/persistence-modules/spring-data-mongodb/src/main/resources/mongoConfig.xml
+++ b/persistence-modules/spring-data-mongodb/src/main/resources/mongoConfig.xml
@@ -14,11 +14,6 @@
 
     
 
-    
-        
-        
-    
-
     
         
         
diff --git a/spring-jooq/.gitignore b/persistence-modules/spring-jooq/.gitignore
similarity index 100%
rename from spring-jooq/.gitignore
rename to persistence-modules/spring-jooq/.gitignore
diff --git a/spring-jooq/README.md b/persistence-modules/spring-jooq/README.md
similarity index 100%
rename from spring-jooq/README.md
rename to persistence-modules/spring-jooq/README.md
diff --git a/spring-jooq/pom.xml b/persistence-modules/spring-jooq/pom.xml
similarity index 99%
rename from spring-jooq/pom.xml
rename to persistence-modules/spring-jooq/pom.xml
index 550d49b5b2..6b3d565175 100644
--- a/spring-jooq/pom.xml
+++ b/persistence-modules/spring-jooq/pom.xml
@@ -9,7 +9,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-jooq/src/main/resources/application.properties b/persistence-modules/spring-jooq/src/main/resources/application.properties
similarity index 100%
rename from spring-jooq/src/main/resources/application.properties
rename to persistence-modules/spring-jooq/src/main/resources/application.properties
diff --git a/spring-jooq/src/main/resources/intro_config.properties b/persistence-modules/spring-jooq/src/main/resources/intro_config.properties
similarity index 100%
rename from spring-jooq/src/main/resources/intro_config.properties
rename to persistence-modules/spring-jooq/src/main/resources/intro_config.properties
diff --git a/spring-jooq/src/main/resources/intro_schema.sql b/persistence-modules/spring-jooq/src/main/resources/intro_schema.sql
similarity index 100%
rename from spring-jooq/src/main/resources/intro_schema.sql
rename to persistence-modules/spring-jooq/src/main/resources/intro_schema.sql
diff --git a/spring-5-mvc/src/main/resources/logback.xml b/persistence-modules/spring-jooq/src/main/resources/logback.xml
similarity index 100%
rename from spring-5-mvc/src/main/resources/logback.xml
rename to persistence-modules/spring-jooq/src/main/resources/logback.xml
diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java
similarity index 100%
rename from spring-jooq/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java
rename to persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/ExceptionTranslator.java
diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/introduction/PersistenceContextIntegrationTest.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/PersistenceContextIntegrationTest.java
similarity index 100%
rename from spring-jooq/src/test/java/com/baeldung/jooq/introduction/PersistenceContextIntegrationTest.java
rename to persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/PersistenceContextIntegrationTest.java
diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java
similarity index 100%
rename from spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java
rename to persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/introduction/QueryIntegrationTest.java
diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/Application.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/springboot/Application.java
similarity index 100%
rename from spring-jooq/src/test/java/com/baeldung/jooq/springboot/Application.java
rename to persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/springboot/Application.java
diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java
similarity index 100%
rename from spring-jooq/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java
rename to persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/springboot/InitialConfiguration.java
diff --git a/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java b/persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java
similarity index 100%
rename from spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java
rename to persistence-modules/spring-jooq/src/test/java/com/baeldung/jooq/springboot/SpringBootIntegrationTest.java
diff --git a/spring-jooq/src/test/resources/application.properties b/persistence-modules/spring-jooq/src/test/resources/application.properties
similarity index 100%
rename from spring-jooq/src/test/resources/application.properties
rename to persistence-modules/spring-jooq/src/test/resources/application.properties
diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/Course.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/Course.java
new file mode 100644
index 0000000000..5add1e4a99
--- /dev/null
+++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/Course.java
@@ -0,0 +1,35 @@
+package com.baeldung.spring.transaction;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "course")
+public class Course implements Serializable {
+    
+    private static final long serialVersionUID = 1L;
+    
+    @Id
+    @Column(name = "id")
+    private Long id;
+    
+    public Course() {
+    }
+    
+    public Course(Long id) {
+        this.id = id;
+    }
+    
+    public Long getId() {
+        return id;
+    }
+    
+    public void setId(Long id) {
+        this.id = id;
+    }
+    
+}
diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/CourseDao.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/CourseDao.java
new file mode 100644
index 0000000000..adf138ba67
--- /dev/null
+++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/CourseDao.java
@@ -0,0 +1,13 @@
+package com.baeldung.spring.transaction;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.spring.hibernate.AbstractHibernateDao;
+
+@Repository
+public class CourseDao extends AbstractHibernateDao {
+    public CourseDao() {
+        super();
+        setClazz(Course.class);
+    }
+}
diff --git a/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/CourseService.java b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/CourseService.java
new file mode 100644
index 0000000000..05e3f32cee
--- /dev/null
+++ b/persistence-modules/spring-jpa-2/src/main/java/com/baeldung/spring/transaction/CourseService.java
@@ -0,0 +1,44 @@
+package com.baeldung.spring.transaction;
+
+import java.sql.SQLException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+
+@Service
+public class CourseService {
+    
+    @Autowired
+    private CourseDao courseDao;
+    
+    @Transactional
+    public void createCourseDeclarativeWithRuntimeException(Course course) {
+        courseDao.create(course);
+        throw new DataIntegrityViolationException("Throwing exception for demoing Rollback!!!");
+    }
+    
+    @Transactional(rollbackFor = { SQLException.class })
+    public void createCourseDeclarativeWithCheckedException(Course course) throws SQLException {
+        courseDao.create(course);
+        throw new SQLException("Throwing exception for demoing Rollback!!!");
+    }
+    
+    public void createCourseDefaultRatingProgramatic(Course course) {
+        try {
+            courseDao.create(course);
+            throw new DataIntegrityViolationException("Throwing exception for demoing Rollback!!!");
+        } catch (Exception e) {
+            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+        }
+    }
+    
+    @Transactional(noRollbackFor = { SQLException.class })
+    public void createCourseDeclarativeWithNoRollBack(Course course) throws SQLException {
+        courseDao.create(course);
+        throw new SQLException("Throwing exception for demoing Rollback!!!");
+    }
+    
+}
diff --git a/persistence-modules/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md
index f60609e0de..937890cd13 100644
--- a/persistence-modules/spring-jpa/README.md
+++ b/persistence-modules/spring-jpa/README.md
@@ -7,6 +7,7 @@
 - [Self-Contained Testing Using an In-Memory Database](https://www.baeldung.com/spring-jpa-test-in-memory-database)
 - [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source)
 - [Obtaining Auto-generated Keys in Spring JDBC](https://www.baeldung.com/spring-jdbc-autogenerated-keys)
+- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
 - More articles: [[next -->]](/spring-jpa-2)
 
 ### Eclipse Config 
diff --git a/pom.xml b/pom.xml
index 67fa58293b..70efb02f4d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -601,7 +601,6 @@
 
                 spring-5
                 spring-5-data-reactive
-                spring-5-mvc
                 spring-5-reactive
                 spring-5-reactive-2
                 spring-5-reactive-client
@@ -651,32 +650,17 @@
                 spring-jersey
                 spring-jinq
                 spring-jms
-                spring-jooq
 
                 spring-kafka
                 spring-katharsis
 
                 spring-mobile
                 spring-mockito
-
-                spring-mvc-forms-thymeleaf
-                spring-mvc-java
-                spring-mvc-java-2
-
-                spring-mvc-velocity
-                spring-mvc-xml
-
                 spring-protobuf
                 spring-quartz
 
                 spring-reactor
                 spring-remoting
-                spring-rest-http-2
-                spring-rest-query-language
-                spring-rest-shell
-                spring-rest-simple
-                spring-resttemplate
-                spring-rest-testing
                 spring-roo
 
                 spring-scheduling
@@ -1069,7 +1053,6 @@
 
                 spring-5
                 spring-5-data-reactive
-                spring-5-mvc
                 spring-5-reactive
                 spring-5-reactive-2
                 spring-5-reactive-client
@@ -1117,7 +1100,6 @@
                 spring-jersey
                 spring-jinq
                 spring-jms
-                spring-jooq
 
                 spring-kafka
                 spring-katharsis
@@ -1125,23 +1107,11 @@
                 spring-mobile
                 spring-mockito
 
-                spring-mvc-forms-thymeleaf
-                spring-mvc-java
-                spring-mvc-java-2
-
-                spring-mvc-velocity
-                spring-mvc-xml
-
                 spring-protobuf
                 spring-quartz
 
                 spring-reactor
                 spring-remoting
-                spring-rest-query-language
-                spring-rest-shell
-                spring-rest-simple
-                spring-resttemplate
-                spring-rest-testing
                 spring-roo
 
                 spring-scheduling
@@ -1403,9 +1373,9 @@
         1.19
         1.6.0
         2.21.0
-        2.5
+        2.8.0
         2.6
-        3.5
+        3.11
         1.4
         3.0.0
         3.1.0
@@ -1413,7 +1383,7 @@
         2.3.1
         1.2
         2.11.1
-        1.3
+        1.4
         1.2.0
         5.2.0
         0.3.1
diff --git a/quarkus/pom.xml b/quarkus/pom.xml
index 7fdf1557fb..9c14afca3c 100644
--- a/quarkus/pom.xml
+++ b/quarkus/pom.xml
@@ -48,7 +48,7 @@
         
             org.apache.commons
             commons-lang3
-            3.9
+            ${commons-lang3.version}
         
         
             org.projectlombok
diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/webclient/json/ReaderConsumerService.java b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/json/ReaderConsumerService.java
new file mode 100644
index 0000000000..17676b3f33
--- /dev/null
+++ b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/json/ReaderConsumerService.java
@@ -0,0 +1,18 @@
+package com.baeldung.webclient.json;
+
+import com.baeldung.webclient.json.model.Book;
+
+import java.util.List;
+
+public interface ReaderConsumerService {
+
+    List processReaderDataFromObjectArray();
+
+    List processReaderDataFromReaderArray();
+
+    List processReaderDataFromReaderList();
+
+    List processNestedReaderDataFromReaderArray();
+
+    List processNestedReaderDataFromReaderList();
+}
diff --git a/spring-5-reactive-client/src/main/java/com/baeldung/webclient/json/ReaderConsumerServiceImpl.java b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/json/ReaderConsumerServiceImpl.java
new file mode 100644
index 0000000000..8f1a4c019a
--- /dev/null
+++ b/spring-5-reactive-client/src/main/java/com/baeldung/webclient/json/ReaderConsumerServiceImpl.java
@@ -0,0 +1,90 @@
+package com.baeldung.webclient.json;
+
+import com.baeldung.webclient.json.model.Book;
+import com.baeldung.webclient.json.model.Reader;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.MediaType;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ReaderConsumerServiceImpl implements ReaderConsumerService {
+
+    private final WebClient webClient;
+    private static final ObjectMapper mapper = new ObjectMapper();
+
+    public ReaderConsumerServiceImpl(WebClient webClient) {
+        this.webClient = webClient;
+    }
+    @Override
+    public List processReaderDataFromObjectArray() {
+        Mono
+        
+            io.projectreactor
+            reactor-test
+            test
+        
+
 
         
         
@@ -149,7 +156,6 @@
     
 
     
-        1.0.1.RELEASE
         1.1.3
         1.0
         1.0
diff --git a/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalWebApplication.java b/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalWebApplication.java
index 1f40798ada..b89f74ad92 100644
--- a/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalWebApplication.java
+++ b/spring-5-reactive/src/main/java/com/baeldung/functional/FunctionalWebApplication.java
@@ -3,7 +3,7 @@ package com.baeldung.functional;
 import static org.springframework.web.reactive.function.BodyInserters.fromObject;
 import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
 import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
-import static org.springframework.web.reactive.function.server.RequestPredicates.path;
+import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
 import static org.springframework.web.reactive.function.server.RouterFunctions.route;
 import static org.springframework.web.reactive.function.server.RouterFunctions.toHttpHandler;
 import static org.springframework.web.reactive.function.server.ServerResponse.ok;
@@ -18,6 +18,7 @@ import org.apache.catalina.startup.Tomcat;
 import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
 import org.springframework.boot.web.server.WebServer;
 import org.springframework.core.io.ClassPathResource;
+import org.springframework.http.MediaType;
 import org.springframework.http.server.reactive.HttpHandler;
 import org.springframework.http.server.reactive.ServletHttpHandlerAdapter;
 import org.springframework.web.reactive.function.server.RouterFunction;
@@ -37,14 +38,14 @@ public class FunctionalWebApplication {
     private RouterFunction routingFunction() {
         FormHandler formHandler = new FormHandler();
 
-        RouterFunction restfulRouter = route(GET("/"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/"), serverRequest -> serverRequest.bodyToMono(Actor.class)
+        RouterFunction restfulRouter = route(GET("/actor"), serverRequest -> ok().body(Flux.fromIterable(actors), Actor.class)).andRoute(POST("/actor"), serverRequest -> serverRequest.bodyToMono(Actor.class)
             .doOnNext(actors::add)
             .then(ok().build()));
 
         return route(GET("/test"), serverRequest -> ok().body(fromObject("helloworld"))).andRoute(POST("/login"), formHandler::handleLogin)
             .andRoute(POST("/upload"), formHandler::handleUpload)
             .and(RouterFunctions.resources("/files/**", new ClassPathResource("files/")))
-            .andNest(path("/actor"), restfulRouter)
+            .andNest(accept(MediaType.APPLICATION_JSON), restfulRouter)
             .filter((request, next) -> {
                 System.out.println("Before handler invocation: " + request.path());
                 return next.handle(request);
diff --git a/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/Foo.java b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/Foo.java
new file mode 100644
index 0000000000..c6e3678832
--- /dev/null
+++ b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/Foo.java
@@ -0,0 +1,24 @@
+package com.baeldung.web.reactive.client;
+
+public class Foo {
+
+    private String name;
+
+    public Foo() {
+        super();
+    }
+
+    public Foo(String name) {
+        super();
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+}
diff --git a/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientApplication.java b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientApplication.java
new file mode 100644
index 0000000000..aa9b81de4f
--- /dev/null
+++ b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientApplication.java
@@ -0,0 +1,14 @@
+package com.baeldung.web.reactive.client;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration;
+
+@SpringBootApplication(exclude = { ReactiveSecurityAutoConfiguration.class })
+public class WebClientApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(WebClientApplication.class, args);
+    }
+
+}
diff --git a/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientController.java b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientController.java
index a719259328..1a91001807 100644
--- a/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientController.java
+++ b/spring-5-reactive/src/main/java/com/baeldung/web/reactive/client/WebClientController.java
@@ -1,83 +1,42 @@
 package com.baeldung.web.reactive.client;
 
-import org.reactivestreams.Publisher;
-import org.reactivestreams.Subscriber;
-import org.springframework.http.*;
-import org.springframework.util.LinkedMultiValueMap;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestPart;
 import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.reactive.function.BodyInserter;
-import org.springframework.web.reactive.function.BodyInserters;
-import org.springframework.web.reactive.function.client.WebClient;
-import reactor.core.publisher.Mono;
 
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.time.ZonedDateTime;
-import java.util.Collections;
+import reactor.core.publisher.Mono;
 
 @RestController
 public class WebClientController {
 
     @ResponseStatus(HttpStatus.OK)
     @GetMapping("/resource")
-    public void getResource() {
+    public Map getResource() {
+        Map response = new HashMap<>();
+        response.put("field", "value");
+        return response;
     }
 
-    public void demonstrateWebClient() {
-        // request
-        WebClient.UriSpec request1 = createWebClientWithServerURLAndDefaultValues().method(HttpMethod.POST);
-        WebClient.UriSpec request2 = createWebClientWithServerURLAndDefaultValues().post();
-
-        // request body specifications
-        WebClient.RequestBodySpec uri1 = createWebClientWithServerURLAndDefaultValues().method(HttpMethod.POST)
-            .uri("/resource");
-        WebClient.RequestBodySpec uri2 = createWebClientWithServerURLAndDefaultValues().post()
-            .uri(URI.create("/resource"));
-
-        // request header specification
-        WebClient.RequestHeadersSpec> requestSpec1 = uri1.body(BodyInserters.fromPublisher(Mono.just("data"), String.class));
-        WebClient.RequestHeadersSpec> requestSpec2 = uri2.body(BodyInserters.fromObject("data"));
-
-        // inserters
-        BodyInserter, ReactiveHttpOutputMessage> inserter1 = BodyInserters
-                .fromPublisher(Subscriber::onComplete, String.class);
-
-        LinkedMultiValueMap map = new LinkedMultiValueMap<>();
-        map.add("key1", "value1");
-        map.add("key2", "value2");
-
-        // BodyInserter, ClientHttpRequest> inserter2 = BodyInserters.fromMultipartData(map);
-        BodyInserter inserter3 = BodyInserters.fromObject("body");
-
-        // responses
-        WebClient.ResponseSpec response1 = uri1.body(inserter3)
-            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
-            .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
-            .acceptCharset(Charset.forName("UTF-8"))
-            .ifNoneMatch("*")
-            .ifModifiedSince(ZonedDateTime.now())
-            .retrieve();
-        WebClient.ResponseSpec response2 = requestSpec2.retrieve();
-
+    @PostMapping("/resource")
+    public Mono postStringResource(@RequestBody Mono bodyString) {
+        return bodyString.map(body -> "processed-" + body);
     }
 
-    private WebClient createWebClient() {
-        return WebClient.create();
+    @PostMapping("/resource-foo")
+    public Mono postFooResource(@RequestBody Mono bodyFoo) {
+        return bodyFoo.map(foo -> "processedFoo-" + foo.getName());
     }
 
-    private WebClient createWebClientWithServerURL() {
-        return WebClient.create("http://localhost:8081");
+    @PostMapping(value = "/resource-multipart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public String handleFormUpload(@RequestPart("key1") String value1, @RequestPart("key2") String value2) {
+        return "processed-" + value1 + "-" + value2;
     }
-
-    private WebClient createWebClientWithServerURLAndDefaultValues() {
-        return WebClient.builder()
-            .baseUrl("http://localhost:8081")
-            .defaultCookie("cookieKey", "cookieValue")
-            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
-            .defaultUriVariables(Collections.singletonMap("url", "http://localhost:8080"))
-            .build();
-    }
-
 }
diff --git a/spring-5-reactive/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java
index 38496d3500..5c0b4f69d0 100644
--- a/spring-5-reactive/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java
+++ b/spring-5-reactive/src/test/java/com/baeldung/functional/FunctionalWebApplicationIntegrationTest.java
@@ -103,7 +103,6 @@ public class FunctionalWebApplicationIntegrationTest {
             .isEqualTo(String.valueOf(resource.contentLength()));
     }
 
-    @Ignore("We get 404 after Spring Boot 2.4 upgrade. We need to solve it in a new task.")
     @Test
     public void givenActors_whenAddActor_thenAdded() throws Exception {
         client.get()
diff --git a/spring-5-reactive/src/test/java/com/baeldung/web/client/SpringContextTest.java b/spring-5-reactive/src/test/java/com/baeldung/web/client/SpringContextTest.java
new file mode 100644
index 0000000000..8d2ca41451
--- /dev/null
+++ b/spring-5-reactive/src/test/java/com/baeldung/web/client/SpringContextTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.web.client;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com.baeldung.web.reactive.client.WebClientApplication;
+
+@SpringBootTest(classes = WebClientApplication.class)
+public class SpringContextTest {
+
+    @Test
+    public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+    }
+}
diff --git a/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java
new file mode 100644
index 0000000000..39adf0b5c0
--- /dev/null
+++ b/spring-5-reactive/src/test/java/com/baeldung/web/client/WebClientIntegrationTest.java
@@ -0,0 +1,331 @@
+package com.baeldung.web.client;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.time.ZonedDateTime;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.Test;
+import org.reactivestreams.Publisher;
+import org.reactivestreams.Subscriber;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.core.codec.CodecException;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ReactiveHttpOutputMessage;
+import org.springframework.http.client.reactive.ClientHttpRequest;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.reactive.function.BodyInserter;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec;
+import org.springframework.web.reactive.function.client.WebClient.RequestBodyUriSpec;
+import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
+import org.springframework.web.reactive.function.client.WebClient.RequestHeadersUriSpec;
+import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
+import org.springframework.web.reactive.function.client.WebClientRequestException;
+
+import com.baeldung.web.reactive.client.Foo;
+import com.baeldung.web.reactive.client.WebClientApplication;
+
+import io.netty.channel.ChannelOption;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.handler.timeout.WriteTimeoutHandler;
+import reactor.core.publisher.Mono;
+import reactor.netty.http.client.HttpClient;
+import reactor.test.StepVerifier;
+
+@SpringBootTest(classes = WebClientApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
+public class WebClientIntegrationTest {
+
+    @LocalServerPort
+    private int port;
+
+    private static final String BODY_VALUE = "bodyValue";
+    private static final ParameterizedTypeReference
 
 
diff --git a/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties b/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties
index 27b7915cff..3d6f37230c 100644
--- a/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties
+++ b/spring-boot-modules/spring-boot-environment/src/main/resources/application.properties
@@ -2,6 +2,7 @@ management.endpoints.web.exposure.include=*
 management.metrics.enable.root=true
 management.metrics.enable.jvm=true
 management.endpoint.restart.enabled=true
-spring.datasource.jmx-enabled=false
+spring.datasource.tomcat.jmx-enabled=false
 spring.main.allow-bean-definition-overriding=true
-management.endpoint.shutdown.enabled=true
\ No newline at end of file
+management.endpoint.shutdown.enabled=true
+spring.config.import=file:./additional.properties,optional:file:/Users/home/config/jdbc.properties
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/properties/ApplicationPropertyImportExternalFileIntegrationTest.java b/spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/properties/ApplicationPropertyImportExternalFileIntegrationTest.java
new file mode 100644
index 0000000000..04f5445639
--- /dev/null
+++ b/spring-boot-modules/spring-boot-environment/src/test/java/com/baeldung/properties/ApplicationPropertyImportExternalFileIntegrationTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.properties;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+public class ApplicationPropertyImportExternalFileIntegrationTest {
+
+    @Value("${bael.property1}")
+    String baelProperty;
+
+    @Test
+    public void whenExternalisedPropertiesLoadedUsinApplicationProperties_thenReadValues() throws IOException {
+        assertEquals(baelProperty, "value1");
+    }
+
+}
diff --git a/spring-boot-modules/spring-boot-jasypt/src/test/java/org/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-jasypt/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-boot-modules/spring-boot-jasypt/src/test/java/org/baeldung/SpringContextTest.java
rename to spring-boot-modules/spring-boot-jasypt/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-boot-modules/spring-boot-libraries/pom.xml b/spring-boot-modules/spring-boot-libraries/pom.xml
index cec035cf93..c96a881573 100644
--- a/spring-boot-modules/spring-boot-libraries/pom.xml
+++ b/spring-boot-modules/spring-boot-libraries/pom.xml
@@ -239,7 +239,7 @@
 
     
         
-        com.baeldung.intro.App
+        com.baeldung.graphql.DemoApplication
         8.5.11
         2.4.1.Final
         1.9.0
diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/demo/DemoApplication.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/graphql/DemoApplication.java
similarity index 96%
rename from spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/demo/DemoApplication.java
rename to spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/graphql/DemoApplication.java
index e30ee6104d..1fd93af3b7 100644
--- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/demo/DemoApplication.java
+++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/graphql/DemoApplication.java
@@ -1,4 +1,4 @@
-package com.baeldung.demo;
+package com.baeldung.graphql;
 
 import com.baeldung.graphql.GraphqlConfiguration;
 import org.springframework.boot.SpringApplication;
diff --git a/spring-boot-modules/spring-boot-logging-log4j2/src/test/java/org/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-logging-log4j2/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-boot-modules/spring-boot-logging-log4j2/src/test/java/org/baeldung/SpringContextTest.java
rename to spring-boot-modules/spring-boot-logging-log4j2/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-boot-modules/spring-boot-mvc-3/pom.xml b/spring-boot-modules/spring-boot-mvc-3/pom.xml
index 1290b0432f..5a5d4c3cd8 100644
--- a/spring-boot-modules/spring-boot-mvc-3/pom.xml
+++ b/spring-boot-modules/spring-boot-mvc-3/pom.xml
@@ -37,8 +37,4 @@
         
     
 
-    
-        2.7
-    
-
 
diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java
index 72fa0e03c0..2a2b535be7 100644
--- a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java
+++ b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/defaults/ValuesWithDefaultsApp.java
@@ -51,21 +51,21 @@ public class ValuesWithDefaultsApp {
     @PostConstruct
     public void afterInitialize() {
     	// strings
-    	Assert.isTrue(stringWithDefaultValue.equals("my default value"));
-    	Assert.isTrue(stringWithBlankDefaultValue.equals(""));
+    	Assert.isTrue(stringWithDefaultValue.equals("my default value"), "unexpected value for stringWithDefaultValue");
+    	Assert.isTrue(stringWithBlankDefaultValue.equals(""), "unexpected value for stringWithBlankDefaultValue");
     	
     	// other primitives
-    	Assert.isTrue(booleanWithDefaultValue);
-    	Assert.isTrue(intWithDefaultValue == 42);
+    	Assert.isTrue(booleanWithDefaultValue, "unexpected value for booleanWithDefaultValue");
+    	Assert.isTrue(intWithDefaultValue == 42, "unexpected value for intWithDefaultValue");
     	
     	// arrays
         List stringListValues = Arrays.asList("one", "two", "three");
-    	Assert.isTrue(Arrays.asList(stringArrayWithDefaults).containsAll(stringListValues));
+    	Assert.isTrue(Arrays.asList(stringArrayWithDefaults).containsAll(stringListValues), "unexpected value for stringArrayWithDefaults");
 
         List intListValues = Arrays.asList(1, 2, 3);
-    	Assert.isTrue(Arrays.asList(ArrayUtils.toObject(intArrayWithDefaults)).containsAll(intListValues));
+    	Assert.isTrue(Arrays.asList(ArrayUtils.toObject(intArrayWithDefaults)).containsAll(intListValues), "unexpected value for intArrayWithDefaults");
 
     	// SpEL
-    	Assert.isTrue(spelWithDefaultValue.equals("my default system property value"));
+    	Assert.isTrue(spelWithDefaultValue.equals("my default system property value"), "unexpected value for spelWithDefaultValue");
     }
 }
diff --git a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/lists/ListsPropertiesUnitTest.java b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/lists/ListsPropertiesUnitTest.java
index 60ba4cc108..1abb643d75 100644
--- a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/lists/ListsPropertiesUnitTest.java
+++ b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/lists/ListsPropertiesUnitTest.java
@@ -13,6 +13,7 @@ import java.util.Collections;
 import java.util.List;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes = SpringListPropertiesApplication.class)
@@ -47,7 +48,7 @@ public class ListsPropertiesUnitTest {
 
     @Test
     public void whenContextIsInitialized_thenInjectedArrayContainsExpectedValues() {
-        assertEquals(new String[] {"Baeldung", "dot", "com"}, arrayOfStrings);
+        assertArrayEquals(new String[] {"Baeldung", "dot", "com"}, arrayOfStrings);
     }
 
     @Test
@@ -82,7 +83,7 @@ public class ListsPropertiesUnitTest {
         String[] arrayOfStrings = environment.getProperty("arrayOfStrings", String[].class);
         List listOfStrings = (List)environment.getProperty("arrayOfStrings", List.class);
 
-        assertEquals(new String[] {"Baeldung", "dot", "com"}, arrayOfStrings);
+        assertArrayEquals(new String[] {"Baeldung", "dot", "com"}, arrayOfStrings);
         assertEquals(Arrays.asList("Baeldung", "dot", "com"), listOfStrings);
     }
 }
diff --git a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlComplexListsUnitTest.java b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlComplexListsUnitTest.java
index 6dc5d61d09..ce9ec38551 100644
--- a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlComplexListsUnitTest.java
+++ b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlComplexListsUnitTest.java
@@ -6,14 +6,14 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
+import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import com.baeldung.properties.yamllist.pojo.ApplicationProps;
 
 @ExtendWith(SpringExtension.class)
-@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
+@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
 @EnableConfigurationProperties(value = ApplicationProps.class)
 class YamlComplexListsUnitTest {
 
diff --git a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlSimpleListUnitTest.java b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlSimpleListUnitTest.java
index 475a73c7d7..5315c7b9bc 100644
--- a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlSimpleListUnitTest.java
+++ b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/yamllist/YamlSimpleListUnitTest.java
@@ -6,14 +6,14 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
+import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import com.baeldung.properties.yamllist.pojo.ApplicationProps;
 
 @ExtendWith(SpringExtension.class)
-@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
+@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
 @EnableConfigurationProperties(value = ApplicationProps.class)
 class YamlSimpleListUnitTest {
 
diff --git a/spring-boot-modules/spring-boot-properties-3/pom.xml b/spring-boot-modules/spring-boot-properties-3/pom.xml
index 44e2ef52ac..809fd6e2d4 100644
--- a/spring-boot-modules/spring-boot-properties-3/pom.xml
+++ b/spring-boot-modules/spring-boot-properties-3/pom.xml
@@ -26,12 +26,6 @@
             org.springframework.boot
             spring-boot-starter-test
             test
-            
-                
-                    org.junit.vintage
-                    junit-vintage-engine
-                
-            
         
         
             org.springframework.boot
diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-multidocument-integration.properties b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-multidocument-integration.properties
new file mode 100644
index 0000000000..f3bac4c614
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application-multidocument-integration.properties
@@ -0,0 +1,4 @@
+spring.datasource.password=password
+spring.datasource.url=jdbc:mysql://localhost:3306/db_integration
+spring.datasource.username=user
+bael.property=integrationValue
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties
index eace1f0e46..a079837942 100644
--- a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties
+++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.properties
@@ -8,4 +8,22 @@ spring.datasource.url=jdbc:h2:dev
 spring.datasource.username=SA
 spring.datasource.password=password
 app.name=MyApp
-app.description=${app.name} is a Spring Boot application
\ No newline at end of file
+app.description=${app.name} is a Spring Boot application
+logging.file.name=myapplication.log
+bael.property=defaultValue
+bael.otherProperty=defaultOtherValue
+#---
+spring.config.activate.on-profile=multidocument-dev
+spring.datasource.password=password
+spring.datasource.url=jdbc:h2:dev
+spring.datasource.username=SA
+bael.property=devValue
+#---
+spring.config.activate.on-profile=multidocument-integration-extension
+bael.otherProperty=integrationExtensionOtherValue
+#---
+spring.config.activate.on-profile=multidocument-prod
+spring.datasource.password=password
+spring.datasource.url=jdbc:h2:prod
+spring.datasource.username=prodUser
+bael.property=prodValue
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml
index 00baeade9c..10570bb738 100644
--- a/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml
+++ b/spring-boot-modules/spring-boot-properties-3/src/main/resources/application.yml
@@ -1,17 +1,21 @@
-logging:
-  file:
-    name: myapplication.log
+bael:
+  root-level-property: defaultRootLevelValue
 spring:
-  datasource:
-    password: 'password'
-    url: jdbc:h2:dev
-    username: SA
+  profiles:
+    group:
+      multidocument-integration: multidocument-integration-extension
 ---
 spring:
+  config:
+    activate:
+      on-profile: multidocument-staging
   datasource:
     password: 'password'
-    url: jdbc:mysql://localhost:3306/db_production
-    username: user
+    url: jdbc:h2:staging
+    username: SA
+bael:
+  property: stagingValue
+---
 application:
   servers:
     -   ip: '127.0.0.1'
diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/DefaultMultidocumentFilesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/DefaultMultidocumentFilesIntegrationTest.java
new file mode 100644
index 0000000000..af1f7f705f
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/DefaultMultidocumentFilesIntegrationTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.boot.properties.multidocument;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+
+import com.baeldung.boot.properties.DemoApplication;
+
+@SpringBootTest(classes = { DemoApplication.class }, webEnvironment = WebEnvironment.MOCK)
+public class DefaultMultidocumentFilesIntegrationTest {
+
+    @Value("${bael.property}")
+    private String baelCustomProperty;
+    
+    @Value("${bael.root-level-property}")
+    private String baelRootProperty;
+
+    @Test
+    public void givenDefaultProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() {
+        assertThat(baelCustomProperty).isEqualTo("defaultValue");
+        assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue");
+    }
+}
diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/DevMultidocumentFilesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/DevMultidocumentFilesIntegrationTest.java
new file mode 100644
index 0000000000..54188595c0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/DevMultidocumentFilesIntegrationTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.boot.properties.multidocument;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.baeldung.boot.properties.DemoApplication;
+
+@SpringBootTest(classes = { DemoApplication.class }, webEnvironment = WebEnvironment.MOCK)
+@ActiveProfiles("multidocument-dev")
+public class DevMultidocumentFilesIntegrationTest {
+
+    @Value("${bael.property}")
+    private String baelCustomProperty;
+    
+    @Value("${bael.root-level-property}")
+    private String baelRootProperty;
+
+    @Test
+    public void givenDefaultProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() {
+        assertThat(baelCustomProperty).isEqualTo("devValue");
+        assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue");
+    }
+}
diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/IntegrationMultidocumentFilesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/IntegrationMultidocumentFilesIntegrationTest.java
new file mode 100644
index 0000000000..e0727154d0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/IntegrationMultidocumentFilesIntegrationTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.boot.properties.multidocument;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.baeldung.boot.properties.DemoApplication;
+
+@SpringBootTest(classes = { DemoApplication.class }, webEnvironment = WebEnvironment.MOCK)
+@ActiveProfiles("multidocument-integration")
+public class IntegrationMultidocumentFilesIntegrationTest {
+
+    @Value("${bael.property}")
+    private String baelCustomProperty;
+    
+    @Value("${bael.otherProperty}")
+    private String baelCustomOtherProperty;
+    
+    @Value("${bael.root-level-property}")
+    private String baelRootProperty;
+
+    @Test
+    public void givenProductionProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() {
+        assertThat(baelCustomProperty).isEqualTo("integrationValue");
+        assertThat(baelCustomOtherProperty).isEqualTo("integrationExtensionOtherValue");
+        assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue");
+    }
+}
diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/ProdMultidocumentFilesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/ProdMultidocumentFilesIntegrationTest.java
new file mode 100644
index 0000000000..9270995da0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/ProdMultidocumentFilesIntegrationTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.boot.properties.multidocument;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.baeldung.boot.properties.DemoApplication;
+
+@SpringBootTest(classes = { DemoApplication.class }, webEnvironment = WebEnvironment.MOCK)
+@ActiveProfiles("multidocument-prod")
+public class ProdMultidocumentFilesIntegrationTest {
+
+    @Value("${bael.property}")
+    private String baelCustomProperty;
+    
+    @Value("${bael.root-level-property}")
+    private String baelRootProperty;
+
+    @Test
+    public void givenProductionProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() {
+        assertThat(baelCustomProperty).isEqualTo("prodValue");
+        assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue");
+    }
+}
diff --git a/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java
new file mode 100644
index 0000000000..8040c93ee0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-properties-3/src/test/java/com/baeldung/boot/properties/multidocument/StagingMultidocumentFilesIntegrationTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.boot.properties.multidocument;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.baeldung.boot.properties.DemoApplication;
+
+@SpringBootTest(classes = { DemoApplication.class }, webEnvironment = WebEnvironment.MOCK)
+@ActiveProfiles("multidocument-staging")
+public class StagingMultidocumentFilesIntegrationTest {
+
+    @Value("${bael.property}")
+    private String baelCustomProperty;
+    
+    @Value("${bael.root-level-property}")
+    private String baelRootProperty;
+
+    @Test
+    public void givenProductionProfileActive_whenApplicationStarts_thenDefaultPropertiesUser() {
+        assertThat(baelCustomProperty).isEqualTo("stagingValue");
+        assertThat(baelRootProperty).isEqualTo("defaultRootLevelValue");
+    }
+}
diff --git a/spring-boot-modules/spring-boot-properties/pom.xml b/spring-boot-modules/spring-boot-properties/pom.xml
index 0260a4a72e..40668f47fd 100644
--- a/spring-boot-modules/spring-boot-properties/pom.xml
+++ b/spring-boot-modules/spring-boot-properties/pom.xml
@@ -141,7 +141,6 @@
         @
         
         com.baeldung.yaml.MyApplication
-        2.4.0
     
 
 
diff --git a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/properties/reloading/configs/ReloadablePropertySource.java b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/properties/reloading/configs/ReloadablePropertySource.java
index 5d4e170226..e63dc1eb54 100644
--- a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/properties/reloading/configs/ReloadablePropertySource.java
+++ b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/properties/reloading/configs/ReloadablePropertySource.java
@@ -15,7 +15,7 @@ public class ReloadablePropertySource extends PropertySource {
     }
 
     public ReloadablePropertySource(String name, String path) {
-        super(StringUtils.hasText(name) ? path : name);
+        super(!StringUtils.hasText(name) ? path : name);
         try {
             this.propertiesConfiguration = new PropertiesConfiguration(path);
             FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
diff --git a/spring-boot-modules/spring-boot-security/README.md b/spring-boot-modules/spring-boot-security/README.md
index 7229ba0f4a..2c9d37eac0 100644
--- a/spring-boot-modules/spring-boot-security/README.md
+++ b/spring-boot-modules/spring-boot-security/README.md
@@ -8,6 +8,8 @@ This module contains articles about Spring Boot Security
 - [Spring Security for Spring Boot Integration Tests](https://www.baeldung.com/spring-security-integration-tests)
 - [Introduction to Spring Security Taglibs](https://www.baeldung.com/spring-security-taglibs)
 - [Guide to @CurrentSecurityContext in Spring Security](https://www.baeldung.com/spring-currentsecuritycontext)
+- [Disable Security for a Profile in Spring Boot](https://www.baeldung.com/spring-security-disable-profile)
+
 
 ### Spring Boot Security Auto-Configuration
 
diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/Application.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/Application.java
similarity index 100%
rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/Application.java
rename to spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/Application.java
diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/ApplicationNoSecurity.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/ApplicationNoSecurity.java
similarity index 100%
rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/ApplicationNoSecurity.java
rename to spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/ApplicationNoSecurity.java
diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/ApplicationSecurity.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/ApplicationSecurity.java
similarity index 100%
rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/ApplicationSecurity.java
rename to spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/ApplicationSecurity.java
diff --git a/spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/EmployeeController.java b/spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/EmployeeController.java
similarity index 100%
rename from spring-security-modules/spring-5-security/src/main/java/com/baeldung/securityprofile/EmployeeController.java
rename to spring-boot-modules/spring-boot-security/src/main/java/com/baeldung/securityprofile/EmployeeController.java
diff --git a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerNoSecurityUnitTest.java b/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerNoSecurityUnitTest.java
similarity index 100%
rename from spring-security-modules/spring-5-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerNoSecurityUnitTest.java
rename to spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerNoSecurityUnitTest.java
diff --git a/spring-security-modules/spring-5-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerUnitTest.java b/spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerUnitTest.java
similarity index 100%
rename from spring-security-modules/spring-5-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerUnitTest.java
rename to spring-boot-modules/spring-boot-security/src/test/java/com/baeldung/securityprofile/EmployeeControllerUnitTest.java
diff --git a/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/RegularRestController.java b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/RegularRestController.java
new file mode 100644
index 0000000000..f3135229d6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/RegularRestController.java
@@ -0,0 +1,31 @@
+package com.baeldung.springdoc.controller;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import io.swagger.v3.oas.annotations.Hidden;
+
+@Hidden
+@RestController
+public class RegularRestController {
+
+    @Hidden
+    @GetMapping("/getAuthor")
+    public String getAuthor() {
+        return "Umang Budhwar";
+    }
+
+    @GetMapping("/getDate")
+    public LocalDate getDate() {
+        return LocalDate.now();
+    }
+
+    @GetMapping("/getTime")
+    public LocalTime getTime() {
+        return LocalTime.now();
+    }
+
+}
diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml
index 5bf626f165..50a1ace2fa 100644
--- a/spring-boot-modules/spring-boot-testing/pom.xml
+++ b/spring-boot-modules/spring-boot-testing/pom.xml
@@ -51,6 +51,17 @@
             spring-boot-starter-test
             test
         
+        
+            org.junit.vintage
+            junit-vintage-engine
+            test
+            
+                
+                    org.hamcrest
+                    hamcrest-core
+                
+            
+        
 
         
         
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingYMLPropertiesUnitTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingYMLPropertiesUnitTest.java
index 5543f5e9e8..99c128997e 100644
--- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingYMLPropertiesUnitTest.java
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/boot/configurationproperties/BindingYMLPropertiesUnitTest.java
@@ -7,13 +7,13 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
+import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 @ExtendWith(SpringExtension.class)
-@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class)
+@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)
 @EnableConfigurationProperties(value = ServerConfig.class)
 @ActiveProfiles("test")
 public class BindingYMLPropertiesUnitTest {
diff --git a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/prevent/commandline/application/runner/execution/LoadSpringContextIntegrationTest.java b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/prevent/commandline/application/runner/execution/LoadSpringContextIntegrationTest.java
index 6698094550..483c67b7a2 100644
--- a/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/prevent/commandline/application/runner/execution/LoadSpringContextIntegrationTest.java
+++ b/spring-boot-modules/spring-boot-testing/src/test/java/com/baeldung/prevent/commandline/application/runner/execution/LoadSpringContextIntegrationTest.java
@@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.boot.CommandLineRunner;
-import org.springframework.boot.test.context.ConfigFileApplicationContextInitializer;
+import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer;
 import org.springframework.boot.test.mock.mockito.SpyBean;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -19,7 +19,7 @@ import static org.mockito.Mockito.verify;
 
 @ExtendWith(SpringExtension.class)
 @ContextConfiguration(classes = { ApplicationCommandLineRunnerApp.class }, 
-  initializers = ConfigFileApplicationContextInitializer.class)
+  initializers = ConfigDataApplicationContextInitializer.class)
 public class LoadSpringContextIntegrationTest {
     @SpyBean
     TaskService taskService;
diff --git a/spring-boot-modules/spring-boot-testing/src/test/resources/application.yml b/spring-boot-modules/spring-boot-testing/src/test/resources/application.yml
index 1b46b0f1ff..056b5baffc 100644
--- a/spring-boot-modules/spring-boot-testing/src/test/resources/application.yml
+++ b/spring-boot-modules/spring-boot-testing/src/test/resources/application.yml
@@ -1,5 +1,7 @@
 spring:
-   profiles: test
+   config:
+    activate:
+      on-profile: test
 server:
    address:
       ip: 192.168.0.4
@@ -7,7 +9,9 @@ server:
       imgs: /etc/test/imgs
 ---
 spring:
-   profiles: dev
+   config:
+    activate:
+      on-profile: dev
 server:
    address:
       ip: 192.168.0.5
diff --git a/spring-boot-modules/spring-boot-vue/src/test/java/org/baeldung/SpringContextTest.java b/spring-boot-modules/spring-boot-vue/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-boot-modules/spring-boot-vue/src/test/java/org/baeldung/SpringContextTest.java
rename to spring-boot-modules/spring-boot-vue/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-boot-modules/spring-boot/pom.xml b/spring-boot-modules/spring-boot/pom.xml
index c1f1ea3072..9023ae92f3 100644
--- a/spring-boot-modules/spring-boot/pom.xml
+++ b/spring-boot-modules/spring-boot/pom.xml
@@ -1,7 +1,7 @@
 
 
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     4.0.0
 
     
@@ -58,6 +58,17 @@
             spring-boot-starter-test
             test
         
+        
+            org.junit.vintage
+            junit-vintage-engine
+            test
+            
+                
+                    org.hamcrest
+                    hamcrest-core
+                
+            
+        
 
         
             io.dropwizard.metrics
diff --git a/spring-cloud/spring-cloud-config/client/pom.xml b/spring-cloud/spring-cloud-config/client/pom.xml
index 805a50bfdb..2400520d2b 100644
--- a/spring-cloud/spring-cloud-config/client/pom.xml
+++ b/spring-cloud/spring-cloud-config/client/pom.xml
@@ -1,7 +1,7 @@
 
 
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     4.0.0
     client
     client
@@ -26,6 +26,17 @@
             spring-boot-starter-test
             test
         
+        
+            org.junit.vintage
+            junit-vintage-engine
+            test
+            
+                
+                    org.hamcrest
+                    hamcrest-core
+                
+            
+        
     
 
     
diff --git a/spring-cloud/spring-cloud-config/pom.xml b/spring-cloud/spring-cloud-config/pom.xml
index 5db18a7245..bfe17044e0 100644
--- a/spring-cloud/spring-cloud-config/pom.xml
+++ b/spring-cloud/spring-cloud-config/pom.xml
@@ -33,8 +33,7 @@
     
 
     
-        Hoxton.SR4
-        2.3.3.RELEASE
+        2020.0.0
     
 
 
diff --git a/spring-cloud/spring-cloud-config/server/pom.xml b/spring-cloud/spring-cloud-config/server/pom.xml
index e32a473cd6..f0f1e43612 100644
--- a/spring-cloud/spring-cloud-config/server/pom.xml
+++ b/spring-cloud/spring-cloud-config/server/pom.xml
@@ -1,11 +1,11 @@
 
 
+    xmlns="http://maven.apache.org/POM/4.0.0"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     4.0.0
     server
     server
-	
+
     
         com.baeldung.spring.cloud
         spring-cloud-config
@@ -30,6 +30,17 @@
             spring-boot-starter-test
             test
         
+        
+            org.junit.vintage
+            junit-vintage-engine
+            test
+            
+                
+                    org.hamcrest
+                    hamcrest-core
+                
+            
+        
     
 
     
diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/GreetingControllerManualTest.java b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/GreetingControllerIntegrationTest.java
similarity index 88%
rename from spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/GreetingControllerManualTest.java
rename to spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/GreetingControllerIntegrationTest.java
index 4d3cede534..7fdc723305 100644
--- a/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/GreetingControllerManualTest.java
+++ b/spring-cloud/spring-cloud-zuul/spring-zuul-rate-limiting/src/test/java/com/baeldung/spring/cloud/zuulratelimitdemo/controller/GreetingControllerIntegrationTest.java
@@ -5,14 +5,21 @@ import static com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateL
 import static com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitConstants.HEADER_REMAINING;
 import static com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitConstants.HEADER_REMAINING_QUOTA;
 import static com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.support.RateLimitConstants.HEADER_RESET;
+import static java.lang.Integer.parseInt;
+import static org.hamcrest.Matchers.both;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThanOrEqualTo;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
 import static org.springframework.http.HttpStatus.OK;
 import static org.springframework.http.HttpStatus.TOO_MANY_REQUESTS;
 
 import java.util.concurrent.TimeUnit;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,7 +33,7 @@ import org.springframework.test.context.junit4.SpringRunner;
 @AutoConfigureTestDatabase
 @RunWith(SpringRunner.class)
 @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-public class GreetingControllerManualTest {
+public class GreetingControllerIntegrationTest {
 
     private static final String SIMPLE_GREETING = "/greeting/simple";
     private static final String ADVANCED_GREETING = "/greeting/advanced";
@@ -44,9 +51,13 @@ public class GreetingControllerManualTest {
         String remaining = headers.getFirst(HEADER_REMAINING + key);
         String reset = headers.getFirst(HEADER_RESET + key);
 
-        assertEquals(limit, "5");
-        assertEquals(remaining, "4");
-        assertEquals(reset, "60000");
+        assertEquals("5", limit);
+        assertEquals(remaining, "4", remaining);
+        assertNotNull(reset);
+        assertThat(
+                parseInt(reset),
+                is(both(greaterThanOrEqualTo(0)).and(lessThanOrEqualTo(60000)))
+        );
 
         assertEquals(OK, response.getStatusCode());
     }
diff --git a/spring-core/pom.xml b/spring-core/pom.xml
index eb25bcd517..7d83fc198c 100644
--- a/spring-core/pom.xml
+++ b/spring-core/pom.xml
@@ -65,7 +65,7 @@
         
             commons-io
             commons-io
-            ${commons.io.version}
+            ${commons-io.version}
         
     
 
@@ -86,7 +86,6 @@
         1.4.4.RELEASE
         1
         20.0
-        2.5
         1.5.2.RELEASE
         1.10.19
         3.12.2
diff --git a/spring-di/pom.xml b/spring-di/pom.xml
index 48cdf60673..df0b685ae2 100644
--- a/spring-di/pom.xml
+++ b/spring-di/pom.xml
@@ -83,7 +83,7 @@
         
             commons-io
             commons-io
-            ${commons.io.version}
+            ${commons-io.version}
         
         
             org.aspectj
@@ -159,7 +159,6 @@
         1.4.4.RELEASE
         1
         20.0
-        2.5
         1.5.2.RELEASE
         1.10.19
         3.12.2
diff --git a/spring-mvc-xml/src/main/resources/messages.properties b/spring-mvc-xml/src/main/resources/messages.properties
deleted file mode 100644
index 2a3cccf76c..0000000000
--- a/spring-mvc-xml/src/main/resources/messages.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-required.name = Name is required!
-NotEmpty.person.password = Password is required!
\ No newline at end of file
diff --git a/spring-security-modules/spring-5-security/README.md b/spring-security-modules/spring-5-security/README.md
index 6847d4bf5c..1917d347fb 100644
--- a/spring-security-modules/spring-5-security/README.md
+++ b/spring-security-modules/spring-5-security/README.md
@@ -9,6 +9,5 @@ This module contains articles about Spring Security 5
 - [New Password Storage In Spring Security 5](https://www.baeldung.com/spring-security-5-password-storage)
 - [Default Password Encoder in Spring Security 5](https://www.baeldung.com/spring-security-5-default-password-encoder)
 - [Guide to the AuthenticationManagerResolver in Spring Security](https://www.baeldung.com/spring-security-authenticationmanagerresolver)
-- [Disable Security for a Profile in Spring Boot](https://www.baeldung.com/spring-security-disable-profile)
 - [Manual Logout With Spring Security](https://www.baeldung.com/spring-security-manual-logout)
 - [How to Disable Spring Security Logout Redirects](https://www.baeldung.com/spring-security-disable-logout-redirects)
diff --git a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java
index aa93201f37..f08b824369 100644
--- a/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java
+++ b/spring-security-modules/spring-security-web-boot-2/src/main/java/com/baeldung/loginredirect/LoginPageInterceptor.java
@@ -1,16 +1,16 @@
 package com.baeldung.loginredirect;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.http.HttpStatus;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.util.UrlPathHelper;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-class LoginPageInterceptor extends HandlerInterceptorAdapter {
+class LoginPageInterceptor implements HandlerInterceptor {
 
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
diff --git a/spring-security-modules/spring-security-web-rest/pom.xml b/spring-security-modules/spring-security-web-rest/pom.xml
index d2468152da..2330243aa6 100644
--- a/spring-security-modules/spring-security-web-rest/pom.xml
+++ b/spring-security-modules/spring-security-web-rest/pom.xml
@@ -168,7 +168,6 @@
             ${springfox-swagger.version}
         
 
-        
         
             commons-fileupload
             commons-fileupload
@@ -271,7 +270,6 @@
 
         
         26.0-jre
-        1.3.2
 
         
         2.9.0
diff --git a/spring-web-modules/pom.xml b/spring-web-modules/pom.xml
index c28ffbeab8..37ee84da25 100644
--- a/spring-web-modules/pom.xml
+++ b/spring-web-modules/pom.xml
@@ -14,17 +14,30 @@
     
 
     
+        spring-5-mvc
         spring-mvc-basics
         spring-mvc-basics-2
         spring-mvc-basics-3
         spring-mvc-basics-4     
         spring-mvc-crash
         spring-mvc-forms-jsp
+        spring-mvc-forms-thymeleaf
+        spring-mvc-java
+        spring-mvc-java-2
+        spring-mvc-velocity
         spring-mvc-views
         spring-mvc-webflow
+        spring-mvc-xml
         spring-rest-angular
         spring-rest-http
+        spring-rest-http-2
+        spring-rest-query-language
+        spring-rest-shell
+        spring-rest-simple
+        spring-rest-testing
+        spring-resttemplate
         spring-resttemplate-2
+        spring-resttemplate-3
         spring-thymeleaf
         spring-thymeleaf-2
         spring-thymeleaf-3
diff --git a/spring-5-mvc/.gitignore b/spring-web-modules/spring-5-mvc/.gitignore
similarity index 100%
rename from spring-5-mvc/.gitignore
rename to spring-web-modules/spring-5-mvc/.gitignore
diff --git a/spring-5-mvc/README.md b/spring-web-modules/spring-5-mvc/README.md
similarity index 100%
rename from spring-5-mvc/README.md
rename to spring-web-modules/spring-5-mvc/README.md
diff --git a/spring-5-mvc/pom.xml b/spring-web-modules/spring-5-mvc/pom.xml
similarity index 97%
rename from spring-5-mvc/pom.xml
rename to spring-web-modules/spring-5-mvc/pom.xml
index 39fcd22824..ddcce8207b 100644
--- a/spring-5-mvc/pom.xml
+++ b/spring-web-modules/spring-5-mvc/pom.xml
@@ -12,8 +12,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
-        
+        ../../parent-boot-2
     
 
     
diff --git a/spring-5-mvc/src/main/java/com/baeldung/Constants.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/Constants.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/Constants.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/Constants.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/html/HtmlApplication.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/html/HtmlApplication.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/html/HtmlApplication.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/html/HtmlApplication.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/html/HtmlController.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/html/HtmlController.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/html/HtmlController.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/html/HtmlController.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/idc/Application.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/Application.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/idc/Application.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/Application.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/idc/Book.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/Book.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/idc/Book.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/Book.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/idc/BookController.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/BookController.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/idc/BookController.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/BookController.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/idc/BookOperations.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/BookOperations.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/idc/BookOperations.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/BookOperations.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/idc/BookRepository.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/BookRepository.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/idc/BookRepository.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/idc/BookRepository.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/model/Foo.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java
similarity index 97%
rename from spring-5-mvc/src/main/java/com/baeldung/web/FooController.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java
index 137864cddd..8d8e03bbaf 100644
--- a/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java
+++ b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java
@@ -1,66 +1,66 @@
-package com.baeldung.web;
-
-import java.util.List;
-
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.http.HttpStatus;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseStatus;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.server.ResponseStatusException;
-
-import com.baeldung.model.Foo;
-import com.baeldung.persistence.FooRepository;
-
-@RestController
-public class FooController {
-
-    @Autowired
-    private FooRepository repo;
-
-    // API - read
-
-    @GetMapping("/foos/{id}")    
-    @Validated
-    public Foo findById(@PathVariable @Min(0) final long id) {
-        return repo.findById(id).orElse(null);
-    }
-
-    @GetMapping("/foos")   
-    public List findAll() {               
-        return repo.findAll();
-    }
-
-    @GetMapping( value="/foos",  params = { "page", "size" })    
-    @Validated
-    public List findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) {
-        return repo.findAll(PageRequest.of(page, size)).getContent();
-    }
-
-    // API - write
-
-    @PutMapping("/foos/{id}")
-    @ResponseStatus(HttpStatus.OK)    
-    public Foo update(@PathVariable("id") final String id, @RequestBody final Foo foo) {
-        return foo;
-    }
-
-    @PostMapping("/foos")
-    @ResponseStatus(HttpStatus.CREATED)    
-    public void create( @RequestBody final Foo foo) {
-        if (null == foo ||  null == foo.getName()) {
-            throw new ResponseStatusException(HttpStatus.BAD_REQUEST," 'name' is required");
-        }
-        repo.save(foo);
-    }
+package com.baeldung.web;
+
+import java.util.List;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ResponseStatusException;
+
+import com.baeldung.model.Foo;
+import com.baeldung.persistence.FooRepository;
+
+@RestController
+public class FooController {
+
+    @Autowired
+    private FooRepository repo;
+
+    // API - read
+
+    @GetMapping("/foos/{id}")    
+    @Validated
+    public Foo findById(@PathVariable @Min(0) final long id) {
+        return repo.findById(id).orElse(null);
+    }
+
+    @GetMapping("/foos")   
+    public List findAll() {               
+        return repo.findAll();
+    }
+
+    @GetMapping( value="/foos",  params = { "page", "size" })    
+    @Validated
+    public List findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) {
+        return repo.findAll(PageRequest.of(page, size)).getContent();
+    }
+
+    // API - write
+
+    @PutMapping("/foos/{id}")
+    @ResponseStatus(HttpStatus.OK)    
+    public Foo update(@PathVariable("id") final String id, @RequestBody final Foo foo) {
+        return foo;
+    }
+
+    @PostMapping("/foos")
+    @ResponseStatus(HttpStatus.CREATED)    
+    public void create( @RequestBody final Foo foo) {
+        if (null == foo ||  null == foo.getName()) {
+            throw new ResponseStatusException(HttpStatus.BAD_REQUEST," 'name' is required");
+        }
+        repo.save(foo);
+    }
 }
\ No newline at end of file
diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/ResponseBodyEmitterController.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/SseEmitterController.java
diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java b/spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java
similarity index 100%
rename from spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java
rename to spring-web-modules/spring-5-mvc/src/main/java/com/baeldung/web/StreamingResponseBodyController.java
diff --git a/spring-5-mvc/src/main/resources/application.properties b/spring-web-modules/spring-5-mvc/src/main/resources/application.properties
similarity index 100%
rename from spring-5-mvc/src/main/resources/application.properties
rename to spring-web-modules/spring-5-mvc/src/main/resources/application.properties
diff --git a/spring-jooq/src/main/resources/logback.xml b/spring-web-modules/spring-5-mvc/src/main/resources/logback.xml
similarity index 100%
rename from spring-jooq/src/main/resources/logback.xml
rename to spring-web-modules/spring-5-mvc/src/main/resources/logback.xml
diff --git a/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-web-modules/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp
similarity index 100%
rename from spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp
rename to spring-web-modules/spring-5-mvc/src/main/webapp/WEB-INF/jsp/index.jsp
diff --git a/spring-5-mvc/src/main/webapp/WEB-INF/web.xml b/spring-web-modules/spring-5-mvc/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from spring-5-mvc/src/main/webapp/WEB-INF/web.xml
rename to spring-web-modules/spring-5-mvc/src/main/webapp/WEB-INF/web.xml
diff --git a/spring-5-mvc/src/test/java/com/baeldung/LiveTest.java b/spring-web-modules/spring-5-mvc/src/test/java/com/baeldung/LiveTest.java
similarity index 100%
rename from spring-5-mvc/src/test/java/com/baeldung/LiveTest.java
rename to spring-web-modules/spring-5-mvc/src/test/java/com/baeldung/LiveTest.java
diff --git a/spring-5-mvc/src/test/java/com/baeldung/Spring5ApplicationIntegrationTest.java b/spring-web-modules/spring-5-mvc/src/test/java/com/baeldung/Spring5ApplicationIntegrationTest.java
similarity index 100%
rename from spring-5-mvc/src/test/java/com/baeldung/Spring5ApplicationIntegrationTest.java
rename to spring-web-modules/spring-5-mvc/src/test/java/com/baeldung/Spring5ApplicationIntegrationTest.java
diff --git a/spring-5-mvc/src/test/java/com/baeldung/html/HtmlControllerTest.java b/spring-web-modules/spring-5-mvc/src/test/java/com/baeldung/html/HtmlControllerTest.java
similarity index 100%
rename from spring-5-mvc/src/test/java/com/baeldung/html/HtmlControllerTest.java
rename to spring-web-modules/spring-5-mvc/src/test/java/com/baeldung/html/HtmlControllerTest.java
diff --git a/spring-web-modules/spring-mvc-basics-2/pom.xml b/spring-web-modules/spring-mvc-basics-2/pom.xml
index e16b54b2c8..0b4515994b 100644
--- a/spring-web-modules/spring-mvc-basics-2/pom.xml
+++ b/spring-web-modules/spring-mvc-basics-2/pom.xml
@@ -168,7 +168,6 @@
         4.0.0
         6.0.10.Final
         enter-location-of-server
-        1.3.2
         3.0.11.RELEASE
         2.4.12
         2.3.27-incubating
diff --git a/spring-web-modules/spring-mvc-basics-3/src/main/java/com/baeldung/exclude_urls_filter/filter/HeaderValidatorFilter.java b/spring-web-modules/spring-mvc-basics-3/src/main/java/com/baeldung/exclude_urls_filter/filter/HeaderValidatorFilter.java
index 2af90badae..d6c1777326 100644
--- a/spring-web-modules/spring-mvc-basics-3/src/main/java/com/baeldung/exclude_urls_filter/filter/HeaderValidatorFilter.java
+++ b/spring-web-modules/spring-mvc-basics-3/src/main/java/com/baeldung/exclude_urls_filter/filter/HeaderValidatorFilter.java
@@ -11,20 +11,23 @@ import java.io.IOException;
 
 @Order(1)
 public class HeaderValidatorFilter extends OncePerRequestFilter {
-	@Override
-	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-	        throws ServletException, IOException {
-	    String path = request.getRequestURI();
-	    if ("/health".equals(path)) {
-	    	filterChain.doFilter(request, response);
-	    	return;
-	    }
-	    String countryCode = request.getHeader("X-Country-Code");
-	    if (!"US".equals(countryCode)) {
-	        response.sendError(HttpStatus.BAD_REQUEST.value(), "Invalid Locale");
-	        return;
-	    }
-	
-	    filterChain.doFilter(request, response);
-	}
-}
\ No newline at end of file
+    @Override
+    protected void doFilterInternal(HttpServletRequest request,
+      HttpServletResponse response,
+      FilterChain filterChain)
+      throws ServletException,
+      IOException {
+        String countryCode = request.getHeader("X-Country-Code");
+        if (!"US".equals(countryCode)) {
+            response.sendError(HttpStatus.BAD_REQUEST.value(), "Invalid Locale");
+            return;
+        }
+        filterChain.doFilter(request, response);
+    }
+
+    @Override
+    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
+        String path = request.getRequestURI();
+        return "/health".equals(path);
+    }
+}
diff --git a/spring-web-modules/spring-mvc-forms-jsp/pom.xml b/spring-web-modules/spring-mvc-forms-jsp/pom.xml
index aba16236da..0ca23bd6cb 100644
--- a/spring-web-modules/spring-mvc-forms-jsp/pom.xml
+++ b/spring-web-modules/spring-mvc-forms-jsp/pom.xml
@@ -54,7 +54,7 @@
         
             commons-fileupload
             commons-fileupload
-            ${fileupload.version}
+            ${commons-fileupload.version}
         
         
             com.fasterxml.jackson.core
@@ -98,7 +98,6 @@
 
     
         6.0.10.Final
-        1.3.3
         5.2.5.Final
         6.0.6
     
diff --git a/spring-mvc-forms-thymeleaf/README.md b/spring-web-modules/spring-mvc-forms-thymeleaf/README.md
similarity index 100%
rename from spring-mvc-forms-thymeleaf/README.md
rename to spring-web-modules/spring-mvc-forms-thymeleaf/README.md
diff --git a/spring-mvc-forms-thymeleaf/pom.xml b/spring-web-modules/spring-mvc-forms-thymeleaf/pom.xml
similarity index 96%
rename from spring-mvc-forms-thymeleaf/pom.xml
rename to spring-web-modules/spring-mvc-forms-thymeleaf/pom.xml
index 2aed7f70ad..641f64b93c 100644
--- a/spring-mvc-forms-thymeleaf/pom.xml
+++ b/spring-web-modules/spring-mvc-forms-thymeleaf/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Book.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BookService.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/BooksCreationDto.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/Config.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/InMemoryBookService.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/ListBindingApplication.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/listbindingexample/MultipleBooksController.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/Config.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/Config.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/Config.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/Config.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/SessionAttrsApplication.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/SessionAttrsApplication.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/SessionAttrsApplication.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/SessionAttrsApplication.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxy.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxy.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxy.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxy.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributes.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributes.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributes.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributes.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoItem.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoItem.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoItem.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoItem.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoList.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoList.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoList.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/java/com/baeldung/sessionattrs/TodoList.java
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/application.properties b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/application.properties
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/application.properties
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/application.properties
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/logback.xml b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/logback.xml
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/logback.xml
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/logback.xml
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/allBooks.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/createBooksForm.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/editBooksForm.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/books/index.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/index.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/index.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/index.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/index.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxyform.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxyform.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxyform.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxyform.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxytodos.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxytodos.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxytodos.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/scopedproxytodos.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributesform.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributesform.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributesform.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributesform.html
diff --git a/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributestodos.html b/spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributestodos.html
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributestodos.html
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/main/resources/templates/sessionattrs/sessionattributestodos.html
diff --git a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextTest.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/listbindingexample/SpringContextTest.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/listbindingexample/SpringContextTest.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/listbindingexample/SpringContextTest.java
diff --git a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/SessionAttrsApplicationIntegrationTest.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/SessionAttrsApplicationIntegrationTest.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/SessionAttrsApplicationIntegrationTest.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/SessionAttrsApplicationIntegrationTest.java
diff --git a/spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextTest.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/SpringContextTest.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/test/java/org/baeldung/sessionattrs/SpringContextTest.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/SpringContextTest.java
diff --git a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TestConfig.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TestConfig.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TestConfig.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TestConfig.java
diff --git a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java
diff --git a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java b/spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java
similarity index 100%
rename from spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java
rename to spring-web-modules/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java
diff --git a/spring-mvc-java-2/.gitignore b/spring-web-modules/spring-mvc-java-2/.gitignore
similarity index 100%
rename from spring-mvc-java-2/.gitignore
rename to spring-web-modules/spring-mvc-java-2/.gitignore
diff --git a/spring-mvc-java-2/README.md b/spring-web-modules/spring-mvc-java-2/README.md
similarity index 100%
rename from spring-mvc-java-2/README.md
rename to spring-web-modules/spring-mvc-java-2/README.md
diff --git a/spring-mvc-java-2/pom.xml b/spring-web-modules/spring-mvc-java-2/pom.xml
similarity index 97%
rename from spring-mvc-java-2/pom.xml
rename to spring-web-modules/spring-mvc-java-2/pom.xml
index 533a24771a..8a025defac 100644
--- a/spring-mvc-java-2/pom.xml
+++ b/spring-web-modules/spring-mvc-java-2/pom.xml
@@ -12,7 +12,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheControlController.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheWebConfig.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheWebConfig.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheWebConfig.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/cache/CacheWebConfig.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeConfig.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeConfig.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeConfig.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeConfig.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeController.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeController.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/datetime/DateTimeController.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/matrix/config/MatrixWebConfig.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/config/MatrixWebConfig.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/matrix/config/MatrixWebConfig.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/config/MatrixWebConfig.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/CompanyController.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/controller/EmployeeController.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Company.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Company.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Company.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Company.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/matrix/model/Employee.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/multiparttesting/MultipartPostRequestController.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/CustomWebMvcConfigurationSupport.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable.dottruncated/SiteController.java
diff --git a/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable/PathVariableAnnotationController.java b/spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable/PathVariableAnnotationController.java
similarity index 100%
rename from spring-mvc-java-2/src/main/java/com/baeldung/pathvariable/PathVariableAnnotationController.java
rename to spring-web-modules/spring-mvc-java-2/src/main/java/com/baeldung/pathvariable/PathVariableAnnotationController.java
diff --git a/spring-mvc-java-2/src/main/resources/targetFile.tmp b/spring-web-modules/spring-mvc-java-2/src/main/resources/targetFile.tmp
similarity index 100%
rename from spring-mvc-java-2/src/main/resources/targetFile.tmp
rename to spring-web-modules/spring-mvc-java-2/src/main/resources/targetFile.tmp
diff --git a/spring-mvc-java-2/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/mvc-servlet.xml
similarity index 100%
rename from spring-mvc-java-2/src/main/webapp/WEB-INF/mvc-servlet.xml
rename to spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/mvc-servlet.xml
diff --git a/spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyHome.jsp b/spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyHome.jsp
similarity index 100%
rename from spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyHome.jsp
rename to spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyHome.jsp
diff --git a/spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyView.jsp b/spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyView.jsp
similarity index 100%
rename from spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyView.jsp
rename to spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/companyView.jsp
diff --git a/spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeHome.jsp b/spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeHome.jsp
similarity index 100%
rename from spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeHome.jsp
rename to spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeHome.jsp
diff --git a/spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeView.jsp b/spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeView.jsp
similarity index 100%
rename from spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeView.jsp
rename to spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/view/employeeView.jsp
diff --git a/spring-mvc-java-2/src/main/webapp/WEB-INF/web.xml b/spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from spring-mvc-java-2/src/main/webapp/WEB-INF/web.xml
rename to spring-web-modules/spring-mvc-java-2/src/main/webapp/WEB-INF/web.xml
diff --git a/spring-mvc-java-2/src/main/webapp/resources/hello.css b/spring-web-modules/spring-mvc-java-2/src/main/webapp/resources/hello.css
similarity index 100%
rename from spring-mvc-java-2/src/main/webapp/resources/hello.css
rename to spring-web-modules/spring-mvc-java-2/src/main/webapp/resources/hello.css
diff --git a/spring-mvc-java-2/src/test/java/com/baeldung/cache/CacheControlControllerIntegrationTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/cache/CacheControlControllerIntegrationTest.java
similarity index 100%
rename from spring-mvc-java-2/src/test/java/com/baeldung/cache/CacheControlControllerIntegrationTest.java
rename to spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/cache/CacheControlControllerIntegrationTest.java
diff --git a/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java
similarity index 100%
rename from spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java
rename to spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeMvcIntegrationTest.java
diff --git a/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeNoMvcIntegrationTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeNoMvcIntegrationTest.java
similarity index 100%
rename from spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeNoMvcIntegrationTest.java
rename to spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/matrix/EmployeeNoMvcIntegrationTest.java
diff --git a/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertMultipartFileUnitTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertMultipartFileUnitTest.java
similarity index 100%
rename from spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertMultipartFileUnitTest.java
rename to spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multipart/file/ConvertMultipartFileUnitTest.java
diff --git a/spring-mvc-java-2/src/test/java/com/baeldung/multiparttesting/MultipartPostRequestControllerUnitTest.java b/spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multiparttesting/MultipartPostRequestControllerUnitTest.java
similarity index 100%
rename from spring-mvc-java-2/src/test/java/com/baeldung/multiparttesting/MultipartPostRequestControllerUnitTest.java
rename to spring-web-modules/spring-mvc-java-2/src/test/java/com/baeldung/multiparttesting/MultipartPostRequestControllerUnitTest.java
diff --git a/spring-mvc-java/.gitignore b/spring-web-modules/spring-mvc-java/.gitignore
similarity index 100%
rename from spring-mvc-java/.gitignore
rename to spring-web-modules/spring-mvc-java/.gitignore
diff --git a/spring-mvc-java/README.md b/spring-web-modules/spring-mvc-java/README.md
similarity index 92%
rename from spring-mvc-java/README.md
rename to spring-web-modules/spring-mvc-java/README.md
index 877d92901a..afd1aea3bf 100644
--- a/spring-mvc-java/README.md
+++ b/spring-web-modules/spring-mvc-java/README.md
@@ -4,7 +4,7 @@ This module contains articles about Spring MVC with Java configuration
 
 ### The Course
 
-The "REST With Spring" Classes: http://bit.ly/restwithspring
+The "REST With Spring" Classes: https://bit.ly/restwithspring
 
 ### Relevant Articles: 
 - [Integration Testing in Spring](https://www.baeldung.com/integration-testing-in-spring)
diff --git a/spring-mvc-java/persons.xls b/spring-web-modules/spring-mvc-java/persons.xls
similarity index 100%
rename from spring-mvc-java/persons.xls
rename to spring-web-modules/spring-mvc-java/persons.xls
diff --git a/spring-mvc-java/persons.xlsx b/spring-web-modules/spring-mvc-java/persons.xlsx
similarity index 100%
rename from spring-mvc-java/persons.xlsx
rename to spring-web-modules/spring-mvc-java/persons.xlsx
diff --git a/spring-mvc-java/pom.xml b/spring-web-modules/spring-mvc-java/pom.xml
similarity index 97%
rename from spring-mvc-java/pom.xml
rename to spring-web-modules/spring-mvc-java/pom.xml
index a45e9c8521..1324511215 100644
--- a/spring-mvc-java/pom.xml
+++ b/spring-web-modules/spring-mvc-java/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
@@ -234,10 +234,6 @@
 
         
         19.0
-        3.5
-        1.3.2
-        2.5
-        1.4
         2.2.0
 
         
diff --git a/spring-mvc-java/src/main/java/com/baeldung/SpringMVCApplication.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/SpringMVCApplication.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/SpringMVCApplication.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/SpringMVCApplication.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/App.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/App.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/App.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/App.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/Controller.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/Controller.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/Controller.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/accessparamsjs/Controller.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/cache/BookService.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/cache/BookService.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/cache/BookService.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/cache/BookService.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/cache/CustomKeyGenerator.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/cache/CustomKeyGenerator.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/cache/CustomKeyGenerator.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/cache/CustomKeyGenerator.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/excel/ExcelPOIHelper.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/excel/ExcelPOIHelper.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/excel/ExcelPOIHelper.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/excel/ExcelPOIHelper.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/excel/MyCell.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/excel/MyCell.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/excel/MyCell.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/excel/MyCell.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/filters/EmptyParamFilter.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/AppListener.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/listeners/RequestListener.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/Article.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/Article.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/model/Article.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/Article.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/Book.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/Book.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/model/Book.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/Book.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/FormDataWithFile.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/FormDataWithFile.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/model/FormDataWithFile.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/FormDataWithFile.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/Greeting.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/Greeting.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/model/Greeting.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/Greeting.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/model/User.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/User.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/model/User.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/model/User.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/CounterServlet.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/servlets/UppercaseServlet.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ApplicationCacheConfig.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ApplicationCacheConfig.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ApplicationCacheConfig.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/ApplicationCacheConfig.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/MainWebAppInitializer.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/spring/web/config/WebConfig.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/BeanA.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/BeanB.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/ExcelController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ExcelController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/ExcelController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ExcelController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/FileUploadController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/FileUploadController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/FileUploadController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/FileUploadController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/GreetController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/GreetController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/GreetController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/GreetController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/ImageController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/MultipartFileUploadStubController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/MultipartFileUploadStubController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/MultipartFileUploadStubController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/MultipartFileUploadStubController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/SampleController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/SampleController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/SampleController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/SampleController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/UserController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/UserController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/UserController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/UserController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/message/MessageController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/message/MessageController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/message/MessageController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/message/MessageController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithOptionalParamController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithRequiredAttributeController.java
diff --git a/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java b/spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java
similarity index 100%
rename from spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java
rename to spring-web-modules/spring-mvc-java/src/main/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsController.java
diff --git a/spring-mvc-java/src/main/resources/annotations.properties b/spring-web-modules/spring-mvc-java/src/main/resources/annotations.properties
similarity index 100%
rename from spring-mvc-java/src/main/resources/annotations.properties
rename to spring-web-modules/spring-mvc-java/src/main/resources/annotations.properties
diff --git a/spring-mvc-java/src/main/resources/annotations.xml b/spring-web-modules/spring-mvc-java/src/main/resources/annotations.xml
similarity index 100%
rename from spring-mvc-java/src/main/resources/annotations.xml
rename to spring-web-modules/spring-mvc-java/src/main/resources/annotations.xml
diff --git a/spring-mvc-java/src/main/resources/application.properties b/spring-web-modules/spring-mvc-java/src/main/resources/application.properties
similarity index 100%
rename from spring-mvc-java/src/main/resources/application.properties
rename to spring-web-modules/spring-mvc-java/src/main/resources/application.properties
diff --git a/spring-mvc-java/src/main/resources/logback.xml b/spring-web-modules/spring-mvc-java/src/main/resources/logback.xml
similarity index 100%
rename from spring-mvc-java/src/main/resources/logback.xml
rename to spring-web-modules/spring-mvc-java/src/main/resources/logback.xml
diff --git a/spring-mvc-java/src/main/resources/messages_en.properties b/spring-web-modules/spring-mvc-java/src/main/resources/messages_en.properties
similarity index 100%
rename from spring-mvc-java/src/main/resources/messages_en.properties
rename to spring-web-modules/spring-mvc-java/src/main/resources/messages_en.properties
diff --git a/spring-mvc-java/src/main/resources/mvc-configuration.xml b/spring-web-modules/spring-mvc-java/src/main/resources/mvc-configuration.xml
similarity index 100%
rename from spring-mvc-java/src/main/resources/mvc-configuration.xml
rename to spring-web-modules/spring-mvc-java/src/main/resources/mvc-configuration.xml
diff --git a/spring-mvc-java/src/main/resources/templates/thymeleaf/index.html b/spring-web-modules/spring-mvc-java/src/main/resources/templates/thymeleaf/index.html
similarity index 100%
rename from spring-mvc-java/src/main/resources/templates/thymeleaf/index.html
rename to spring-web-modules/spring-mvc-java/src/main/resources/templates/thymeleaf/index.html
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/images/image-example.jpg b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/images/image-example.jpg
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/images/image-example.jpg
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/images/image-example.jpg
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/jsp/index.jsp b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/jsp/index.jsp
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/jsp/index.jsp
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/jsp/index.jsp
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/mvc-servlet.xml
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/mvc-servlet.xml
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/mvc-servlet.xml
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/templates/footer.html b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/footer.html
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/templates/footer.html
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/footer.html
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/templates/hello.html b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/hello.html
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/templates/hello.html
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/hello.html
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/templates/index.html b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/index.html
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/templates/index.html
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/index.html
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/templates/message.html b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/message.html
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/templates/message.html
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/templates/message.html
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/excel.jsp b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/excel.jsp
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/view/excel.jsp
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/excel.jsp
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadForm.jsp b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadForm.jsp
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadForm.jsp
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadForm.jsp
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadView.jsp b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadView.jsp
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadView.jsp
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/fileUploadView.jsp
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/index.jsp b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/index.jsp
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/view/index.jsp
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/index.jsp
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/view/sample.jsp b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/sample.jsp
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/view/sample.jsp
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/view/sample.jsp
diff --git a/spring-mvc-java/src/main/webapp/WEB-INF/web_old.xml b/spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/web_old.xml
similarity index 100%
rename from spring-mvc-java/src/main/webapp/WEB-INF/web_old.xml
rename to spring-web-modules/spring-mvc-java/src/main/webapp/WEB-INF/web_old.xml
diff --git a/spring-mvc-java/src/main/webapp/js/jquery.js b/spring-web-modules/spring-mvc-java/src/main/webapp/js/jquery.js
similarity index 100%
rename from spring-mvc-java/src/main/webapp/js/jquery.js
rename to spring-web-modules/spring-mvc-java/src/main/webapp/js/jquery.js
diff --git a/spring-mvc-java/src/main/webapp/js/script-async-jquery.js b/spring-web-modules/spring-mvc-java/src/main/webapp/js/script-async-jquery.js
similarity index 100%
rename from spring-mvc-java/src/main/webapp/js/script-async-jquery.js
rename to spring-web-modules/spring-mvc-java/src/main/webapp/js/script-async-jquery.js
diff --git a/spring-mvc-java/src/main/webapp/js/script-async.js b/spring-web-modules/spring-mvc-java/src/main/webapp/js/script-async.js
similarity index 100%
rename from spring-mvc-java/src/main/webapp/js/script-async.js
rename to spring-web-modules/spring-mvc-java/src/main/webapp/js/script-async.js
diff --git a/spring-mvc-java/src/main/webapp/js/script.js b/spring-web-modules/spring-mvc-java/src/main/webapp/js/script.js
similarity index 100%
rename from spring-mvc-java/src/main/webapp/js/script.js
rename to spring-web-modules/spring-mvc-java/src/main/webapp/js/script.js
diff --git a/spring-mvc-java/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/accessparamsjs/ControllerUnitTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndJUnitLiveTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndJUnitLiveTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndJUnitLiveTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndJUnitLiveTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndSpringLiveTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndSpringLiveTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndSpringLiveTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitAndSpringLiveTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitWebScrapingLiveTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitWebScrapingLiveTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitWebScrapingLiveTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/HtmlUnitWebScrapingLiveTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/htmlunit/TestConfig.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/TestConfig.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/htmlunit/TestConfig.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/htmlunit/TestConfig.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerIntegrationTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerRealIntegrationTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/GreetControllerUnitTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/README.md b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/README.md
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/README.md
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/README.md
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerIntegrationTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithOptionalParamIntegrationTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerControllerWithRequiredAttributeIntegrationTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithMapParamIntegrationTest.java
diff --git a/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java b/spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java
similarity index 100%
rename from spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java
rename to spring-web-modules/spring-mvc-java/src/test/java/com/baeldung/web/controller/optionalpathvars/ArticleViewerWithTwoSeparateMethodsIntegrationTest.java
diff --git a/spring-mvc-java/src/test/resources/.gitignore b/spring-web-modules/spring-mvc-java/src/test/resources/.gitignore
similarity index 100%
rename from spring-mvc-java/src/test/resources/.gitignore
rename to spring-web-modules/spring-mvc-java/src/test/resources/.gitignore
diff --git a/spring-mvc-java/src/test/resources/logback-test.xml b/spring-web-modules/spring-mvc-java/src/test/resources/logback-test.xml
similarity index 100%
rename from spring-mvc-java/src/test/resources/logback-test.xml
rename to spring-web-modules/spring-mvc-java/src/test/resources/logback-test.xml
diff --git a/spring-mvc-velocity/README.md b/spring-web-modules/spring-mvc-velocity/README.md
similarity index 100%
rename from spring-mvc-velocity/README.md
rename to spring-web-modules/spring-mvc-velocity/README.md
diff --git a/spring-mvc-velocity/pom.xml b/spring-web-modules/spring-mvc-velocity/pom.xml
similarity index 98%
rename from spring-mvc-velocity/pom.xml
rename to spring-web-modules/spring-mvc-velocity/pom.xml
index 2269f05fa4..05016962a5 100644
--- a/spring-mvc-velocity/pom.xml
+++ b/spring-web-modules/spring-mvc-velocity/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-spring-4
         0.0.1-SNAPSHOT
-        ../parent-spring-4
+        ../../parent-spring-4
     
 
     
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java b/spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java
similarity index 100%
rename from spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java
rename to spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/controller/MainController.java
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java b/spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java
similarity index 100%
rename from spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java
rename to spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/domain/Tutorial.java
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/ITutorialsService.java b/spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/ITutorialsService.java
similarity index 100%
rename from spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/ITutorialsService.java
rename to spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/ITutorialsService.java
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/TutorialsService.java b/spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/TutorialsService.java
similarity index 100%
rename from spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/TutorialsService.java
rename to spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/service/TutorialsService.java
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java b/spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java
similarity index 100%
rename from spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java
rename to spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/MainWebAppInitializer.java
diff --git a/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java b/spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java
similarity index 100%
rename from spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java
rename to spring-web-modules/spring-mvc-velocity/src/main/java/com/baeldung/mvc/velocity/spring/config/WebConfig.java
diff --git a/spring-mvc-velocity/src/main/resources/logback.xml b/spring-web-modules/spring-mvc-velocity/src/main/resources/logback.xml
similarity index 100%
rename from spring-mvc-velocity/src/main/resources/logback.xml
rename to spring-web-modules/spring-mvc-velocity/src/main/resources/logback.xml
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/footer.vm b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/footer.vm
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/footer.vm
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/footer.vm
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/header.vm b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/header.vm
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/header.vm
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/fragments/header.vm
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/layouts/layout.vm
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/mvc-servlet.xml
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/mvc-servlet.xml
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/mvc-servlet.xml
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/spring-context.xml b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/spring-context.xml
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/spring-context.xml
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/spring-context.xml
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/views/index.vm
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/views/list.vm
diff --git a/spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml b/spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml
similarity index 100%
rename from spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml
rename to spring-web-modules/spring-mvc-velocity/src/main/webapp/WEB-INF/web_old.xml
diff --git a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerIntegrationTest.java b/spring-web-modules/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerIntegrationTest.java
similarity index 100%
rename from spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerIntegrationTest.java
rename to spring-web-modules/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/DataContentControllerIntegrationTest.java
diff --git a/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java b/spring-web-modules/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java
similarity index 100%
rename from spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java
rename to spring-web-modules/spring-mvc-velocity/src/test/java/com/baeldung/mvc/velocity/test/config/TestConfig.java
diff --git a/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java b/spring-web-modules/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java
rename to spring-web-modules/spring-mvc-velocity/src/test/java/org/baeldung/SpringContextTest.java
diff --git a/spring-mvc-velocity/src/test/resources/mvc-servlet.xml b/spring-web-modules/spring-mvc-velocity/src/test/resources/mvc-servlet.xml
similarity index 100%
rename from spring-mvc-velocity/src/test/resources/mvc-servlet.xml
rename to spring-web-modules/spring-mvc-velocity/src/test/resources/mvc-servlet.xml
diff --git a/spring-mvc-xml/.gitignore b/spring-web-modules/spring-mvc-xml/.gitignore
similarity index 100%
rename from spring-mvc-xml/.gitignore
rename to spring-web-modules/spring-mvc-xml/.gitignore
diff --git a/spring-mvc-xml/README.md b/spring-web-modules/spring-mvc-xml/README.md
similarity index 100%
rename from spring-mvc-xml/README.md
rename to spring-web-modules/spring-mvc-xml/README.md
diff --git a/spring-mvc-xml/pom.xml b/spring-web-modules/spring-mvc-xml/pom.xml
similarity index 100%
rename from spring-mvc-xml/pom.xml
rename to spring-web-modules/spring-mvc-xml/pom.xml
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleOne.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleOne.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleOne.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleOne.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleThree.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleThree.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleThree.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/jsp/ExampleThree.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfig.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/ClientWebConfigJava.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ConstraintViolationExceptionHandler.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ErrorController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ErrorController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ErrorController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ErrorController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GeoIPTestController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GreetingController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GreetingController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GreetingController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/GreetingController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloGuestController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloGuestController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloGuestController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloGuestController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloWorldController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloWorldController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloWorldController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/HelloWorldController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ImageController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ImageController.java
similarity index 97%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ImageController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ImageController.java
index fc46c07e06..c02e76d4c0 100644
--- a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ImageController.java
+++ b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/ImageController.java
@@ -1,61 +1,61 @@
-package com.baeldung.spring.controller;
-
-import org.apache.commons.io.IOUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.Resource;
-import org.springframework.http.*;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.context.support.ServletContextResource;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.InputStream;
-
-@Controller
-public class ImageController {
-
-    @Autowired
-    private ServletContext servletContext;
-
-    @RequestMapping(value = "/image-view", method = RequestMethod.GET)
-    public String imageView() throws IOException {
-        return "image-download";
-    }
-
-    @RequestMapping(value = "/image-manual-response", method = RequestMethod.GET)
-    public void getImageAsByteArray(HttpServletResponse response) throws IOException {
-        final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
-        response.setContentType(MediaType.IMAGE_JPEG_VALUE);
-        IOUtils.copy(in, response.getOutputStream());
-    }
-
-    @RequestMapping(value = "/image-byte-array", method = RequestMethod.GET)
-    @ResponseBody
-    public byte[] getImageAsByteArray() throws IOException {
-        final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
-        return IOUtils.toByteArray(in);
-    }
-
-    @RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
-    public ResponseEntity getImageAsResponseEntity() throws IOException {
-        ResponseEntity responseEntity;
-        final HttpHeaders headers = new HttpHeaders();
-        final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
-        byte[] media = IOUtils.toByteArray(in);
-        headers.setCacheControl(CacheControl.noCache().getHeaderValue());
-        responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
-        return responseEntity;
-    }
-
-    @RequestMapping(value = "/image-resource", method = RequestMethod.GET)
-    @ResponseBody
-    public ResponseEntity getImageAsResource() {
-        final HttpHeaders headers = new HttpHeaders();
-        Resource resource = new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
-        return new ResponseEntity<>(resource, headers, HttpStatus.OK);
-    }
-}
+package com.baeldung.spring.controller;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.http.*;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.context.support.ServletContextResource;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+
+@Controller
+public class ImageController {
+
+    @Autowired
+    private ServletContext servletContext;
+
+    @RequestMapping(value = "/image-view", method = RequestMethod.GET)
+    public String imageView() throws IOException {
+        return "image-download";
+    }
+
+    @RequestMapping(value = "/image-manual-response", method = RequestMethod.GET)
+    public void getImageAsByteArray(HttpServletResponse response) throws IOException {
+        final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
+        response.setContentType(MediaType.IMAGE_JPEG_VALUE);
+        IOUtils.copy(in, response.getOutputStream());
+    }
+
+    @RequestMapping(value = "/image-byte-array", method = RequestMethod.GET)
+    @ResponseBody
+    public byte[] getImageAsByteArray() throws IOException {
+        final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
+        return IOUtils.toByteArray(in);
+    }
+
+    @RequestMapping(value = "/image-response-entity", method = RequestMethod.GET)
+    public ResponseEntity getImageAsResponseEntity() throws IOException {
+        ResponseEntity responseEntity;
+        final HttpHeaders headers = new HttpHeaders();
+        final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
+        byte[] media = IOUtils.toByteArray(in);
+        headers.setCacheControl(CacheControl.noCache().getHeaderValue());
+        responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK);
+        return responseEntity;
+    }
+
+    @RequestMapping(value = "/image-resource", method = RequestMethod.GET)
+    @ResponseBody
+    public ResponseEntity getImageAsResource() {
+        final HttpHeaders headers = new HttpHeaders();
+        Resource resource = new ServletContextResource(servletContext, "/WEB-INF/images/image-example.jpg");
+        return new ResponseEntity<>(resource, headers, HttpStatus.OK);
+    }
+}
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/PersonController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/PersonController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/PersonController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/PersonController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/RequestAndPathVariableValidationController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/RequestAndPathVariableValidationController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/RequestAndPathVariableValidationController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/RequestAndPathVariableValidationController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/WelcomeController.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/WelcomeController.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/controller/WelcomeController.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/controller/WelcomeController.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/GeoIP.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/form/GeoIP.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/form/GeoIP.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/form/GeoIP.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/form/Person.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java
similarity index 100%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/service/RawDBDemoGeoIPLocationService.java
diff --git a/spring-mvc-xml/src/main/java/com/baeldung/spring/validator/PersonValidator.java b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/validator/PersonValidator.java
similarity index 96%
rename from spring-mvc-xml/src/main/java/com/baeldung/spring/validator/PersonValidator.java
rename to spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/validator/PersonValidator.java
index f7625bacd9..cda756cdfc 100644
--- a/spring-mvc-xml/src/main/java/com/baeldung/spring/validator/PersonValidator.java
+++ b/spring-web-modules/spring-mvc-xml/src/main/java/com/baeldung/spring/validator/PersonValidator.java
@@ -1,22 +1,22 @@
-package com.baeldung.spring.validator;
-
-import com.baeldung.spring.form.Person;
-import org.springframework.stereotype.Component;
-import org.springframework.validation.Errors;
-import org.springframework.validation.ValidationUtils;
-import org.springframework.validation.Validator;
-
-@Component
-public class PersonValidator implements Validator {
-
-    @Override
-    public boolean supports(final Class calzz) {
-        return Person.class.isAssignableFrom(calzz);
-    }
-
-    @Override
-    public void validate(final Object obj, final Errors errors) {
-
-        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name");
-    }
+package com.baeldung.spring.validator;
+
+import com.baeldung.spring.form.Person;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+@Component
+public class PersonValidator implements Validator {
+
+    @Override
+    public boolean supports(final Class calzz) {
+        return Person.class.isAssignableFrom(calzz);
+    }
+
+    @Override
+    public void validate(final Object obj, final Errors errors) {
+
+        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name");
+    }
 }
\ No newline at end of file
diff --git a/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml b/spring-web-modules/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml
similarity index 100%
rename from spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml
rename to spring-web-modules/spring-mvc-xml/src/main/resources/contentManagementWebMvcConfig.xml
diff --git a/spring-mvc-xml/src/main/resources/logback.xml b/spring-web-modules/spring-mvc-xml/src/main/resources/logback.xml
similarity index 100%
rename from spring-mvc-xml/src/main/resources/logback.xml
rename to spring-web-modules/spring-mvc-xml/src/main/resources/logback.xml
diff --git a/spring-web-modules/spring-mvc-xml/src/main/resources/messages.properties b/spring-web-modules/spring-mvc-xml/src/main/resources/messages.properties
new file mode 100644
index 0000000000..8d886c8449
--- /dev/null
+++ b/spring-web-modules/spring-mvc-xml/src/main/resources/messages.properties
@@ -0,0 +1,2 @@
+required.name = Name is required!
+NotEmpty.person.password = Password is required!
\ No newline at end of file
diff --git a/spring-mvc-xml/src/main/resources/webMvcConfig.xml b/spring-web-modules/spring-mvc-xml/src/main/resources/webMvcConfig.xml
similarity index 100%
rename from spring-mvc-xml/src/main/resources/webMvcConfig.xml
rename to spring-web-modules/spring-mvc-xml/src/main/resources/webMvcConfig.xml
diff --git a/spring-mvc-xml/src/main/webapp/GeoIpTest.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/GeoIpTest.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/GeoIpTest.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/GeoIpTest.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message.groovy b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message.groovy
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message.groovy
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message.groovy
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message2.java b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message2.java
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message2.java
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/commands/message2.java
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/crash/crash.properties b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/crash.properties
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/crash/crash.properties
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/crash.properties
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/crash/telnet.properties b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/telnet.properties
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/crash/telnet.properties
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/crash/telnet.properties
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/images/image-example.jpg b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/images/image-example.jpg
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/images/image-example.jpg
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/images/image-example.jpg
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/mvc-servlet.xml
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/error.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/error.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/error.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/error.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/errorPage.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/errorPage.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/errorPage.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/errorPage.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/greeting.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/greeting.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/greeting.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/greeting.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/hello.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/hello.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/hello.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/hello.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/helloworld.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/helloworld.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/helloworld.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/helloworld.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/image-download.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/image-download.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/image-download.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/image-download.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/personForm.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/personForm.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/personForm.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/personForm.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/personView.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/personView.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/personView.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/personView.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/sample.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/sample.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/sample.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/sample.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/view/welcome.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/welcome.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/view/welcome.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/view/welcome.jsp
diff --git a/spring-mvc-xml/src/main/webapp/WEB-INF/web.xml b/spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/WEB-INF/web.xml
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/WEB-INF/web.xml
diff --git a/spring-mvc-xml/src/main/webapp/index.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/index.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/index.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/index.jsp
diff --git a/spring-mvc-xml/src/main/webapp/jsp/ExampleThree.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/jsp/ExampleThree.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/jsp/ExampleThree.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/jsp/ExampleThree.jsp
diff --git a/spring-mvc-xml/src/main/webapp/jsp/ExampleTwo.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/jsp/ExampleTwo.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/jsp/ExampleTwo.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/jsp/ExampleTwo.jsp
diff --git a/spring-mvc-xml/src/main/webapp/jsp/index.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/jsp/index.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/jsp/index.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/jsp/index.jsp
diff --git a/spring-mvc-xml/src/main/webapp/spring-handler-index.jsp b/spring-web-modules/spring-mvc-xml/src/main/webapp/spring-handler-index.jsp
similarity index 100%
rename from spring-mvc-xml/src/main/webapp/spring-handler-index.jsp
rename to spring-web-modules/spring-mvc-xml/src/main/webapp/spring-handler-index.jsp
diff --git a/spring-mvc-xml/src/test/java/org/baeldung/SpringContextTest.java b/spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-mvc-xml/src/test/java/org/baeldung/SpringContextTest.java
rename to spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java b/spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java
similarity index 100%
rename from spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java
rename to spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/geoip/GeoIpIntegrationTest.java
diff --git a/spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java b/spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java
similarity index 100%
rename from spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java
rename to spring-web-modules/spring-mvc-xml/src/test/java/com/baeldung/spring/controller/RequestAndPathVariableValidationControllerIntegrationTest.java
diff --git a/spring-rest-http-2/README.md b/spring-web-modules/spring-rest-http-2/README.md
similarity index 75%
rename from spring-rest-http-2/README.md
rename to spring-web-modules/spring-rest-http-2/README.md
index 97cdc2d068..b5358f888f 100644
--- a/spring-rest-http-2/README.md
+++ b/spring-web-modules/spring-rest-http-2/README.md
@@ -8,3 +8,4 @@ The "REST With Spring 2" Classes: http://bit.ly/restwithspring
 ### Relevant Articles:
 
 - [How to Turn Off Swagger-ui in Production](https://www.baeldung.com/swagger-ui-turn-off-in-production)
+- [Setting a Request Timeout for a Spring REST API](https://www.baeldung.com/spring-rest-timeout)
diff --git a/spring-rest-http-2/pom.xml b/spring-web-modules/spring-rest-http-2/pom.xml
similarity index 95%
rename from spring-rest-http-2/pom.xml
rename to spring-web-modules/spring-rest-http-2/pom.xml
index 8678d7243d..6aa8be365c 100644
--- a/spring-rest-http-2/pom.xml
+++ b/spring-web-modules/spring-rest-http-2/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-rest-http-2/src/main/java/com/baeldung/SpringBootRest2Application.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/SpringBootRest2Application.java
similarity index 100%
rename from spring-rest-http-2/src/main/java/com/baeldung/SpringBootRest2Application.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/SpringBootRest2Application.java
diff --git a/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java
similarity index 100%
rename from spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java
diff --git a/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java
similarity index 100%
rename from spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java
rename to spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java
diff --git a/spring-rest-query-language/.gitignore b/spring-web-modules/spring-rest-query-language/.gitignore
similarity index 100%
rename from spring-rest-query-language/.gitignore
rename to spring-web-modules/spring-rest-query-language/.gitignore
diff --git a/spring-rest-query-language/README.md b/spring-web-modules/spring-rest-query-language/README.md
similarity index 100%
rename from spring-rest-query-language/README.md
rename to spring-web-modules/spring-rest-query-language/README.md
diff --git a/spring-rest-query-language/pom.xml b/spring-web-modules/spring-rest-query-language/pom.xml
similarity index 99%
rename from spring-rest-query-language/pom.xml
rename to spring-web-modules/spring-rest-query-language/pom.xml
index 4458aa0580..5e7ca023dd 100644
--- a/spring-rest-query-language/pom.xml
+++ b/spring-web-modules/spring-rest-query-language/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/GenericSpecificationsBuilder.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/GenericSpecificationsBuilder.java
similarity index 97%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/GenericSpecificationsBuilder.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/GenericSpecificationsBuilder.java
index 75fb4456c4..b6623e8885 100644
--- a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/GenericSpecificationsBuilder.java
+++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/GenericSpecificationsBuilder.java
@@ -1,100 +1,100 @@
-package com.baeldung.persistence.dao;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-import org.springframework.data.jpa.domain.Specification;
-
-import com.baeldung.web.util.SearchOperation;
-import com.baeldung.web.util.SpecSearchCriteria;
-
-public class GenericSpecificationsBuilder {
-
-    private final List params;
-
-    public GenericSpecificationsBuilder() {
-        this.params = new ArrayList<>();
-    }
-
-    public final GenericSpecificationsBuilder with(final String key, final String operation, final Object value, final String prefix, final String suffix) {
-        return with(null, key, operation, value, prefix, suffix);
-    }
-
-    public final GenericSpecificationsBuilder with(final String precedenceIndicator, final String key, final String operation, final Object value, final String prefix, final String suffix) {
-        SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
-        if (op != null) {
-            if (op == SearchOperation.EQUALITY) // the operation may be complex operation
-            {
-                final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
-                final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
-
-                if (startWithAsterisk && endWithAsterisk) {
-                    op = SearchOperation.CONTAINS;
-                } else if (startWithAsterisk) {
-                    op = SearchOperation.ENDS_WITH;
-                } else if (endWithAsterisk) {
-                    op = SearchOperation.STARTS_WITH;
-                }
-            }
-            params.add(new SpecSearchCriteria(precedenceIndicator, key, op, value));
-        }
-        return this;
-    }
-
-    public Specification build(Function> converter) {
-
-        if (params.size() == 0) {
-            return null;
-        }
-
-        final List> specs = params.stream()
-            .map(converter)
-            .collect(Collectors.toCollection(ArrayList::new));
-
-        Specification result = specs.get(0);
-
-        for (int idx = 1; idx < specs.size(); idx++) {
-            result = params.get(idx)
-                .isOrPredicate()
-                    ? Specification.where(result)
-                        .or(specs.get(idx))
-                    : Specification.where(result)
-                        .and(specs.get(idx));
-        }
-        
-        return result;
-    }
-
-    public Specification build(Deque> postFixedExprStack, Function> converter) {
-
-        Deque> specStack = new LinkedList<>();
-
-        Collections.reverse((List>) postFixedExprStack);
-
-        while (!postFixedExprStack.isEmpty()) {
-            Object mayBeOperand = postFixedExprStack.pop();
-
-            if (!(mayBeOperand instanceof String)) {
-                specStack.push(converter.apply((SpecSearchCriteria) mayBeOperand));
-            } else {
-                Specification operand1 = specStack.pop();
-                Specification operand2 = specStack.pop();
-                if (mayBeOperand.equals(SearchOperation.AND_OPERATOR))
-                    specStack.push(Specification.where(operand1)
-                        .and(operand2));
-                else if (mayBeOperand.equals(SearchOperation.OR_OPERATOR))
-                    specStack.push(Specification.where(operand1)
-                        .or(operand2));
-            }
-
-        }
-        return specStack.pop();
-
-    }
-
-}
+package com.baeldung.persistence.dao;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.springframework.data.jpa.domain.Specification;
+
+import com.baeldung.web.util.SearchOperation;
+import com.baeldung.web.util.SpecSearchCriteria;
+
+public class GenericSpecificationsBuilder {
+
+    private final List params;
+
+    public GenericSpecificationsBuilder() {
+        this.params = new ArrayList<>();
+    }
+
+    public final GenericSpecificationsBuilder with(final String key, final String operation, final Object value, final String prefix, final String suffix) {
+        return with(null, key, operation, value, prefix, suffix);
+    }
+
+    public final GenericSpecificationsBuilder with(final String precedenceIndicator, final String key, final String operation, final Object value, final String prefix, final String suffix) {
+        SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
+        if (op != null) {
+            if (op == SearchOperation.EQUALITY) // the operation may be complex operation
+            {
+                final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
+                final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
+
+                if (startWithAsterisk && endWithAsterisk) {
+                    op = SearchOperation.CONTAINS;
+                } else if (startWithAsterisk) {
+                    op = SearchOperation.ENDS_WITH;
+                } else if (endWithAsterisk) {
+                    op = SearchOperation.STARTS_WITH;
+                }
+            }
+            params.add(new SpecSearchCriteria(precedenceIndicator, key, op, value));
+        }
+        return this;
+    }
+
+    public Specification build(Function> converter) {
+
+        if (params.size() == 0) {
+            return null;
+        }
+
+        final List> specs = params.stream()
+            .map(converter)
+            .collect(Collectors.toCollection(ArrayList::new));
+
+        Specification result = specs.get(0);
+
+        for (int idx = 1; idx < specs.size(); idx++) {
+            result = params.get(idx)
+                .isOrPredicate()
+                    ? Specification.where(result)
+                        .or(specs.get(idx))
+                    : Specification.where(result)
+                        .and(specs.get(idx));
+        }
+        
+        return result;
+    }
+
+    public Specification build(Deque> postFixedExprStack, Function> converter) {
+
+        Deque> specStack = new LinkedList<>();
+
+        Collections.reverse((List>) postFixedExprStack);
+
+        while (!postFixedExprStack.isEmpty()) {
+            Object mayBeOperand = postFixedExprStack.pop();
+
+            if (!(mayBeOperand instanceof String)) {
+                specStack.push(converter.apply((SpecSearchCriteria) mayBeOperand));
+            } else {
+                Specification operand1 = specStack.pop();
+                Specification operand2 = specStack.pop();
+                if (mayBeOperand.equals(SearchOperation.AND_OPERATOR))
+                    specStack.push(Specification.where(operand1)
+                        .and(operand2));
+                else if (mayBeOperand.equals(SearchOperation.OR_OPERATOR))
+                    specStack.push(Specification.where(operand1)
+                        .or(operand2));
+            }
+
+        }
+        return specStack.pop();
+
+    }
+
+}
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/IUserDAO.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/IUserDAO.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/IUserDAO.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/IUserDAO.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicate.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicate.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicate.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicate.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicatesBuilder.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicatesBuilder.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicatesBuilder.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserPredicatesBuilder.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserRepository.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserRepository.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserRepository.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/MyUserRepository.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserDAO.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserRepository.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserRepository.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserRepository.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserRepository.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSearchQueryCriteriaConsumer.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecification.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecificationsBuilder.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecificationsBuilder.java
similarity index 97%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecificationsBuilder.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecificationsBuilder.java
index 72d7274226..eac1562294 100644
--- a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecificationsBuilder.java
+++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/UserSpecificationsBuilder.java
@@ -1,70 +1,70 @@
-package com.baeldung.persistence.dao;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.springframework.data.jpa.domain.Specification;
-
-import com.baeldung.persistence.model.User;
-import com.baeldung.web.util.SearchOperation;
-import com.baeldung.web.util.SpecSearchCriteria;
-
-public final class UserSpecificationsBuilder {
-
-    private final List params;
-
-    public UserSpecificationsBuilder() {
-        params = new ArrayList<>();
-    }
-
-    // API
-
-    public final UserSpecificationsBuilder with(final String key, final String operation, final Object value, final String prefix, final String suffix) {
-        return with(null, key, operation, value, prefix, suffix);
-    }
-
-    public final UserSpecificationsBuilder with(final String orPredicate, final String key, final String operation, final Object value, final String prefix, final String suffix) {
-        SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
-        if (op != null) {
-            if (op == SearchOperation.EQUALITY) { // the operation may be complex operation
-                final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
-                final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
-
-                if (startWithAsterisk && endWithAsterisk) {
-                    op = SearchOperation.CONTAINS;
-                } else if (startWithAsterisk) {
-                    op = SearchOperation.ENDS_WITH;
-                } else if (endWithAsterisk) {
-                    op = SearchOperation.STARTS_WITH;
-                }
-            }
-            params.add(new SpecSearchCriteria(orPredicate, key, op, value));
-        }
-        return this;
-    }
-
-    public Specification build() {
-        if (params.size() == 0)
-            return null;
-
-        Specification result = new UserSpecification(params.get(0));
-     
-        for (int i = 1; i < params.size(); i++) {
-            result = params.get(i).isOrPredicate()
-              ? Specification.where(result).or(new UserSpecification(params.get(i))) 
-              : Specification.where(result).and(new UserSpecification(params.get(i)));
-        }
-        
-        return result;
-    }
-
-    public final UserSpecificationsBuilder with(UserSpecification spec) {
-        params.add(spec.getCriteria());
-        return this;
-    }
-
-    public final UserSpecificationsBuilder with(SpecSearchCriteria criteria) {
-        params.add(criteria);
-        return this;
-    }
-}
+package com.baeldung.persistence.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.data.jpa.domain.Specification;
+
+import com.baeldung.persistence.model.User;
+import com.baeldung.web.util.SearchOperation;
+import com.baeldung.web.util.SpecSearchCriteria;
+
+public final class UserSpecificationsBuilder {
+
+    private final List params;
+
+    public UserSpecificationsBuilder() {
+        params = new ArrayList<>();
+    }
+
+    // API
+
+    public final UserSpecificationsBuilder with(final String key, final String operation, final Object value, final String prefix, final String suffix) {
+        return with(null, key, operation, value, prefix, suffix);
+    }
+
+    public final UserSpecificationsBuilder with(final String orPredicate, final String key, final String operation, final Object value, final String prefix, final String suffix) {
+        SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
+        if (op != null) {
+            if (op == SearchOperation.EQUALITY) { // the operation may be complex operation
+                final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
+                final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
+
+                if (startWithAsterisk && endWithAsterisk) {
+                    op = SearchOperation.CONTAINS;
+                } else if (startWithAsterisk) {
+                    op = SearchOperation.ENDS_WITH;
+                } else if (endWithAsterisk) {
+                    op = SearchOperation.STARTS_WITH;
+                }
+            }
+            params.add(new SpecSearchCriteria(orPredicate, key, op, value));
+        }
+        return this;
+    }
+
+    public Specification build() {
+        if (params.size() == 0)
+            return null;
+
+        Specification result = new UserSpecification(params.get(0));
+     
+        for (int i = 1; i < params.size(); i++) {
+            result = params.get(i).isOrPredicate()
+              ? Specification.where(result).or(new UserSpecification(params.get(i))) 
+              : Specification.where(result).and(new UserSpecification(params.get(i)));
+        }
+        
+        return result;
+    }
+
+    public final UserSpecificationsBuilder with(UserSpecification spec) {
+        params.add(spec.getCriteria());
+        return this;
+    }
+
+    public final UserSpecificationsBuilder with(SpecSearchCriteria criteria) {
+        params.add(criteria);
+        return this;
+    }
+}
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/CustomRsqlVisitor.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/CustomRsqlVisitor.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/CustomRsqlVisitor.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/CustomRsqlVisitor.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecBuilder.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecBuilder.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecBuilder.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecBuilder.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/GenericRsqlSpecification.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/RsqlSearchOperation.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/RsqlSearchOperation.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/RsqlSearchOperation.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/dao/rsql/RsqlSearchOperation.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/MyUser.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/persistence/model/User_.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/Application.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/spring/PersistenceConfig.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/PersistenceConfig.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/spring/PersistenceConfig.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/PersistenceConfig.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/spring/WebConfig.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/WebConfig.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/spring/WebConfig.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/spring/WebConfig.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/controller/HomeController.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/controller/HomeController.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/controller/HomeController.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/controller/HomeController.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/controller/UserController.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/controller/UserController.java
similarity index 97%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/controller/UserController.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/controller/UserController.java
index 54e8618b27..73a97f84ae 100644
--- a/spring-rest-query-language/src/main/java/com/baeldung/web/controller/UserController.java
+++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/controller/UserController.java
@@ -1,171 +1,171 @@
-package com.baeldung.web.controller;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.data.querydsl.binding.QuerydslPredicate;
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-import com.baeldung.persistence.dao.GenericSpecificationsBuilder;
-import com.baeldung.persistence.dao.IUserDAO;
-import com.baeldung.persistence.dao.MyUserPredicatesBuilder;
-import com.baeldung.persistence.dao.MyUserRepository;
-import com.baeldung.persistence.dao.UserRepository;
-import com.baeldung.persistence.dao.UserSpecification;
-import com.baeldung.persistence.dao.UserSpecificationsBuilder;
-import com.baeldung.persistence.dao.rsql.CustomRsqlVisitor;
-import com.baeldung.persistence.model.MyUser;
-import com.baeldung.persistence.model.User;
-import com.baeldung.web.util.CriteriaParser;
-import com.baeldung.web.util.SearchCriteria;
-import com.baeldung.web.util.SearchOperation;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.querydsl.core.types.Predicate;
-import com.querydsl.core.types.dsl.BooleanExpression;
-
-import cz.jirutka.rsql.parser.RSQLParser;
-import cz.jirutka.rsql.parser.ast.Node;
-
-//@EnableSpringDataWebSupport
-@Controller
-@RequestMapping(value = "/auth/")
-public class UserController {
-
-    @Autowired
-    private IUserDAO service;
-
-    @Autowired
-    private UserRepository dao;
-
-    @Autowired
-    private MyUserRepository myUserRepository;
-
-    public UserController() {
-        super();
-    }
-
-    // API - READ
-
-    @RequestMapping(method = RequestMethod.GET, value = "/users")
-    @ResponseBody
-    public List search(@RequestParam(value = "search", required = false) String search) {
-        List params = new ArrayList();
-        if (search != null) {
-            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
-            Matcher matcher = pattern.matcher(search + ",");
-            while (matcher.find()) {
-                params.add(new SearchCriteria(matcher.group(1), matcher.group(2), matcher.group(3)));
-            }
-        }
-        return service.searchUser(params);
-    }
-
-    @RequestMapping(method = RequestMethod.GET, value = "/users/spec")
-    @ResponseBody
-    public List findAllBySpecification(@RequestParam(value = "search") String search) {
-        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
-        String operationSetExper = Joiner.on("|")
-            .join(SearchOperation.SIMPLE_OPERATION_SET);
-        Pattern pattern = Pattern.compile("(\\w+?)(" + operationSetExper + ")(\\p{Punct}?)(\\w+?)(\\p{Punct}?),");
-        Matcher matcher = pattern.matcher(search + ",");
-        while (matcher.find()) {
-            builder.with(matcher.group(1), matcher.group(2), matcher.group(4), matcher.group(3), matcher.group(5));
-        }
-
-        Specification spec = builder.build();
-        return dao.findAll(spec);
-    }
-
-    @GetMapping(value = "/users/espec")
-    @ResponseBody
-    public List findAllByOrPredicate(@RequestParam(value = "search") String search) {
-        Specification spec = resolveSpecification(search);
-        return dao.findAll(spec);
-    }
-
-    @GetMapping(value = "/users/spec/adv")
-    @ResponseBody
-    public List findAllByAdvPredicate(@RequestParam(value = "search") String search) {
-        Specification spec = resolveSpecificationFromInfixExpr(search);
-        return dao.findAll(spec);
-    }
-
-    protected Specification resolveSpecificationFromInfixExpr(String searchParameters) {
-        CriteriaParser parser = new CriteriaParser();
-        GenericSpecificationsBuilder specBuilder = new GenericSpecificationsBuilder<>();
-        return specBuilder.build(parser.parse(searchParameters), UserSpecification::new);
-    }
-
-    protected Specification resolveSpecification(String searchParameters) {
-
-        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
-        String operationSetExper = Joiner.on("|")
-            .join(SearchOperation.SIMPLE_OPERATION_SET);
-        Pattern pattern = Pattern.compile("(\\p{Punct}?)(\\w+?)(" + operationSetExper + ")(\\p{Punct}?)(\\w+?)(\\p{Punct}?),");
-        Matcher matcher = pattern.matcher(searchParameters + ",");
-        while (matcher.find()) {
-            builder.with(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(5), matcher.group(4), matcher.group(6));
-        }
-        return builder.build();
-    }
-
-    @RequestMapping(method = RequestMethod.GET, value = "/myusers")
-    @ResponseBody
-    public Iterable findAllByQuerydsl(@RequestParam(value = "search") String search) {
-        MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder();
-        if (search != null) {
-            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
-            Matcher matcher = pattern.matcher(search + ",");
-            while (matcher.find()) {
-                builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
-            }
-        }
-        BooleanExpression exp = builder.build();
-        return myUserRepository.findAll(exp);
-    }
-
-    @RequestMapping(method = RequestMethod.GET, value = "/users/rsql")
-    @ResponseBody
-    public List findAllByRsql(@RequestParam(value = "search") String search) {
-        Node rootNode = new RSQLParser().parse(search);
-        Specification spec = rootNode.accept(new CustomRsqlVisitor());
-        return dao.findAll(spec);
-    }
-
-    @RequestMapping(method = RequestMethod.GET, value = "/api/myusers")
-    @ResponseBody
-    public Iterable findAllByWebQuerydsl(@QuerydslPredicate(root = MyUser.class) Predicate predicate) {
-        return myUserRepository.findAll(predicate);
-    }
-
-    // API - WRITE
-
-    @RequestMapping(method = RequestMethod.POST, value = "/users")
-    @ResponseStatus(HttpStatus.CREATED)
-    public void create(@RequestBody User resource) {
-        Preconditions.checkNotNull(resource);
-        dao.save(resource);
-    }
-
-    @RequestMapping(method = RequestMethod.POST, value = "/myusers")
-    @ResponseStatus(HttpStatus.CREATED)
-    public void addMyUser(@RequestBody MyUser resource) {
-        Preconditions.checkNotNull(resource);
-        myUserRepository.save(resource);
-
-    }
-
-}
+package com.baeldung.web.controller;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.querydsl.binding.QuerydslPredicate;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import com.baeldung.persistence.dao.GenericSpecificationsBuilder;
+import com.baeldung.persistence.dao.IUserDAO;
+import com.baeldung.persistence.dao.MyUserPredicatesBuilder;
+import com.baeldung.persistence.dao.MyUserRepository;
+import com.baeldung.persistence.dao.UserRepository;
+import com.baeldung.persistence.dao.UserSpecification;
+import com.baeldung.persistence.dao.UserSpecificationsBuilder;
+import com.baeldung.persistence.dao.rsql.CustomRsqlVisitor;
+import com.baeldung.persistence.model.MyUser;
+import com.baeldung.persistence.model.User;
+import com.baeldung.web.util.CriteriaParser;
+import com.baeldung.web.util.SearchCriteria;
+import com.baeldung.web.util.SearchOperation;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.querydsl.core.types.Predicate;
+import com.querydsl.core.types.dsl.BooleanExpression;
+
+import cz.jirutka.rsql.parser.RSQLParser;
+import cz.jirutka.rsql.parser.ast.Node;
+
+//@EnableSpringDataWebSupport
+@Controller
+@RequestMapping(value = "/auth/")
+public class UserController {
+
+    @Autowired
+    private IUserDAO service;
+
+    @Autowired
+    private UserRepository dao;
+
+    @Autowired
+    private MyUserRepository myUserRepository;
+
+    public UserController() {
+        super();
+    }
+
+    // API - READ
+
+    @RequestMapping(method = RequestMethod.GET, value = "/users")
+    @ResponseBody
+    public List search(@RequestParam(value = "search", required = false) String search) {
+        List params = new ArrayList();
+        if (search != null) {
+            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
+            Matcher matcher = pattern.matcher(search + ",");
+            while (matcher.find()) {
+                params.add(new SearchCriteria(matcher.group(1), matcher.group(2), matcher.group(3)));
+            }
+        }
+        return service.searchUser(params);
+    }
+
+    @RequestMapping(method = RequestMethod.GET, value = "/users/spec")
+    @ResponseBody
+    public List findAllBySpecification(@RequestParam(value = "search") String search) {
+        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
+        String operationSetExper = Joiner.on("|")
+            .join(SearchOperation.SIMPLE_OPERATION_SET);
+        Pattern pattern = Pattern.compile("(\\w+?)(" + operationSetExper + ")(\\p{Punct}?)(\\w+?)(\\p{Punct}?),");
+        Matcher matcher = pattern.matcher(search + ",");
+        while (matcher.find()) {
+            builder.with(matcher.group(1), matcher.group(2), matcher.group(4), matcher.group(3), matcher.group(5));
+        }
+
+        Specification spec = builder.build();
+        return dao.findAll(spec);
+    }
+
+    @GetMapping(value = "/users/espec")
+    @ResponseBody
+    public List findAllByOrPredicate(@RequestParam(value = "search") String search) {
+        Specification spec = resolveSpecification(search);
+        return dao.findAll(spec);
+    }
+
+    @GetMapping(value = "/users/spec/adv")
+    @ResponseBody
+    public List findAllByAdvPredicate(@RequestParam(value = "search") String search) {
+        Specification spec = resolveSpecificationFromInfixExpr(search);
+        return dao.findAll(spec);
+    }
+
+    protected Specification resolveSpecificationFromInfixExpr(String searchParameters) {
+        CriteriaParser parser = new CriteriaParser();
+        GenericSpecificationsBuilder specBuilder = new GenericSpecificationsBuilder<>();
+        return specBuilder.build(parser.parse(searchParameters), UserSpecification::new);
+    }
+
+    protected Specification resolveSpecification(String searchParameters) {
+
+        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
+        String operationSetExper = Joiner.on("|")
+            .join(SearchOperation.SIMPLE_OPERATION_SET);
+        Pattern pattern = Pattern.compile("(\\p{Punct}?)(\\w+?)(" + operationSetExper + ")(\\p{Punct}?)(\\w+?)(\\p{Punct}?),");
+        Matcher matcher = pattern.matcher(searchParameters + ",");
+        while (matcher.find()) {
+            builder.with(matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(5), matcher.group(4), matcher.group(6));
+        }
+        return builder.build();
+    }
+
+    @RequestMapping(method = RequestMethod.GET, value = "/myusers")
+    @ResponseBody
+    public Iterable findAllByQuerydsl(@RequestParam(value = "search") String search) {
+        MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder();
+        if (search != null) {
+            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
+            Matcher matcher = pattern.matcher(search + ",");
+            while (matcher.find()) {
+                builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
+            }
+        }
+        BooleanExpression exp = builder.build();
+        return myUserRepository.findAll(exp);
+    }
+
+    @RequestMapping(method = RequestMethod.GET, value = "/users/rsql")
+    @ResponseBody
+    public List findAllByRsql(@RequestParam(value = "search") String search) {
+        Node rootNode = new RSQLParser().parse(search);
+        Specification spec = rootNode.accept(new CustomRsqlVisitor());
+        return dao.findAll(spec);
+    }
+
+    @RequestMapping(method = RequestMethod.GET, value = "/api/myusers")
+    @ResponseBody
+    public Iterable findAllByWebQuerydsl(@QuerydslPredicate(root = MyUser.class) Predicate predicate) {
+        return myUserRepository.findAll(predicate);
+    }
+
+    // API - WRITE
+
+    @RequestMapping(method = RequestMethod.POST, value = "/users")
+    @ResponseStatus(HttpStatus.CREATED)
+    public void create(@RequestBody User resource) {
+        Preconditions.checkNotNull(resource);
+        dao.save(resource);
+    }
+
+    @RequestMapping(method = RequestMethod.POST, value = "/myusers")
+    @ResponseStatus(HttpStatus.CREATED)
+    public void addMyUser(@RequestBody MyUser resource) {
+        Preconditions.checkNotNull(resource);
+        myUserRepository.save(resource);
+
+    }
+
+}
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/error/RestResponseEntityExceptionHandler.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/util/CriteriaParser.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/CriteriaParser.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/util/CriteriaParser.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/CriteriaParser.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchCriteria.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchCriteria.java
similarity index 100%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchCriteria.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchCriteria.java
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchOperation.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchOperation.java
similarity index 96%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchOperation.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchOperation.java
index acc9e0c0a8..86ad9ad749 100644
--- a/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchOperation.java
+++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SearchOperation.java
@@ -1,36 +1,36 @@
-package com.baeldung.web.util;
-
-public enum SearchOperation {
-    EQUALITY, NEGATION, GREATER_THAN, LESS_THAN, LIKE, STARTS_WITH, ENDS_WITH, CONTAINS;
-
-    public static final String[] SIMPLE_OPERATION_SET = { ":", "!", ">", "<", "~" };
-
-    public static final String OR_PREDICATE_FLAG = "'";
-
-    public static final String ZERO_OR_MORE_REGEX = "*";
-
-    public static final String OR_OPERATOR = "OR";
-
-    public static final String AND_OPERATOR = "AND";
-
-    public static final String LEFT_PARANTHESIS = "(";
-
-    public static final String RIGHT_PARANTHESIS = ")";
-
-    public static SearchOperation getSimpleOperation(final char input) {
-        switch (input) {
-        case ':':
-            return EQUALITY;
-        case '!':
-            return NEGATION;
-        case '>':
-            return GREATER_THAN;
-        case '<':
-            return LESS_THAN;
-        case '~':
-            return LIKE;
-        default:
-            return null;
-        }
-    }
-}
+package com.baeldung.web.util;
+
+public enum SearchOperation {
+    EQUALITY, NEGATION, GREATER_THAN, LESS_THAN, LIKE, STARTS_WITH, ENDS_WITH, CONTAINS;
+
+    public static final String[] SIMPLE_OPERATION_SET = { ":", "!", ">", "<", "~" };
+
+    public static final String OR_PREDICATE_FLAG = "'";
+
+    public static final String ZERO_OR_MORE_REGEX = "*";
+
+    public static final String OR_OPERATOR = "OR";
+
+    public static final String AND_OPERATOR = "AND";
+
+    public static final String LEFT_PARANTHESIS = "(";
+
+    public static final String RIGHT_PARANTHESIS = ")";
+
+    public static SearchOperation getSimpleOperation(final char input) {
+        switch (input) {
+        case ':':
+            return EQUALITY;
+        case '!':
+            return NEGATION;
+        case '>':
+            return GREATER_THAN;
+        case '<':
+            return LESS_THAN;
+        case '~':
+            return LIKE;
+        default:
+            return null;
+        }
+    }
+}
diff --git a/spring-rest-query-language/src/main/java/com/baeldung/web/util/SpecSearchCriteria.java b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SpecSearchCriteria.java
similarity index 96%
rename from spring-rest-query-language/src/main/java/com/baeldung/web/util/SpecSearchCriteria.java
rename to spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SpecSearchCriteria.java
index 73b690673b..22b55c78fb 100644
--- a/spring-rest-query-language/src/main/java/com/baeldung/web/util/SpecSearchCriteria.java
+++ b/spring-web-modules/spring-rest-query-language/src/main/java/com/baeldung/web/util/SpecSearchCriteria.java
@@ -1,82 +1,82 @@
-package com.baeldung.web.util;
-
-public class SpecSearchCriteria {
-
-    private String key;
-    private SearchOperation operation;
-    private Object value;
-    private boolean orPredicate;
-
-    public SpecSearchCriteria() {
-
-    }
-
-    public SpecSearchCriteria(final String key, final SearchOperation operation, final Object value) {
-        super();
-        this.key = key;
-        this.operation = operation;
-        this.value = value;
-    }
-
-    public SpecSearchCriteria(final String orPredicate, final String key, final SearchOperation operation, final Object value) {
-        super();
-        this.orPredicate = orPredicate != null && orPredicate.equals(SearchOperation.OR_PREDICATE_FLAG);
-        this.key = key;
-        this.operation = operation;
-        this.value = value;
-    }
-
-    public SpecSearchCriteria(String key, String operation, String prefix, String value, String suffix) {
-        SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
-        if (op != null) {
-            if (op == SearchOperation.EQUALITY) { // the operation may be complex operation
-                final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
-                final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
-
-                if (startWithAsterisk && endWithAsterisk) {
-                    op = SearchOperation.CONTAINS;
-                } else if (startWithAsterisk) {
-                    op = SearchOperation.ENDS_WITH;
-                } else if (endWithAsterisk) {
-                    op = SearchOperation.STARTS_WITH;
-                }
-            }
-        }
-        this.key = key;
-        this.operation = op;
-        this.value = value;
-    }
-
-    public String getKey() {
-        return key;
-    }
-
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
-    public SearchOperation getOperation() {
-        return operation;
-    }
-
-    public void setOperation(final SearchOperation operation) {
-        this.operation = operation;
-    }
-
-    public Object getValue() {
-        return value;
-    }
-
-    public void setValue(final Object value) {
-        this.value = value;
-    }
-
-    public boolean isOrPredicate() {
-        return orPredicate;
-    }
-
-    public void setOrPredicate(boolean orPredicate) {
-        this.orPredicate = orPredicate;
-    }
-
-}
+package com.baeldung.web.util;
+
+public class SpecSearchCriteria {
+
+    private String key;
+    private SearchOperation operation;
+    private Object value;
+    private boolean orPredicate;
+
+    public SpecSearchCriteria() {
+
+    }
+
+    public SpecSearchCriteria(final String key, final SearchOperation operation, final Object value) {
+        super();
+        this.key = key;
+        this.operation = operation;
+        this.value = value;
+    }
+
+    public SpecSearchCriteria(final String orPredicate, final String key, final SearchOperation operation, final Object value) {
+        super();
+        this.orPredicate = orPredicate != null && orPredicate.equals(SearchOperation.OR_PREDICATE_FLAG);
+        this.key = key;
+        this.operation = operation;
+        this.value = value;
+    }
+
+    public SpecSearchCriteria(String key, String operation, String prefix, String value, String suffix) {
+        SearchOperation op = SearchOperation.getSimpleOperation(operation.charAt(0));
+        if (op != null) {
+            if (op == SearchOperation.EQUALITY) { // the operation may be complex operation
+                final boolean startWithAsterisk = prefix != null && prefix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
+                final boolean endWithAsterisk = suffix != null && suffix.contains(SearchOperation.ZERO_OR_MORE_REGEX);
+
+                if (startWithAsterisk && endWithAsterisk) {
+                    op = SearchOperation.CONTAINS;
+                } else if (startWithAsterisk) {
+                    op = SearchOperation.ENDS_WITH;
+                } else if (endWithAsterisk) {
+                    op = SearchOperation.STARTS_WITH;
+                }
+            }
+        }
+        this.key = key;
+        this.operation = op;
+        this.value = value;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    public SearchOperation getOperation() {
+        return operation;
+    }
+
+    public void setOperation(final SearchOperation operation) {
+        this.operation = operation;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(final Object value) {
+        this.value = value;
+    }
+
+    public boolean isOrPredicate() {
+        return orPredicate;
+    }
+
+    public void setOrPredicate(boolean orPredicate) {
+        this.orPredicate = orPredicate;
+    }
+
+}
diff --git a/spring-rest-query-language/src/main/resources/application.properties b/spring-web-modules/spring-rest-query-language/src/main/resources/application.properties
similarity index 100%
rename from spring-rest-query-language/src/main/resources/application.properties
rename to spring-web-modules/spring-rest-query-language/src/main/resources/application.properties
diff --git a/spring-rest-query-language/src/main/resources/data.sql b/spring-web-modules/spring-rest-query-language/src/main/resources/data.sql
similarity index 100%
rename from spring-rest-query-language/src/main/resources/data.sql
rename to spring-web-modules/spring-rest-query-language/src/main/resources/data.sql
diff --git a/spring-rest-query-language/src/main/resources/logback.xml b/spring-web-modules/spring-rest-query-language/src/main/resources/logback.xml
similarity index 100%
rename from spring-rest-query-language/src/main/resources/logback.xml
rename to spring-web-modules/spring-rest-query-language/src/main/resources/logback.xml
diff --git a/spring-rest-query-language/src/main/resources/persistence-h2.properties b/spring-web-modules/spring-rest-query-language/src/main/resources/persistence-h2.properties
similarity index 100%
rename from spring-rest-query-language/src/main/resources/persistence-h2.properties
rename to spring-web-modules/spring-rest-query-language/src/main/resources/persistence-h2.properties
diff --git a/spring-rest-query-language/src/main/resources/persistence-mysql.properties b/spring-web-modules/spring-rest-query-language/src/main/resources/persistence-mysql.properties
similarity index 100%
rename from spring-rest-query-language/src/main/resources/persistence-mysql.properties
rename to spring-web-modules/spring-rest-query-language/src/main/resources/persistence-mysql.properties
diff --git a/spring-rest-query-language/src/main/resources/springDataPersistenceConfig.xml b/spring-web-modules/spring-rest-query-language/src/main/resources/springDataPersistenceConfig.xml
similarity index 100%
rename from spring-rest-query-language/src/main/resources/springDataPersistenceConfig.xml
rename to spring-web-modules/spring-rest-query-language/src/main/resources/springDataPersistenceConfig.xml
diff --git a/spring-rest-query-language/src/main/webapp/WEB-INF/api-servlet.xml b/spring-web-modules/spring-rest-query-language/src/main/webapp/WEB-INF/api-servlet.xml
similarity index 100%
rename from spring-rest-query-language/src/main/webapp/WEB-INF/api-servlet.xml
rename to spring-web-modules/spring-rest-query-language/src/main/webapp/WEB-INF/api-servlet.xml
diff --git a/spring-rest-query-language/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-web-modules/spring-rest-query-language/src/main/webapp/WEB-INF/view/homepage.jsp
similarity index 100%
rename from spring-rest-query-language/src/main/webapp/WEB-INF/view/homepage.jsp
rename to spring-web-modules/spring-rest-query-language/src/main/webapp/WEB-INF/view/homepage.jsp
diff --git a/spring-rest-query-language/src/main/webapp/WEB-INF/web.xml b/spring-web-modules/spring-rest-query-language/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from spring-rest-query-language/src/main/webapp/WEB-INF/web.xml
rename to spring-web-modules/spring-rest-query-language/src/main/webapp/WEB-INF/web.xml
diff --git a/spring-rest-query-language/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-rest-query-language/src/test/java/com/baeldung/SpringContextTest.java
rename to spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPACriteriaQueryIntegrationTest.java b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPACriteriaQueryIntegrationTest.java
similarity index 100%
rename from spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPACriteriaQueryIntegrationTest.java
rename to spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPACriteriaQueryIntegrationTest.java
diff --git a/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPAQuerydslIntegrationTest.java b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPAQuerydslIntegrationTest.java
similarity index 100%
rename from spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPAQuerydslIntegrationTest.java
rename to spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPAQuerydslIntegrationTest.java
diff --git a/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationIntegrationTest.java b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationIntegrationTest.java
similarity index 97%
rename from spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationIntegrationTest.java
rename to spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationIntegrationTest.java
index 707426769e..f6fff10506 100644
--- a/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationIntegrationTest.java
+++ b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationIntegrationTest.java
@@ -1,180 +1,180 @@
-package com.baeldung.persistence.query;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.test.annotation.Rollback;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
-
-import com.baeldung.persistence.dao.GenericSpecificationsBuilder;
-import com.baeldung.persistence.dao.UserRepository;
-import com.baeldung.persistence.dao.UserSpecification;
-import com.baeldung.persistence.dao.UserSpecificationsBuilder;
-import com.baeldung.persistence.model.User;
-import com.baeldung.spring.PersistenceConfig;
-import com.baeldung.web.util.CriteriaParser;
-import com.baeldung.web.util.SearchOperation;
-import com.baeldung.web.util.SpecSearchCriteria;
-
-import java.util.List;
-import java.util.function.Function;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
-import static org.hamcrest.collection.IsIn.isIn;
-import static org.hamcrest.core.IsNot.not;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(classes = { PersistenceConfig.class })
-@Transactional
-@Rollback
-public class JPASpecificationIntegrationTest {
-
-    @Autowired
-    private UserRepository repository;
-
-    private User userJohn;
-
-    private User userTom;
-
-    private User userPercy;
-
-    @Before
-    public void init() {
-        userJohn = new User();
-        userJohn.setFirstName("john");
-        userJohn.setLastName("doe");
-        userJohn.setEmail("john@doe.com");
-        userJohn.setAge(22);
-        repository.save(userJohn);
-
-        userTom = new User();
-        userTom.setFirstName("tom");
-        userTom.setLastName("doe");
-        userTom.setEmail("tom@doe.com");
-        userTom.setAge(26);
-        repository.save(userTom);
-
-        userPercy = new User();
-        userPercy.setFirstName("percy");
-        userPercy.setLastName("blackney");
-        userPercy.setEmail("percy@blackney.com");
-        userPercy.setAge(30);
-        repository.save(userPercy);
-    }
-
-    @Test
-    public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
-        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.EQUALITY, "john"));
-        final UserSpecification spec1 = new UserSpecification(new SpecSearchCriteria("lastName", SearchOperation.EQUALITY, "doe"));
-        final List results = repository.findAll(Specification
-          .where(spec)
-          .and(spec1));
-
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, not(isIn(results)));
-    }
-
-    @Test
-    public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect() {
-        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
-
-        SpecSearchCriteria spec = new SpecSearchCriteria("firstName", SearchOperation.EQUALITY, "john");
-        SpecSearchCriteria spec1 = new SpecSearchCriteria("'","lastName", SearchOperation.EQUALITY, "doe");
-
-        List results = repository.findAll(builder
-          .with(spec)
-          .with(spec1)
-          .build());
-
-        assertThat(results, hasSize(2));
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, isIn(results));
-    }
-
-    @Test
-    public void givenFirstOrLastNameAndAgeGenericBuilder_whenGettingListOfUsers_thenCorrect() {
-        GenericSpecificationsBuilder builder = new GenericSpecificationsBuilder<>();
-        Function> converter = UserSpecification::new;
-        
-        CriteriaParser parser=new CriteriaParser();
-        List results = repository.findAll(builder.build(parser.parse("( lastName:doe OR firstName:john ) AND age:22"), converter));
-
-        assertThat(results, hasSize(1));
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, not(isIn(results)));
-    }
-
-    @Test
-    public void givenFirstOrLastNameGenericBuilder_whenGettingListOfUsers_thenCorrect() {
-        GenericSpecificationsBuilder builder = new GenericSpecificationsBuilder<>();
-        Function> converter = UserSpecification::new;
-        
-        builder.with("firstName", ":", "john", null, null);
-        builder.with("'", "lastName", ":", "doe", null, null);
-
-        List results = repository.findAll(builder.build(converter));
-
-        assertThat(results, hasSize(2));
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, isIn(results));
-    }
-
-    @Test
-    public void givenFirstNameInverse_whenGettingListOfUsers_thenCorrect() {
-        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.NEGATION, "john"));
-        final List results = repository.findAll(Specification.where(spec));
-
-        assertThat(userTom, isIn(results));
-        assertThat(userJohn, not(isIn(results)));
-    }
-
-    @Test
-    public void givenMinAge_whenGettingListOfUsers_thenCorrect() {
-        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.GREATER_THAN, "25"));
-        final List results = repository.findAll(Specification.where(spec));
-        assertThat(userTom, isIn(results));
-        assertThat(userJohn, not(isIn(results)));
-    }
-
-    @Test
-    public void givenFirstNamePrefix_whenGettingListOfUsers_thenCorrect() {
-        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.STARTS_WITH, "jo"));
-        final List results = repository.findAll(spec);
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, not(isIn(results)));
-    }
-
-    @Test
-    public void givenFirstNameSuffix_whenGettingListOfUsers_thenCorrect() {
-        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.ENDS_WITH, "n"));
-        final List results = repository.findAll(spec);
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, not(isIn(results)));
-    }
-
-    @Test
-    public void givenFirstNameSubstring_whenGettingListOfUsers_thenCorrect() {
-        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.CONTAINS, "oh"));
-        final List results = repository.findAll(spec);
-
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, not(isIn(results)));
-    }
-
-    @Test
-    public void givenAgeRange_whenGettingListOfUsers_thenCorrect() {
-        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.GREATER_THAN, "20"));
-        final UserSpecification spec1 = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.LESS_THAN, "25"));
-        final List results = repository.findAll(Specification
-          .where(spec)
-          .and(spec1));
-
-        assertThat(userJohn, isIn(results));
-        assertThat(userTom, not(isIn(results)));
-    }
-}
+package com.baeldung.persistence.query;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.test.annotation.Rollback;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.baeldung.persistence.dao.GenericSpecificationsBuilder;
+import com.baeldung.persistence.dao.UserRepository;
+import com.baeldung.persistence.dao.UserSpecification;
+import com.baeldung.persistence.dao.UserSpecificationsBuilder;
+import com.baeldung.persistence.model.User;
+import com.baeldung.spring.PersistenceConfig;
+import com.baeldung.web.util.CriteriaParser;
+import com.baeldung.web.util.SearchOperation;
+import com.baeldung.web.util.SpecSearchCriteria;
+
+import java.util.List;
+import java.util.function.Function;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
+import static org.hamcrest.collection.IsIn.isIn;
+import static org.hamcrest.core.IsNot.not;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = { PersistenceConfig.class })
+@Transactional
+@Rollback
+public class JPASpecificationIntegrationTest {
+
+    @Autowired
+    private UserRepository repository;
+
+    private User userJohn;
+
+    private User userTom;
+
+    private User userPercy;
+
+    @Before
+    public void init() {
+        userJohn = new User();
+        userJohn.setFirstName("john");
+        userJohn.setLastName("doe");
+        userJohn.setEmail("john@doe.com");
+        userJohn.setAge(22);
+        repository.save(userJohn);
+
+        userTom = new User();
+        userTom.setFirstName("tom");
+        userTom.setLastName("doe");
+        userTom.setEmail("tom@doe.com");
+        userTom.setAge(26);
+        repository.save(userTom);
+
+        userPercy = new User();
+        userPercy.setFirstName("percy");
+        userPercy.setLastName("blackney");
+        userPercy.setEmail("percy@blackney.com");
+        userPercy.setAge(30);
+        repository.save(userPercy);
+    }
+
+    @Test
+    public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
+        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.EQUALITY, "john"));
+        final UserSpecification spec1 = new UserSpecification(new SpecSearchCriteria("lastName", SearchOperation.EQUALITY, "doe"));
+        final List results = repository.findAll(Specification
+          .where(spec)
+          .and(spec1));
+
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, not(isIn(results)));
+    }
+
+    @Test
+    public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect() {
+        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
+
+        SpecSearchCriteria spec = new SpecSearchCriteria("firstName", SearchOperation.EQUALITY, "john");
+        SpecSearchCriteria spec1 = new SpecSearchCriteria("'","lastName", SearchOperation.EQUALITY, "doe");
+
+        List results = repository.findAll(builder
+          .with(spec)
+          .with(spec1)
+          .build());
+
+        assertThat(results, hasSize(2));
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, isIn(results));
+    }
+
+    @Test
+    public void givenFirstOrLastNameAndAgeGenericBuilder_whenGettingListOfUsers_thenCorrect() {
+        GenericSpecificationsBuilder builder = new GenericSpecificationsBuilder<>();
+        Function> converter = UserSpecification::new;
+        
+        CriteriaParser parser=new CriteriaParser();
+        List results = repository.findAll(builder.build(parser.parse("( lastName:doe OR firstName:john ) AND age:22"), converter));
+
+        assertThat(results, hasSize(1));
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, not(isIn(results)));
+    }
+
+    @Test
+    public void givenFirstOrLastNameGenericBuilder_whenGettingListOfUsers_thenCorrect() {
+        GenericSpecificationsBuilder builder = new GenericSpecificationsBuilder<>();
+        Function> converter = UserSpecification::new;
+        
+        builder.with("firstName", ":", "john", null, null);
+        builder.with("'", "lastName", ":", "doe", null, null);
+
+        List results = repository.findAll(builder.build(converter));
+
+        assertThat(results, hasSize(2));
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, isIn(results));
+    }
+
+    @Test
+    public void givenFirstNameInverse_whenGettingListOfUsers_thenCorrect() {
+        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.NEGATION, "john"));
+        final List results = repository.findAll(Specification.where(spec));
+
+        assertThat(userTom, isIn(results));
+        assertThat(userJohn, not(isIn(results)));
+    }
+
+    @Test
+    public void givenMinAge_whenGettingListOfUsers_thenCorrect() {
+        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.GREATER_THAN, "25"));
+        final List results = repository.findAll(Specification.where(spec));
+        assertThat(userTom, isIn(results));
+        assertThat(userJohn, not(isIn(results)));
+    }
+
+    @Test
+    public void givenFirstNamePrefix_whenGettingListOfUsers_thenCorrect() {
+        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.STARTS_WITH, "jo"));
+        final List results = repository.findAll(spec);
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, not(isIn(results)));
+    }
+
+    @Test
+    public void givenFirstNameSuffix_whenGettingListOfUsers_thenCorrect() {
+        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.ENDS_WITH, "n"));
+        final List results = repository.findAll(spec);
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, not(isIn(results)));
+    }
+
+    @Test
+    public void givenFirstNameSubstring_whenGettingListOfUsers_thenCorrect() {
+        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("firstName", SearchOperation.CONTAINS, "oh"));
+        final List results = repository.findAll(spec);
+
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, not(isIn(results)));
+    }
+
+    @Test
+    public void givenAgeRange_whenGettingListOfUsers_thenCorrect() {
+        final UserSpecification spec = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.GREATER_THAN, "20"));
+        final UserSpecification spec1 = new UserSpecification(new SpecSearchCriteria("age", SearchOperation.LESS_THAN, "25"));
+        final List results = repository.findAll(Specification
+          .where(spec)
+          .and(spec1));
+
+        assertThat(userJohn, isIn(results));
+        assertThat(userTom, not(isIn(results)));
+    }
+}
diff --git a/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationLiveTest.java b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationLiveTest.java
similarity index 97%
rename from spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationLiveTest.java
rename to spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationLiveTest.java
index ad6a4259e7..d1fded3f10 100644
--- a/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationLiveTest.java
+++ b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/JPASpecificationLiveTest.java
@@ -1,147 +1,147 @@
-package com.baeldung.persistence.query;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import io.restassured.RestAssured;
-import io.restassured.response.Response;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.test.context.ActiveProfiles;
-
-import com.baeldung.persistence.model.User;
-
-//@RunWith(SpringJUnit4ClassRunner.class)
-//@ContextConfiguration(classes = { ConfigTest.class,
-//		PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class)
-@ActiveProfiles("test")
-public class JPASpecificationLiveTest {
-
-    // @Autowired
-    // private UserRepository repository;
-
-    private User userJohn;
-
-    private User userTom;
-
-    private final String URL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/spec?search=";
-
-    @Before
-    public void init() {
-        userJohn = new User();
-        userJohn.setFirstName("john");
-        userJohn.setLastName("doe");
-        userJohn.setEmail("john@doe.com");
-        userJohn.setAge(22);
-        // repository.save(userJohn);
-
-        userTom = new User();
-        userTom.setFirstName("tom");
-        userTom.setLastName("doe");
-        userTom.setEmail("tom@doe.com");
-        userTom.setAge(26);
-        // repository.save(userTom);
-    }
-
-    private final String EURL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/espec?search=";
-
-    @Test
-    public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(EURL_PREFIX + "firstName:john,'lastName:doe");
-        final String result = response.body()
-            .asString();
-        assertTrue(result.contains(userJohn.getEmail()));
-        assertTrue(result.contains(userTom.getEmail()));
-    }
-
-    @Test
-    public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(URL_PREFIX + "firstName:john,lastName:doe");
-        final String result = response.body()
-            .asString();
-
-        assertTrue(result.contains(userJohn.getEmail()));
-        assertFalse(result.contains(userTom.getEmail()));
-    }
-
-    @Test
-    public void givenFirstNameInverse_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(URL_PREFIX + "firstName!john");
-        final String result = response.body()
-            .asString();
-
-        assertTrue(result.contains(userTom.getEmail()));
-        assertFalse(result.contains(userJohn.getEmail()));
-    }
-
-    @Test
-    public void givenMinAge_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(URL_PREFIX + "age>25");
-        final String result = response.body()
-            .asString();
-
-        assertTrue(result.contains(userTom.getEmail()));
-        assertFalse(result.contains(userJohn.getEmail()));
-    }
-
-    @Test
-    public void givenFirstNamePrefix_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(URL_PREFIX + "firstName:jo*");
-        final String result = response.body()
-            .asString();
-
-        assertTrue(result.contains(userJohn.getEmail()));
-        assertFalse(result.contains(userTom.getEmail()));
-    }
-
-    @Test
-    public void givenFirstNameSuffix_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(URL_PREFIX + "firstName:*n");
-        final String result = response.body()
-            .asString();
-
-        assertTrue(result.contains(userJohn.getEmail()));
-        assertFalse(result.contains(userTom.getEmail()));
-    }
-
-    @Test
-    public void givenFirstNameSubstring_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(URL_PREFIX + "firstName:*oh*");
-        final String result = response.body()
-            .asString();
-
-        assertTrue(result.contains(userJohn.getEmail()));
-        assertFalse(result.contains(userTom.getEmail()));
-    }
-
-    @Test
-    public void givenAgeRange_whenGettingListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(URL_PREFIX + "age>20,age<25");
-        final String result = response.body()
-            .asString();
-
-        assertTrue(result.contains(userJohn.getEmail()));
-        assertFalse(result.contains(userTom.getEmail()));
-    }
-
-    private final String ADV_URL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/spec/adv?search=";
-
-    @Test
-    public void givenFirstOrLastName_whenGettingAdvListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(ADV_URL_PREFIX + "firstName:john OR lastName:doe");
-        final String result = response.body()
-            .asString();
-        assertTrue(result.contains(userJohn.getEmail()));
-        assertTrue(result.contains(userTom.getEmail()));
-    }
-
-    @Test
-    public void givenFirstOrFirstNameAndAge_whenGettingAdvListOfUsers_thenCorrect() {
-        final Response response = RestAssured.get(ADV_URL_PREFIX + "( firstName:john OR firstName:tom ) AND age>22");
-        final String result = response.body()
-            .asString();
-        assertFalse(result.contains(userJohn.getEmail()));
-        assertTrue(result.contains(userTom.getEmail()));
-    }
-
-}
+package com.baeldung.persistence.query;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import io.restassured.RestAssured;
+import io.restassured.response.Response;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.test.context.ActiveProfiles;
+
+import com.baeldung.persistence.model.User;
+
+//@RunWith(SpringJUnit4ClassRunner.class)
+//@ContextConfiguration(classes = { ConfigTest.class,
+//		PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class)
+@ActiveProfiles("test")
+public class JPASpecificationLiveTest {
+
+    // @Autowired
+    // private UserRepository repository;
+
+    private User userJohn;
+
+    private User userTom;
+
+    private final String URL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/spec?search=";
+
+    @Before
+    public void init() {
+        userJohn = new User();
+        userJohn.setFirstName("john");
+        userJohn.setLastName("doe");
+        userJohn.setEmail("john@doe.com");
+        userJohn.setAge(22);
+        // repository.save(userJohn);
+
+        userTom = new User();
+        userTom.setFirstName("tom");
+        userTom.setLastName("doe");
+        userTom.setEmail("tom@doe.com");
+        userTom.setAge(26);
+        // repository.save(userTom);
+    }
+
+    private final String EURL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/espec?search=";
+
+    @Test
+    public void givenFirstOrLastName_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(EURL_PREFIX + "firstName:john,'lastName:doe");
+        final String result = response.body()
+            .asString();
+        assertTrue(result.contains(userJohn.getEmail()));
+        assertTrue(result.contains(userTom.getEmail()));
+    }
+
+    @Test
+    public void givenFirstAndLastName_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(URL_PREFIX + "firstName:john,lastName:doe");
+        final String result = response.body()
+            .asString();
+
+        assertTrue(result.contains(userJohn.getEmail()));
+        assertFalse(result.contains(userTom.getEmail()));
+    }
+
+    @Test
+    public void givenFirstNameInverse_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(URL_PREFIX + "firstName!john");
+        final String result = response.body()
+            .asString();
+
+        assertTrue(result.contains(userTom.getEmail()));
+        assertFalse(result.contains(userJohn.getEmail()));
+    }
+
+    @Test
+    public void givenMinAge_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(URL_PREFIX + "age>25");
+        final String result = response.body()
+            .asString();
+
+        assertTrue(result.contains(userTom.getEmail()));
+        assertFalse(result.contains(userJohn.getEmail()));
+    }
+
+    @Test
+    public void givenFirstNamePrefix_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(URL_PREFIX + "firstName:jo*");
+        final String result = response.body()
+            .asString();
+
+        assertTrue(result.contains(userJohn.getEmail()));
+        assertFalse(result.contains(userTom.getEmail()));
+    }
+
+    @Test
+    public void givenFirstNameSuffix_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(URL_PREFIX + "firstName:*n");
+        final String result = response.body()
+            .asString();
+
+        assertTrue(result.contains(userJohn.getEmail()));
+        assertFalse(result.contains(userTom.getEmail()));
+    }
+
+    @Test
+    public void givenFirstNameSubstring_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(URL_PREFIX + "firstName:*oh*");
+        final String result = response.body()
+            .asString();
+
+        assertTrue(result.contains(userJohn.getEmail()));
+        assertFalse(result.contains(userTom.getEmail()));
+    }
+
+    @Test
+    public void givenAgeRange_whenGettingListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(URL_PREFIX + "age>20,age<25");
+        final String result = response.body()
+            .asString();
+
+        assertTrue(result.contains(userJohn.getEmail()));
+        assertFalse(result.contains(userTom.getEmail()));
+    }
+
+    private final String ADV_URL_PREFIX = "http://localhost:8082/spring-rest-query-language/auth/users/spec/adv?search=";
+
+    @Test
+    public void givenFirstOrLastName_whenGettingAdvListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(ADV_URL_PREFIX + "firstName:john OR lastName:doe");
+        final String result = response.body()
+            .asString();
+        assertTrue(result.contains(userJohn.getEmail()));
+        assertTrue(result.contains(userTom.getEmail()));
+    }
+
+    @Test
+    public void givenFirstOrFirstNameAndAge_whenGettingAdvListOfUsers_thenCorrect() {
+        final Response response = RestAssured.get(ADV_URL_PREFIX + "( firstName:john OR firstName:tom ) AND age>22");
+        final String result = response.body()
+            .asString();
+        assertFalse(result.contains(userJohn.getEmail()));
+        assertTrue(result.contains(userTom.getEmail()));
+    }
+
+}
diff --git a/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/RsqlIntegrationTest.java b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/RsqlIntegrationTest.java
similarity index 100%
rename from spring-rest-query-language/src/test/java/com/baeldung/persistence/query/RsqlIntegrationTest.java
rename to spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/persistence/query/RsqlIntegrationTest.java
diff --git a/spring-rest-query-language/src/test/java/com/baeldung/web/MyUserLiveTest.java b/spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/web/MyUserLiveTest.java
similarity index 100%
rename from spring-rest-query-language/src/test/java/com/baeldung/web/MyUserLiveTest.java
rename to spring-web-modules/spring-rest-query-language/src/test/java/com/baeldung/web/MyUserLiveTest.java
diff --git a/spring-rest-query-language/src/test/resources/.gitignore b/spring-web-modules/spring-rest-query-language/src/test/resources/.gitignore
similarity index 100%
rename from spring-rest-query-language/src/test/resources/.gitignore
rename to spring-web-modules/spring-rest-query-language/src/test/resources/.gitignore
diff --git a/spring-rest-shell/README.md b/spring-web-modules/spring-rest-shell/README.md
similarity index 100%
rename from spring-rest-shell/README.md
rename to spring-web-modules/spring-rest-shell/README.md
diff --git a/spring-rest-shell/pom.xml b/spring-web-modules/spring-rest-shell/pom.xml
similarity index 96%
rename from spring-rest-shell/pom.xml
rename to spring-web-modules/spring-rest-shell/pom.xml
index 1148a5c093..f5792fd6ca 100644
--- a/spring-rest-shell/pom.xml
+++ b/spring-web-modules/spring-rest-shell/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-rest-shell/src/main/java/com/baeldung/Application.java b/spring-web-modules/spring-rest-shell/src/main/java/com/baeldung/Application.java
similarity index 100%
rename from spring-rest-shell/src/main/java/com/baeldung/Application.java
rename to spring-web-modules/spring-rest-shell/src/main/java/com/baeldung/Application.java
diff --git a/spring-rest-shell/src/main/java/com/baeldung/acticle/Article.java b/spring-web-modules/spring-rest-shell/src/main/java/com/baeldung/acticle/Article.java
similarity index 100%
rename from spring-rest-shell/src/main/java/com/baeldung/acticle/Article.java
rename to spring-web-modules/spring-rest-shell/src/main/java/com/baeldung/acticle/Article.java
diff --git a/spring-rest-shell/src/main/java/com/baeldung/acticle/ArticleRepository.java b/spring-web-modules/spring-rest-shell/src/main/java/com/baeldung/acticle/ArticleRepository.java
similarity index 100%
rename from spring-rest-shell/src/main/java/com/baeldung/acticle/ArticleRepository.java
rename to spring-web-modules/spring-rest-shell/src/main/java/com/baeldung/acticle/ArticleRepository.java
diff --git a/spring-rest-shell/src/main/resources/logback.xml b/spring-web-modules/spring-rest-shell/src/main/resources/logback.xml
similarity index 100%
rename from spring-rest-shell/src/main/resources/logback.xml
rename to spring-web-modules/spring-rest-shell/src/main/resources/logback.xml
diff --git a/spring-rest-simple/README.md b/spring-web-modules/spring-rest-simple/README.md
similarity index 100%
rename from spring-rest-simple/README.md
rename to spring-web-modules/spring-rest-simple/README.md
diff --git a/spring-rest-simple/pom.xml b/spring-web-modules/spring-rest-simple/pom.xml
similarity index 99%
rename from spring-rest-simple/pom.xml
rename to spring-web-modules/spring-rest-simple/pom.xml
index 291053c87f..b9d5100fbf 100644
--- a/spring-rest-simple/pom.xml
+++ b/spring-web-modules/spring-rest-simple/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
@@ -314,7 +314,6 @@
     
 
     
-        1.3.3
         4.0.0
         1.4
         3.1.0
diff --git a/spring-rest-simple/src/main/java/com/baeldung/Application.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/Application.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/Application.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/Application.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/apachefileupload/UploadController.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/apachefileupload/UploadController.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/apachefileupload/UploadController.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/apachefileupload/UploadController.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/config/MvcConfig.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/config/converter/KryoHttpMessageConverter.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/config/converter/KryoHttpMessageConverter.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/config/converter/KryoHttpMessageConverter.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/config/converter/KryoHttpMessageConverter.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/repository/BookRepository.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/repository/BookRepository.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/repository/BookRepository.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/repository/BookRepository.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/controller/ApiExceptionHandler.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/controller/ApiExceptionHandler.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/controller/ApiExceptionHandler.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/controller/ApiExceptionHandler.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/controller/BookController.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/controller/BookController.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/controller/BookController.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/controller/BookController.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/controller/FooController.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/controller/FooController.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/controller/FooController.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/controller/FooController.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/dto/Bazz.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/Bazz.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/dto/Bazz.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/Bazz.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/dto/Book.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/Book.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/dto/Book.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/Book.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/dto/Foo.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/Foo.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/dto/Foo.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/Foo.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/dto/FooProtos.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/FooProtos.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/dto/FooProtos.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/dto/FooProtos.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/error/ApiErrorResponse.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/error/ApiErrorResponse.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/error/ApiErrorResponse.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/error/ApiErrorResponse.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/error/BookNotFoundException.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/error/BookNotFoundException.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/error/BookNotFoundException.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/error/BookNotFoundException.java
diff --git a/spring-rest-simple/src/main/java/com/baeldung/web/util/LinkUtil.java b/spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/util/LinkUtil.java
similarity index 100%
rename from spring-rest-simple/src/main/java/com/baeldung/web/util/LinkUtil.java
rename to spring-web-modules/spring-rest-simple/src/main/java/com/baeldung/web/util/LinkUtil.java
diff --git a/spring-rest-simple/src/main/resources/application.properties b/spring-web-modules/spring-rest-simple/src/main/resources/application.properties
similarity index 100%
rename from spring-rest-simple/src/main/resources/application.properties
rename to spring-web-modules/spring-rest-simple/src/main/resources/application.properties
diff --git a/spring-rest-simple/src/main/resources/logback.xml b/spring-web-modules/spring-rest-simple/src/main/resources/logback.xml
similarity index 100%
rename from spring-rest-simple/src/main/resources/logback.xml
rename to spring-web-modules/spring-rest-simple/src/main/resources/logback.xml
diff --git a/spring-rest-simple/src/main/webapp/WEB-INF/company.html b/spring-web-modules/spring-rest-simple/src/main/webapp/WEB-INF/company.html
similarity index 100%
rename from spring-rest-simple/src/main/webapp/WEB-INF/company.html
rename to spring-web-modules/spring-rest-simple/src/main/webapp/WEB-INF/company.html
diff --git a/spring-rest-simple/src/main/webapp/WEB-INF/spring-views.xml b/spring-web-modules/spring-rest-simple/src/main/webapp/WEB-INF/spring-views.xml
similarity index 100%
rename from spring-rest-simple/src/main/webapp/WEB-INF/spring-views.xml
rename to spring-web-modules/spring-rest-simple/src/main/webapp/WEB-INF/spring-views.xml
diff --git a/spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml b/spring-web-modules/spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml
similarity index 100%
rename from spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml
rename to spring-web-modules/spring-rest-simple/src/main/webapp/WEB-INF/spring-web-config.xml
diff --git a/spring-rest-simple/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/SpringContextTest.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/repository/BookRepositoryUnitTest.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/repository/BookRepositoryUnitTest.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/repository/BookRepositoryUnitTest.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/repository/BookRepositoryUnitTest.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/controller/BookControllerIntegrationTest.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/controller/BookControllerIntegrationTest.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/web/controller/BookControllerIntegrationTest.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/controller/BookControllerIntegrationTest.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/controller/mediatypes/TestConfig.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/controller/mediatypes/TestConfig.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/web/controller/mediatypes/TestConfig.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/controller/mediatypes/TestConfig.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/test/RequestMappingLiveTest.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/RequestMappingLiveTest.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/web/test/RequestMappingLiveTest.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/RequestMappingLiveTest.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/test/RestTemplateBasicLiveTest.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/RestTemplateBasicLiveTest.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/web/test/RestTemplateBasicLiveTest.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/RestTemplateBasicLiveTest.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/SpringHttpMessageConvertersLiveTest.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/test/TestRestTemplateBasicLiveTest.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/TestRestTemplateBasicLiveTest.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/web/test/TestRestTemplateBasicLiveTest.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/test/TestRestTemplateBasicLiveTest.java
diff --git a/spring-rest-simple/src/test/java/com/baeldung/web/util/HTTPLinkHeaderUtil.java b/spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/util/HTTPLinkHeaderUtil.java
similarity index 100%
rename from spring-rest-simple/src/test/java/com/baeldung/web/util/HTTPLinkHeaderUtil.java
rename to spring-web-modules/spring-rest-simple/src/test/java/com/baeldung/web/util/HTTPLinkHeaderUtil.java
diff --git a/spring-rest-simple/src/test/resources/.gitignore b/spring-web-modules/spring-rest-simple/src/test/resources/.gitignore
similarity index 100%
rename from spring-rest-simple/src/test/resources/.gitignore
rename to spring-web-modules/spring-rest-simple/src/test/resources/.gitignore
diff --git a/spring-rest-testing/.gitignore b/spring-web-modules/spring-rest-testing/.gitignore
similarity index 100%
rename from spring-rest-testing/.gitignore
rename to spring-web-modules/spring-rest-testing/.gitignore
diff --git a/spring-rest-testing/README.md b/spring-web-modules/spring-rest-testing/README.md
similarity index 100%
rename from spring-rest-testing/README.md
rename to spring-web-modules/spring-rest-testing/README.md
diff --git a/spring-rest-testing/pom.xml b/spring-web-modules/spring-rest-testing/pom.xml
similarity index 99%
rename from spring-rest-testing/pom.xml
rename to spring-web-modules/spring-rest-testing/pom.xml
index 0e947260f4..fea8d25e4d 100644
--- a/spring-rest-testing/pom.xml
+++ b/spring-web-modules/spring-rest-testing/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java
similarity index 97%
rename from spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java
index facc300dfa..b6e62b7295 100644
--- a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java
+++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/ExceptionTestingApplication.java
@@ -1,25 +1,25 @@
-package com.baeldung.exceptiontesting;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
-
-/**
- * Main Application Class - uses Spring Boot. Just run this as a normal Java
- * class to run up a Jetty Server (on http://localhost:8082/spring-rest-full)
- *
- */
-@EnableScheduling
-@EnableAutoConfiguration
-@ComponentScan("com.baeldung.exceptiontesting")
-@SpringBootApplication
-public class ExceptionTestingApplication extends SpringBootServletInitializer {
-
-    public static void main(final String[] args) {
-        SpringApplication.run(ExceptionTestingApplication.class, args);
-    }
-
+package com.baeldung.exceptiontesting;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * Main Application Class - uses Spring Boot. Just run this as a normal Java
+ * class to run up a Jetty Server (on http://localhost:8082/spring-rest-full)
+ *
+ */
+@EnableScheduling
+@EnableAutoConfiguration
+@ComponentScan("com.baeldung.exceptiontesting")
+@SpringBootApplication
+public class ExceptionTestingApplication extends SpringBootServletInitializer {
+
+    public static void main(final String[] args) {
+        SpringApplication.run(ExceptionTestingApplication.class, args);
+    }
+
 }
\ No newline at end of file
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java
similarity index 97%
rename from spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java
index 0f458b5f10..6d98337e40 100644
--- a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java
+++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/controller/ExceptionController.java
@@ -1,31 +1,31 @@
-package com.baeldung.exceptiontesting.controller;
-
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RestController;
-
-import com.baeldung.exceptiontesting.exception.BadArgumentsException;
-import com.baeldung.exceptiontesting.exception.InternalException;
-import com.baeldung.exceptiontesting.exception.ResourceNotFoundException;
-
-@RestController
-public class ExceptionController {
-
-    @GetMapping("/exception/{exception_id}")
-    public void getSpecificException(@PathVariable("exception_id") String pException) {
-        if("not_found".equals(pException)) {
-            throw new ResourceNotFoundException("resource not found");
-        }
-        else if("bad_arguments".equals(pException)) {
-            throw new BadArgumentsException("bad arguments");
-        }
-        else {
-            throw new InternalException("internal error");
-        }
-    }
-
-    @GetMapping("/exception/throw")
-    public void getException() throws Exception {
-        throw new Exception("error");
-    }
-}
+package com.baeldung.exceptiontesting.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.exceptiontesting.exception.BadArgumentsException;
+import com.baeldung.exceptiontesting.exception.InternalException;
+import com.baeldung.exceptiontesting.exception.ResourceNotFoundException;
+
+@RestController
+public class ExceptionController {
+
+    @GetMapping("/exception/{exception_id}")
+    public void getSpecificException(@PathVariable("exception_id") String pException) {
+        if("not_found".equals(pException)) {
+            throw new ResourceNotFoundException("resource not found");
+        }
+        else if("bad_arguments".equals(pException)) {
+            throw new BadArgumentsException("bad arguments");
+        }
+        else {
+            throw new InternalException("internal error");
+        }
+    }
+
+    @GetMapping("/exception/throw")
+    public void getException() throws Exception {
+        throw new Exception("error");
+    }
+}
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java
similarity index 96%
rename from spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java
index 1eb1e6a3c9..1f0e1c1ddb 100644
--- a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java
+++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/BadArgumentsException.java
@@ -1,13 +1,13 @@
-package com.baeldung.exceptiontesting.exception;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@SuppressWarnings("serial")
-@ResponseStatus(HttpStatus.BAD_REQUEST)
-public class BadArgumentsException extends RuntimeException {
-
-    public BadArgumentsException(String message) {
-        super(message);
-    }
-}
+package com.baeldung.exceptiontesting.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@SuppressWarnings("serial")
+@ResponseStatus(HttpStatus.BAD_REQUEST)
+public class BadArgumentsException extends RuntimeException {
+
+    public BadArgumentsException(String message) {
+        super(message);
+    }
+}
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java
similarity index 96%
rename from spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java
index 8e9f0f60f3..854d6a57f0 100644
--- a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java
+++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/InternalException.java
@@ -1,13 +1,13 @@
-package com.baeldung.exceptiontesting.exception;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@SuppressWarnings("serial")
-@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
-public class InternalException extends RuntimeException {
-
-    public InternalException(String message) {
-        super(message);
-    }
-}
+package com.baeldung.exceptiontesting.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@SuppressWarnings("serial")
+@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+public class InternalException extends RuntimeException {
+
+    public InternalException(String message) {
+        super(message);
+    }
+}
diff --git a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java
similarity index 96%
rename from spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java
index 469d5af96f..6d6e6ef712 100644
--- a/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java
+++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/exceptiontesting/exception/ResourceNotFoundException.java
@@ -1,13 +1,13 @@
-package com.baeldung.exceptiontesting.exception;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.ResponseStatus;
-
-@SuppressWarnings("serial")
-@ResponseStatus(HttpStatus.NOT_FOUND)
-public class ResourceNotFoundException extends RuntimeException {
-
-    public ResourceNotFoundException(String message) {
-        super(message);
-    }
-}
+package com.baeldung.exceptiontesting.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@SuppressWarnings("serial")
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class ResourceNotFoundException extends RuntimeException {
+
+    public ResourceNotFoundException(String message) {
+        super(message);
+    }
+}
diff --git a/spring-rest-testing/src/main/java/com/baeldung/persistence/IOperations.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/IOperations.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/persistence/IOperations.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/IOperations.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/persistence/dao/IFooDao.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/dao/IFooDao.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/persistence/dao/IFooDao.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/dao/IFooDao.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/Foo.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/model/User.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/persistence/service/IFooService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/IFooService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/persistence/service/IFooService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/IFooService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/common/AbstractService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/persistence/service/impl/FooService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/spring/Application.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/Application.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/spring/Application.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/Application.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/spring/PersistenceConfig.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/PersistenceConfig.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/spring/PersistenceConfig.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/PersistenceConfig.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/spring/WebConfig.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/WebConfig.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/spring/WebConfig.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/WebConfig.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/FooController.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/controller/HomeController.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/HomeController.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/controller/HomeController.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/HomeController.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/controller/RootController.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/RootController.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/controller/RootController.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/RootController.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/exception/MyResourceNotFoundException.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/metric/ActuatorMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ActuatorMetricService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/metric/ActuatorMetricService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ActuatorMetricService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/metric/CustomActuatorMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/CustomActuatorMetricService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/metric/CustomActuatorMetricService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/CustomActuatorMetricService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/metric/IActuatorMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IActuatorMetricService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/metric/IActuatorMetricService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IActuatorMetricService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/metric/ICustomActuatorMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ICustomActuatorMetricService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/metric/ICustomActuatorMetricService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ICustomActuatorMetricService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/metric/IMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IMetricService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/metric/IMetricService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IMetricService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricFilter.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricFilter.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricFilter.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricFilter.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricService.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricService.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricService.java
diff --git a/spring-rest-testing/src/main/java/com/baeldung/web/util/RestPreconditions.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/util/RestPreconditions.java
similarity index 100%
rename from spring-rest-testing/src/main/java/com/baeldung/web/util/RestPreconditions.java
rename to spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/util/RestPreconditions.java
diff --git a/spring-rest-testing/src/main/resources/application.properties b/spring-web-modules/spring-rest-testing/src/main/resources/application.properties
similarity index 100%
rename from spring-rest-testing/src/main/resources/application.properties
rename to spring-web-modules/spring-rest-testing/src/main/resources/application.properties
diff --git a/spring-rest-testing/src/main/resources/logback.xml b/spring-web-modules/spring-rest-testing/src/main/resources/logback.xml
similarity index 100%
rename from spring-rest-testing/src/main/resources/logback.xml
rename to spring-web-modules/spring-rest-testing/src/main/resources/logback.xml
diff --git a/spring-rest-testing/src/main/resources/persistence-h2.properties b/spring-web-modules/spring-rest-testing/src/main/resources/persistence-h2.properties
similarity index 100%
rename from spring-rest-testing/src/main/resources/persistence-h2.properties
rename to spring-web-modules/spring-rest-testing/src/main/resources/persistence-h2.properties
diff --git a/spring-rest-testing/src/main/resources/persistence-mysql.properties b/spring-web-modules/spring-rest-testing/src/main/resources/persistence-mysql.properties
similarity index 100%
rename from spring-rest-testing/src/main/resources/persistence-mysql.properties
rename to spring-web-modules/spring-rest-testing/src/main/resources/persistence-mysql.properties
diff --git a/spring-rest-testing/src/main/resources/springDataPersistenceConfig.xml b/spring-web-modules/spring-rest-testing/src/main/resources/springDataPersistenceConfig.xml
similarity index 100%
rename from spring-rest-testing/src/main/resources/springDataPersistenceConfig.xml
rename to spring-web-modules/spring-rest-testing/src/main/resources/springDataPersistenceConfig.xml
diff --git a/spring-rest-testing/src/main/webapp/WEB-INF/api-servlet.xml b/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/api-servlet.xml
similarity index 100%
rename from spring-rest-testing/src/main/webapp/WEB-INF/api-servlet.xml
rename to spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/api-servlet.xml
diff --git a/spring-rest-testing/src/main/webapp/WEB-INF/view/graph.jsp b/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/graph.jsp
similarity index 100%
rename from spring-rest-testing/src/main/webapp/WEB-INF/view/graph.jsp
rename to spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/graph.jsp
diff --git a/spring-rest-testing/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/homepage.jsp
similarity index 100%
rename from spring-rest-testing/src/main/webapp/WEB-INF/view/homepage.jsp
rename to spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/homepage.jsp
diff --git a/spring-rest-testing/src/main/webapp/WEB-INF/web.xml b/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from spring-rest-testing/src/main/webapp/WEB-INF/web.xml
rename to spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/web.xml
diff --git a/spring-rest-testing/src/test/java/com/baeldung/Consts.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/Consts.java
similarity index 100%
rename from spring-rest-testing/src/test/java/com/baeldung/Consts.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/Consts.java
diff --git a/spring-rest-testing/src/test/java/com/baeldung/SpringContextIntegrationTest.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/SpringContextIntegrationTest.java
similarity index 100%
rename from spring-rest-testing/src/test/java/com/baeldung/SpringContextIntegrationTest.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/SpringContextIntegrationTest.java
diff --git a/spring-rest-testing/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/SpringContextTest.java
similarity index 100%
rename from spring-rest-testing/src/test/java/com/baeldung/SpringContextTest.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/SpringContextTest.java
diff --git a/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java
similarity index 97%
rename from spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java
index d624efcdd0..8e1eaad977 100644
--- a/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java
+++ b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/exceptiontesting/controller/ExceptionControllerUnitTest.java
@@ -1,65 +1,65 @@
-package com.baeldung.exceptiontesting.controller;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.http.MediaType;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.servlet.MockMvc;
-
-import com.baeldung.exceptiontesting.controller.ExceptionController;
-import com.baeldung.exceptiontesting.exception.BadArgumentsException;
-import com.baeldung.exceptiontesting.exception.InternalException;
-import com.baeldung.exceptiontesting.exception.ResourceNotFoundException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
-
-@RunWith(SpringRunner.class)
-@WebMvcTest(ExceptionController.class)
-public class ExceptionControllerUnitTest{
-
-    @Autowired
-    private MockMvc mvc;
-
-    @Test
-    public void givenNotFound_whenGetSpecificException_thenNotFoundCode() throws Exception {
-        String exceptionParam = "not_found";
-
-        mvc.perform(get("/exception/{exception_id}", exceptionParam)
-            .contentType(MediaType.APPLICATION_JSON))
-            .andExpect(status().isNotFound())
-            .andExpect(result -> assertTrue(result.getResolvedException() instanceof ResourceNotFoundException))
-            .andExpect(result -> assertEquals("resource not found", result.getResolvedException().getMessage()));
-    }
-
-    @Test
-    public void givenBadArguments_whenGetSpecificException_thenBadRequest() throws Exception {
-        String exceptionParam = "bad_arguments";
-
-        mvc.perform(get("/exception/{exception_id}", exceptionParam)
-            .contentType(MediaType.APPLICATION_JSON))
-            .andExpect(status().isBadRequest())
-            .andExpect(result -> assertTrue(result.getResolvedException() instanceof BadArgumentsException))
-            .andExpect(result -> assertEquals("bad arguments", result.getResolvedException().getMessage()));
-    }
-
-    @Test
-    public void givenOther_whenGetSpecificException_thenInternalServerError() throws Exception {
-        String exceptionParam = "dummy";
-
-        mvc.perform(get("/exception/{exception_id}", exceptionParam)
-            .contentType(MediaType.APPLICATION_JSON))
-            .andExpect(status().isInternalServerError())
-            .andExpect(result -> assertTrue(result.getResolvedException() instanceof InternalException))
-            .andExpect(result -> assertEquals("internal error", result.getResolvedException().getMessage()));
-    }
-
-    @Test(expected = Exception.class)
-    public void whenGetException_thenInternalServerError() throws Exception {
-        mvc.perform(get("/exception/throw")
-            .contentType(MediaType.APPLICATION_JSON));
-    }
-}
+package com.baeldung.exceptiontesting.controller;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+import com.baeldung.exceptiontesting.controller.ExceptionController;
+import com.baeldung.exceptiontesting.exception.BadArgumentsException;
+import com.baeldung.exceptiontesting.exception.InternalException;
+import com.baeldung.exceptiontesting.exception.ResourceNotFoundException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+@RunWith(SpringRunner.class)
+@WebMvcTest(ExceptionController.class)
+public class ExceptionControllerUnitTest{
+
+    @Autowired
+    private MockMvc mvc;
+
+    @Test
+    public void givenNotFound_whenGetSpecificException_thenNotFoundCode() throws Exception {
+        String exceptionParam = "not_found";
+
+        mvc.perform(get("/exception/{exception_id}", exceptionParam)
+            .contentType(MediaType.APPLICATION_JSON))
+            .andExpect(status().isNotFound())
+            .andExpect(result -> assertTrue(result.getResolvedException() instanceof ResourceNotFoundException))
+            .andExpect(result -> assertEquals("resource not found", result.getResolvedException().getMessage()));
+    }
+
+    @Test
+    public void givenBadArguments_whenGetSpecificException_thenBadRequest() throws Exception {
+        String exceptionParam = "bad_arguments";
+
+        mvc.perform(get("/exception/{exception_id}", exceptionParam)
+            .contentType(MediaType.APPLICATION_JSON))
+            .andExpect(status().isBadRequest())
+            .andExpect(result -> assertTrue(result.getResolvedException() instanceof BadArgumentsException))
+            .andExpect(result -> assertEquals("bad arguments", result.getResolvedException().getMessage()));
+    }
+
+    @Test
+    public void givenOther_whenGetSpecificException_thenInternalServerError() throws Exception {
+        String exceptionParam = "dummy";
+
+        mvc.perform(get("/exception/{exception_id}", exceptionParam)
+            .contentType(MediaType.APPLICATION_JSON))
+            .andExpect(status().isInternalServerError())
+            .andExpect(result -> assertTrue(result.getResolvedException() instanceof InternalException))
+            .andExpect(result -> assertEquals("internal error", result.getResolvedException().getMessage()));
+    }
+
+    @Test(expected = Exception.class)
+    public void whenGetException_thenInternalServerError() throws Exception {
+        mvc.perform(get("/exception/throw")
+            .contentType(MediaType.APPLICATION_JSON));
+    }
+}
diff --git a/spring-rest-testing/src/test/java/com/baeldung/persistence/PersistenceTestSuite.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/PersistenceTestSuite.java
similarity index 100%
rename from spring-rest-testing/src/test/java/com/baeldung/persistence/PersistenceTestSuite.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/PersistenceTestSuite.java
diff --git a/spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java
similarity index 100%
rename from spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/AbstractServicePersistenceIntegrationTest.java
diff --git a/spring-rest-testing/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java
similarity index 100%
rename from spring-rest-testing/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java
diff --git a/spring-rest-testing/src/test/java/com/baeldung/util/IDUtil.java b/spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/util/IDUtil.java
similarity index 100%
rename from spring-rest-testing/src/test/java/com/baeldung/util/IDUtil.java
rename to spring-web-modules/spring-rest-testing/src/test/java/com/baeldung/util/IDUtil.java
diff --git a/spring-rest-testing/src/test/resources/.gitignore b/spring-web-modules/spring-rest-testing/src/test/resources/.gitignore
similarity index 100%
rename from spring-rest-testing/src/test/resources/.gitignore
rename to spring-web-modules/spring-rest-testing/src/test/resources/.gitignore
diff --git a/spring-rest-testing/src/testFile b/spring-web-modules/spring-rest-testing/src/testFile
similarity index 100%
rename from spring-rest-testing/src/testFile
rename to spring-web-modules/spring-rest-testing/src/testFile
diff --git a/spring-web-modules/spring-resttemplate-3/.gitignore b/spring-web-modules/spring-resttemplate-3/.gitignore
new file mode 100644
index 0000000000..8f98975dc9
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate-3/.gitignore
@@ -0,0 +1,12 @@
+*.class
+
+#folders#
+/target
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/spring-web-modules/spring-resttemplate-3/README.md b/spring-web-modules/spring-resttemplate-3/README.md
new file mode 100644
index 0000000000..6a00d226db
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate-3/README.md
@@ -0,0 +1,11 @@
+## Spring RestTemplate
+
+This module contains articles about Spring RestTemplate
+
+### The Course
+The "REST With Spring" Classes: http://bit.ly/restwithspring
+
+### Relevant Articles:
+- [Uploading MultipartFile with Spring RestTemplate](https://www.baeldung.com/spring-rest-template-multipart-upload)
+- [Get and Post Lists of Objects with RestTemplate](https://www.baeldung.com/spring-rest-template-list)
+- [Download a Large File Through a Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-download-large-file)
\ No newline at end of file
diff --git a/spring-web-modules/spring-resttemplate-3/pom.xml b/spring-web-modules/spring-resttemplate-3/pom.xml
new file mode 100644
index 0000000000..b1c26e002f
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate-3/pom.xml
@@ -0,0 +1,29 @@
+
+
+    4.0.0
+    spring-resttemplate-3
+    0.1-SNAPSHOT
+    spring-resttemplate-3
+    war
+
+    
+        com.baeldung
+        parent-boot-2
+        0.0.1-SNAPSHOT
+        ../../parent-boot-2
+    
+
+    
+        
+        
+            org.springframework.boot
+            spring-boot-starter-web
+        
+        
+            org.springframework.boot
+            spring-boot-starter-test
+        
+    
+
+
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/EmployeeApplication.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/EmployeeApplication.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/EmployeeApplication.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/EmployeeApplication.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/client/EmployeeClient.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/client/EmployeeClient.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/client/EmployeeClient.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/client/EmployeeClient.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/controller/EmployeeResource.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/controller/EmployeeResource.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/controller/EmployeeResource.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/controller/EmployeeResource.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/dto/Employee.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/dto/Employee.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/dto/Employee.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/dto/Employee.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/dto/EmployeeList.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/dto/EmployeeList.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/dto/EmployeeList.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/dto/EmployeeList.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/service/EmployeeService.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/service/EmployeeService.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/lists/service/EmployeeService.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/resttemplate/lists/service/EmployeeService.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/web/upload/app/UploadApplication.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/web/upload/app/UploadApplication.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/web/upload/app/UploadApplication.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/web/upload/app/UploadApplication.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/web/upload/client/MultipartFileUploadClient.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java b/spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java
rename to spring-web-modules/spring-resttemplate-3/src/main/java/com/baeldung/web/upload/controller/FileServerResource.java
diff --git a/spring-resttemplate/src/main/resources/application.properties b/spring-web-modules/spring-resttemplate-3/src/main/resources/application.properties
similarity index 100%
rename from spring-resttemplate/src/main/resources/application.properties
rename to spring-web-modules/spring-resttemplate-3/src/main/resources/application.properties
diff --git a/spring-resttemplate/src/main/resources/logback.xml b/spring-web-modules/spring-resttemplate-3/src/main/resources/logback.xml
similarity index 100%
rename from spring-resttemplate/src/main/resources/logback.xml
rename to spring-web-modules/spring-resttemplate-3/src/main/resources/logback.xml
diff --git a/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/SpringContextTest.java
new file mode 100644
index 0000000000..26972a0aca
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/SpringContextTest.java
@@ -0,0 +1,15 @@
+package com.baeldung;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = { com.baeldung.web.upload.app.UploadApplication.class, })
+public class SpringContextTest {
+
+    @Test
+    public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+    }
+}
diff --git a/spring-resttemplate/src/test/java/com/baeldung/resttemplate/LargeFileDownloadIntegrationTest.java b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/largefile/LargeFileDownloadIntegrationTest.java
similarity index 94%
rename from spring-resttemplate/src/test/java/com/baeldung/resttemplate/LargeFileDownloadIntegrationTest.java
rename to spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/largefile/LargeFileDownloadIntegrationTest.java
index eb5d01d06f..d8fc58319f 100644
--- a/spring-resttemplate/src/test/java/com/baeldung/resttemplate/LargeFileDownloadIntegrationTest.java
+++ b/spring-web-modules/spring-resttemplate-3/src/test/java/com/baeldung/largefile/LargeFileDownloadIntegrationTest.java
@@ -1,21 +1,17 @@
-package com.baeldung.resttemplate;
+package com.baeldung.largefile;
+
+import java.io.File;
+import java.io.FileOutputStream;
 
 import org.assertj.core.api.Assertions;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.springframework.core.io.FileSystemResource;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
-import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.util.StreamUtils;
 import org.springframework.web.client.RestTemplate;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
 public class LargeFileDownloadIntegrationTest {
 
     static String FILE_URL = "http://ovh.net/files/1Mio.dat";
diff --git a/spring-resttemplate/.gitignore b/spring-web-modules/spring-resttemplate-3/src/test/resources/.gitignore
similarity index 100%
rename from spring-resttemplate/.gitignore
rename to spring-web-modules/spring-resttemplate-3/src/test/resources/.gitignore
diff --git a/spring-resttemplate/src/test/resources/logback-test.xml b/spring-web-modules/spring-resttemplate-3/src/test/resources/logback-test.xml
similarity index 100%
rename from spring-resttemplate/src/test/resources/logback-test.xml
rename to spring-web-modules/spring-resttemplate-3/src/test/resources/logback-test.xml
diff --git a/spring-resttemplate/src/test/resources/.gitignore b/spring-web-modules/spring-resttemplate/.gitignore
similarity index 100%
rename from spring-resttemplate/src/test/resources/.gitignore
rename to spring-web-modules/spring-resttemplate/.gitignore
diff --git a/spring-resttemplate/README.md b/spring-web-modules/spring-resttemplate/README.md
similarity index 73%
rename from spring-resttemplate/README.md
rename to spring-web-modules/spring-resttemplate/README.md
index 952f35e90b..e8c240d86b 100644
--- a/spring-resttemplate/README.md
+++ b/spring-web-modules/spring-resttemplate/README.md
@@ -11,10 +11,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
 - [Spring RestTemplate Error Handling](https://www.baeldung.com/spring-rest-template-error-handling)
 - [Configure a RestTemplate with RestTemplateBuilder](https://www.baeldung.com/spring-rest-template-builder)
 - [Mocking a RestTemplate in Spring](https://www.baeldung.com/spring-mock-rest-template)
-- [Download a Large File Through a Spring RestTemplate](https://www.baeldung.com/spring-resttemplate-download-large-file)
 - [Using the Spring RestTemplate Interceptor](https://www.baeldung.com/spring-rest-template-interceptor)
-- [Uploading MultipartFile with Spring RestTemplate](https://www.baeldung.com/spring-rest-template-multipart-upload)
-- [Get and Post Lists of Objects with RestTemplate](https://www.baeldung.com/spring-rest-template-list)
 - [HTTP PUT vs HTTP PATCH in a REST API](https://www.baeldung.com/http-put-patch-difference-spring) 
 
 ### NOTE:
diff --git a/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml
similarity index 99%
rename from spring-resttemplate/pom.xml
rename to spring-web-modules/spring-resttemplate/pom.xml
index 05660f5210..c0f266fd62 100644
--- a/spring-resttemplate/pom.xml
+++ b/spring-web-modules/spring-resttemplate/pom.xml
@@ -11,7 +11,7 @@
         com.baeldung
         parent-boot-2
         0.0.1-SNAPSHOT
-        ../parent-boot-2
+        ../../parent-boot-2
     
 
     
diff --git a/spring-resttemplate/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/ResponseHeadersApplication.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/FilterResponseHeaderController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/controllers/ResponseHeaderController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/responseheaders/filter/AddResponseHeaderFilter.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/RestTemplateConfigurationApplication.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/RestTemplateConfigurationApplication.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/RestTemplateConfigurationApplication.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/RestTemplateConfigurationApplication.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomClientHttpRequestInterceptor.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/CustomRestTemplateCustomizer.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/FooController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/HelloController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/HelloController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/HelloController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/HelloController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/configuration/SpringConfig.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/dto/Foo.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/dto/Foo.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/dto/Foo.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/dto/Foo.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/exception/NotFoundException.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/exception/NotFoundException.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/exception/NotFoundException.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/exception/NotFoundException.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/handler/RestTemplateResponseErrorHandler.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Bar.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Bar.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Bar.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Bar.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Employee.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Employee.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Employee.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/model/Employee.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/BarConsumerService.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/BarConsumerService.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/BarConsumerService.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/BarConsumerService.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/EmployeeService.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/EmployeeService.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/EmployeeService.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/resttemplate/web/service/EmployeeService.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/MainApplication.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/MainApplication.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/MainApplication.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/MainApplication.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/RestClientConfig.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/RestClientConfig.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/RestClientConfig.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/RestClientConfig.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/WebConfig.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/WebConfig.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/WebConfig.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/config/WebConfig.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/interceptors/RestTemplateHeaderModifierInterceptor.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/interceptors/RestTemplateHeaderModifierInterceptor.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/interceptors/RestTemplateHeaderModifierInterceptor.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/interceptors/RestTemplateHeaderModifierInterceptor.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/repository/HeavyResourceRepository.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/repository/HeavyResourceRepository.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/repository/HeavyResourceRepository.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/repository/HeavyResourceRepository.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/BarMappingExamplesController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/BarMappingExamplesController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/BarMappingExamplesController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/BarMappingExamplesController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/CompanyController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/CompanyController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/CompanyController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/CompanyController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/DeferredResultController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/DeferredResultController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/DeferredResultController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/DeferredResultController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/HeavyResourceController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/HeavyResourceController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/HeavyResourceController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/HeavyResourceController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/ItemController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/ItemController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/ItemController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/ItemController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/MyFooController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/PactController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/PactController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/PactController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/PactController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/SimplePostController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/SimplePostController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/SimplePostController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/SimplePostController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/controller/redirect/RedirectController.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Company.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Company.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Company.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Company.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Foo.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Foo.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Foo.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Foo.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResource.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResource.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResource.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResource.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressOnly.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressOnly.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressOnly.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressOnly.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressPartialUpdate.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressPartialUpdate.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressPartialUpdate.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/HeavyResourceAddressPartialUpdate.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Item.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Item.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Item.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Item.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/ItemManager.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/ItemManager.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/ItemManager.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/ItemManager.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/PactDto.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/PactDto.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/PactDto.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/PactDto.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Views.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Views.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Views.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/dto/Views.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/exception/ResourceNotFoundException.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/exception/ResourceNotFoundException.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/exception/ResourceNotFoundException.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/sampleapp/web/exception/ResourceNotFoundException.java
diff --git a/spring-resttemplate/src/main/java/com/baeldung/transfer/LoginForm.java b/spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/transfer/LoginForm.java
similarity index 100%
rename from spring-resttemplate/src/main/java/com/baeldung/transfer/LoginForm.java
rename to spring-web-modules/spring-resttemplate/src/main/java/com/baeldung/transfer/LoginForm.java
diff --git a/spring-web-modules/spring-resttemplate/src/main/resources/application.properties b/spring-web-modules/spring-resttemplate/src/main/resources/application.properties
new file mode 100644
index 0000000000..1a26e3ad99
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+server.port=8082
+server.servlet.context-path=/spring-rest
\ No newline at end of file
diff --git a/spring-web-modules/spring-resttemplate/src/main/resources/logback.xml b/spring-web-modules/spring-resttemplate/src/main/resources/logback.xml
new file mode 100644
index 0000000000..9f48d36486
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate/src/main/resources/logback.xml
@@ -0,0 +1,23 @@
+
+
+    
+        
+            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            
+        
+    
+    
+    
+		
+	
+
+    
+    
+
+    
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java
similarity index 75%
rename from spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java
index 43901cf37f..dc176f5322 100644
--- a/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java
+++ b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringContextTest.java
@@ -8,12 +8,10 @@ import org.springframework.test.context.junit4.SpringRunner;
 import com.baeldung.responseheaders.ResponseHeadersApplication;
 
 @RunWith(SpringRunner.class)
-@SpringBootTest(classes = { ResponseHeadersApplication.class,
-        com.baeldung.web.upload.app.UploadApplication.class,
-		})
+@SpringBootTest(classes = { ResponseHeadersApplication.class })
 public class SpringContextTest {
 
     @Test
-    public void whenSpringContextIsBootstrapped_thenNoExceptions() {	
+    public void whenSpringContextIsBootstrapped_thenNoExceptions() {
     }
 }
diff --git a/spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/SpringTestConfig.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/client/Consts.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/Consts.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/client/Consts.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/Consts.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/client/TestRestTemplateBasicLiveTest.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/pact/PactProviderLiveTest.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateBasicLiveTest.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/resttemplate/RestTemplateLiveTest.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/controller/redirect/RedirectControllerIntegrationTest.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/handler/RestTemplateResponseErrorHandlerIntegrationTest.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceMockRestServiceServerUnitTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceMockRestServiceServerUnitTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceMockRestServiceServerUnitTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceMockRestServiceServerUnitTest.java
diff --git a/spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceUnitTest.java b/spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceUnitTest.java
similarity index 100%
rename from spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceUnitTest.java
rename to spring-web-modules/spring-resttemplate/src/test/java/com/baeldung/web/service/EmployeeServiceUnitTest.java
diff --git a/spring-web-modules/spring-resttemplate/src/test/resources/.gitignore b/spring-web-modules/spring-resttemplate/src/test/resources/.gitignore
new file mode 100644
index 0000000000..83c05e60c8
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate/src/test/resources/.gitignore
@@ -0,0 +1,13 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/spring-web-modules/spring-resttemplate/src/test/resources/logback-test.xml b/spring-web-modules/spring-resttemplate/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..9f48d36486
--- /dev/null
+++ b/spring-web-modules/spring-resttemplate/src/test/resources/logback-test.xml
@@ -0,0 +1,23 @@
+
+
+    
+        
+            %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            
+        
+    
+    
+    
+		
+	
+
+    
+    
+
+    
+    
+
+    
+        
+    
+
\ No newline at end of file
diff --git a/testing-modules/mockito-2/README.md b/testing-modules/mockito-2/README.md
index c7b62182b5..4bd2ff9759 100644
--- a/testing-modules/mockito-2/README.md
+++ b/testing-modules/mockito-2/README.md
@@ -9,3 +9,4 @@
 - [Mockito – Using Spies](https://www.baeldung.com/mockito-spy)
 - [Using Mockito ArgumentCaptor](https://www.baeldung.com/mockito-argumentcaptor)
 - [Difference Between when() and doXxx() Methods in Mockito](https://www.baeldung.com/java-mockito-when-vs-do)
+- [Overview of Mockito MockSettings](https://www.baeldung.com/mockito-mocksettings)
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/AbstractCoffee.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/AbstractCoffee.java
new file mode 100644
index 0000000000..99fd686951
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/AbstractCoffee.java
@@ -0,0 +1,15 @@
+package com.baeldung.mockito.mocksettings;
+
+public abstract class AbstractCoffee {
+
+    protected String name;
+
+    protected AbstractCoffee(String name) {
+        this.name = name;
+    }
+
+    protected String getName() {
+        return name;
+    }
+
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/SimpleService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/SimpleService.java
new file mode 100644
index 0000000000..034517acbf
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/SimpleService.java
@@ -0,0 +1,10 @@
+package com.baeldung.mockito.mocksettings;
+
+public class SimpleService {
+
+    public SimpleService(SpecialInterface special) {
+        Runnable runnable = (Runnable) special;
+        runnable.run();
+    }
+
+}
diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/SpecialInterface.java b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/SpecialInterface.java
new file mode 100644
index 0000000000..e5f88247d6
--- /dev/null
+++ b/testing-modules/mockito-2/src/main/java/com/baeldung/mockito/mocksettings/SpecialInterface.java
@@ -0,0 +1,5 @@
+package com.baeldung.mockito.mocksettings;
+
+public interface SpecialInterface {
+
+}
diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/mocksettings/MockSettingsUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/mocksettings/MockSettingsUnitTest.java
new file mode 100644
index 0000000000..907abc3d76
--- /dev/null
+++ b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/mocksettings/MockSettingsUnitTest.java
@@ -0,0 +1,56 @@
+package com.baeldung.mockito.mocksettings;
+
+import static org.mockito.Answers.RETURNS_SMART_NULLS;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Answers.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.exceptions.verification.SmartNullPointerException;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import com.baeldung.mockito.fluentapi.Pizza;
+import com.baeldung.mockito.fluentapi.PizzaService;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MockSettingsUnitTest {
+
+    @Test(expected = SmartNullPointerException.class)
+    public void whenServiceMockedWithSmartNulls_thenExceptionHasExtraInfo() {
+        PizzaService service = mock(PizzaService.class, withSettings().defaultAnswer(RETURNS_SMART_NULLS));
+        Pizza pizza = service.orderHouseSpecial();
+        pizza.getSize();
+    }
+
+    @Test
+    public void whenServiceMockedWithNameAndVerboseLogging_thenLogsMethodInvocations() {
+        PizzaService service = mock(PizzaService.class, withSettings().name("pizzaServiceMock")
+            .verboseLogging());
+
+        Pizza pizza = mock(Pizza.class);
+        when(service.orderHouseSpecial()).thenReturn(pizza);
+
+        service.orderHouseSpecial();
+
+        verify(service).orderHouseSpecial();
+    }
+
+    @Test
+    public void whenServiceMockedWithExtraInterfaces_thenConstructorSuccess() {
+        SpecialInterface specialMock = mock(SpecialInterface.class, withSettings().extraInterfaces(Runnable.class));
+        new SimpleService(specialMock);
+    }
+
+    @Test
+    public void whenMockSetupWithConstructor_thenConstructorIsInvoked() {
+        AbstractCoffee coffeeSpy = mock(AbstractCoffee.class, withSettings().useConstructor("espresso")
+            .defaultAnswer(CALLS_REAL_METHODS));
+
+        assertEquals("Coffee name: ", "espresso", coffeeSpy.getName());
+    }
+
+}
diff --git a/testing-modules/spring-testing-2/README.md b/testing-modules/spring-testing-2/README.md
index 702a02ff27..16b47adeac 100644
--- a/testing-modules/spring-testing-2/README.md
+++ b/testing-modules/spring-testing-2/README.md
@@ -1,3 +1,5 @@
 ## Relevant Articles:
 
 - [Guide to @DynamicPropertySource in Spring](https://www.baeldung.com/spring-dynamicpropertysource)
+- [Concurrent Test Execution in Spring 5](https://www.baeldung.com/spring-5-concurrent-tests)
+- [Spring 5 Testing with @EnabledIf Annotation](https://www.baeldung.com/spring-5-enabledIf)
diff --git a/testing-modules/spring-testing-2/pom.xml b/testing-modules/spring-testing-2/pom.xml
index 807b84c676..4686a20202 100644
--- a/testing-modules/spring-testing-2/pom.xml
+++ b/testing-modules/spring-testing-2/pom.xml
@@ -54,8 +54,25 @@
         
         
     
+    
+    
+        
+        
+            
+                org.apache.maven.plugins
+                maven-surefire-plugin
+                ${maven-surefire-plugin.version}
+                
+                    methods
+                    true
+                
+            
+        
+    
 
     
         1.12.2
+        2.21.0
     
 
\ No newline at end of file
diff --git a/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/concurrent/Spring5JUnit4ConcurrentIntegrationTest.java
similarity index 98%
rename from spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java
rename to testing-modules/spring-testing-2/src/test/java/com/baeldung/concurrent/Spring5JUnit4ConcurrentIntegrationTest.java
index 7e494465b2..8a0947ba44 100644
--- a/spring-5/src/test/java/com/baeldung/Spring5JUnit4ConcurrentIntegrationTest.java
+++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/concurrent/Spring5JUnit4ConcurrentIntegrationTest.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.concurrent;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/enabledif/EnabledOnJava8.java
similarity index 93%
rename from spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java
rename to testing-modules/spring-testing-2/src/test/java/com/baeldung/enabledif/EnabledOnJava8.java
index c6d3b7ff10..01bdc176e0 100644
--- a/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java
+++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/enabledif/EnabledOnJava8.java
@@ -1,4 +1,4 @@
-package com.baeldung.jupiter;
+package com.baeldung.enabledif;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationIntegrationTest.java b/testing-modules/spring-testing-2/src/test/java/com/baeldung/enabledif/Spring5EnabledAnnotationIntegrationTest.java
similarity index 97%
rename from spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationIntegrationTest.java
rename to testing-modules/spring-testing-2/src/test/java/com/baeldung/enabledif/Spring5EnabledAnnotationIntegrationTest.java
index 35363e0ea3..b6ccb2204b 100644
--- a/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationIntegrationTest.java
+++ b/testing-modules/spring-testing-2/src/test/java/com/baeldung/enabledif/Spring5EnabledAnnotationIntegrationTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.jupiter;
+package com.baeldung.enabledif;
 
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml
index 9fe0fd8895..9e0c986bb2 100644
--- a/testing-modules/spring-testing/pom.xml
+++ b/testing-modules/spring-testing/pom.xml
@@ -39,6 +39,17 @@
             spring-boot-starter-test
             test
         
+        
+            org.junit.vintage
+            junit-vintage-engine
+            test
+            
+                
+                    org.hamcrest
+                    hamcrest-core
+                
+            
+        
         
             org.springframework
             spring-core
diff --git a/webrtc/src/main/resources/static/client.js b/webrtc/src/main/resources/static/client.js
index 059dc84bcb..9b3de9ef6d 100644
--- a/webrtc/src/main/resources/static/client.js
+++ b/webrtc/src/main/resources/static/client.js
@@ -38,11 +38,7 @@ var input = document.getElementById("messageInput");
 function initialize() {
     var configuration = null;
 
-    peerConnection = new RTCPeerConnection(configuration, {
-        optional : [ {
-            RtpDataChannels : true
-        } ]
-    });
+    peerConnection = new RTCPeerConnection(configuration);
 
     // Setup ice handling
     peerConnection.onicecandidate = function(event) {
@@ -71,6 +67,11 @@ function initialize() {
     dataChannel.onclose = function() {
         console.log("data channel is closed");
     };
+  
+  	peerConnection.ondatachannel = function (event) {
+        dataChannel = event.channel;
+  	};
+    
 }
 
 function createOffer() {
diff --git a/xml/pom.xml b/xml/pom.xml
index 8b2df41af6..837f918b46 100644
--- a/xml/pom.xml
+++ b/xml/pom.xml
@@ -364,7 +364,6 @@
         1.2.0
         2.0.6
         1.6.2
-        2.5
         4.1
         1.2.4.5
         2.3.1
@@ -379,7 +378,6 @@
         2.3.29
         0.9.6
         
-        3.5
         2.4
         1.8