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