Add an option to block all third-party requests. https://redmine.stoutner.com/issues/209
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / helpers / BlockListHelper.java
1 /*
2  * Copyright © 2018 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.helpers;
21
22 import android.content.res.AssetManager;
23 import android.net.Uri;
24
25 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
26
27 import java.io.BufferedReader;
28 import java.io.IOException;
29 import java.io.InputStreamReader;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.regex.Pattern;
33
34 public class BlockListHelper {
35     public ArrayList<List<String[]>> parseBlockList(AssetManager assets, String blockListName) {
36         // Initialize the header list.
37         List<String[]> headers = new ArrayList<>();  // 0.
38
39         // Initialize the whitelists.
40         List<String[]> mainWhiteList = new ArrayList<>();  // 1.
41         List<String[]> finalWhiteList = new ArrayList<>();  // 2.
42         List<String[]> domainWhiteList = new ArrayList<>();  // 3.
43         List<String[]> domainInitialWhiteList = new ArrayList<>();  // 4.
44         List<String[]> domainFinalWhiteList = new ArrayList<>();  // 5.
45         List<String[]> thirdPartyWhiteList = new ArrayList<>();  // 6.
46         List<String[]> thirdPartyDomainWhiteList = new ArrayList<>();  // 7.
47         List<String[]> thirdPartyDomainInitialWhiteList = new ArrayList<>();  // 8.
48
49         // Initialize the blacklists
50         List<String[]> mainBlackList = new ArrayList<>();  // 9.
51         List<String[]> initialBlackList = new ArrayList<>();  // 10.
52         List<String[]> finalBlackList = new ArrayList<>();  // 11.
53         List<String[]> domainBlackList = new ArrayList<>();  // 12.
54         List<String[]> domainInitialBlackList = new ArrayList<>();  // 13.
55         List<String[]> domainFinalBlackList = new ArrayList<>();  // 14.
56         List<String[]> domainRegularExpressionBlackList = new ArrayList<>();  // 15.
57         List<String[]> thirdPartyBlackList = new ArrayList<>();  // 16.
58         List<String[]> thirdPartyInitialBlackList = new ArrayList<>();  // 17.
59         List<String[]> thirdPartyDomainBlackList = new ArrayList<>();  // 18.
60         List<String[]> thirdPartyDomainInitialBlackList = new ArrayList<>();  // 19.
61         List<String[]> regularExpressionBlackList = new ArrayList<>();  // 20.
62         List<String[]> thirdPartyRegularExpressionBlackList = new ArrayList<>();  // 21.
63         List<String[]> thirdPartyDomainRegularExpressionBlackList = new ArrayList<>();  // 22.
64
65
66         // Populate the block lists.  The `try` is required by `InputStreamReader`.
67         try {
68             // Load the block list into a `BufferedReader`.
69             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(assets.open(blockListName)));
70
71             // Create a string for storing the block list entries.
72             String blockListEntry;
73
74             // Parse the block list.
75             while ((blockListEntry = bufferedReader.readLine()) != null) {
76                 // Store the original block list entry.
77                 String originalBlockListEntry = blockListEntry;
78
79                 // Remove any `^` from the block list entry.  Privacy Browser does not process them in the interest of efficiency.
80                 blockListEntry = blockListEntry.replace("^", "");
81
82                 //noinspection StatementWithEmptyBody
83                 if (blockListEntry.contains("##") || blockListEntry.contains("#?#") || blockListEntry.contains("#@#") || blockListEntry.startsWith("[")) {
84                     // Entries that contain `##`, `#?#`, and `#@#` are for hiding elements in the main page's HTML.  Entries that start with `[` describe the AdBlock compatibility level.
85                     // Do nothing.  Privacy Browser does not currently use these entries.
86
87                     //Log.i("BlockLists", "Not added: " + blockListEntry);
88                 } else //noinspection StatementWithEmptyBody
89                     if (blockListEntry.contains("$csp=script-src")) {  // Ignore entries that contain `$csp=script-src`.
90                     // Do nothing.  It is uncertain what this directive is even supposed to mean, and it is blocking entire websites like androidcentral.com.  https://redmine.stoutner.com/issues/306.
91
92                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
93                 } else if (blockListEntry.startsWith("!")) {  //  Comment entries.
94                     if (blockListEntry.startsWith("! Version:")) {
95                         // Get the list version number.
96                         String[] listVersion = {blockListEntry.substring(11)};
97
98                         // Store the list version in the headers list.
99                         headers.add(listVersion);
100                     }
101
102                     if (blockListEntry.startsWith("! Title:")) {
103                         // Get the list title.
104                         String[] listTitle = {blockListEntry.substring(9)};
105
106                         // Store the list title in the headers list.
107                         headers.add(listTitle);
108                     }
109
110                     //Log.i("BlockLists", "Not added: " + blockListEntry);
111                 } else if (blockListEntry.startsWith("@@")) {  // Entries that begin with `@@` are whitelists.
112                     // Remove the `@@`
113                     blockListEntry = blockListEntry.substring(2);
114
115                     // Strip out any initial `||`.  Privacy Browser doesn't differentiate items that only match against the end of the domain name.
116                     if (blockListEntry.startsWith("||")) {
117                         blockListEntry = blockListEntry.substring(2);
118                     }
119
120                     if (blockListEntry.contains("$")) {  // Filter entries.
121                         //noinspection StatementWithEmptyBody
122                         if (blockListEntry.contains("~third-party")) {  // Ignore entries that contain `~third-party`.
123                             // Do nothing.
124
125                             //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
126                         } else if (blockListEntry.contains("third-party")) {  // Third-party white list entries.
127                             if (blockListEntry.contains("domain=")) {  // Third-party domain white list entries.
128                                 // Parse the entry.
129                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
130                                 String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
131                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
132
133                                 //noinspection StatementWithEmptyBody
134                                 if (domains.contains("~")) {  // It is uncertain what a `~` domain means inside an `@@` entry.
135                                     // Do Nothing
136
137                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
138                                 } else if (blockListEntry.startsWith("|")) {  // Third-party domain initial white list entries.
139                                     // Strip out the initial `|`.
140                                     entry = entry.substring(1);
141
142                                     //noinspection StatementWithEmptyBody
143                                     if (entry.equals("http://") || entry.equals("https://")) {  // Ignore generic entries.
144                                         // Do nothing.  These entries are designed for filter options that Privacy Browser does not use.
145
146                                         //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
147                                     } else {  // Process third-party domain initial white list entries.
148                                         // Process each domain.
149                                         do {
150                                             // Create a string to keep track of the current domain.
151                                             String domain;
152
153                                             if (domains.contains("|")) {  // There is more than one domain in the list.
154                                                 // Get the first domain from the list.
155                                                 domain = domains.substring(0, domains.indexOf("|"));
156
157                                                 // Remove the first domain from the list.
158                                                 domains = domains.substring(domains.indexOf("|") + 1);
159                                             } else {  // There is only one domain in the list.
160                                                 domain = domains;
161                                             }
162
163                                             if (entry.contains("*")) {  // Process a third-party domain initial white list double entry.
164                                                 // Get the index of the wildcard.
165                                                 int wildcardIndex = entry.indexOf("*");
166
167                                                 // Split the entry into components.
168                                                 String firstEntry = entry.substring(0, wildcardIndex);
169                                                 String secondEntry = entry.substring(wildcardIndex + 1);
170
171                                                 // Create an entry string array.
172                                                 String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
173
174                                                 // Add the entry to the white list.
175                                                 thirdPartyDomainInitialWhiteList.add(domainDoubleEntry);
176
177                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial white list added: " + domain + " , " + firstEntry + " , " + secondEntry +
178                                                 //        "  -  " + originalBlockListEntry);
179                                             } else {  // Process a third-party domain initial white list single entry.
180                                                 // Create a domain entry string array.
181                                                 String[] domainEntry = {domain, entry, originalBlockListEntry};
182
183                                                 // Add the entry to the third party domain initial white list.
184                                                 thirdPartyDomainInitialWhiteList.add(domainEntry);
185
186                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
187                                             }
188                                         } while (domains.contains("|"));
189                                     }
190                                 } else {  // Third-party domain entries.
191                                     // Process each domain.
192                                     do {
193                                         // Create a string to keep track of the current domain.
194                                         String domain;
195
196                                         if (domains.contains("|")) {  // three is more than one domain in the list.
197                                             // Get the first domain from the list.
198                                             domain = domains.substring(0, domains.indexOf("|"));
199
200                                             // Remove the first domain from the list.
201                                             domains = domains.substring(domains.indexOf("|") + 1);
202                                         } else {  // There is only one domain in the list.
203                                             domain = domains;
204                                         }
205
206                                         // Remove any trailing `*` from the entry.
207                                         if (entry.endsWith("*")) {
208                                             entry = entry.substring(0, entry.length() - 1);
209                                         }
210
211                                         if (entry.contains("*")) {  // Process a third-party domain double entry.
212                                             // Get the index of the wildcard.
213                                             int wildcardIndex = entry.indexOf("*");
214
215                                             // Split the entry into components.
216                                             String firstEntry = entry.substring(0, wildcardIndex);
217                                             String secondEntry = entry.substring(wildcardIndex + 1);
218
219                                             // Create an entry string array.
220                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
221
222                                             // Add the entry to the white list.
223                                             thirdPartyDomainWhiteList.add(domainDoubleEntry);
224
225                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
226                                             //        originalBlockListEntry);
227                                         } else {  // Process a third-party domain single entry.
228                                             // Create an entry string array.
229                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
230
231                                             // Add the entry to the white list.
232                                             thirdPartyDomainWhiteList.add(domainEntry);
233
234                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
235                                         }
236                                     } while (domains.contains("|"));
237                                 }
238                             } else {  // Process third-party white list entries.
239                                 // Parse the entry
240                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
241
242                                 if (entry.contains("*")) {  // There are two or more entries.
243                                     // Get the index of the wildcard.
244                                     int wildcardIndex = entry.indexOf("*");
245
246                                     // Split the entry into components.
247                                     String firstEntry = entry.substring(0, wildcardIndex);
248                                     String secondEntry = entry.substring(wildcardIndex + 1);
249
250                                     if (secondEntry.contains("*")) {  // There are three or more entries.
251                                         // Get the index of the wildcard.
252                                         int secondWildcardIndex = secondEntry.indexOf("*");
253
254                                         // Split the entry into components.
255                                         String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
256                                         String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
257
258                                         if (thirdEntry.contains("*")) {  // There are four or more entries.
259                                             // Get the index of the wildcard.
260                                             int thirdWildcardIndex = thirdEntry.indexOf("*");
261
262                                             // Split the entry into components.
263                                             String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
264                                             String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
265
266                                             if (fourthEntry.contains("*")) {  // Process a third-party white list quintuple entry.
267                                                 // Get the index of the wildcard.
268                                                 int fourthWildcardIndex = fourthEntry.indexOf("*");
269
270                                                 // Split the entry into components.
271                                                 String realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex);
272                                                 String fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1);
273
274                                                 // Create an entry string array.
275                                                 String[] quintupleEntry = {firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalBlockListEntry};
276
277                                                 // Add the entry to the white list.
278                                                 thirdPartyWhiteList.add(quintupleEntry);
279
280                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
281                                                 //        realFourthEntry + " , " + fifthEntry + "  -  " + originalBlockListEntry);
282                                             } else {  // Process a third-party white list quadruple entry.
283                                                 // Create an entry string array.
284                                                 String[] quadrupleEntry = {firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
285
286                                                 // Add the entry to the white list.
287                                                 thirdPartyWhiteList.add(quadrupleEntry);
288
289                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
290                                                 //        fourthEntry + "  -  " + originalBlockListEntry);
291                                             }
292                                         } else {  // Process a third-party white list triple entry.
293                                             // Create an entry string array.
294                                             String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
295
296                                             // Add the entry to the white list.
297                                             thirdPartyWhiteList.add(tripleEntry);
298
299                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
300                                             //        originalBlockListEntry);
301                                         }
302                                     } else {  // Process a third-party white list double entry.
303                                         // Create an entry string array.
304                                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
305
306                                         // Add the entry to the white list.
307                                         thirdPartyWhiteList.add(doubleEntry);
308
309                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
310                                     }
311                                 } else {  // Process a third-party white list single entry.
312                                     // Create an entry string array.
313                                     String[] singleEntry = {entry, originalBlockListEntry};
314
315                                     // Add the entry to the white list.
316                                     thirdPartyWhiteList.add(singleEntry);
317
318                                     //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + entry + "  -  " + originalBlockListEntry);
319                                 }
320                             }
321                         } else if (blockListEntry.contains("domain=")) {  // Process domain white list entries.
322                             // Parse the entry
323                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
324                             String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
325                             String domains = filters.substring(filters.indexOf("domain=") + 7);
326
327                             if (entry.startsWith("|")) {  // Initial domain white list entries.
328                                 // Strip the initial `|`.
329                                 entry = entry.substring(1);
330
331                                 //noinspection StatementWithEmptyBody
332                                 if (entry.equals("http://") || entry.equals("https://")) {  // Ignore generic entries.
333                                     // Do nothing.  These entries are designed for filter options that Privacy Browser does not use.
334
335                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
336                                 } else {  // Initial domain white list entry.
337                                     // Process each domain.
338                                     do {
339                                         // Create a string to keep track of the current domain.
340                                         String domain;
341
342                                         if (domains.contains("|")) {  // There is more than one domain in the list.
343                                             // Get the first domain from the list.
344                                             domain = domains.substring(0, domains.indexOf("|"));
345
346                                             // Remove the first domain from the list.
347                                             domains = domains.substring(domains.indexOf("|") + 1);
348                                         } else {  // There is only one domain in the list.
349                                             domain = domains;
350                                         }
351
352                                         if (entry.contains("*")) {  // There are two or more entries.
353                                             // Get the index of the wildcard.
354                                             int wildcardIndex = entry.indexOf("*");
355
356                                             // Split the entry into components.
357                                             String firstEntry = entry.substring(0, wildcardIndex);
358                                             String secondEntry = entry.substring(wildcardIndex + 1);
359
360                                             if (secondEntry.contains("*")) {  // Process a domain initial triple entry.
361                                                 // Get the index of the wildcard.
362                                                 int secondWildcardIndex = secondEntry.indexOf("*");
363
364                                                 // Split the entry into components.
365                                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
366                                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
367
368                                                 // Create an entry string array.
369                                                 String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
370
371                                                 // Add the entry to the white list.
372                                                 domainInitialWhiteList.add(domainTripleEntry);
373
374                                                 //Log.i("BlockLists", headers.get(1)[0] + " domain initial white list entry added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
375                                                 //        thirdEntry + "  -  " + originalBlockListEntry);
376                                             } else {  // Process a domain initial double entry.
377                                                 // Create an entry string array.
378                                                 String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
379
380                                                 // Add the entry to the white list.
381                                                 domainInitialWhiteList.add(domainDoubleEntry);
382
383                                                 //Log.i("BlockLists", headers.get(1)[0] + " domain initial white list entry added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
384                                                 //        originalBlockListEntry);
385                                             }
386                                         } else {  // Process a domain initial single entry.
387                                             // Create an entry string array.
388                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
389
390                                             // Add the entry to the white list.
391                                             domainInitialWhiteList.add(domainEntry);
392
393                                             //Log.i("BlockLists", headers.get(1)[0] + " domain initial white list entry added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
394                                         }
395                                     } while (domains.contains("|"));
396                                 }
397                             } else if (entry.endsWith("|")) {  // Final domain white list entries.
398                                 // Strip the `|` from the end of the entry.
399                                 entry = entry.substring(0, entry.length() - 1);
400
401                                 // Process each domain.
402                                 do {
403                                     // Create a string to keep track of the current domain.
404                                     String domain;
405
406                                     if (domains.contains("|")) {  // There is more than one domain in the list.
407                                         // Get the first domain from the list.
408                                         domain = domains.substring(0, domains.indexOf("|"));
409
410                                         // Remove the first domain from the list.
411                                         domains = domains.substring(domains.indexOf("|") + 1);
412                                     } else {  // There is only one domain in the list.
413                                         domain = domains;
414                                     }
415
416                                     if (entry.contains("*")) {  // Process a domain final white list double entry.
417                                         // Get the index of the wildcard.
418                                         int wildcardIndex = entry.indexOf("*");
419
420                                         // Split the entry into components.
421                                         String firstEntry = entry.substring(0, wildcardIndex);
422                                         String secondEntry = entry.substring(wildcardIndex + 1);
423
424                                         // Create an entry string array.
425                                         String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
426
427                                         // Add the entry to the white list.
428                                         domainFinalWhiteList.add(domainDoubleEntry);
429
430                                         //Log.i("BlockLists", headers.get(1)[0] + " domain final white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
431                                         //        originalBlockListEntry);
432                                     } else {  // Process a domain final white list single entry.
433                                         // create an entry string array.
434                                         String[] domainEntry = {domain, entry, originalBlockListEntry};
435
436                                         // Add the entry to the white list.
437                                         domainFinalWhiteList.add(domainEntry);
438
439                                         //Log.i("BlockLists", headers.get(1)[0] + " domain final white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
440                                     }
441                                 } while (domains.contains("|"));
442
443                             } else {  // Standard domain white list entries with filters.
444                                 //noinspection StatementWithEmptyBody
445                                 if (domains.contains("~")) {  // It is uncertain what a `~` domain means inside an `@@` entry.
446                                     // Do Nothing
447
448                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
449                                 } else {
450                                     // Process each domain.
451                                     do {
452                                         // Create a string to keep track of the current domain.
453                                         String domain;
454
455                                         if (domains.contains("|")) {  // There is more than one domain in the list.
456                                             // Get the first domain from the list.
457                                             domain = domains.substring(0, domains.indexOf("|"));
458
459                                             // Remove the first domain from the list.
460                                             domains = domains.substring(domains.indexOf("|") + 1);
461                                         } else {  // There is only one domain in the list.
462                                             domain = domains;
463                                         }
464
465                                         if (entry.contains("*")) {  // There are two or more entries.
466                                             // Get the index of the wildcard.
467                                             int wildcardIndex = entry.indexOf("*");
468
469                                             // Split the entry into components.
470                                             String firstEntry = entry.substring(0, wildcardIndex);
471                                             String secondEntry = entry.substring(wildcardIndex + 1);
472
473                                             if (secondEntry.contains("*")) {  // There are three or more entries.
474                                                 // Get the index of the wildcard.
475                                                 int secondWildcardIndex = secondEntry.indexOf("*");
476
477                                                 // Split the entry into components.
478                                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
479                                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
480
481                                                 if (thirdEntry.contains("*")) {  // Process a domain white list quadruple entry.
482                                                     // Get the index of the wildcard.
483                                                     int thirdWildcardIndex = thirdEntry.indexOf("*");
484
485                                                     // Split the entry into components.
486                                                     String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
487                                                     String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
488
489                                                     // Create an entry string array.
490                                                     String[] domainQuadrupleEntry = {domain, firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
491
492                                                     // Add the entry to the white list.
493                                                     domainWhiteList.add(domainQuadrupleEntry);
494
495                                                     //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
496                                                     //        realThirdEntry + " , " + fourthEntry + "  -  " + originalBlockListEntry);
497                                                 } else {  // Process a domain white list triple entry.
498                                                     // Create an entry string array.
499                                                     String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
500
501                                                     // Add the entry to the white list.
502                                                     domainWhiteList.add(domainTripleEntry);
503
504                                                     //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " +
505                                                     //        thirdEntry + "  -  " + originalBlockListEntry);
506                                                 }
507                                             } else {  // Process a domain white list double entry.
508                                                 // Create an entry string array.
509                                                 String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
510
511                                                 // Add the entry to the white list.
512                                                 domainWhiteList.add(domainDoubleEntry);
513
514                                                 //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
515                                                 //        originalBlockListEntry);
516                                             }
517                                         } else {  // Process a domain white list single entry.
518                                             // Create an entry string array.
519                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
520
521                                             // Add the entry to the white list.
522                                             domainWhiteList.add(domainEntry);
523
524                                             //Log.i("BlockLists", headers.get(1)[0] + " domain white list added : " + domain + " , " + entry + "  -  " + originalBlockListEntry);
525                                         }
526                                     } while (domains.contains("|"));
527                                 }
528                             }
529                         }  // Ignore all other filter entries.
530                     } else if (blockListEntry.endsWith("|")) {  // Final white list entries.
531                         // Remove the final `|` from the entry.
532                         String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
533
534                         if (entry.contains("*")) {  // Process a final white list double entry
535                             // Get the index of the wildcard.
536                             int wildcardIndex = entry.indexOf("*");
537
538                             // split the entry into components.
539                             String firstEntry = entry.substring(0, wildcardIndex);
540                             String secondEntry = entry.substring(wildcardIndex + 1);
541
542                             // Create an entry string array.
543                             String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
544
545                             // Add the entry to the white list.
546                             finalWhiteList.add(doubleEntry);
547
548                             //Log.i("BlockLists", headers.get(1)[0] + " final white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
549                         } else {  // Process a final white list single entry.
550                             // Create an entry string array.
551                             String[] singleEntry = {entry, originalBlockListEntry};
552
553                             // Add the entry to the white list.
554                             finalWhiteList.add(singleEntry);
555
556                             //Log.i("BlockLists", headers.get(1)[0] + " final white list added: " + entry + "  -  " + originalBlockListEntry);
557                         }
558                     } else {  // Main white list entries.
559                         if (blockListEntry.contains("*")) {  // There are two or more entries.
560                             // Get the index of the wildcard.
561                             int wildcardIndex = blockListEntry.indexOf("*");
562
563                             // Split the entry into components.
564                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
565                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
566
567                             if (secondEntry.contains("*")) {  // Process a main white list triple entry.
568                                 // Get the index of the wildcard.
569                                 int secondWildcardIndex = secondEntry.indexOf("*");
570
571                                 // Split the entry into components.
572                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
573                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
574
575                                 // Create an entry string array.
576                                 String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
577
578                                 // Add the entry to the white list.
579                                 mainWhiteList.add(tripleEntry);
580
581                                 //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalBlockListEntry);
582                             } else {  // Process a main white list double entry.
583                                 // Create an entry string array.
584                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
585
586                                 // Add the entry to the white list.
587                                 mainWhiteList.add(doubleEntry);
588
589                                 //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
590                             }
591                         } else {  // Process a main white list single entry.
592                             // Create an entry string array.
593                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
594
595                             // Add the entry to the white list.
596                             mainWhiteList.add(singleEntry);
597
598                             //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + blockListEntry + "  -  " + originalBlockListEntry);
599                         }
600                     }
601                 } else if (blockListEntry.endsWith("|")) {  // Final black list entries.
602                     // Strip out the final "|"
603                     String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
604
605                     // Strip out any initial `||`.  They are redundant in this case because the block list entry is being matched against the end of the URL.
606                     if (entry.startsWith("||")) {
607                         entry = entry.substring(2);
608                     }
609
610                     if (entry.contains("*")) {  // Process a final black list double entry.
611                         // Get the index of the wildcard.
612                         int wildcardIndex = entry.indexOf("*");
613
614                         // Split the entry into components.
615                         String firstEntry = entry.substring(0, wildcardIndex);
616                         String secondEntry = entry.substring(wildcardIndex + 1);
617
618                         // Create an entry string array.
619                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
620
621                         // Add the entry to the black list.
622                         finalBlackList.add(doubleEntry);
623
624                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
625                     } else {  // Process a final black list single entry.
626                         // create an entry string array.
627                         String[] singleEntry = {entry, originalBlockListEntry};
628
629                         // Add the entry to the black list.
630                         finalBlackList.add(singleEntry);
631
632                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + entry + "  -  " + originalBlockListEntry);
633                     }
634                 } else if (blockListEntry.contains("$")) {  // Entries with filter options.
635                     // Strip out any initial `||`.  These will be treated like any other entry.
636                     if (blockListEntry.startsWith("||")) {
637                         blockListEntry = blockListEntry.substring(2);
638                     }
639
640                     if (blockListEntry.contains("third-party")) {  // Third-party entries.
641                         //noinspection StatementWithEmptyBody
642                         if (blockListEntry.contains("~third-party")) {  // Third-party filter white list entries.
643                             // Do not process these white list entries.  They are designed to combine with block filters that Privacy Browser doesn't use, like `subdocument` and `xmlhttprequest`.
644
645                             //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
646                         } else if (blockListEntry.contains("domain=")) {  // Third-party domain entries.
647                             if (blockListEntry.startsWith("|")) {  // Third-party domain initial entries.
648                                 // Strip the initial `|`.
649                                 blockListEntry = blockListEntry.substring(1);
650
651                                 // Parse the entry
652                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
653                                 String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
654                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
655
656                                 //noinspection StatementWithEmptyBody
657                                 if (entry.equals("http:") || entry.equals("https:") || entry.equals("http://") || entry.equals("https://")) {  // Ignore generic entries.
658                                     // Do nothing.  These entries will almost entirely disable the website.
659                                     // Often the original entry blocks filter options like `$script`, which Privacy Browser does not differentiate.
660
661                                     //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
662                                 } else {  // Third-party domain initial entries.
663                                     // Process each domain.
664                                     do {
665                                         // Create a string to keep track of the current domain.
666                                         String domain;
667
668                                         if (domains.contains("|")) {  // There is more than one domain in the list.
669                                             // Get the first domain from the list.
670                                             domain = domains.substring(0, domains.indexOf("|"));
671
672                                             // Remove the first domain from the list.
673                                             domains = domains.substring(domains.indexOf("|") + 1);
674                                         } else {  // There is only one domain in the list.
675                                             domain = domains;
676                                         }
677
678                                         if (entry.contains("*")) {  // Three are two or more entries.
679                                             // Get the index of the wildcard.
680                                             int wildcardIndex = entry.indexOf("*");
681
682                                             // Split the entry into components.
683                                             String firstEntry = entry.substring(0, wildcardIndex);
684                                             String secondEntry = entry.substring(wildcardIndex + 1);
685
686                                             if (secondEntry.contains("*")) {  // Process a third-party domain initial black list triple entry.
687                                                 // Get the index of the wildcard.
688                                                 int secondWildcardIndex = secondEntry.indexOf("*");
689
690                                                 // Split the entry into components.
691                                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
692                                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
693
694                                                 // Create an entry string array.
695                                                 String[] tripleDomainEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
696
697                                                 // Add the entry to the black list.
698                                                 thirdPartyDomainInitialBlackList.add(tripleDomainEntry);
699
700                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial black list added: " + domain + " , " + firstEntry + " , " + realSecondEntry +
701                                                 //        " , " + thirdEntry + "  -  " + originalBlockListEntry);
702                                             } else {  // Process a third-party domain initial black list double entry.
703                                                 // Create an entry string array.
704                                                 String[] doubleDomainEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
705
706                                                 // Add the entry to the black list.
707                                                 thirdPartyDomainInitialBlackList.add(doubleDomainEntry);
708
709                                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial black list added: " + domain + " , " + firstEntry + " , " + secondEntry +
710                                                 //        "  -  " + originalBlockListEntry);
711                                             }
712                                         } else {  // Process a third-party domain initial black list single entry.
713                                             // Create an entry string array.
714                                             String[] singleEntry = {domain, entry, originalBlockListEntry};
715
716                                             // Add the entry to the black list.
717                                             thirdPartyDomainInitialBlackList.add(singleEntry);
718
719                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain initial black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
720                                         }
721                                     } while (domains.contains("|"));
722                                 }
723                             } else if (blockListEntry.contains("\\")) {  // Process a third-party domain black list regular expression.
724                                 // Parse the entry.  At least one regular expression in this entry contains `$`, so the parser uses `/$`.
725                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("/$") + 1);
726                                 String filters = blockListEntry.substring(blockListEntry.indexOf("/$") + 2);
727                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
728
729                                 // Process each domain.
730                                 do {
731                                     // Create a string to keep track of the current domain.
732                                     String domain;
733
734                                     if (domains.contains("|")) {  // There is more than one domain in the list.
735                                         // Get the first domain from the list.
736                                         domain = domains.substring(0, domains.indexOf("|"));
737
738                                         // Remove the first domain from the list.
739                                         domains = domains.substring(domains.indexOf("|") + 1);
740                                     } else {  // There is only one domain in the list.
741                                         domain = domains;
742                                     }
743
744                                     // Create an entry string array.
745                                     String[] domainEntry = {domain, entry, originalBlockListEntry};
746
747                                     // Add the entry to the black list.
748                                     thirdPartyDomainRegularExpressionBlackList.add(domainEntry);
749
750                                     //Log.i("BlockLists", headers.get(1)[0] + " third-party domain regular expression black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
751                                 } while (domains.contains("|"));
752                             } else {  // Third-party domain entries.
753                                 // Parse the entry
754                                 String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
755                                 String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
756                                 String domains = filters.substring(filters.indexOf("domain=") + 7);
757
758                                 // Strip any trailing "*" from the entry.
759                                 if (entry.endsWith("*")) {
760                                     entry = entry.substring(0, entry.length() - 1);
761                                 }
762
763                                 // Track if any third-party white list filters are applied.
764                                 boolean whiteListDomain = false;
765
766                                 // Process each domain.
767                                 do {
768                                     // Create a string to keep track of the current domain.
769                                     String domain;
770
771                                     if (domains.contains("|")) {  // There is more than one domain in the list.
772                                         // Get the first domain from the list.
773                                         domain = domains.substring(0, domains.indexOf("|"));
774
775                                         // Remove the first domain from the list.
776                                         domains = domains.substring(domains.indexOf("|") + 1);
777                                     } else {  // The is only one domain in the list.
778                                         domain = domains;
779                                     }
780
781                                     // Differentiate between block list domains and white list domains.
782                                     if (domain.startsWith("~")) {  // White list third-party domain entry.
783                                         // Strip the initial `~`.
784                                         domain = domain.substring(1);
785
786                                         // Set the white list domain flag.
787                                         whiteListDomain = true;
788
789                                         if (entry.contains("*")) {  // Process a third-party domain white list double entry.
790                                             // Get the index of the wildcard.
791                                             int wildcardIndex = entry.indexOf("*");
792
793                                             // Split the entry into components.
794                                             String firstEntry = entry.substring(0, wildcardIndex);
795                                             String secondEntry = entry.substring(wildcardIndex + 1);
796
797                                             // Create an entry string array.
798                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
799
800                                             // Add the entry to the white list.
801                                             thirdPartyDomainWhiteList.add(domainDoubleEntry);
802
803                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
804                                             //        originalBlockListEntry);
805                                         } else {  // Process a third-party domain white list single entry.
806                                             // Create an entry string array.
807                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
808
809                                             // Add the entry to the white list.
810                                             thirdPartyDomainWhiteList.add(domainEntry);
811
812                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
813                                         }
814                                     } else {  // Third-party domain black list entries.
815                                         if (entry.contains("*")) {  // Process a third-party domain black list double entry.
816                                             // Get the index of the wildcard.
817                                             int wildcardIndex = entry.indexOf("*");
818
819                                             // Split the entry into components.
820                                             String firstEntry = entry.substring(0, wildcardIndex);
821                                             String secondEntry = entry.substring(wildcardIndex + 1);
822
823                                             // Create an entry string array.
824                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
825
826                                             // Add the entry to the black list
827                                             thirdPartyDomainBlackList.add(domainDoubleEntry);
828
829                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain black list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
830                                             //        originalBlockListEntry);
831                                         } else {  // Process a third-party domain black list single entry.
832                                             // Create an entry string array.
833                                             String[] domainEntry = {domain, entry, originalBlockListEntry};
834
835                                             // Add the entry to the black list.
836                                             thirdPartyDomainBlackList.add(domainEntry);
837
838                                             //Log.i("BlockLists", headers.get(1)[0] + " third-party domain block list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
839                                         }
840                                     }
841                                 } while (domains.contains("|"));
842
843                                 // Add a third-party black list entry if a white list domain was processed.
844                                 if (whiteListDomain) {
845                                     if (entry.contains("*")) {  // Process a third-party black list double entry.
846                                         // Get the index of the wildcard.
847                                         int wildcardIndex = entry.indexOf("*");
848
849                                         // Split the entry into components.
850                                         String firstEntry = entry.substring(0, wildcardIndex);
851                                         String secondEntry = entry.substring(wildcardIndex + 1);
852
853                                         // Create an entry string array.
854                                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
855
856                                         // Add the entry to the black list.
857                                         thirdPartyBlackList.add(doubleEntry);
858
859                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
860                                     } else {  // Process a third-party black list single entry.
861                                         // Create an entry string array.
862                                         String[] singleEntry = {entry, originalBlockListEntry};
863
864                                         // Add an entry to the black list.
865                                         thirdPartyBlackList.add(singleEntry);
866
867                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + entry + "  -  " + originalBlockListEntry);
868                                     }
869                                 }
870                             }
871                         } else if (blockListEntry.startsWith("|")) {  // Third-party initial black list entries.
872                             // Strip the initial `|`.
873                             blockListEntry = blockListEntry.substring(1);
874
875                             // Get the entry.
876                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
877
878                             if (entry.contains("*")) {  // Process a third-party initial black list double entry.
879                                 // Get the index of the wildcard.
880                                 int wildcardIndex = entry.indexOf("*");
881
882                                 // Split the entry into components.
883                                 String firstEntry = entry.substring(0, wildcardIndex);
884                                 String secondEntry = entry.substring(wildcardIndex + 1);
885
886                                 // Create an entry string array.
887                                 String[] thirdPartyDoubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
888
889                                 // Add the entry to the black list.
890                                 thirdPartyInitialBlackList.add(thirdPartyDoubleEntry);
891
892                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party initial black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
893                             } else {  // Process a third-party initial black list single entry.
894                                 // Create an entry string array.
895                                 String[] singleEntry = {entry, originalBlockListEntry};
896
897                                 // Add the entry to the black list.
898                                 thirdPartyInitialBlackList.add(singleEntry);
899
900                                 //Log.i("BlockLists", headers.get(1)[0] + " third-party initial black list added: " + entry + "  -  " + originalBlockListEntry);
901                             }
902                         } else if (blockListEntry.contains("\\")) {  // Process a regular expression black list entry.
903                             // Prepare a string to hold the entry.
904                             String entry;
905
906                             // Get the entry.
907                             if (blockListEntry.contains("$/$")) {  // The first `$` is part of the regular expression.
908                                 entry = blockListEntry.substring(0, blockListEntry.indexOf("$/$") + 2);
909                             } else {  // The only `$` indicates the filter options.
910                                 entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
911                             }
912
913                             // Create an entry string array.
914                             String[] singleEntry = {entry, originalBlockListEntry};
915
916                             // Add the entry to the black list.
917                             thirdPartyRegularExpressionBlackList.add(singleEntry);
918
919                             //Log.i("BlockLists", headers.get(1)[0] + " third-party regular expression black list added: " + entry + "  -  " + originalBlockListEntry);
920                         } else if (blockListEntry.contains("*")) {  // Third-party and regular expression black list entries.
921                             // Get the entry.
922                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
923
924                             if (entry.endsWith("*")) {  // Process a third-party black list single entry.
925                                 // Strip the final `*`.
926                                 entry = entry.substring(0, entry.length() - 1);
927
928                                 // Create an entry string array.
929                                 String[] singleEntry = {entry, originalBlockListEntry};
930
931                                 // Add the entry to the black list.
932                                 thirdPartyBlackList.add(singleEntry);
933
934                                 //Log.i("BlockLists", headers.get(1)[0] + " third party black list added: " + entry + "  -  " + originalBlockListEntry);
935                             } else {  // There are two or more entries.
936                                 // Get the index of the wildcard.
937                                 int wildcardIndex = entry.indexOf("*");
938
939                                 // Split the entry into components.
940                                 String firstEntry = entry.substring(0, wildcardIndex);
941                                 String secondEntry = entry.substring(wildcardIndex + 1);
942
943                                 if (secondEntry.contains("*")) {  // There are three or more entries.
944                                     // Get the index of the wildcard.
945                                     int secondWildcardIndex = secondEntry.indexOf("*");
946
947                                     // Split the entry into components.
948                                     String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
949                                     String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
950
951                                     if (thirdEntry.contains("*")) {  // Process a third-party black list quadruple entry.
952                                         // Get the index of the wildcard.
953                                         int thirdWildcardIndex = thirdEntry.indexOf("*");
954
955                                         // Split the entry into components.
956                                         String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
957                                         String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
958
959                                         // Create an entry string array.
960                                         String[] quadrupleEntry = {firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
961
962                                         // Add the entry to the black list.
963                                         thirdPartyBlackList.add(quadrupleEntry);
964
965                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
966                                         //        fourthEntry + "  -  " + originalBlockListEntry);
967                                     } else {  // Process a third-party black list triple entry.
968                                         // Create an entry string array.
969                                         String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
970
971                                         // Add the entry to the black list.
972                                         thirdPartyBlackList.add(tripleEntry);
973
974                                         //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
975                                         //        originalBlockListEntry);
976                                     }
977                                 } else {  // Process a third-party black list double entry.
978                                     // Create an entry string array.
979                                     String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
980
981                                     // Add the entry to the black list.
982                                     thirdPartyBlackList.add(doubleEntry);
983
984                                     //Log.i("BlockLists", headers.get(1)[0] + " third-party black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
985                                 }
986                             }
987                         } else {  // Process a third party black list single entry.
988                             // Get the entry.
989                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
990
991                             // Create an entry string array.
992                             String[] singleEntry = {entry, originalBlockListEntry};
993
994                             // Add the entry to the black list.
995                             thirdPartyBlackList.add(singleEntry);
996
997                             //Log.i("BlockLists", headers.get(1)[0] + " third party black list added: " + entry + "  -  " + originalBlockListEntry);
998                         }
999                     } else if (blockListEntry.substring(blockListEntry.indexOf("$")).contains("domain=")) {  // Domain entries.
1000                         if (blockListEntry.contains("~")) {  // Domain white list entries.
1001                             // Separate the filters.
1002                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1003                             String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
1004                             String domains = filters.substring(filters.indexOf("domain=") + 7);
1005
1006                             // Strip any final `*` from the entry.  They are redundant.
1007                             if (entry.endsWith("*")) {
1008                                 entry = entry.substring(0, entry.length() - 1);
1009                             }
1010
1011                             // Process each domain.
1012                             do {
1013                                 // Create a string to keep track of the current domain.
1014                                 String domain;
1015
1016                                 if (domains.contains("|")) {  // There is more than one domain in the list.
1017                                     // Get the first domain from the list.
1018                                     domain = domains.substring(0, domains.indexOf("|"));
1019
1020                                     // Remove the first domain from the list.
1021                                     domains = domains.substring(domains.indexOf("|") + 1);
1022                                 } else {  // There is only one domain in the list.
1023                                     domain = domains;
1024                                 }
1025
1026                                 // Strip the initial `~`.
1027                                 domain = domain.substring(1);
1028
1029                                 if (entry.contains("*")) {  // There are two or more entries.
1030                                     // Get the index of the wildcard.
1031                                     int wildcardIndex = entry.indexOf("*");
1032
1033                                     // Split the entry into components.
1034                                     String firstEntry = entry.substring(0, wildcardIndex);
1035                                     String secondEntry = entry.substring(wildcardIndex + 1);
1036
1037                                     if (secondEntry.contains("*")) {  // Process a domain white list triple entry.
1038                                         // Get the index of the wildcard.
1039                                         int secondWildcardIndex = secondEntry.indexOf("*");
1040
1041                                         // Split the entry into components.
1042                                         String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1043                                         String thirdEntry = secondEntry.substring((secondWildcardIndex + 1));
1044
1045                                         // Create an entry string array.
1046                                         String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1047
1048                                         // Add the entry to the white list.
1049                                         domainWhiteList.add(domainTripleEntry);
1050
1051                                         //Log.i("BlockLists", headers.get(1)[0] + " domain white list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1052                                         //        "  -  " + originalBlockListEntry);
1053                                     } else {  // Process a domain white list double entry.
1054                                         // Create an entry string array.
1055                                         String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
1056
1057                                         // Add the entry to the white list.
1058                                         domainWhiteList.add(domainDoubleEntry);
1059
1060                                         //Log.i("BlockLists", headers.get(1)[0] + " domain white list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1061                                     }
1062                                 } else {  // Process a domain white list single entry.
1063                                     // Create an entry string array.
1064                                     String[] domainEntry = {domain, entry, originalBlockListEntry};
1065
1066                                     // Add the entry to the white list.
1067                                     domainWhiteList.add(domainEntry);
1068
1069                                     //Log.i("BlockLists", headers.get(1)[0] + " domain white list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
1070                                 }
1071                             } while (domains.contains("|"));
1072                         } else {  // Domain black list entries.
1073                             // Separate the filters.
1074                             String entry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1075                             String filters = blockListEntry.substring(blockListEntry.indexOf("$") + 1);
1076                             String domains = filters.substring(filters.indexOf("domain=") + 7);
1077
1078                             // Only process the item if the entry is not null.  For example, some lines begin with `$websocket`, which create a null entry.
1079                             if (!entry.equals("")) {
1080                                 // Process each domain.
1081                                 do {
1082                                     // Create a string to keep track of the current domain.
1083                                     String domain;
1084
1085                                     if (domains.contains("|")) {  // There is more than one domain in the list.
1086                                         // Get the first domain from the list.
1087                                         domain = domains.substring(0, domains.indexOf("|"));
1088
1089                                         // Remove the first domain from the list.
1090                                         domains = domains.substring(domains.indexOf("|") + 1);
1091                                     } else {  // There is only one domain in the list.
1092                                         domain = domains;
1093                                     }
1094
1095                                     if (entry.startsWith("|")) {  // Domain initial black list entries.
1096                                         // Remove the initial `|`;
1097                                         String entryBase = entry.substring(1);
1098
1099                                         //noinspection StatementWithEmptyBody
1100                                         if (entryBase.equals("http://") || entryBase.equals("https://")) {
1101                                             // Do nothing.  These entries will entirely block the website.
1102                                             // Often the original entry blocks `$script` but Privacy Browser does not currently differentiate between scripts and other entries.
1103
1104                                             //Log.i("BlockLists", headers.get(1)[0] + " not added: " + originalBlockListEntry);
1105                                         } else {  // Process a domain initial black list entry
1106                                             // Create an entry string array.
1107                                             String[] domainEntry = {domain, entryBase, originalBlockListEntry};
1108
1109                                             // Add the entry to the black list.
1110                                             domainInitialBlackList.add(domainEntry);
1111
1112                                             //Log.i("BlockLists", headers.get(1)[0] + " domain initial black list added: " + domain + " , " + entryBase + "  -  " + originalBlockListEntry);
1113                                         }
1114                                     } else if (entry.endsWith("|")) {  // Domain final black list entries.
1115                                         // Remove the final `|`.
1116                                         String entryBase = entry.substring(0, entry.length() - 1);
1117
1118                                         if (entryBase.contains("*")) {  // Process a domain final black list double entry.
1119                                             // Get the index of the wildcard.
1120                                             int wildcardIndex = entry.indexOf("*");
1121
1122                                             // Split the entry into components.
1123                                             String firstEntry = entryBase.substring(0, wildcardIndex);
1124                                             String secondEntry = entryBase.substring(wildcardIndex + 1);
1125
1126                                             // Create an entry string array.
1127                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
1128
1129                                             // Add the entry to the black list.
1130                                             domainFinalBlackList.add(domainDoubleEntry);
1131
1132                                             //Log.i("BlockLists", headers.get(1)[0] + " domain final black list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
1133                                             //        originalBlockListEntry);
1134                                         } else {  // Process a domain final black list single entry.
1135                                             // Create an entry string array.
1136                                             String[] domainEntry = {domain, entryBase, originalBlockListEntry};
1137
1138                                             // Add the entry to the black list.
1139                                             domainFinalBlackList.add(domainEntry);
1140
1141                                             //Log.i("BlockLists", headers.get(1)[0] + " domain final black list added: " + domain + " , " + entryBase + "  -  " + originalBlockListEntry);
1142                                         }
1143                                     } else if (entry.contains("\\")) {  // Process a domain regular expression black list entry.
1144                                         // Create an entry string array.
1145                                         String[] domainEntry = {domain, entry, originalBlockListEntry};
1146
1147                                         // Add the entry to the black list.
1148                                         domainRegularExpressionBlackList.add(domainEntry);
1149
1150                                         //Log.i("BlockLists", headers.get(1)[0] + " domain regular expression black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
1151                                     } else if (entry.contains("*")) {  // There are two or more entries.
1152                                         // Get the index of the wildcard.
1153                                         int wildcardIndex = entry.indexOf("*");
1154
1155                                         // Split the entry into components.
1156                                         String firstEntry = entry.substring(0, wildcardIndex);
1157                                         String secondEntry = entry.substring(wildcardIndex + 1);
1158
1159                                         if (secondEntry.contains("*")) {  // Process a domain black list triple entry.
1160                                             // Get the index of the wildcard.
1161                                             int secondWildcardIndex = secondEntry.indexOf("*");
1162
1163                                             // Split the entry into components.
1164                                             String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1165                                             String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1166
1167                                             // Create an entry string array.
1168                                             String[] domainTripleEntry = {domain, firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1169
1170                                             // Add the entry to the black list.
1171                                             domainBlackList.add(domainTripleEntry);
1172
1173                                             //Log.i("BlockLists", headers.get(1)[0] + " domain black list added: " + domain + " , " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry +
1174                                             //        "  -  " + originalBlockListEntry);
1175                                         } else {  // Process a domain black list double entry.
1176                                             // Create an entry string array.
1177                                             String[] domainDoubleEntry = {domain, firstEntry, secondEntry, originalBlockListEntry};
1178
1179                                             // Add the entry to the black list.
1180                                             domainBlackList.add(domainDoubleEntry);
1181
1182                                             //Log.i("BlockLists", headers.get(1)[0] + " domain black list added: " + domain + " , " + firstEntry + " , " + secondEntry + "  -  " +
1183                                             //        originalBlockListEntry);
1184                                         }
1185                                     } else {  // Process a domain black list single entry.
1186                                         // Create an entry string array.
1187                                         String[] domainEntry = {domain, entry, originalBlockListEntry};
1188
1189                                         // Add the entry to the black list.
1190                                         domainBlackList.add(domainEntry);
1191
1192                                         //Log.i("BlockLists", headers.get(1)[0] + " domain black list added: " + domain + " , " + entry + "  -  " + originalBlockListEntry);
1193                                     }
1194                                 } while (domains.contains("|"));
1195                             }
1196                         }
1197                     } else if (blockListEntry.contains("~")) {  // White list entries.  Privacy Browser does not differentiate against these filter options, so they are just generally white listed.
1198                         // Remove the filter options.
1199                         blockListEntry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1200
1201                         // Strip any trailing `*`.
1202                         if (blockListEntry.endsWith("*")) {
1203                             blockListEntry = blockListEntry.substring(0, blockListEntry.length() - 1);
1204                         }
1205
1206                         if (blockListEntry.contains("*")) {  // Process a white list double entry.
1207                             // Get the index of the wildcard.
1208                             int wildcardIndex = blockListEntry.indexOf("*");
1209
1210                             // Split the entry into components.
1211                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
1212                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
1213
1214                             // Create an entry string array.
1215                             String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1216
1217                             // Add the entry to the white list.
1218                             mainWhiteList.add(doubleEntry);
1219
1220                             //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1221                         } else {  // Process a white list single entry.
1222                             // Create an entry string array.
1223                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
1224
1225                             // Add the entry to the white list.
1226                             mainWhiteList.add(singleEntry);
1227
1228                             //Log.i("BlockLists", headers.get(1)[0] + " main white list added: " + blockListEntry + "  -  + " + originalBlockListEntry);
1229                         }
1230                     } else if (blockListEntry.contains("\\")) {  // Process a regular expression black list entry.
1231                         // Remove the filter options.
1232                         blockListEntry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1233
1234                         // Create an entry string array.
1235                         String[] singleEntry = {blockListEntry, originalBlockListEntry};
1236
1237                         // Add the entry to the black list.
1238                         regularExpressionBlackList.add(singleEntry);
1239
1240                         //Log.i("BlockLists", headers.get(1)[0] + " regular expression black list added: " + blockListEntry + "  -  " + originalBlockListEntry);
1241                     } else {  // Black list entries.
1242                         // Remove the filter options.
1243                         if (!blockListEntry.contains("$file")) {  // EasyPrivacy contains an entry with `$file` that does not have filter options.
1244                             blockListEntry = blockListEntry.substring(0, blockListEntry.indexOf("$"));
1245                         }
1246
1247                         // Strip any trailing `*`.  These are redundant.
1248                         if (blockListEntry.endsWith("*")) {
1249                             blockListEntry = blockListEntry.substring(0, blockListEntry.length() - 1);
1250                         }
1251
1252                         if (blockListEntry.startsWith("|")) {  // Initial black list entries.
1253                             // Strip the initial `|`.
1254                             String entry = blockListEntry.substring(1);
1255
1256                             if (entry.contains("*")) {  // Process an initial black list double entry.
1257                                 // Get the index of the wildcard.
1258                                 int wildcardIndex = entry.indexOf("*");
1259
1260                                 // Split the entry into components.
1261                                 String firstEntry = entry.substring(0, wildcardIndex);
1262                                 String secondEntry = entry.substring(wildcardIndex + 1);
1263
1264                                 // Create an entry string array.
1265                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1266
1267                                 // Add the entry to the black list.
1268                                 initialBlackList.add(doubleEntry);
1269
1270                                 //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1271                             } else {  // Process an initial black list single entry.
1272                                 // Create an entry string array.
1273                                 String[] singleEntry = {entry, originalBlockListEntry};
1274
1275                                 // Add the entry to the black list.
1276                                 initialBlackList.add(singleEntry);
1277
1278                                 //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + entry + "  -  " + originalBlockListEntry);
1279                             }
1280                         } else if (blockListEntry.endsWith("|")) {  // Final black list entries.
1281                             // Ignore entries with `object` filters.  They can block entire websites and don't have any meaning in the context of Privacy Browser.
1282                             if (!originalBlockListEntry.contains("$object")) {
1283                                 // Strip the final `|`.
1284                                 String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
1285
1286                                 if (entry.contains("*")) {  // There are two or more entries.
1287                                     // Get the index of the wildcard.
1288                                     int wildcardIndex = entry.indexOf("*");
1289
1290                                     // Split the entry into components.
1291                                     String firstEntry = entry.substring(0, wildcardIndex);
1292                                     String secondEntry = entry.substring(wildcardIndex + 1);
1293
1294                                     if (secondEntry.contains("*")) {  // Process a final black list triple entry.
1295                                         // Get the index of the wildcard.
1296                                         int secondWildcardIndex = secondEntry.indexOf("*");
1297
1298                                         // Split the entry into components.
1299                                         String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1300                                         String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1301
1302                                         // Create an entry string array.
1303                                         String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1304
1305                                         // Add the entry to the black list.
1306                                         finalBlackList.add(tripleEntry);
1307
1308                                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
1309                                         //        originalBlockListEntry);
1310                                     } else {  // Process a final black list double entry.
1311                                         // Create an entry string array.
1312                                         String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1313
1314                                         // Add the entry to the black list.
1315                                         finalBlackList.add(doubleEntry);
1316
1317                                         //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1318                                     }
1319                                 } else {  // Process a final black list single entry.
1320                                     // Create an entry sting array.
1321                                     String[] singleEntry = {entry, originalBlockListEntry};
1322
1323                                     // Add the entry to the black list.
1324                                     finalBlackList.add(singleEntry);
1325
1326                                     //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + entry + "  -  " + originalBlockListEntry);
1327                                 }
1328                             }
1329                         } else if (blockListEntry.contains("*")) {  // There are two or more entries.
1330                             // Get the index of the wildcard.
1331                             int wildcardIndex = blockListEntry.indexOf("*");
1332
1333                             // Split the entry into components.
1334                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
1335                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
1336
1337                             if (secondEntry.contains("*")) {  // Process a main black list triple entry.
1338                                 // Get the index of the wildcard.
1339                                 int secondWildcardIndex = secondEntry.indexOf("*");
1340
1341                                 // Split the entry into components.
1342                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1343                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1344
1345                                 // Create an entry string array.
1346                                 String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1347
1348                                 // Add the entry to the black list.
1349                                 mainBlackList.add(tripleEntry);
1350
1351                                 //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalBlockListEntry);
1352                             } else {  // Process a main black list double entry.
1353                                 // Create an entry string array.
1354                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1355
1356                                 // Add the entry to the black list.
1357                                 mainBlackList.add(doubleEntry);
1358
1359                                 //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1360                             }
1361                         } else {  // Process a main black list single entry.
1362                             // Create an entry string array.
1363                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
1364
1365                             // Add the entry to the black list.
1366                             mainBlackList.add(singleEntry);
1367
1368                             //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + blockListEntry + "  -  " + originalBlockListEntry);
1369                         }
1370                     }
1371                 } else {  // Main black list entries
1372                     // Strip out any initial `||`.  These will be treated like any other entry.
1373                     if (blockListEntry.startsWith("||")) {
1374                         blockListEntry = blockListEntry.substring(2);
1375                     }
1376
1377                     // Strip out any initial `*`.
1378                     if (blockListEntry.startsWith("*")) {
1379                         blockListEntry = blockListEntry.substring(1);
1380                     }
1381
1382                     // Strip out any trailing `*`.
1383                     if (blockListEntry.endsWith("*")) {
1384                         blockListEntry = blockListEntry.substring(0, blockListEntry.length() - 1);
1385                     }
1386
1387                     if (blockListEntry.startsWith("|")) {  // Initial black list entries.
1388                         // Strip the initial `|`.
1389                         String entry = blockListEntry.substring(1);
1390
1391                         if (entry.contains("*")) {  // Process an initial black list double entry.
1392                             // Get the index of the wildcard.
1393                             int wildcardIndex = entry.indexOf("*");
1394
1395                             // Split the entry into components.
1396                             String firstEntry = entry.substring(0, wildcardIndex);
1397                             String secondEntry = entry.substring(wildcardIndex + 1);
1398
1399                             // Create an entry string array.
1400                             String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1401
1402                             // Add the entry to the black list.
1403                             initialBlackList.add(doubleEntry);
1404
1405                             //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1406                         } else {  // Process an initial black list single entry.
1407                             // Create an entry string array.
1408                             String[] singleEntry = {entry, originalBlockListEntry};
1409
1410                             // Add the entry to the black list.
1411                             initialBlackList.add(singleEntry);
1412
1413                             //Log.i("BlockLists", headers.get(1)[0] + " initial black list added: " + entry + "  -  " + originalBlockListEntry);
1414                         }
1415                     } else if (blockListEntry.endsWith("|")) {  // Final black list entries.
1416                         // Strip the final `|`.
1417                         String entry = blockListEntry.substring(0, blockListEntry.length() - 1);
1418
1419                         if (entry.contains("*")) {  // There are two or more entries.
1420                             // Get the index of the wildcard.
1421                             int wildcardIndex = entry.indexOf("*");
1422
1423                             // Split the entry into components.
1424                             String firstEntry = entry.substring(0, wildcardIndex);
1425                             String secondEntry = entry.substring(wildcardIndex + 1);
1426
1427                             if (secondEntry.contains("*")) {  // Process a final black list triple entry.
1428                                 // Get the index of the wildcard.
1429                                 int secondWildcardIndex = secondEntry.indexOf("*");
1430
1431                                 // Split the entry into components.
1432                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1433                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1434
1435                                 // Create an entry string array.
1436                                 String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1437
1438                                 // Add the entry to the black list.
1439                                 finalBlackList.add(tripleEntry);
1440
1441                                 //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " +
1442                                 //        originalBlockListEntry);
1443                             } else {  // Process a final black list double entry.
1444                                 // Create an entry string array.
1445                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1446
1447                                 // Add the entry to the black list.
1448                                 finalBlackList.add(doubleEntry);
1449
1450                                 //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1451                             }
1452                         } else {  // Process a final black list single entry.
1453                             // Create an entry string array.
1454                             String[] singleEntry = {entry, originalBlockListEntry};
1455
1456                             // Add the entry to the black list.
1457                             finalBlackList.add(singleEntry);
1458
1459                             //Log.i("BlockLists", headers.get(1)[0] + " final black list added: " + entry + "  -  " + originalBlockListEntry);
1460                         }
1461                     } else {  // Main black list entries.
1462                         if (blockListEntry.contains("*")) {  // There are two or more entries.
1463                             // Get the index of the wildcard.
1464                             int wildcardIndex = blockListEntry.indexOf("*");
1465
1466                             // Split the entry into components.
1467                             String firstEntry = blockListEntry.substring(0, wildcardIndex);
1468                             String secondEntry = blockListEntry.substring(wildcardIndex + 1);
1469
1470                             if (secondEntry.contains("*")) {  // There are three or more entries.
1471                                 // Get the index of the wildcard.
1472                                 int secondWildcardIndex = secondEntry.indexOf("*");
1473
1474                                 // Split the entry into components.
1475                                 String realSecondEntry = secondEntry.substring(0, secondWildcardIndex);
1476                                 String thirdEntry = secondEntry.substring(secondWildcardIndex + 1);
1477
1478                                 if (thirdEntry.contains("*")) {  // There are four or more entries.
1479                                     // Get the index of the wildcard.
1480                                     int thirdWildcardIndex = thirdEntry.indexOf("*");
1481
1482                                     // Split the entry into components.
1483                                     String realThirdEntry = thirdEntry.substring(0, thirdWildcardIndex);
1484                                     String fourthEntry = thirdEntry.substring(thirdWildcardIndex + 1);
1485
1486                                     if (fourthEntry.contains("*")) {  // Process a main black list quintuple entry.
1487                                         // Get the index of the wildcard.
1488                                         int fourthWildcardIndex = fourthEntry.indexOf("*");
1489
1490                                         // Split the entry into components.
1491                                         String realFourthEntry = fourthEntry.substring(0, fourthWildcardIndex);
1492                                         String fifthEntry = fourthEntry.substring(fourthWildcardIndex + 1);
1493
1494                                         // Create an entry string array.
1495                                         String[] quintupleEntry = {firstEntry, realSecondEntry, realThirdEntry, realFourthEntry, fifthEntry, originalBlockListEntry};
1496
1497                                         // Add the entry to the black list.
1498                                         mainBlackList.add(quintupleEntry);
1499
1500                                         //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
1501                                         //        realFourthEntry + " , " + fifthEntry + "  -  " + originalBlockListEntry);
1502                                     } else {  // Process a main black list quadruple entry.
1503                                         // Create an entry string array.
1504                                         String[] quadrupleEntry = {firstEntry, realSecondEntry, realThirdEntry, fourthEntry, originalBlockListEntry};
1505
1506                                         // Add the entry to the black list.
1507                                         mainBlackList.add(quadrupleEntry);
1508
1509                                         //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + realThirdEntry + " , " +
1510                                         //        fourthEntry + "  -  " + originalBlockListEntry);
1511                                     }
1512                                 } else {  // Process a main black list triple entry.
1513                                     // Create an entry string array.
1514                                     String[] tripleEntry = {firstEntry, realSecondEntry, thirdEntry, originalBlockListEntry};
1515
1516                                     // Add the entry to the black list.
1517                                     mainBlackList.add(tripleEntry);
1518
1519                                     //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + realSecondEntry + " , " + thirdEntry + "  -  " + originalBlockListEntry);
1520                                 }
1521                             } else {  // Process a main black list double entry.
1522                                 // Create an entry string array.
1523                                 String[] doubleEntry = {firstEntry, secondEntry, originalBlockListEntry};
1524
1525                                 // Add the entry to the black list.
1526                                 mainBlackList.add(doubleEntry);
1527
1528                                 //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + firstEntry + " , " + secondEntry + "  -  " + originalBlockListEntry);
1529                             }
1530                         } else {  // Process a main black list single entry.
1531                             // Create an entry string array.
1532                             String[] singleEntry = {blockListEntry, originalBlockListEntry};
1533
1534                             // Add the entry to the black list.
1535                             mainBlackList.add(singleEntry);
1536
1537                             //Log.i("BlockLists", headers.get(1)[0] + " main black list added: " + blockListEntry + "  -  " + originalBlockListEntry);
1538                         }
1539                     }
1540                 }
1541             }
1542             // Close `bufferedReader`.
1543             bufferedReader.close();
1544         } catch (IOException e) {
1545             // The asset exists, so the `IOException` will never be thrown.
1546         }
1547
1548         // Initialize the combined list.
1549         ArrayList<List<String[]>> combinedLists = new ArrayList<>();
1550
1551         // Add the headers (0).
1552         combinedLists.add(headers);  // 0.
1553
1554         // Add the white lists (1-8).
1555         combinedLists.add(mainWhiteList);  // 1.
1556         combinedLists.add(finalWhiteList);  // 2.
1557         combinedLists.add(domainWhiteList);  // 3.
1558         combinedLists.add(domainInitialWhiteList);  // 4.
1559         combinedLists.add(domainFinalWhiteList); // 5.
1560         combinedLists.add(thirdPartyWhiteList);  // 6.
1561         combinedLists.add(thirdPartyDomainWhiteList);  // 7.
1562         combinedLists.add(thirdPartyDomainInitialWhiteList);  // 8.
1563
1564         // Add the black lists (9-22).
1565         combinedLists.add(mainBlackList);  // 9.
1566         combinedLists.add(initialBlackList);  // 10.
1567         combinedLists.add(finalBlackList);  // 11.
1568         combinedLists.add(domainBlackList);  //  12.
1569         combinedLists.add(domainInitialBlackList);  // 13.
1570         combinedLists.add(domainFinalBlackList);  // 14.
1571         combinedLists.add(domainRegularExpressionBlackList);  // 15.
1572         combinedLists.add(thirdPartyBlackList);  // 16.
1573         combinedLists.add(thirdPartyInitialBlackList);  // 17.
1574         combinedLists.add(thirdPartyDomainBlackList);  // 18.
1575         combinedLists.add(thirdPartyDomainInitialBlackList);  // 19.
1576         combinedLists.add(thirdPartyRegularExpressionBlackList);  // 20.
1577         combinedLists.add(thirdPartyDomainRegularExpressionBlackList);  // 21.
1578         combinedLists.add(regularExpressionBlackList);  // 22.
1579
1580         return combinedLists;
1581     }
1582
1583     public boolean isBlocked(String currentDomain, String resourceUrl, boolean isThirdPartyRequest, ArrayList<List<String[]>> blockList) {
1584         // Get the block list name.
1585         String BLOCK_LIST_NAME_STRING = blockList.get(0).get(1)[0];
1586
1587         // Assert that currentDomain != null only if this is a third party request.  Apparently, lint can't tell that this isn't redundant.
1588         //noinspection RedundantIfStatement
1589         if (isThirdPartyRequest) {
1590             assert currentDomain != null;
1591         }
1592
1593         // Process the white lists.
1594         // Main white list.
1595         for (String[] whiteListEntry : blockList.get(MainWebViewActivity.MAIN_WHITELIST)) {
1596             switch (whiteListEntry.length) {
1597                 case 2:  // There is one entry.
1598                     if (resourceUrl.contains(whiteListEntry[0])) {
1599                         // Store the entry in the resource request log.
1600                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1601                                 String.valueOf(MainWebViewActivity.MAIN_WHITELIST), whiteListEntry[0], whiteListEntry[1]};
1602
1603                         // Not blocked.
1604                         return false;
1605                     }
1606                     break;
1607
1608                 case 3:  // There are two entries.
1609                     if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1610                         // Store the entry in the resource request log.
1611                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1612                                 String.valueOf(MainWebViewActivity.MAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1],
1613                                 whiteListEntry[2]};
1614
1615                         // Not blocked.
1616                         return false;
1617                     }
1618                     break;
1619
1620                 case 4:  // There are three entries.
1621                     if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1622                         // Store the entry in the resource request log.
1623                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1624                                 String.valueOf(MainWebViewActivity.MAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1625
1626                         // Not blocked.
1627                         return false;
1628                     }
1629                     break;
1630             }
1631         }
1632
1633         // Final white list.
1634         for (String[] whiteListEntry : blockList.get(MainWebViewActivity.FINAL_WHITELIST)) {
1635             if (whiteListEntry.length == 2) {  // There is one entry.
1636                 if (resourceUrl.contains(whiteListEntry[0])) {
1637                     // Store the entry in the resource request log.
1638                     MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1639                             String.valueOf(MainWebViewActivity.FINAL_WHITELIST), whiteListEntry[0], whiteListEntry[1]};
1640
1641                     // Not blocked.
1642                     return false;
1643                 }
1644             } else {  // There are two entries.
1645                 if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1646                     // Store the entry in the resource request log.
1647                     MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1648                             String.valueOf(MainWebViewActivity.FINAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1649
1650                     // Not blocked.
1651                     return false;
1652                 }
1653             }
1654         }
1655
1656         // Only check the domain lists if the current domain is not null (like `about:blank`).
1657         if (currentDomain != null) {
1658             // Domain white list.
1659             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.DOMAIN_WHITELIST)) {
1660                 switch (whiteListEntry.length) {
1661                     case 3:  // There is one entry.
1662                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1663                             // Store the entry in the resource request log.
1664                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1665                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1666
1667                             // Not blocked.
1668                             return false;
1669                         }
1670                         break;
1671
1672                     case 4:  // There are two entries.
1673                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1674                             // Store the entry in the resource request log.
1675                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1676                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1677
1678                             // Not blocked.
1679                             return false;
1680                         }
1681                         break;
1682
1683                     case 5:  // There are three entries.
1684                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3])) {
1685                             // Store the entry in the resource request log.
1686                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1687                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3],
1688                                     whiteListEntry[4]};
1689
1690                             // Not blocked.
1691                             return false;
1692                         }
1693                         break;
1694
1695                     case 6:  // There are four entries.
1696                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3]) &&
1697                                 resourceUrl.contains(whiteListEntry[4])) {
1698                             // Store the entry in the resource request log.
1699                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1700                                     String.valueOf(MainWebViewActivity.DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3] + "\n" +
1701                                     whiteListEntry[4], whiteListEntry[5]};
1702
1703                             // Not blocked.
1704                             return false;
1705                         }
1706                         break;
1707                 }
1708             }
1709
1710             // Domain initial white list.
1711             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST)) {
1712                 switch (whiteListEntry.length) {
1713                     case 3:  // There is one entry.
1714                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1])) {
1715                             // Store the entry in the resource request log.
1716                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1717                                     String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1718
1719                             // Not blocked.
1720                             return false;
1721                         }
1722                         break;
1723
1724                     case 4:  // There are two entries.
1725                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1726                             // Store the entry in the resource request log.
1727                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1728                                     String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1729
1730                             // Not blocked.
1731                             return false;
1732                         }
1733                         break;
1734
1735                     case 5:  // There are three entries.
1736                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.startsWith(whiteListEntry[3])) {
1737                             // Store the entry in the resource request log.
1738                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1739                                     String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3],
1740                                     whiteListEntry[4]};
1741
1742                             // Not blocked.
1743                             return false;
1744                         }
1745                         break;
1746                 }
1747             }
1748
1749             // Domain final white list.
1750             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.DOMAIN_FINAL_WHITELIST)) {
1751                 switch (whiteListEntry.length) {
1752                     case 3:  // There is one entry;
1753                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.endsWith(whiteListEntry[1])) {
1754                             // Store the entry in the resource request log.
1755                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1756                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1757
1758                             // Not blocked.
1759                             return false;
1760                         }
1761                         break;
1762
1763                     case 4:  // There are two entries;
1764                         if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.endsWith(whiteListEntry[2])) {
1765                             // Store the entry in the resource request log.
1766                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1767                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1768
1769
1770                             // Not blocked.
1771                             return false;
1772                         }
1773                         break;
1774                 }
1775             }
1776         }
1777
1778         // Only check the third-party white lists if this is a third-party request.
1779         if (isThirdPartyRequest) {
1780             // Third-party white list.
1781             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_WHITELIST)) {
1782                 switch (whiteListEntry.length) {
1783                     case 2:  // There is one entry
1784                         if (resourceUrl.contains(whiteListEntry[0])) {
1785                             // Store the entry in the resource request log.
1786                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1787                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0], whiteListEntry[1]};
1788
1789                             // Not blocked.
1790                             return false;
1791                         }
1792                         break;
1793
1794                     case 3:  // There are two entries.
1795                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1796                             // Store the entry in the resource request log.
1797                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1798                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1799
1800                             // Not blocked.
1801                             return false;
1802                         }
1803                         break;
1804
1805                     case 4:  // There are three entries.
1806                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1807                             // Store the entry in the resource request log.
1808                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1809                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1810
1811                             // Not blocked.
1812                             return false;
1813                         }
1814                         break;
1815
1816                     case 5:  // There are four entries.
1817                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3])) {
1818                             // Store the entry in the resource request log.
1819                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1820                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3],
1821                                     whiteListEntry[4]};
1822                             // Not blocked.
1823                             return false;
1824                         }
1825                         break;
1826
1827                     case 6:  // There are five entries.
1828                         if (resourceUrl.contains(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2]) && resourceUrl.contains(whiteListEntry[3]) &&
1829                                 resourceUrl.contains(whiteListEntry[4])) {
1830                             // Store the entry in the resource request log.
1831                             MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1832                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2] + "\n" + whiteListEntry[3] + "\n" +
1833                                     whiteListEntry[4], whiteListEntry[5]};
1834
1835                             // Not blocked.
1836                             return false;
1837                         }
1838                         break;
1839                 }
1840             }
1841
1842             // Third-party domain white list.
1843             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST)) {
1844                 if (whiteListEntry.length == 3) {  // There is one entry.
1845                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1])) {
1846                         // Store the entry in the resource request log.
1847                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1848                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1849
1850                         // Not blocked.
1851                         return false;
1852                     }
1853                 } else {  // There are two entries.
1854                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.contains(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1855                         // Store the entry in the resource request log.
1856                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1857                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1858
1859                         // Not blocked.
1860                         return false;
1861                     }
1862                 }
1863             }
1864
1865             // Third-party domain initial white list.
1866             for (String[] whiteListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_DOMAIN_INITIAL_WHITELIST)) {
1867                 if (whiteListEntry.length == 3) {  // There is one entry.
1868                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1])) {
1869                         // Store the entry in the resource request log.
1870                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1871                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_INITIAL_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1], whiteListEntry[2]};
1872
1873                         // Not blocked.
1874                         return false;
1875                     }
1876                 } else {  // There are two entries.
1877                     if (currentDomain.endsWith(whiteListEntry[0]) && resourceUrl.startsWith(whiteListEntry[1]) && resourceUrl.contains(whiteListEntry[2])) {
1878                         // Store the entry in the resource request log.
1879                         MainWebViewActivity.whiteListResultStringArray = new String[] {String.valueOf(MainWebViewActivity.REQUEST_ALLOWED), resourceUrl, BLOCK_LIST_NAME_STRING,
1880                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_DOMAIN_WHITELIST), whiteListEntry[0] + "\n" + whiteListEntry[1] + "\n" + whiteListEntry[2], whiteListEntry[3]};
1881
1882                         // Not blocked.
1883                         return false;
1884                     }
1885                 }
1886             }
1887         }
1888
1889         // Process the black lists.
1890         // Main black list.
1891         for (String[] blackListEntry : blockList.get(MainWebViewActivity.MAIN_BLACKLIST)) {
1892             switch (blackListEntry.length) {
1893                 case 2:  // There is one entry.
1894                     if (resourceUrl.contains(blackListEntry[0])) {
1895                         // Store the entry in the resource request log.
1896                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1897                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0], blackListEntry[1]});
1898
1899                         // Blocked.
1900                         return true;
1901                     }
1902                     break;
1903
1904                 case 3:  // There are two entries.
1905                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
1906                         // Store the entry in the resource request log.
1907                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1908                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
1909
1910                         // Blocked.
1911                         return true;
1912                     }
1913                     break;
1914
1915                 case 4:  // There are three entries.
1916                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2])) {
1917                         // Store the entry in the resource request log.
1918                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1919                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
1920
1921                         // Blocked.
1922                         return true;
1923                     }
1924                     break;
1925
1926                 case 5:  // There are four entries.
1927                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3])) {
1928                         // Store the entry in the resource request log.
1929                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1930                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3], blackListEntry[4]});
1931
1932                         // Blocked.
1933                         return true;
1934                     }
1935                     break;
1936
1937                 case 6:  // There are five entries.
1938                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3]) &&
1939                             resourceUrl.contains(blackListEntry[4])) {
1940                         // Store the entry in the resource request log.
1941                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1942                                 String.valueOf(MainWebViewActivity.MAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3] + "\n" +
1943                                 blackListEntry[4], blackListEntry[5]});
1944
1945                         // Blocked.
1946                         return true;
1947                     }
1948                     break;
1949             }
1950         }
1951
1952         // Initial black list.
1953         for (String[] blackListEntry : blockList.get(MainWebViewActivity.INITIAL_BLACKLIST)) {
1954             if (blackListEntry.length == 2) {  // There is one entry.
1955                 if (resourceUrl.startsWith(blackListEntry[0])) {
1956                     // Store the entry in the resource request log.
1957                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1958                             String.valueOf(MainWebViewActivity.INITIAL_BLACKLIST), blackListEntry[0], blackListEntry[1]});
1959
1960                     // Blocked.
1961                     return true;
1962                 }
1963             } else {  // There are two entries
1964                 if (resourceUrl.startsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
1965                     // Store the entry in the resource request log.
1966                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1967                             String.valueOf(MainWebViewActivity.INITIAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
1968
1969                     // Blocked.
1970                     return true;
1971                 }
1972             }
1973         }
1974
1975         // Final black list.
1976         for (String[] blackListEntry : blockList.get(MainWebViewActivity.FINAL_BLACKLIST)) {
1977             switch (blackListEntry.length) {
1978                 case 2:  // There is one entry.
1979                     if (resourceUrl.endsWith(blackListEntry[0])) {
1980                         // Store the entry in the resource request log.
1981                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1982                                 String.valueOf(MainWebViewActivity.FINAL_BLACKLIST), blackListEntry[0], blackListEntry[1]});
1983
1984                         // Blocked.
1985                         return true;
1986                     }
1987                     break;
1988
1989                 case 3:  // There are two entries.
1990                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.endsWith(blackListEntry[1])) {
1991                         // Store the entry in the resource request log.
1992                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
1993                                 String.valueOf(MainWebViewActivity.FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
1994
1995                         // Blocked.
1996                         return true;
1997                     }
1998                     break;
1999
2000                 case 4:  // There are three entries.
2001                     if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.endsWith(blackListEntry[2])) {
2002                         // Store the entry in the resource request log.
2003                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2004                                 String.valueOf(MainWebViewActivity.FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2005
2006                         // Blocked.
2007                         return true;
2008                     }
2009                     break;
2010             }
2011         }
2012
2013         // Only check the domain lists if the current domain is not null (like `about:blank`).
2014         if (currentDomain != null) {
2015             // Domain black list.
2016             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_BLACKLIST)) {
2017                 switch (blackListEntry.length) {
2018                     case 3:  // There is one entry.
2019                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
2020                             // Store the entry in the resource request log.
2021                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2022                                     String.valueOf(MainWebViewActivity.DOMAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2023
2024                             // Blocked.
2025                             return true;
2026                         }
2027                         break;
2028
2029                     case 4:  // There are two entries.
2030                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2])) {
2031                             // Store the entry in the resource request log.
2032                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2033                                     String.valueOf(MainWebViewActivity.DOMAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2034
2035                             // Blocked.
2036                             return true;
2037                         }
2038                         break;
2039
2040                     case 5:  // There are three entries.
2041                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3])) {
2042                             // Store the entry in the resource request log.
2043                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2044                                     String.valueOf(MainWebViewActivity.DOMAIN_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3],
2045                                     blackListEntry[4]});
2046
2047                             // Blocked.
2048                             return true;
2049                         }
2050                         break;
2051                 }
2052             }
2053
2054             // Domain initial black list.
2055             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_INITIAL_BLACKLIST)) {
2056                 // Store the entry in the resource request log.
2057                 if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.startsWith(blackListEntry[1])) {
2058                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2059                             String.valueOf(MainWebViewActivity.DOMAIN_INITIAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1],
2060                             blackListEntry[2]});
2061
2062                     // Blocked.
2063                     return true;
2064                 }
2065             }
2066
2067             // Domain final black list.
2068             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_FINAL_BLACKLIST)) {
2069                 switch (blackListEntry.length) {
2070                     case 3:  // There is one entry.
2071                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.endsWith(blackListEntry[1])) {
2072                             // Store the entry in the resource request log.
2073                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2074                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2075
2076                             // Blocked.
2077                             return true;
2078                         }
2079                         break;
2080
2081                     case 4:  // There are two entries.
2082                         if (currentDomain.endsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.endsWith(blackListEntry[2])) {
2083                             // Store the entry in the resource request log.
2084                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2085                                     String.valueOf(MainWebViewActivity.DOMAIN_FINAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2086
2087                             // Blocked.
2088                             return true;
2089                         }
2090                         break;
2091                 }
2092             }
2093
2094             // Domain regular expression black list.
2095             for (String[] blackListEntry : blockList.get(MainWebViewActivity.DOMAIN_REGULAR_EXPRESSION_BLACKLIST)) {
2096                 if (currentDomain.endsWith(blackListEntry[0]) && Pattern.matches(blackListEntry[1], resourceUrl)) {
2097                     // Store the entry in the resource request log.
2098                     MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2099                             String.valueOf(MainWebViewActivity.DOMAIN_REGULAR_EXPRESSION_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2100
2101                     // Blocked.
2102                     return true;
2103                 }
2104             }
2105         }
2106
2107         // Only check the third-party black lists if this is a third-party request.
2108         if (isThirdPartyRequest) {
2109             // Third-party black list.
2110             for (String[] blackListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_BLACKLIST)) {
2111                 switch (blackListEntry.length) {
2112                     case 2:  // There is one entry.
2113                         if (resourceUrl.contains(blackListEntry[0])) {
2114                             // Store the entry in the resource request log.
2115                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2116                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0], blackListEntry[1]});
2117
2118                             // Blocked.
2119                             return true;
2120                         }
2121                         break;
2122
2123                     case 3:  // There are two entries.
2124                         if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
2125                             // Store the entry in the resource request log.
2126                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2127                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});
2128
2129                             // Blocked.
2130                             return true;
2131                         }
2132                         break;
2133
2134                     case 4:  // There are three entries.
2135                         if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2])) {
2136                             // Store the entry in the resource request log.
2137                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2138                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2], blackListEntry[3]});
2139
2140                             // Blocked.
2141                             return true;
2142                         }
2143                         break;
2144
2145                     case 5:  // There are four entries.
2146                         if (resourceUrl.contains(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1]) && resourceUrl.contains(blackListEntry[2]) && resourceUrl.contains(blackListEntry[3])) {
2147                             // Store the entry in the resource request log.
2148                             MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2149                                     String.valueOf(MainWebViewActivity.THIRD_PARTY_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1] + "\n" + blackListEntry[2] + "\n" + blackListEntry[3],
2150                                     blackListEntry[4]});
2151
2152                             // Blocked.
2153                             return true;
2154                         }
2155                         break;
2156                 }
2157             }
2158
2159             // Third-party initial black list.
2160             for (String[] blackListEntry : blockList.get(MainWebViewActivity.THIRD_PARTY_INITIAL_BLACKLIST)) {
2161                 if (blackListEntry.length == 2) {  // There is one entry.
2162                     if (resourceUrl.startsWith(blackListEntry[0])) {
2163                         // Store the entry in the resource request log.
2164                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2165                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_INITIAL_BLACKLIST), blackListEntry[0], blackListEntry[1]});
2166
2167                         // Blocked.
2168                         return true;
2169                     }
2170                 } else {  // There are two entries.
2171                     if (resourceUrl.startsWith(blackListEntry[0]) && resourceUrl.contains(blackListEntry[1])) {
2172                         // Store the entry in the resource request log.
2173                         MainWebViewActivity.resourceRequests.add(new String[] {String.valueOf(MainWebViewActivity.REQUEST_BLOCKED), resourceUrl, BLOCK_LIST_NAME_STRING,
2174                                 String.valueOf(MainWebViewActivity.THIRD_PARTY_INITIAL_BLACKLIST), blackListEntry[0] + "\n" + blackListEntry[1], blackListEntry[2]});