diff --git a/pom.xml b/pom.xml
index 0f4da65..adb0d15 100644
--- a/pom.xml
+++ b/pom.xml
@@ -160,7 +160,7 @@
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
-            <version>1.5.11</version>
+            <version>1.7.30</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -173,7 +173,7 @@
         <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
-            <version>1.0.13</version>
+            <version>1.2.3</version>
             <scope>provided</scope>
             <optional>true</optional>
         </dependency>
@@ -203,5 +203,17 @@
             <version>${hamcrest.version}</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <version>2.0.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito2</artifactId>
+            <version>2.0.5</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/junit/impl/TestsManagerImpl.java b/src/main/java/org/apache/sling/junit/impl/TestsManagerImpl.java
index 57abf84..ed7c6f2 100644
--- a/src/main/java/org/apache/sling/junit/impl/TestsManagerImpl.java
+++ b/src/main/java/org/apache/sling/junit/impl/TestsManagerImpl.java
@@ -53,12 +53,15 @@
 
     private static final Logger log = LoggerFactory.getLogger(TestsManagerImpl.class);
 
-    // the inactivity timeout is the maximum time after the last bundle became active
-    // before waiting for more bundles to become active should be aborted
-    private static final int DEFAULT_SYSTEM_STARTUP_INACTIVITY_TIMEOUT_SECONDS = 10;
+    // Global Timeout up to which it stop waiting for bundles to be all active, default to 40 seconds.
+    public static final String PROPERTY_SYSTEM_STARTUP_GLOBAL_TIMEOUT_SECONDS = "sling.junit.core.system_startup_global_timeout";
+
+    private static volatile int globalTimeoutSeconds = Integer.parseInt(System.getProperty(PROPERTY_SYSTEM_STARTUP_GLOBAL_TIMEOUT_SECONDS, "40"));
 
     private static volatile boolean waitForSystemStartup = true;
 
+    private static volatile long timeWaitForSystemStartup = 0;
+
     private ServiceTracker tracker;
 
     private int lastTrackingCount = -1;
@@ -66,7 +69,7 @@
     private BundleContext bundleContext;
     
     // List of providers
-    private List<TestsProvider> providers = new ArrayList<TestsProvider>();
+    private final List<TestsProvider> providers = new ArrayList<TestsProvider>();
     
     // Map of test names to their provider's PID
     private Map<String, String> tests = new ConcurrentHashMap<String, String>();
@@ -126,7 +129,7 @@
         boolean reload = false;
         for(TestsProvider p : providers) {
             final Long lastMod = lastModified.get(p.getServicePid());
-            if(lastMod == null || lastMod.longValue() != p.lastModified()) {
+            if(lastMod == null || lastMod != p.lastModified()) {
                 reload = true;
                 log.debug("{} updated, will reload test names from all providers", p);
                 break;
@@ -141,7 +144,7 @@
                     log.warn("{} has null PID, ignored", p);
                     continue;
                 }
-                lastModified.put(pid, new Long(p.lastModified()));
+                lastModified.put(pid, p.lastModified());
                 final List<String> names = p.getTestNames(); 
                 for(String name : names) {
                     tests.put(name, pid);
@@ -162,7 +165,7 @@
                     result.add(test);
                 }
             }
-            log.debug("{} selected {} tests out of {}", new Object[] { selector, result.size(), allTests.size() });
+            log.debug("{} selected {} tests out of {}", selector, result.size(), allTests.size());
             return result;
         }
     }
@@ -222,7 +225,7 @@
         }
     }
 
-    public void listTests(Collection<String> testNames, Renderer renderer) throws Exception {
+    public void listTests(Collection<String> testNames, Renderer renderer) {
         renderer.title(2, "Test classes");
         final String note = "The test set can be restricted using partial test names"
                 + " as a suffix to this URL"
@@ -244,9 +247,9 @@
             }
 
             // wait max inactivityTimeout after the last bundle became active before giving up
-            long inactivityTimeout = TimeUnit.SECONDS.toMillis(DEFAULT_SYSTEM_STARTUP_INACTIVITY_TIMEOUT_SECONDS);
-            long lastChange = System.currentTimeMillis();
-            while (!bundlesToWaitFor.isEmpty() || (lastChange + inactivityTimeout < System.currentTimeMillis())) {
+            long startTime = System.currentTimeMillis();
+            long globalTimeout = startTime + TimeUnit.SECONDS.toMillis(globalTimeoutSeconds);
+            while (isWaitNeeded(globalTimeout, bundlesToWaitFor)) {
                 log.info("Waiting for the following bundles to start: {}", bundlesToWaitFor);
                 try {
                     TimeUnit.SECONDS.sleep(1);
@@ -259,20 +262,27 @@
                     if (bundle.getState() == Bundle.ACTIVE) {
                         bundles.remove();
                         log.debug("Bundle {} has become active", bundle.getSymbolicName());
-                        lastChange = System.currentTimeMillis();
                     }
                 }
             }
 
+            timeWaitForSystemStartup = System.currentTimeMillis() - startTime;
+
             if (!bundlesToWaitFor.isEmpty()) {
-                log.warn("Waited {} seconds but the following bundles are not yet started: {}",
-                        DEFAULT_SYSTEM_STARTUP_INACTIVITY_TIMEOUT_SECONDS, bundlesToWaitFor);
+                log.warn("Waited {} milliseconds but the following bundles are not yet started: {}",
+                    timeWaitForSystemStartup, bundlesToWaitFor);
             } else {
                 log.info("All bundles are active, starting to run tests.");
             }
         }
     }
 
+    private static boolean isWaitNeeded(final long globalTimeout, final Set<Bundle> bundlesToWaitFor) {
+        long currentTime = System.currentTimeMillis();
+        boolean globallyTimeout = globalTimeout < currentTime;
+        return !globallyTimeout && !bundlesToWaitFor.isEmpty();
+    }
+
     private static boolean isFragment(final Bundle bundle) {
         return bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null;
     }
diff --git a/src/test/java/org/apache/sling/junit/impl/TestsManagerImplTest.java b/src/test/java/org/apache/sling/junit/impl/TestsManagerImplTest.java
new file mode 100644
index 0000000..3367ba1
--- /dev/null
+++ b/src/test/java/org/apache/sling/junit/impl/TestsManagerImplTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.junit.impl;
+
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertTrue;
+import static org.powermock.api.mockito.PowerMockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import org.apache.sling.junit.Activator;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.reflect.Whitebox;
+
+/**
+ * Validate waitForSystemStartup method, along with private some implementations.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ Activator.class, TestsManagerImpl.class })
+public class TestsManagerImplTest {
+
+  static {
+    // Set the system properties for this test as the default would wait longer.
+    System.setProperty(TestsManagerImpl.PROPERTY_SYSTEM_STARTUP_GLOBAL_TIMEOUT_SECONDS, "2");
+  }
+
+  /**
+   * case if isWaitNeeded should return true, mainly it still have some bundles in the list to wait, and global timeout didn't pass.
+   */
+  @Test
+  public void isWaitNeededPositiveNotEmptyListNotGloballyTimeout() throws Exception {
+    final TestsManagerImpl testsManager = new TestsManagerImpl();
+    long globalTimeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10);
+    final Set<Bundle> bundlesToWaitFor = new HashSet<Bundle>();
+    bundlesToWaitFor.add(Mockito.mock(Bundle.class));
+    boolean isWaitNeeded = Whitebox.invokeMethod(TestsManagerImpl.class, "isWaitNeeded", globalTimeout, bundlesToWaitFor);
+    assertTrue(isWaitNeeded);
+  }
+
+  /**
+   * case if isWaitNeeded should return false, when for example it reached the global timeout limit.
+   */
+  @Test
+  public void isWaitNeededNegativeForGlobalTimeout() throws Exception {
+    final TestsManagerImpl testsManager = new TestsManagerImpl();
+    long lastChange = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(1);
+    long globalTimeout = lastChange - TimeUnit.SECONDS.toMillis(1);
+    final Set<Bundle> bundlesToWaitFor = new HashSet<Bundle>();
+    boolean isWaitNeeded = Whitebox.invokeMethod(TestsManagerImpl.class, "isWaitNeeded", globalTimeout, bundlesToWaitFor);
+    assertFalse(isWaitNeeded);
+  }
+
+  /**
+   * case if isWaitNeeded should return false, when for example it reached the global timeout limit.
+   */
+  @Test
+  public void isWaitNeededNegativeForEmptyList() throws Exception {
+    final TestsManagerImpl testsManager = new TestsManagerImpl();
+    long lastChange = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(1);
+    long globalTimeout = lastChange + TimeUnit.SECONDS.toMillis(10);
+    final Set<Bundle> bundlesToWaitFor = new HashSet<Bundle>();
+    boolean isWaitNeeded = Whitebox.invokeMethod(TestsManagerImpl.class, "isWaitNeeded", globalTimeout, bundlesToWaitFor);
+    assertFalse(isWaitNeeded);
+  }
+
+  @Test
+  public void waitForSystemStartupTimeout() {
+    setupBundleContextMock(Bundle.INSTALLED);
+    TestsManagerImpl.waitForSystemStartup();
+    long timeWaitForSystemStartup = Whitebox.getInternalState(TestsManagerImpl.class, "timeWaitForSystemStartup");
+    assertTrue(timeWaitForSystemStartup > TimeUnit.SECONDS.toMillis(2));
+    assertTrue(timeWaitForSystemStartup < TimeUnit.SECONDS.toMillis(3));
+    assertFalse((Boolean) Whitebox.getInternalState(TestsManagerImpl.class, "waitForSystemStartup"));
+  }
+
+  @Test
+  public void waitForSystemStartupAllActiveBundles() {
+    setupBundleContextMock(Bundle.ACTIVE);
+    TestsManagerImpl.waitForSystemStartup();
+    long timeWaitForSystemStartup = Whitebox.getInternalState(TestsManagerImpl.class, "timeWaitForSystemStartup");
+    assertTrue(timeWaitForSystemStartup < TimeUnit.SECONDS.toMillis(2));
+    assertFalse((Boolean) Whitebox.getInternalState(TestsManagerImpl.class, "waitForSystemStartup"));
+  }
+
+  private void setupBundleContextMock(final int bundleState) {
+    PowerMockito.mockStatic(Activator.class);
+    BundleContext mockedBundleContext = mock(BundleContext.class);
+    Bundle mockedBundle = mock(Bundle.class);
+    Hashtable<String, String> bundleHeaders = new Hashtable<String, String>();
+    when(mockedBundle.getState()).thenReturn(bundleState);
+    when(mockedBundle.getHeaders()).thenReturn(bundleHeaders);
+    when(mockedBundleContext.getBundles()).thenReturn(new Bundle[] { mockedBundle });
+    when(Activator.getBundleContext()).thenReturn(mockedBundleContext);
+    Whitebox.setInternalState(TestsManagerImpl.class, "waitForSystemStartup", true);
+  }
+}
\ No newline at end of file
