Fully featured, open source, privacy friendly email app for Android
This report summarizes scanner evidence for M66B/FairEmail, a Java project with 4,743 GitHub stars. SynthScan examined 912,324 lines of code across 2295 source files, recording 331 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 2.5 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 159 finding(s).
Are imports declared and package/API names verified? 172 finding(s).
Are wrappers, guards, and repeated structures necessary? 2 finding(s).
Which changes need focused human review? 331 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 331 distinct pattern matches across 7 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL⚡ | index.html | 185 | at io.requery.android.database.sqlite.SQLiteConnection.nativeExecute(SourceFile:-2) | CODE |
| CRITICAL⚡ | index.html | 186 | at io.requery.android.database.sqlite.SQLiteConnection.execute(SQLiteConnection:595) | CODE |
| CRITICAL⚡ | index.html | 187 | at io.requery.android.database.sqlite.SQLiteSession.endTransactionUnchecked(SQLiteSession:447) | CODE |
| CRITICAL⚡ | index.html | 188 | at io.requery.android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession:411) | CODE |
| CRITICAL⚡ | index.html | 189 | at io.requery.android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase:551) | CODE |
| CRITICAL⚡ | FAQ.md | 192 | at io.requery.android.database.sqlite.SQLiteConnection.nativeExecute(SourceFile:-2) | CODE |
| CRITICAL⚡ | FAQ.md | 193 | at io.requery.android.database.sqlite.SQLiteConnection.execute(SQLiteConnection:595) | CODE |
| CRITICAL⚡ | FAQ.md | 194 | at io.requery.android.database.sqlite.SQLiteSession.endTransactionUnchecked(SQLiteSession:447) | CODE |
| CRITICAL⚡ | FAQ.md | 195 | at io.requery.android.database.sqlite.SQLiteSession.endTransaction(SQLiteSession:411) | CODE |
| CRITICAL⚡ | FAQ.md | 196 | at io.requery.android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase:551) | CODE |
| CRITICAL | app/src/main/java/androidx/room/TableInfo.java | 694 | ? Collections.nCopies(columns.size(), androidx.room.Index.Order.ASC.name()) | CODE |
| CRITICAL | …java/androidx/emoji2/text/flatbuffer/MetadataList.java | 34 | public androidx.emoji2.text.flatbuffer.MetadataItem.Vector listVector() { return listVector(new androidx.emoji2.text.f | CODE |
| CRITICAL | app/src/main/java/javax/mail/EventQueue.java | 165 | at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1248) | CODE |
| CRITICAL | app/src/main/java/javax/mail/EventQueue.java | 166 | at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:344) | CODE |
| CRITICAL | app/src/main/java/javax/mail/internet/MimeUtility.java | 1340 | javax.mail.internet.MimeUtility.class.getResourceAsStream( | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/MessageHelper.java | 4965 | if (!org.apache.poi.hsmf.datatypes.MAPIProperty.RTF_COMPRESSED.equals(attr.getProperty()) && | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/MessageHelper.java | 4966 | !org.apache.poi.hsmf.datatypes.MAPIProperty.BODY_HTML.equals(attr.getProperty())) | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/MessageHelper.java | 5329 | at com.sun.mail.util.ASCIIUtility.getBytes(ASCIIUtility:279) | CODE |
| CRITICAL | …p/src/main/java/eu/faircode/email/EditTextCompose.java | 833 | // at com.android.internal.inputmethod.EditableInputConnection.commitText(EditableInputConnection | COMMENT |
| CRITICAL | …/src/main/java/eu/faircode/email/EncryptionHelper.java | 34 | at org.apache.harmony.security.utils.JarUtils.verifySignature(JarUtils.java:223) | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/FragmentOAuth.java | 440 | at net.openid.appauth.browser.CustomTabManager.bind(SourceFile:27) | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/EditTextPlain.java | 88 | at com.android.internal.widget.EditableInputConnection.commitText(EditableInputConnection.ja | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/EditTextPlain.java | 91 | at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper. | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/EditTextPlain.java | 113 | at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.ja | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/ActivityMain.java | 424 | java.lang.NullPointerException: Attempt to invoke virtual method 'int com.android.se | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/ActivityMain.java | 439 | at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/ActivityMain.java | 444 | at com.android.server.am.TaskChangeNotificationController.forAllLocalListeners(T | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/ActivityMain.java | 445 | at com.android.server.am.TaskChangeNotificationController.notifyTaskStackChanged | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/Helper.java | 1371 | E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/Helper.java | 2783 | at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuB | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/Helper.java | 2784 | at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:157) | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/Helper.java | 2785 | at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder. | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/Helper.java | 2786 | at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder. | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/Helper.java | 3370 | at androidx.core.hardware.fingerprint.FingerprintManagerCompat.isHardwareDetected(SourceFile:3) | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/Helper.java | 3627 | at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941) | CODE |
| CRITICAL | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 1115 | at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 1986 | at com.sun.mail.imap.IMAPFolder.open(SourceFile:61) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 1987 | at com.sun.mail.imap.IMAPFolder.open(SourceFile:1) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 1993 | at com.sun.mail.iap.Protocol.handleResult(SourceFile:8) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 1994 | at com.sun.mail.imap.protocol.IMAPProtocol.select(SourceFile:19) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 1995 | at com.sun.mail.imap.IMAPFolder.open(SourceFile:16) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2004 | at com.sun.mail.imap.IMAPFolder.open(SourceFile:61) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2005 | at com.sun.mail.imap.IMAPFolder.open(SourceFile:1) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2016 | at com.sun.mail.iap.Protocol.handleResult(SourceFile:8) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2017 | at com.sun.mail.imap.protocol.IMAPProtocol.select(SourceFile:19) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2018 | at com.sun.mail.imap.IMAPFolder.open(SourceFile:16) | CODE |
| CRITICAL | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2117 | at com.sun.mail.imap.IMAPFolder.handleIdle(SourceFile:252) | CODE |
| CRITICAL | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2118 | at com.sun.mail.imap.IMAPFolder.idle(SourceFile:7) | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2383 | at com.sun.mail.imap.IMAPFolder.open(SourceF | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2384 | at com.sun.mail.imap.IMAPFolder.open(SourceF | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2393 | at com.sun.mail.iap.Protocol.handleResult(So | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2394 | at com.sun.mail.imap.protocol.IMAPProtocol.s | CODE |
| CRITICAL⚡ | …rc/main/java/eu/faircode/email/ServiceSynchronize.java | 2395 | at com.sun.mail.imap.IMAPFolder.open(SourceF | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/StyleHelper.java | 1933 | at androidx.core.content.res.ResourcesCompat.loadFont(SourceFile:17) | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/StyleHelper.java | 1934 | at androidx.core.content.res.ResourcesCompat.loadFont(SourceFile:3) | CODE |
| CRITICAL⚡ | app/src/main/java/eu/faircode/email/StyleHelper.java | 1935 | at androidx.core.content.res.ResourcesCompat.getFont(SourceFile:2) | CODE |
| CRITICAL | …p/src/main/java/eu/faircode/email/FixedScrollView.java | 94 | at com.android.internal.policy.DecorView.onLayout(DecorView.java:889) | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/Core.java | 2837 | 06-21 10:02:38.035 9927 10024 E fairemail: at com.sun.mail.imap.IMAPStore.newIMAPFolder(Source | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/Core.java | 2838 | 06-21 10:02:38.035 9927 10024 E fairemail: at com.sun.mail.imap.DefaultFolder.listSubscribed(S | CODE |
| CRITICAL | app/src/main/java/eu/faircode/email/Core.java | 3816 | at com.sun.mail.pop3.POP3Message.loadHeaders(SourceFile:15) | CODE |
| 110 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | app/src/extra/java/eu/faircode/email/Bimi.java | 241 | // https://datatracker.ietf.org/doc/html/rfc3709#page-6 | COMMENT |
| LOW | app/src/main/java/androidx/emoji2/text/EmojiCompat.java | 561 | @SuppressWarnings("GuardedBy") // same rationale as double-check lock | COMMENT |
| LOW | …/androidx/recyclerview/selection/SelectionTracker.java | 781 | ResetManager<K> resetMgr = new ResetManager<>(); | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/MessageHelper.java | 381 | // Flags | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/MessageHelper.java | 3221 | // Stamp = From-domain By-domain Opt-info ";" FWS date-time | COMMENT |
| LOW | …/main/java/eu/faircode/email/AlarmManagerCompatEx.java | 41 | try { | COMMENT |
| LOW | …p/src/main/java/eu/faircode/email/EditTextCompose.java | 821 | COMMENT | |
| LOW | app/src/main/java/eu/faircode/email/EmailProvider.java | 781 | Log.i("Name=" + display); | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/Core.java | 641 | // com.sun.mail.iap.BadCommandException: BAD [TOOBIG] Message too large | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/Core.java | 661 | // Fetch: BAD Error in IMAP command FETCH: Invalid messageset (n.nnn + n .nnn secs). | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/Core.java | 681 | // Move: NO mailbox selected READ-ONLY | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/Core.java | 701 | // Add: NO [OVERQUOTA] Quota exceeded (mailbox for user is full) (n.nnn + n.nnn secs). | COMMENT |
| LOW | …/src/main/java/eu/faircode/email/ConnectionHelper.java | 761 | COMMENT | |
| LOW | app/src/main/java/eu/faircode/email/Log.java | 381 | } | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/Log.java | 401 | // at android.os.BaseBundle.initializeFromParcelLocked(BaseBundle.java:273) | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/Log.java | 1601 | COMMENT | |
| LOW | app/src/main/java/eu/faircode/email/EmailService.java | 181 | // org.bouncycastle.jsse.client.dh.minimumPrimeBits: Integer property, default 2048, | COMMENT |
| LOW | app/src/main/java/eu/faircode/email/ApplicationEx.java | 341 | WorkerSync.init(this); | COMMENT |
| LOW | …c/main/java/eu/faircode/email/FragmentDialogPrint.java | 481 | PrintDocumentAdapter adapter = printWebView.createPrintDocumentAdapter(jobName); | COMMENT |
| LOW | app/src/main/jni/cld_3/protos/task_spec.pb.h | 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! | COMMENT |
| LOW | app/src/main/jni/cld_3/protos/task_spec.pb.h | 21 | COMMENT | |
| LOW | app/src/main/jni/cld_3/protos/sentence.pb.h | 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! | COMMENT |
| LOW | app/src/main/jni/cld_3/protos/sentence.pb.h | 21 | COMMENT | |
| LOW | app/src/main/jni/cld_3/protos/feature_extractor.pb.h | 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! | COMMENT |
| LOW | app/src/main/jni/cld_3/protos/feature_extractor.pb.h | 21 | COMMENT | |
| LOW | app/src/main/jni/cld_3/src/feature_types.h | 21 | #include <algorithm> | COMMENT |
| LOW | app/src/main/jni/cld_3/src/feature_types.h | 61 | COMMENT | |
| LOW | app/src/main/jni/cld_3/src/feature_types.h | 121 | }; | COMMENT |
| LOW | …/src/main/jni/cld_3/src/language_identifier_features.h | 21 | #include "feature_extractor.h" | COMMENT |
| LOW | …/src/main/jni/cld_3/src/language_identifier_features.h | 41 | FeatureValue GetDomainSize() const override; | COMMENT |
| LOW | …/src/main/jni/cld_3/src/language_identifier_features.h | 81 | // in the input). Otherwise, weighs each unique ngram by (ngram count) / | COMMENT |
| LOW | app/src/main/jni/cld_3/src/casts.h | 21 | #ifndef CASTS_H_ | COMMENT |
| LOW | app/src/main/jni/cld_3/src/casts.h | 41 | // int i = * reinterpret_cast<int*>(&f); // WRONG | COMMENT |
| LOW | app/src/main/jni/cld_3/src/casts.h | 61 | // | COMMENT |
| LOW | app/src/main/jni/cld_3/src/unicodetext.h | 1 | // Copyright (C) 2006 Google Inc. | COMMENT |
| LOW | app/src/main/jni/cld_3/src/unicodetext.h | 21 | #include <utility> | COMMENT |
| LOW | app/src/main/jni/cld_3/src/unicodetext.h | 41 | // 0x10FFFF], but UnicodeText has the additional restriction that it | COMMENT |
| LOW | app/src/main/jni/cld_3/src/fml_parser.h | 21 | // | COMMENT |
| LOW | app/src/main/jni/cld_3/src/registry.h | 21 | // | COMMENT |
| LOW | app/src/main/jni/cld_3/src/registry.h | 41 | // | COMMENT |
| LOW | app/src/main/jni/cld_3/src/workspace.h | 21 | #define WORKSPACE_H_ | COMMENT |
| LOW | app/src/main/jni/cld_3/src/float16.h | 21 | #include "base.h" | COMMENT |
| LOW | app/src/main/jni/cld_3/src/feature_extractor.h | 21 | // A feature extractor consists of a hierarchy of feature functions. Each | COMMENT |
| LOW | app/src/main/jni/cld_3/src/feature_extractor.h | 41 | #include <string> | COMMENT |
| LOW | app/src/main/jni/cld_3/src/feature_extractor.h | 121 | // The generic feature extractor is the type-independent part of a feature | COMMENT |
| LOW | app/src/main/jni/cld_3/src/feature_extractor.h | 201 | COMMENT | |
| LOW | app/src/main/jni/cld_3/src/feature_extractor.h | 321 | // OBJ: The "object" from which features are extracted; e.g., a sentence. This | COMMENT |
| LOW | app/src/main/jni/cld_3/src/feature_extractor.h | 381 | // are of type NES, which may be different from the type of the parent function. | COMMENT |
| LOW | …p/src/main/jni/cld_3/src/embedding_feature_extractor.h | 21 | #include <vector> | COMMENT |
| LOW | app/src/main/jni/cld_3/src/nnet_language_identifier.h | 21 | #include "base.h" | COMMENT |
| LOW | app/src/main/jni/cld_3/src/nnet_language_identifier.h | 81 | // bytes and max_num_bytes_. If N is less than min_num_bytes_ long, then this | COMMENT |
| LOW | app/src/main/jni/cld_3/src/nnet_language_identifier.h | 161 | ContinuousBagOfNgramsFunction ngram_function_; | COMMENT |
| LOW | app/src/main/jni/cld_3/src/relevant_script_feature.h | 21 | #include "sentence_features.h" | COMMENT |
| LOW | app/src/main/jni/cld_3/src/embedding_network_params.h | 141 | // are treated as repeated fields with 0 or 1 instances. As such, we have | COMMENT |
| LOW | app/src/main/jni/cld_3/src/embedding_network.h | 21 | #include "embedding_network_params.h" | COMMENT |
| LOW | app/src/main/jni/cld_3/src/base.h | 41 | #define CLD3_DISALLOW_COPY_AND_ASSIGN(TypeName) \ | COMMENT |
| LOW | app/src/main/jni/cld_3/src/base.h | 81 | (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) | COMMENT |
| LOW | app/src/main/jni/cld_3/src/script_span/stringpiece.h | 1 | // Copyright 2013 Google Inc. All Rights Reserved. | COMMENT |
| LOW | app/src/main/jni/cld_3/src/script_span/port.h | 1 | // Copyright 2013 Google Inc. All Rights Reserved. | COMMENT |
| LOW | app/src/main/jni/cld_3/src/script_span/port.h | 21 | COMMENT | |
| 93 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | …dx/recyclerview/selection/DefaultSelectionTracker.java | 363 | // representation of it. But there are some nuanced areas cases where | COMMENT |
| MEDIUM | …idx/recyclerview/selection/GestureSelectionHelper.java | 152 | // Essentially, since this means all gesture movement is over, reset everything and apply | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | FAQ.md | 1505 | If you can't solve the problem, [please contact me](#get-support), and I'll explain how to send the debug info for a pro | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | app/src/main/res/layout/include_message_addresses.xml | 364 | android:text="user@example.org" | CODE |
| LOW | decrypt/purify.min.js | 2 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | app/src/main/java/javax/mail/internet/MimeBodyPart.java | 1690 | static class MimePartDataHandler extends DataHandler { | CODE |
| LOW | app/src/main/java/javax/activation/DataHandler.java | 69 | public class DataHandler /*implements Transferable*/ { | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | app/src/main/java/javax/mail/package.html | 67 | Don't forget to see the | CODE |