diff --git a/src/org/openstreetmap/josm/gui/preferences/plugin/PluginCheckBox.java b/src/org/openstreetmap/josm/gui/preferences/plugin/PluginCheckBox.java
index d021169a68..2918430a87 100644
--- a/src/org/openstreetmap/josm/gui/preferences/plugin/PluginCheckBox.java
+++ b/src/org/openstreetmap/josm/gui/preferences/plugin/PluginCheckBox.java
@@ -4,15 +4,23 @@ package org.openstreetmap.josm.gui.preferences.plugin;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trn;
 
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import javax.swing.AbstractAction;
+import javax.swing.Action;
 import javax.swing.JCheckBox;
+import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.event.PopupMenuEvent;
 
+import org.openstreetmap.josm.data.preferences.NamedColorProperty;
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.plugins.PluginInformation;
 import org.openstreetmap.josm.tools.Utils;
@@ -22,9 +30,26 @@ import org.openstreetmap.josm.tools.Utils;
  * @since 10228
  */
 public class PluginCheckBox extends JCheckBox implements ActionListener {
+    private static final String PREFERENCE_PREFIX = "plugins.";
+
+    /* Background colors for checkboxes */
+    private static final NamedColorProperty COLOR_INSTALLED = new NamedColorProperty(PREFERENCE_PREFIX + PluginInstallation.INSTALLED,
+            Color.GREEN.darker().darker());
+    private static final NamedColorProperty COLOR_REINSTALL = new NamedColorProperty(PREFERENCE_PREFIX + PluginInstallation.REINSTALL,
+            Color.GREEN);
+    private static final NamedColorProperty COLOR_UPGRADE = new NamedColorProperty(PREFERENCE_PREFIX + PluginInstallation.UPGRADE,
+            Color.GREEN.brighter().brighter());
+    private static final NamedColorProperty COLOR_REMOVE = new NamedColorProperty(PREFERENCE_PREFIX + PluginInstallation.REMOVE,
+            Color.RED.darker().darker());
+    private static final NamedColorProperty COLOR_COMPLETE_REMOVE = new NamedColorProperty(PREFERENCE_PREFIX + PluginInstallation.COMPLETE_REMOVE,
+            Color.RED);
+    private final Color originalColor;
+
     private final transient PluginInformation pi;
     private final PluginListPanel panel;
     private final transient PluginPreferencesModel ppModel;
+    private final boolean wasInstalled;
+    private PluginInstallation state;
 
     PluginCheckBox(PluginInformation pi, boolean selected, PluginListPanel panel, PluginPreferencesModel ppModel) {
         this.pi = pi;
@@ -33,6 +58,14 @@ public class PluginCheckBox extends JCheckBox implements ActionListener {
         setSelected(selected);
         setToolTipText(PluginListPanel.formatCheckboxTooltipText(pi));
         addActionListener(this);
+        wasInstalled = selected;
+        this.originalColor = this.getBackground();
+        if (wasInstalled) {
+            this.setBackground(COLOR_INSTALLED.get());
+            state = PluginInstallation.INSTALLED;
+        } else {
+            state = PluginInstallation.ALL;
+        }
     }
 
     protected void selectRequiredPlugins(PluginInformation info) {
@@ -67,8 +100,73 @@ public class PluginCheckBox extends JCheckBox implements ActionListener {
                 alertPluginStillRequired(panel, pi.getName(), otherPlugins);
             }
         }
+        setState();
     }
 
+    private void setState() {
+        if (isSelected() && this.wasInstalled) {
+            state = PluginInstallation.INSTALLED;
+            updateBackgroundColor();
+        } else if (isSelected()) {
+            // Really should use a specific state for "to install"
+            state = PluginInstallation.UPGRADE;
+            updateBackgroundColor();
+        } else if (!isSelected() && this.wasInstalled) {
+            final JPopupMenu jPopupMenu = new JPopupMenu();
+            Action action = new AbstractAction() {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    final String actionCommand = e.getActionCommand();
+                    if (tr("Mark for Reinstallation").equals(actionCommand)) {
+                        state = PluginInstallation.REINSTALL;
+                    } else if (tr("Mark for Complete Removal").equals(actionCommand)) {
+                        state = PluginInstallation.COMPLETE_REMOVE;
+                    } else {
+                        state = PluginInstallation.REMOVE;
+                    }
+                    jPopupMenu.setVisible(false);
+                    updateBackgroundColor();
+                }
+            };
+            jPopupMenu.add(new JMenuItem(action)).setText(tr("Mark for Reinstallation"));
+            jPopupMenu.add(new JMenuItem(action)).setText(tr("Mark for Removal"));
+            jPopupMenu.add(new JMenuItem(action)).setText(tr("Mark for Complete Removal"));
+            jPopupMenu.show(this, 0, this.getHeight());
+        } else {
+            state = PluginInstallation.AVAILABLE;
+            updateBackgroundColor();
+        }
+    }
+
+    private void updateBackgroundColor() {
+        final Color color;
+        switch (state) {
+        case ALL:
+        case AVAILABLE:
+        case INSTALLED:
+            // INSTALLED should use COLOR_INSTALLED, but it also has a checkbox
+            color = this.originalColor;
+            break;
+        case REMOVE:
+            color = COLOR_REMOVE.get();
+            break;
+        case COMPLETE_REMOVE:
+            color = COLOR_COMPLETE_REMOVE.get();
+            break;
+        case REINSTALL:
+            color = COLOR_REINSTALL.get();
+            break;
+        case UPGRADE:
+            color = COLOR_UPGRADE.get();
+            break;
+        default:
+            throw new IllegalStateException("Unknown plugin state");
+        }
+        this.setOpaque(!Objects.equals(this.originalColor, color));
+        this.setBackground(color);
+    }
+
+
     /**
      * Alerts the user if an unselected plugin is still required by another plugins
      *
diff --git a/src/org/openstreetmap/josm/gui/preferences/plugin/PluginInstallation.java b/src/org/openstreetmap/josm/gui/preferences/plugin/PluginInstallation.java
index ab42df7fb0..ca6e4f3b4d 100644
--- a/src/org/openstreetmap/josm/gui/preferences/plugin/PluginInstallation.java
+++ b/src/org/openstreetmap/josm/gui/preferences/plugin/PluginInstallation.java
@@ -11,5 +11,25 @@ public enum PluginInstallation {
     /** Plugins not loaded **/
     AVAILABLE,
     /** All plugins **/
-    ALL
+    ALL,
+    /**
+     * Plugins to reinstall -- this involves <i>deleting</i> the plugin file
+     * @since xxx
+     */
+    REINSTALL,
+    /**
+     * Plugins to upgrade
+     * @since xxx
+     */
+    UPGRADE,
+    /**
+     * Plugins to remove
+     * @since xxx
+     */
+    REMOVE,
+    /**
+     * Plugins to completely remove -- this involves <i>deleting</i> the plugin file
+     * @since xxx
+     */
+    COMPLETE_REMOVE
 }
