Index: lib/matcher.js
===================================================================
--- a/lib/matcher.js
+++ b/lib/matcher.js
@@ -63,94 +63,96 @@
  */
 class Matcher
 {
   constructor()
   {
     /**
      * Lookup table for filters by their associated keyword
      * @type {Map.<string,(Filter|Set.<Filter>)>}
+     * @private
      */
-    this.filterByKeyword = new Map();
+    this._filterByKeyword = new Map();
   }
 
   /**
    * Removes all known filters
    */
   clear()
   {
-    this.filterByKeyword.clear();
+    this._filterByKeyword.clear();
   }
 
   /**
    * Adds a filter to the matcher
    * @param {RegExpFilter} filter
    */
   add(filter)
   {
     // Look for a suitable keyword
     let keyword = this.findKeyword(filter);
-    let set = this.filterByKeyword.get(keyword);
+    let set = this._filterByKeyword.get(keyword);
     if (typeof set == "undefined")
     {
-      this.filterByKeyword.set(keyword, filter);
+      this._filterByKeyword.set(keyword, filter);
     }
     else if (set.size == 1)
     {
       if (filter != set)
-        this.filterByKeyword.set(keyword, new Set([set, filter]));
+        this._filterByKeyword.set(keyword, new Set([set, filter]));
     }
     else
     {
       set.add(filter);
     }
   }
 
   /**
    * Removes a filter from the matcher
    * @param {RegExpFilter} filter
    */
   remove(filter)
   {
     let keyword = this.findKeyword(filter);
-    let set = this.filterByKeyword.get(keyword);
+    let set = this._filterByKeyword.get(keyword);
     if (typeof set == "undefined")
       return;
 
     if (set.size == 1)
     {
       if (filter == set)
-        this.filterByKeyword.delete(keyword);
+        this._filterByKeyword.delete(keyword);
     }
     else
     {
       set.delete(filter);
 
       if (set.size == 1)
-        this.filterByKeyword.set(keyword, [...set][0]);
+        this._filterByKeyword.set(keyword, [...set][0]);
     }
   }
 
   /**
    * Chooses a keyword to be associated with the filter
    * @param {Filter} filter
    * @returns {string} keyword or an empty string if no keyword could be found
+   * @protected
    */
   findKeyword(filter)
   {
     let result = "";
     let {pattern} = filter;
     if (pattern == null)
       return result;
 
     let candidates = pattern.toLowerCase().match(allKeywordsRegExp);
     if (!candidates)
       return result;
 
-    let hash = this.filterByKeyword;
+    let hash = this._filterByKeyword;
     let resultCount = 0xFFFFFF;
     let resultLength = 0;
     for (let i = 0, l = candidates.length; i < l; i++)
     {
       let candidate = candidates[i].substr(1);
       let filters = hash.get(candidate);
       let count = typeof filters != "undefined" ? filters.size : 0;
       if (count < resultCount ||
@@ -169,21 +171,22 @@
    * @param {string} keyword
    * @param {string} location
    * @param {number} typeMask
    * @param {string} [docDomain]
    * @param {boolean} [thirdParty]
    * @param {string} [sitekey]
    * @param {boolean} [specificOnly]
    * @returns {?Filter}
+   * @protected
    */
-  _checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey,
+  checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey,
                    specificOnly)
   {
-    let set = this.filterByKeyword.get(keyword);
+    let set = this._filterByKeyword.get(keyword);
     if (typeof set == "undefined")
       return null;
 
     for (let filter of set)
     {
       if (specificOnly && filter.isGeneric() &&
           !(filter instanceof WhitelistFilter))
         continue;
@@ -214,17 +217,17 @@
   matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly)
   {
     let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
     if (candidates === null)
       candidates = [];
     candidates.push("");
     for (let i = 0, l = candidates.length; i < l; i++)
     {
-      let result = this._checkEntryMatch(candidates[i], location, typeMask,
+      let result = this.checkEntryMatch(candidates[i], location, typeMask,
                                          docDomain, thirdParty, sitekey,
                                          specificOnly);
       if (result)
         return result;
     }
 
     return null;
   }
@@ -245,119 +248,121 @@
      * @type {number}
      */
     this.maxCacheEntries = 1000;
 
     /**
      * Matcher for blocking rules.
      * @type {Matcher}
      */
-    this.blacklist = new Matcher();
+    this._blacklist = new Matcher();
 
     /**
      * Matcher for exception rules.
      * @type {Matcher}
      */
-    this.whitelist = new Matcher();
+    this._whitelist = new Matcher();
 
     /**
      * Lookup table of previous {@link Matcher#matchesAny} results
      * @type {Map.<string,Filter>}
      */
-    this.resultCache = new Map();
+    this._resultCache = new Map();
   }
 
   /**
    * @see Matcher#clear
    */
   clear()
   {
-    this.blacklist.clear();
-    this.whitelist.clear();
-    this.resultCache.clear();
+    this._blacklist.clear();
+    this._whitelist.clear();
+    this._resultCache.clear();
   }
 
   /**
    * @see Matcher#add
    * @param {Filter} filter
    */
   add(filter)
   {
     if (filter instanceof WhitelistFilter)
-      this.whitelist.add(filter);
+      this._whitelist.add(filter);
     else
-      this.blacklist.add(filter);
+      this._blacklist.add(filter);
 
-    this.resultCache.clear();
+    this._resultCache.clear();
   }
 
   /**
    * @see Matcher#remove
    * @param {Filter} filter
    */
   remove(filter)
   {
     if (filter instanceof WhitelistFilter)
-      this.whitelist.remove(filter);
+      this._whitelist.remove(filter);
     else
-      this.blacklist.remove(filter);
+      this._blacklist.remove(filter);
 
-    this.resultCache.clear();
+    this._resultCache.clear();
   }
 
   /**
    * @see Matcher#findKeyword
    * @param {Filter} filter
    * @returns {string} keyword
+   * @protected
    */
   findKeyword(filter)
   {
     if (filter instanceof WhitelistFilter)
-      return this.whitelist.findKeyword(filter);
-    return this.blacklist.findKeyword(filter);
+      return this._whitelist.findKeyword(filter);
+    return this._blacklist.findKeyword(filter);
   }
 
   /**
    * Optimized filter matching testing both whitelist and blacklist matchers
    * simultaneously. For parameters see
      {@link Matcher#matchesAny Matcher.matchesAny()}.
    * @see Matcher#matchesAny
    * @inheritdoc
+   * @private
    */
-  matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey,
+  _matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey,
                      specificOnly)
   {
     let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
     if (candidates === null)
       candidates = [];
     candidates.push("");
 
     let whitelistHit = null;
     let blacklistHit = null;
 
     // If the type mask includes no types other than whitelist-only types, we
     // can skip the blacklist.
     if ((typeMask & ~WHITELIST_ONLY_TYPES) != 0)
     {
       for (let i = 0, l = candidates.length; !blacklistHit && i < l; i++)
       {
-        blacklistHit = this.blacklist._checkEntryMatch(candidates[i], location,
+        blacklistHit = this._blacklist.checkEntryMatch(candidates[i], location,
                                                        typeMask, docDomain,
                                                        thirdParty, sitekey,
                                                        specificOnly);
       }
     }
 
     // If the type mask includes any whitelist-only types, we need to check the
     // whitelist.
     if (blacklistHit || (typeMask & WHITELIST_ONLY_TYPES) != 0)
     {
       for (let i = 0, l = candidates.length; !whitelistHit && i < l; i++)
       {
-        whitelistHit = this.whitelist._checkEntryMatch(candidates[i], location,
+        whitelistHit = this._whitelist.checkEntryMatch(candidates[i], location,
                                                        typeMask, docDomain,
                                                        thirdParty, sitekey);
       }
     }
 
     return whitelistHit || blacklistHit;
   }
 
@@ -365,27 +370,27 @@
    * @see Matcher#matchesAny
    * @inheritdoc
    */
   matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly)
   {
     let key = location + " " + typeMask + " " + docDomain + " " + thirdParty +
       " " + sitekey + " " + specificOnly;
 
-    let result = this.resultCache.get(key);
+    let result = this._resultCache.get(key);
     if (typeof result != "undefined")
       return result;
 
-    result = this.matchesAnyInternal(location, typeMask, docDomain,
+    result = this._matchesAnyInternal(location, typeMask, docDomain,
                                      thirdParty, sitekey, specificOnly);
 
-    if (this.resultCache.size >= this.maxCacheEntries)
-      this.resultCache.clear();
+    if (this._resultCache.size >= this.maxCacheEntries)
+      this._resultCache.clear();
 
-    this.resultCache.set(key, result);
+    this._resultCache.set(key, result);
 
     return result;
   }
 }
 
 exports.CombinedMatcher = CombinedMatcher;
 
 /**
