Download problem index only if system & server enabled

-Download check on startup & when settings change
-Avoid duplicate downloads

Bug: 471778
Change-Id: Id7942312335e73fe70837667e3d46c35e658506e
Signed-off-by: Daniel Haftstein <haftsteind@gmail.com>
diff --git a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnection.java b/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnection.java
index 0e94d0b..d8684c1 100644
--- a/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnection.java
+++ b/bundles/org.eclipse.epp.logging.aeri.ide/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnection.java
@@ -9,9 +9,11 @@
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Predicates.alwaysFalse;
-import static java.util.concurrent.TimeUnit.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import static org.eclipse.epp.internal.logging.aeri.ide.IIdePackage.*;
 import static org.eclipse.epp.internal.logging.aeri.ide.processors.AnonymizeStackTracesProcessor.CTX_ACCEPTED_PACKAGES_PATTERNS;
+import static org.eclipse.epp.logging.aeri.core.IModelPackage.*;
 import static org.eclipse.epp.logging.aeri.core.util.Formats.format;
 import static org.eclipse.epp.logging.aeri.core.util.Links.*;
 
@@ -23,12 +25,15 @@
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.client.fluent.Executor;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
 import org.eclipse.epp.internal.logging.aeri.ide.IServerDescriptor;
 import org.eclipse.epp.internal.logging.aeri.ide.l10n.LogMessages;
 import org.eclipse.epp.internal.logging.aeri.ide.l10n.Messages;
@@ -43,6 +48,7 @@
 import org.eclipse.epp.logging.aeri.core.IServerConnection;
 import org.eclipse.epp.logging.aeri.core.ISystemSettings;
 import org.eclipse.epp.logging.aeri.core.ProblemStatus;
+import org.eclipse.epp.logging.aeri.core.SendMode;
 import org.eclipse.epp.logging.aeri.core.filters.AcceptFreezeFilter;
 import org.eclipse.epp.logging.aeri.core.filters.AcceptedPluginsFilter;
 import org.eclipse.epp.logging.aeri.core.filters.AcceptedProductsFilter;
@@ -53,12 +59,33 @@
 import org.eclipse.epp.logging.aeri.core.util.Logs;
 import org.eclipse.epp.logging.aeri.core.util.Reports;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.util.concurrent.AbstractIdleService;
 
 public class ServerConnection extends AbstractIdleService implements IServerConnection {
 
+    private final class UpdateDatabaseOnFeatureChangeAdapter extends AdapterImpl {
+        private final Class<?> featureClass;
+        private final int[] observedFeatureIds;
+
+        UpdateDatabaseOnFeatureChangeAdapter(Class<?> featureClass, int... observedFeatureIds) {
+            this.featureClass = featureClass;
+            this.observedFeatureIds = observedFeatureIds;
+        }
+
+        @Override
+        public void notifyChanged(Notification msg) {
+            int featureID = msg.getFeatureID(featureClass);
+            if (msg.getEventType() == Notification.SET && ArrayUtils.contains(observedFeatureIds, featureID)) {
+                if (shouldUpdateProblemDatabase(io, systemSettings, remoteHistory)) {
+                    updateProblemDatabase(io, systemSettings, remoteHistory);
+                }
+            }
+        }
+    }
+
     private final IServerDescriptor server;
     private final ISystemSettings systemSettings;
     private final File configurationArea;
@@ -66,6 +93,7 @@
     private IO io;
     private ServerProblemsHistory remoteHistory;
     private LocalReportsHistory localHistory;
+    private UpdateIndexJob updateIndexJob;
 
     @Inject
     public ServerConnection(IServerDescriptor descriptor, ISystemSettings system, File configurationArea) {
@@ -95,7 +123,7 @@
             }
             {
                 File file = new File(configurationArea, "server-config.json"); //$NON-NLS-1$
-                io = new IO(Executor.newInstance(), file);
+                io = createIO(file);
                 if (file.exists()) {
                     io.loadConfiguration();
                 }
@@ -103,18 +131,23 @@
                     io.refreshConfiguration(checkNotNull(getLink(server, REL_DISCOVERY)).getHref(), new NullProgressMonitor());
                     io.saveConfiguration();
                 }
-
-                if (io.isProblemsDatabaseOutdated()) {
-                    // start problem-db download - but wait a few minutes to let everything else settle
-                    new UpdateIndexJob(io, systemSettings, remoteHistory).schedule(MINUTES.toMillis(5));
+                if (shouldUpdateProblemDatabase(io, systemSettings, remoteHistory)) {
+                    updateProblemDatabase(io, systemSettings, remoteHistory);
                 }
             }
-
+            {
+                server.eAdapters().add(new UpdateDatabaseOnFeatureChangeAdapter(IServerDescriptor.class, SERVER_DESCRIPTOR__ENABLED,
+                        SERVER_DESCRIPTOR__CONFIGURED));
+                systemSettings.eAdapters().add(new UpdateDatabaseOnFeatureChangeAdapter(ISystemSettings.class, SYSTEM_SETTINGS__CONFIGURED,
+                        SYSTEM_SETTINGS__SEND_MODE));
+            }
             {
                 // make sure we can operate before removing the AlwaysFalse filter...
                 ServerConfiguration configuration = io.getConfiguration();
                 checkNotNull(configuration, "no configuration available"); //$NON-NLS-1$
                 checkNotNull(localHistory);
+
+                @SuppressWarnings("unchecked")
                 Predicate<? super IStatus>[] statusFilters = DecoratingDebugFilter.decorate(
                 // @formatter:off
                 new LocalHistorySeenFilter(localHistory, systemSettings),
@@ -135,6 +168,26 @@
         }
     }
 
+    private boolean shouldUpdateProblemDatabase(IO io, ISystemSettings systemSettings, ServerProblemsHistory remoteHistory) {
+        return !isUpdating() && server.isConfigured() && server.isEnabled() && systemSettings.isConfigured()
+                && systemSettings.getSendMode() != SendMode.NEVER && io.isProblemsDatabaseOutdated();
+    }
+
+    private boolean isUpdating() {
+        return updateIndexJob != null && updateIndexJob.getResult() == null;
+    }
+
+    @VisibleForTesting
+    protected IO createIO(File file) {
+        return new IO(Executor.newInstance(), file);
+    }
+
+    @VisibleForTesting
+    protected void updateProblemDatabase(IO io, ISystemSettings systemSettings, ServerProblemsHistory remoteHistory) {
+        updateIndexJob = new UpdateIndexJob(io, systemSettings, remoteHistory);
+        updateIndexJob.schedule();
+    }
+
     @Override
     public IProblemState interested(IStatus status, IEclipseContext context, IProgressMonitor monitor) {
         if (!isRunning() || !statusFilters.apply(status)) {
diff --git a/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnectionDatabaseDownloadTest.java b/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnectionDatabaseDownloadTest.java
new file mode 100644
index 0000000..a510fd6
--- /dev/null
+++ b/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnectionDatabaseDownloadTest.java
@@ -0,0 +1,231 @@
+package org.eclipse.epp.internal.logging.aeri.ide.server.mars;
+
+import static org.eclipse.epp.logging.aeri.core.SendMode.BACKGROUND;
+import static org.eclipse.epp.logging.aeri.core.SendMode.NEVER;
+import static org.eclipse.epp.logging.aeri.core.SendMode.NOTIFY;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.epp.internal.logging.aeri.ide.IIdeFactory;
+import org.eclipse.epp.internal.logging.aeri.ide.IServerDescriptor;
+import org.eclipse.epp.logging.aeri.core.IModelFactory;
+import org.eclipse.epp.logging.aeri.core.ISystemSettings;
+import org.eclipse.epp.logging.aeri.core.SendMode;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.mockito.verification.VerificationMode;
+
+@RunWith(Parameterized.class)
+public class ServerConnectionDatabaseDownloadTest {
+
+    private static final boolean ENABLED = true;
+    private static final boolean NOT_ENABLED = false;
+    private static final boolean CONFIGURED = true;
+    private static final boolean NOT_CONFIGURED = false;
+    private static final boolean DB_OUTDATED = true;
+    private static final boolean NOT_DB_OUTDATED = false;
+    private static final boolean ENABLED_AFTER_START = true;
+    private static final boolean NOT_ENABLED_AFTER_START = false;
+    private static final boolean CONFIGURED_AFTER_START = true;
+    private static final boolean NOT_CONFIGURED_AFTER_START = false;
+
+    @Parameters(name = "{0},{1},{2},{3},{4},{5}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                //
+                { BACKGROUND, ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { BACKGROUND, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NEVER, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, times(1) },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, CONFIGURED_AFTER_START, never() },
+                { NOTIFY, NOT_ENABLED, NOT_CONFIGURED, NOT_DB_OUTDATED, NOT_ENABLED_AFTER_START, NOT_CONFIGURED_AFTER_START, never() },
+                //
+        });
+    }
+
+    @Parameter(0)
+    public SendMode sendMode;
+
+    @Parameter(1)
+    public boolean isInitialEnabled;
+
+    @Parameter(2)
+    public boolean isInitialConfigured;
+
+    @Parameter(3)
+    public boolean isDatabaseOutdated;
+
+    @Parameter(4)
+    public boolean isEnabledAfterStartup;
+
+    @Parameter(5)
+    public boolean isConfiguredAfterStartup;
+
+    @Parameter(6)
+    public VerificationMode timesUpdateCalled;
+
+    private IModelFactory mFac = IModelFactory.eINSTANCE;
+    private IIdeFactory iFac = IIdeFactory.eINSTANCE;
+    private ServerConnection sut;
+    private IO io;
+
+    @Rule
+    public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+    private IServerDescriptor descriptor;
+    private ISystemSettings settings;
+
+    private boolean isMockDatabaseDownloaded;
+
+    @Before
+    public void setup() throws IOException {
+        descriptor = iFac.createServerDescriptor();
+        descriptor.setEnabled(false);
+        descriptor.setConfigured(false);
+        io = Mockito.mock(IO.class);
+        when(io.isProblemsDatabaseOutdated()).thenAnswer(new Answer<Boolean>() {
+            @Override
+            public Boolean answer(InvocationOnMock invocation) throws Throwable {
+                return isDatabaseOutdated && !isMockDatabaseDownloaded;
+            }
+        });
+        File configurationArea = temporaryFolder.newFolder();
+        settings = mFac.createSystemSettings();
+        settings.setConfigured(true);
+        ServerConnection serverConnection = new ServerConnection(descriptor, settings, configurationArea);
+        sut = Mockito.spy(serverConnection);
+        isMockDatabaseDownloaded = false;
+        Mockito.doAnswer(new Answer<Void>() {
+            public Void answer(InvocationOnMock invocation) {
+                isMockDatabaseDownloaded = true;
+                return null;
+            }
+        }).when(sut).updateProblemDatabase(any(), any(), any());
+        when(sut.createIO(any())).thenReturn(io);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        sut.shutDown();
+    }
+
+    @Test
+    public void test() throws Exception {
+        settings.setSendMode(sendMode);
+        descriptor.setEnabled(isInitialEnabled);
+        descriptor.setConfigured(isInitialConfigured);
+
+        sut.startUp();
+
+        descriptor.setEnabled(isEnabledAfterStartup);
+        descriptor.setConfigured(isConfiguredAfterStartup);
+
+        verify(sut, timesUpdateCalled).updateProblemDatabase(any(), any(), any());
+    }
+
+}
diff --git a/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnectionTest.java b/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnectionTest.java
index 1828612..361b738 100644
--- a/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnectionTest.java
+++ b/tests/org.eclipse.epp.logging.aeri.ide.tests/src/org/eclipse/epp/internal/logging/aeri/ide/server/mars/ServerConnectionTest.java
@@ -31,7 +31,7 @@
     }
 
     @Test
-    public void test() {
+    public void testMessagesContainLink() {
         IProblemState state = mFac.createProblemState();
         addLink(state, REL_BUG, "http://bugzilla.org", "Bug #3485");
         addLink(state, REL_SUBMISSION, "http://submission.org", "Submission");