Merge branch 'stable-2.10'

* stable-2.10:
  Consume API version 2.9
  Suppress unused method warnings
  Consume API version 2.10
  fix typo, 'action.config' should be 'actions.config'
  Make work with Gerrit core stable-2.10 branch.

Merge made by the 'ours' strategy.

Change-Id: I0f0b1464d394dbc43c7c49287d2de50d7671ddad
diff --git a/pom.xml b/pom.xml
index deab462..08dacb8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
   <groupId>com.googlesource.gerrit.plugins.its</groupId>
   <artifactId>its-base</artifactId>
   <packaging>jar</packaging>
-  <version>2.10</version>
+  <version>2.11-SNAPSHOT</version>
   <name>Gerrit Code Review - Issue tracker support</name>
 
   <properties>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java
index 52bca59..2504937 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/ItsHookModule.java
@@ -14,7 +14,7 @@
 
 package com.googlesource.gerrit.plugins.hooks;
 
-import com.google.gerrit.common.ChangeListener;
+import com.google.gerrit.common.EventListener;
 import com.google.gerrit.extensions.annotations.Exports;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.registration.DynamicSet;
@@ -57,17 +57,17 @@
         .annotatedWith(Exports.named("enabled"))
         .toInstance(new ItsHookEnabledConfigEntry(pluginName, pluginCfgFactory));
     bind(ItsConfig.class);
-    DynamicSet.bind(binder(), ChangeListener.class).to(
+    DynamicSet.bind(binder(), EventListener.class).to(
         GerritHookFilterAddRelatedLinkToChangeId.class);
-    DynamicSet.bind(binder(), ChangeListener.class).to(
+    DynamicSet.bind(binder(), EventListener.class).to(
         GerritHookFilterAddComment.class);
-    DynamicSet.bind(binder(), ChangeListener.class).to(
+    DynamicSet.bind(binder(), EventListener.class).to(
         GerritHookFilterChangeState.class);
-    DynamicSet.bind(binder(), ChangeListener.class).to(
+    DynamicSet.bind(binder(), EventListener.class).to(
         GerritHookFilterAddRelatedLinkToGitWeb.class);
     DynamicSet.bind(binder(), CommitValidationListener.class).to(
         ItsValidateComment.class);
-    DynamicSet.bind(binder(), ChangeListener.class).to(
+    DynamicSet.bind(binder(), EventListener.class).to(
         ActionController.class);
     factory(ActionRequest.Factory.class);
     factory(Property.Factory.class);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
index d816801..4c59b5c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/its/InitIts.java
@@ -16,11 +16,11 @@
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.data.RefConfigSection;
-import com.google.gerrit.pgm.init.AllProjectsConfig;
-import com.google.gerrit.pgm.init.AllProjectsNameOnInitProvider;
-import com.google.gerrit.pgm.init.InitStep;
-import com.google.gerrit.pgm.init.Section;
-import com.google.gerrit.pgm.util.ConsoleUI;
+import com.google.gerrit.pgm.init.api.AllProjectsConfig;
+import com.google.gerrit.pgm.init.api.AllProjectsNameOnInitProvider;
+import com.google.gerrit.pgm.init.api.InitStep;
+import com.google.gerrit.pgm.init.api.Section;
+import com.google.gerrit.pgm.init.api.ConsoleUI;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
@@ -61,7 +61,7 @@
 
   @Override
   public void postRun() throws IOException, ConfigInvalidException {
-    Config cfg = allProjectsConfig.load();
+    Config cfg = allProjectsConfig.load().getConfig();
     ui.message("\n");
     ui.header(itsDisplayName + " Integration");
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
index 6fa5d9b..83ed535 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/its/ItsConfig.java
@@ -20,10 +20,10 @@
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.events.ChangeAbandonedEvent;
-import com.google.gerrit.server.events.ChangeEvent;
 import com.google.gerrit.server.events.ChangeMergedEvent;
 import com.google.gerrit.server.events.ChangeRestoredEvent;
 import com.google.gerrit.server.events.CommentAddedEvent;
+import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.PatchSetCreatedEvent;
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.gerrit.server.project.ProjectCache;
@@ -49,7 +49,7 @@
     this.pluginCfgFactory = pluginCfgFactory;
   }
 
-  public boolean isEnabled(ChangeEvent event) {
+  public boolean isEnabled(Event event) {
     if (event instanceof PatchSetCreatedEvent) {
       PatchSetCreatedEvent e = (PatchSetCreatedEvent) event;
       return isEnabled(e.change.project, e.change.branch);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyAttributeExtractor.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyAttributeExtractor.java
index 4ef5e41..e6dfe7a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyAttributeExtractor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyAttributeExtractor.java
@@ -58,6 +58,7 @@
     properties.add(propertyFactory.create("branch", changeAttribute.branch));
     properties.add(propertyFactory.create("topic", changeAttribute.topic));
     properties.add(propertyFactory.create("subject", changeAttribute.subject));
+    properties.add(propertyFactory.create("commit-message", changeAttribute.commitMessage));
     properties.add(propertyFactory.create("change-id", changeAttribute.id));
     properties.add(propertyFactory.create("change-number", changeAttribute.number));
     properties.add(propertyFactory.create("change-url", changeAttribute.url));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractor.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractor.java
index 77ef563..0f6f937 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractor.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractor.java
@@ -27,6 +27,7 @@
 import com.google.gerrit.server.events.ChangeRestoredEvent;
 import com.google.gerrit.server.events.CommentAddedEvent;
 import com.google.gerrit.server.events.DraftPublishedEvent;
+import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.PatchSetCreatedEvent;
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.inject.Inject;
@@ -197,7 +198,7 @@
    * @param event The event to extract property sets from.
    * @return sets of property sets extracted from the event.
    */
-  public Set<Set<Property>> extractFrom(ChangeEvent event) {
+  public Set<Set<Property>> extractFrom(Event event) {
     Map<String,Set<String>> associations = null;
     Set<Set<Property>> ret = Sets.newHashSet();
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java
index 9b5f4c6..885db3e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionController.java
@@ -14,23 +14,23 @@
 
 package com.googlesource.gerrit.plugins.hooks.workflow;
 
-import java.util.Collection;
-import java.util.Set;
-
-import com.google.gerrit.common.ChangeListener;
-import com.google.gerrit.server.events.ChangeEvent;
+import com.google.gerrit.common.EventListener;
+import com.google.gerrit.server.events.Event;
 import com.google.inject.Inject;
 
 import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.util.PropertyExtractor;
 
+import java.util.Collection;
+import java.util.Set;
+
 /**
  * Controller that takes actions according to {@code ChangeEvents@}.
  *
  * The taken actions are typically Its related (e.g.: adding an Its comment, or
  * changing an issue's status).
  */
-public class ActionController implements ChangeListener {
+public class ActionController implements EventListener {
   private final PropertyExtractor propertyExtractor;
   private final RuleBase ruleBase;
   private final ActionExecutor actionExecutor;
@@ -46,7 +46,7 @@
   }
 
   @Override
-  public void onChangeEvent(ChangeEvent event) {
+  public void onEvent(Event event) {
     if (!itsConfig.isEnabled(event)) {
       return;
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
index 6ab647c..da062bc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/GerritHookFilter.java
@@ -14,17 +14,12 @@
 
 package com.googlesource.gerrit.plugins.hooks.workflow;
 
-import java.io.IOException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.gerrit.common.ChangeListener;
+import com.google.gerrit.common.EventListener;
 import com.google.gerrit.server.events.ChangeAbandonedEvent;
-import com.google.gerrit.server.events.ChangeEvent;
 import com.google.gerrit.server.events.ChangeMergedEvent;
 import com.google.gerrit.server.events.ChangeRestoredEvent;
 import com.google.gerrit.server.events.CommentAddedEvent;
+import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.PatchSetCreatedEvent;
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.gwtorm.server.OrmException;
@@ -33,7 +28,12 @@
 import com.googlesource.gerrit.plugins.hooks.its.ItsConfig;
 import com.googlesource.gerrit.plugins.hooks.util.CommitMessageFetcher;
 
-public class GerritHookFilter implements ChangeListener {
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+public class GerritHookFilter implements EventListener {
   private static final Logger log = LoggerFactory.getLogger(GerritHookFilter.class);
 
   @Inject
@@ -69,7 +69,7 @@
   }
 
   @Override
-  public void onChangeEvent(ChangeEvent event) {
+  public void onEvent(Event event) {
     if (!itsConfig.isEnabled(event)) {
       return;
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBase.java b/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBase.java
index 685a639..cfa70ac 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBase.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBase.java
@@ -19,6 +19,7 @@
 import java.util.Collection;
 
 import com.google.common.collect.Lists;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.server.config.SitePath;
 import com.google.inject.Inject;
 
@@ -35,18 +36,23 @@
   private static final Logger log = LoggerFactory.getLogger(RuleBase.class);
 
   /**
-   * File (relative to site) to load rules from
+   * File beginning (relative to site) to load rules from
    */
-  private static final String ITS_CONFIG_FILE = "etc" + File.separatorChar +
-      "its" + File.separator + "actions.config";
+  private static final String ITS_CONFIG_FILE_START = "etc" +
+      File.separatorChar + "its" + File.separator + "actions";
 
   /**
-   * The section for rules within {@link #ITS_CONFIG_FILE}
+   * File end to load rules from
+   */
+  private static final String ITS_CONFIG_FILE_END = ".config";
+
+  /**
+   * The section for rules within rulebases
    */
   private static final String RULE_SECTION = "rule";
 
   /**
-   * The key for actions within {@link #ITS_CONFIG_FILE}
+   * The key for actions within rulebases
    */
   private static final String ACTION_KEY = "action";
 
@@ -54,6 +60,7 @@
   private final Rule.Factory ruleFactory;
   private final Condition.Factory conditionFactory;
   private final ActionRequest.Factory actionRequestFactory;
+  private final String pluginName;
 
   private Collection<Rule> rules;
 
@@ -64,11 +71,13 @@
   @Inject
   public RuleBase(@SitePath File sitePath, Rule.Factory ruleFactory,
       Condition.Factory conditionFactory,
-      ActionRequest.Factory actionRequestFactory) {
+      ActionRequest.Factory actionRequestFactory,
+      @PluginName String pluginName) {
     this.sitePath = sitePath;
     this.ruleFactory = ruleFactory;
     this.conditionFactory = conditionFactory;
     this.actionRequestFactory = actionRequestFactory;
+    this.pluginName = pluginName;
     reloadRules();
   }
 
@@ -109,8 +118,6 @@
         }
         rules.add(rule);
       }
-    } else {
-      log.warn("ITS actions configuration file (" + ruleFile + ") does not exist.");
     }
   }
 
@@ -138,8 +145,26 @@
     }
 
     // Add global rules
-    File globalRuleFile = new File(sitePath, ITS_CONFIG_FILE);
+    File globalRuleFile = new File(sitePath, ITS_CONFIG_FILE_START +
+        ITS_CONFIG_FILE_END);
     addRulesFromFile(globalRuleFile);
+
+    // Add its-specific rules
+    File itsSpecificRuleFile = new File(sitePath, ITS_CONFIG_FILE_START + "-" +
+        pluginName + ITS_CONFIG_FILE_END);
+    addRulesFromFile(itsSpecificRuleFile);
+
+    if (!globalRuleFile.exists() && !itsSpecificRuleFile.exists()) {
+      try {
+        log.warn("Neither global rule file "
+            + globalRuleFile.getCanonicalPath() + " nor Its specific rule file"
+            + itsSpecificRuleFile.getCanonicalPath() + " exist. Please configure "
+            + "rules.");
+      } catch (IOException e) {
+        log.warn("Neither global rule file nor Its specific rule files exist. "
+            + "Please configure rules.");
+      }
+    }
   }
 
   /**
diff --git a/src/main/resources/Documentation/config-rulebase-common.md b/src/main/resources/Documentation/config-rulebase-common.md
index 4712e31..60e1185 100644
--- a/src/main/resources/Documentation/config-rulebase-common.md
+++ b/src/main/resources/Documentation/config-rulebase-common.md
@@ -18,13 +18,16 @@
 ‘Resolved’”) on the ITS.
 
 Actions on the ITS and conditions for the action to take place are
-configured through the rule base in `etc/its/actions.config` in the
-site directory. The rule base is a git config file, and may contain an
-arbitrary number of rules. Each rule can have an arbitrary number of
-conditions and actions. A rule fires all associated actions, once all
-of its conditions are met.
+configured through the rule bases in `etc/its/actions.config` (for global rules
+to be picked up by all configured ITS plugins) and
+`etc/its/actions-@PLUGIN@.config` (for rules to be picked up only by @PLUGIN@)
+in the site directory. A rule base is a git config file, and may contain an
+arbitrary number of rules. Each rule can have an arbitrary number of conditions
+and actions. A rule fires all associated actions, once all of its conditions are
+met.
 
-A simple `etc/its/actions.config` may look like
+A simple `etc/its/actions.config` (or
+`etc/its/actions-@PLUGIN@.config`) may look like
 
 ```
 [rule "rule1"]
@@ -394,6 +397,9 @@
 `subject`
 : first line of the change's most recent patch set's commit message.
 
+`commit-message`
+: full commit message of the most recent patch set
+
 `status`
 :	status of the change (`null`, `NEW`, `SUBMITTED`, `DRAFT`, `MERGED`,
 	or `ABANDONED` )
diff --git a/src/test/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractorTest.java b/src/test/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractorTest.java
index 5ca50e9..7657f24 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/hooks/util/PropertyExtractorTest.java
@@ -15,14 +15,10 @@
 
 import static org.easymock.EasyMock.expect;
 
-import java.util.HashMap;
-import java.util.Set;
-
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.FactoryModule;
 import com.google.gerrit.server.data.AccountAttribute;
 import com.google.gerrit.server.data.ApprovalAttribute;
@@ -30,21 +26,22 @@
 import com.google.gerrit.server.data.PatchSetAttribute;
 import com.google.gerrit.server.data.RefUpdateAttribute;
 import com.google.gerrit.server.events.ChangeAbandonedEvent;
-import com.google.gerrit.server.events.ChangeEvent;
 import com.google.gerrit.server.events.ChangeMergedEvent;
 import com.google.gerrit.server.events.ChangeRestoredEvent;
 import com.google.gerrit.server.events.CommentAddedEvent;
 import com.google.gerrit.server.events.DraftPublishedEvent;
+import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.PatchSetCreatedEvent;
 import com.google.gerrit.server.events.RefUpdatedEvent;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
 import com.googlesource.gerrit.plugins.hooks.testutil.LoggingMockingTestCase;
-import com.googlesource.gerrit.plugins.hooks.util.IssueExtractor;
-import com.googlesource.gerrit.plugins.hooks.util.PropertyExtractor;
 import com.googlesource.gerrit.plugins.hooks.workflow.Property;
 
+import java.util.HashMap;
+import java.util.Set;
+
 public class PropertyExtractorTest extends LoggingMockingTestCase {
   private Injector injector;
 
@@ -58,13 +55,13 @@
 
     Property property1 = createMock(Property.class);
     expect(propertyFactory.create("event", "com.googlesource.gerrit.plugins." +
-        "hooks.util.PropertyExtractorTest$DummyChangeEvent"))
+        "hooks.util.PropertyExtractorTest$DummyEvent"))
         .andReturn(property1);
 
     replayMocks();
 
     Set<Set<Property>> actual = propertyExtractor.extractFrom(
-        new DummyChangeEvent());
+        new DummyEvent());
 
     Set<Set<Property>> expected = Sets.newHashSet();
     assertEquals("Properties do not match", expected, actual);
@@ -375,7 +372,7 @@
     eventHelper(event, "RefUpdatedEvent", "ref-updated", common, false);
   }
 
-  private void eventHelper(ChangeEvent event, String className, String type,
+  private void eventHelper(Event event, String className, String type,
       Set<Property> common, boolean withRevision) {
     PropertyExtractor propertyExtractor = injector.getInstance(
         PropertyExtractor.class);
@@ -466,25 +463,9 @@
     }
   }
 
-  private class DummyChangeEvent extends ChangeEvent {
-    @SuppressWarnings("unused")
-    public String getType() {
-      return null;
-    }
-
-    @SuppressWarnings("unused")
-    public Project.NameKey getProjectNameKey() {
-      return null;
-    }
-
-    @SuppressWarnings("unused")
-    public Change.Key getChangeKey() {
-      return null;
-    }
-
-    @SuppressWarnings("unused")
-    public String getRefName() {
-      return null;
+  private class DummyEvent extends Event {
+    public DummyEvent() {
+      super(null);
     }
   }
-}
+}
\ No newline at end of file
diff --git a/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java b/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java
index 7266d81..8819040 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/ActionControllerTest.java
@@ -23,6 +23,7 @@
 import com.google.common.collect.Sets;
 import com.google.gerrit.server.config.FactoryModule;
 import com.google.gerrit.server.events.ChangeEvent;
+import com.google.gerrit.server.events.Event;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
@@ -48,7 +49,7 @@
 
     replayMocks();
 
-    actionController.onChangeEvent(event);
+    actionController.onEvent(event);
   }
 
   public void testNoActions() {
@@ -68,7 +69,7 @@
 
     replayMocks();
 
-    actionController.onChangeEvent(event);
+    actionController.onEvent(event);
   }
 
   public void testNoIssues() {
@@ -90,7 +91,7 @@
 
     replayMocks();
 
-    actionController.onChangeEvent(event);
+    actionController.onEvent(event);
   }
 
   public void testSinglePropertySetSingleActionSingleIssue() {
@@ -122,7 +123,7 @@
 
     replayMocks();
 
-    actionController.onChangeEvent(event);
+    actionController.onEvent(event);
   }
 
   public void testMultiplePropertySetsMultipleActionMultipleIssue() {
@@ -175,7 +176,7 @@
 
     replayMocks();
 
-    actionController.onChangeEvent(event);
+    actionController.onEvent(event);
   }
   private ActionController createActionController() {
     return injector.getInstance(ActionController.class);
@@ -200,7 +201,7 @@
 
       bind(ItsConfig.class).toInstance(new ItsConfig(null, null, null) {
         @Override
-        public boolean isEnabled(ChangeEvent event) {
+        public boolean isEnabled(Event event) {
           return true;
         }
       });
diff --git a/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBaseTest.java b/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBaseTest.java
index b8d20d9..ffadc1d 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBaseTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/hooks/workflow/RuleBaseTest.java
@@ -27,10 +27,12 @@
 import org.eclipse.jgit.util.FileUtils;
 
 import com.google.common.collect.Lists;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.server.config.FactoryModule;
 import com.google.gerrit.server.config.SitePath;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
+
 import com.googlesource.gerrit.plugins.hooks.testutil.LoggingMockingTestCase;
 
 public class RuleBaseTest extends LoggingMockingTestCase {
@@ -43,12 +45,18 @@
 
   private boolean cleanupSitePath;
 
+  private enum RuleBaseKind {
+      GLOBAL,
+      ITS,
+      FAULTY
+  }
+
   public void testWarnNonExistingRuleBase() {
     replayMocks();
 
     createRuleBase();
 
-    assertLogMessageContains("does not exist");
+    assertLogMessageContains("Neither global");
   }
 
   public void testEmptyRuleBase() throws IOException {
@@ -219,20 +227,20 @@
   }
 
   public void testWarnExistingFaultyNameRuleBaseFile() throws IOException {
-    injectRuleBase("", true);
+    injectRuleBase("", RuleBaseKind.FAULTY);
 
     replayMocks();
 
     createRuleBase();
 
     assertLogMessageContains("Please migrate"); // Migration warning for old name
-    assertLogMessageContains("does not exist"); // For global rule file at new name
+    assertLogMessageContains("Neither global"); // For rule file at at usual places
   }
 
   public void testSimpleFaultyNameRuleBase() throws IOException {
     injectRuleBase("[rule \"rule1\"]\n" +
         "\tconditionA = value1\n" +
-        "\taction = action1", true);
+        "\taction = action1", RuleBaseKind.FAULTY);
 
     Rule rule1 = createMock(Rule.class);
     expect(ruleFactory.create("rule1")).andReturn(rule1);
@@ -250,15 +258,39 @@
     createRuleBase();
 
     assertLogMessageContains("Please migrate"); // Migration warning for old name
-    assertLogMessageContains("does not exist"); // For global rule file at new name
+    assertLogMessageContains("Neither global"); // For rule file at at usual places
   }
 
-  public void testGlobalRuleBaseFileAndFaultyNameFileAreLoaded() throws IOException {
+  public void testSimpleItsRuleBase() throws IOException {
     injectRuleBase("[rule \"rule1\"]\n" +
-        "\taction = action1", false);
+        "\tconditionA = value1\n" +
+        "\taction = action1", RuleBaseKind.ITS);
+
+    Rule rule1 = createMock(Rule.class);
+    expect(ruleFactory.create("rule1")).andReturn(rule1);
+
+    Condition condition1 = createMock(Condition.class);
+    expect(conditionFactory.create("conditionA", "value1")).andReturn(condition1);
+    rule1.addCondition(condition1);
+
+    ActionRequest actionRequest1 = createMock(ActionRequest.class);
+    expect(actionRequestFactory.create("action1")).andReturn(actionRequest1);
+    rule1.addActionRequest(actionRequest1);
+
+    replayMocks();
+
+    createRuleBase();
+  }
+
+  public void testAllRuleBaseFilesAreLoaded() throws IOException {
+    injectRuleBase("[rule \"rule1\"]\n" +
+        "\taction = action1", RuleBaseKind.FAULTY);
 
     injectRuleBase("[rule \"rule2\"]\n" +
-        "\taction = action2", true);
+        "\taction = action2", RuleBaseKind.GLOBAL);
+
+    injectRuleBase("[rule \"rule3\"]\n" +
+        "\taction = action3", RuleBaseKind.ITS);
 
     Collection<Property> properties = Collections.emptySet();
 
@@ -281,18 +313,30 @@
     rule2.addActionRequest(actionRequest2);
 
     List<ActionRequest> rule2Match = Lists.newArrayListWithCapacity(1);
-    rule1Match.add(actionRequest2);
+    rule2Match.add(actionRequest2);
     expect(rule2.actionRequestsFor(properties)).andReturn(rule2Match);
 
+    Rule rule3 = createMock(Rule.class);
+    expect(ruleFactory.create("rule3")).andReturn(rule3);
+
+    ActionRequest actionRequest3 = createMock(ActionRequest.class);
+    expect(actionRequestFactory.create("action3")).andReturn(actionRequest3);
+    rule3.addActionRequest(actionRequest3);
+
+    List<ActionRequest> rule3Match = Lists.newArrayListWithCapacity(1);
+    rule3Match.add(actionRequest3);
+    expect(rule3.actionRequestsFor(properties)).andReturn(rule3Match);
+
     replayMocks();
 
     RuleBase ruleBase = createRuleBase();
 
     Collection<ActionRequest> actual = ruleBase.actionRequestsFor(properties);
 
-    List<ActionRequest> expected = Lists.newArrayListWithCapacity(2);
+    List<ActionRequest> expected = Lists.newArrayListWithCapacity(3);
     expected.add(actionRequest1);
     expected.add(actionRequest2);
+    expected.add(actionRequest3);
 
     assertEquals("Matched actionRequests do not match", expected, actual);
 
@@ -304,12 +348,27 @@
   }
 
   private void injectRuleBase(String rules) throws IOException {
-    injectRuleBase(rules, false);
+    injectRuleBase(rules, RuleBaseKind.GLOBAL);
   }
 
-  private void injectRuleBase(String rules, Boolean faultyName) throws IOException {
+  private void injectRuleBase(String rules, RuleBaseKind ruleBaseKind) throws IOException {
+    String baseName = "";
+    switch (ruleBaseKind) {
+      case GLOBAL:
+        baseName = "actions";
+        break;
+      case ITS:
+        baseName = "actions-ItsTestName";
+        break;
+      case FAULTY:
+        baseName = "action";
+        break;
+      default:
+        fail("Unknown ruleBaseKind");
+    }
     File ruleBaseFile = new File(sitePath, "etc" + File.separatorChar + "its" +
-        File.separator + "action" + (faultyName ? "" : "s") + ".config");
+        File.separator + baseName + ".config");
+
     File ruleBaseParentFile = ruleBaseFile.getParentFile();
     if (!ruleBaseParentFile.exists()) {
       assertTrue("Failed to create parent (" + ruleBaseParentFile + ") for " +
@@ -346,6 +405,9 @@
     @Override
     protected void configure() {
 
+      bind(String.class).annotatedWith(PluginName.class)
+          .toInstance("ItsTestName");
+
       sitePath = randomTargetFile();
       assertFalse("sitePath already (" + sitePath + ") already exists",
           sitePath.exists());