Functional Scope (In-Scope)
- Nested Folder Tree: A recursive folder hierarchy enabling explicit, exclusive email moves and placement tree navigation.
- Thread Grouping Chains: Reconstructing interactive conversations by grouping emails matching mutual parent/references headers.
- Weighted Inverted Search Index: Scoring query matches over subject (3x weight) and body tokens (1x weight) to return ranked email lists.
- Inbound Filtering Router: Automating folder assignment triggers based on sender addresses or text keyword checks.
- Folder Pagination: Maintaining performant scrolling and bounded payload memory by pulling emails inside structured indices.
Explicit Boundaries (Out-of-Scope)
- Low-Level Protocol Transport: Writing socket parsers for actual SMTP, IMAP, or POP3 packet handlers.
- Rich-Text / HTML Parser: Rendering complex layouts, inline styling, CSS formatting, or sanitizing malicious scripting inside sandboxes.
Clean reference designs demonstrating search token index and routing rules in Java and Python:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.*;
class Email {
private final String id;
private final String sender;
private final List<String> recipients;
private final String subject;
private final String body;
private final List<String> attachments;
private volatile boolean read;
private final String messageId;
private final String inReplyTo; // Parent message ID
private volatile String threadId;
public Email(String id, String sender, List<String> recipients, String subject, String body, List<String> attachments, String messageId, String inReplyTo) {
this.id = id;
this.sender = sender;
this.recipients = recipients;
this.subject = subject;
this.body = body;
this.attachments = attachments;
this.read = false;
this.messageId = messageId;
this.inReplyTo = inReplyTo;
}
public String getId() { return id; }
public String getSender() { return sender; }
public List<String> getRecipients() { return recipients; }
public String getSubject() { return subject; }
public String getBody() { return body; }
public List<String> getAttachments() { return attachments; }
public boolean isRead() { return read; }
public void setRead(boolean read) { this.read = read; }
public String getMessageId() { return messageId; }
public String getInReplyTo() { return inReplyTo; }
public String getThreadId() { return threadId; }
public void setThreadId(String threadId) { this.threadId = threadId; }
@Override
public String toString() {
return "Email{id='" + id + "', sender='" + sender + "', subject='" + subject + "', threadId='" + threadId + "'}";
}
}
class Folder {
private final String id;
private final String name;
private final String parentId;
private final Set<String> emailIds = ConcurrentHashMap.newKeySet();
public Folder(String id, String name, String parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
public String getId() { return id; }
public String getName() { return name; }
public String getParentId() { return parentId; }
public Set<String> getEmailIds() { return emailIds; }
}
interface FilterStrategy {
boolean matches(Email email);
}
class SenderFilterStrategy implements FilterStrategy {
private final String pattern;
public SenderFilterStrategy(String pattern) { this.pattern = pattern; }
@Override public boolean matches(Email email) { return email.getSender().contains(pattern); }
}
class SubjectFilterStrategy implements FilterStrategy {
private final String keyword;
public SubjectFilterStrategy(String keyword) { this.keyword = keyword; }
@Override public boolean matches(Email email) { return email.getSubject().toLowerCase().contains(keyword.toLowerCase()); }
}
class FilterRule {
private final FilterStrategy strategy;
private final String targetFolderId;
public FilterRule(FilterStrategy strategy, String targetFolderId) {
this.strategy = strategy;
this.targetFolderId = targetFolderId;
}
public boolean matches(Email email) {
return strategy.matches(email);
}
public String getTargetFolderId() { return targetFolderId; }
}
class FilterStrategyFactory {
public static FilterStrategy createSenderFilter(String pattern) {
return new SenderFilterStrategy(pattern);
}
public static FilterStrategy createSubjectFilter(String keyword) {
return new SubjectFilterStrategy(keyword);
}
}
class SearchIndex {
private final Map<String, Map<String, Integer>> subjectIndex = new ConcurrentHashMap<>();
private final Map<String, Map<String, Integer>> bodyIndex = new ConcurrentHashMap<>();
public void index(Email email) {
indexText(email.getId(), email.getSubject(), subjectIndex);
indexText(email.getId(), email.getBody(), bodyIndex);
}
private void indexText(String emailId, String text, Map<String, Map<String, Integer>> index) {
if (text == null) return;
// Using bracket-range split to prevent backslash escapes issue under Next.js Turbopack
String[] tokens = text.toLowerCase().split("[^a-zA-Z0-9]+");
for (String token : tokens) {
if (token.isEmpty()) continue;
index.computeIfAbsent(token, k -> new ConcurrentHashMap<>())
.merge(emailId, 1, Integer::sum);
}
}
public List<String> search(String query) {
if (query == null || query.trim().isEmpty()) return Collections.emptyList();
String[] tokens = query.toLowerCase().split("[^a-zA-Z0-9]+");
Map<String, Double> scores = new HashMap<>();
for (String token : tokens) {
if (token.isEmpty()) continue;
Map<String, Integer> subMatches = subjectIndex.get(token);
if (subMatches != null) {
for (Map.Entry<String, Integer> entry : subMatches.entrySet()) {
scores.merge(entry.getKey(), entry.getValue() * 3.0, Double::sum);
}
}
Map<String, Integer> bodyMatches = bodyIndex.get(token);
if (bodyMatches != null) {
for (Map.Entry<String, Integer> entry : bodyMatches.entrySet()) {
scores.merge(entry.getKey(), entry.getValue() * 1.0, Double::sum);
}
}
}
List<Map.Entry<String, Double>> sorted = new ArrayList<>(scores.entrySet());
sorted.sort((a, b) -> Double.compare(b.getValue(), a.getValue()));
List<String> results = new ArrayList<>();
for (Map.Entry<String, Double> entry : sorted) {
results.add(entry.getKey());
}
return results;
}
}
class EmailClient {
private final Map<String, Email> emails = new ConcurrentHashMap<>();
private final Map<String, Folder> folders = new ConcurrentHashMap<>();
private final SearchIndex searchIndex = new SearchIndex();
private final List<FilterRule> filterRules = new CopyOnWriteArrayList<>();
public EmailClient() {
createFolder("INBOX", "Inbox", null);
}
public void createFolder(String id, String name, String parentId) {
folders.put(id, new Folder(id, name, parentId));
}
public void addFilterRule(FilterRule rule) {
filterRules.add(rule);
}
public void receiveEmail(Email email) {
emails.put(email.getId(), email);
searchIndex.index(email);
resolveThreading(email);
String targetFolderId = "INBOX";
for (FilterRule rule : filterRules) {
if (rule.matches(email)) {
targetFolderId = rule.getTargetFolderId();
break;
}
}
moveEmail(email.getId(), targetFolderId);
}
private void resolveThreading(Email email) {
if (email.getInReplyTo() != null && emails.containsKey(email.getInReplyTo())) {
Email parent = emails.get(email.getInReplyTo());
email.setThreadId(parent.getThreadId());
} else {
email.setThreadId(email.getId());
}
}
public void moveEmail(String emailId, String targetFolderId) {
Email email = emails.get(emailId);
if (email == null) return;
// Remove from any folder it's currently inside
for (Folder folder : folders.values()) {
folder.getEmailIds().remove(emailId);
}
Folder target = folders.computeIfAbsent(targetFolderId, k -> new Folder(k, k, null));
target.getEmailIds().add(emailId);
}
public List<Email> getFolderEmailsPaginated(String folderId, int page, int pageSize) {
Folder folder = folders.get(folderId);
if (folder == null) return Collections.emptyList();
List<String> ids = new ArrayList<>(folder.getEmailIds());
int start = Math.min(page * pageSize, ids.size());
int end = Math.min(start + pageSize, ids.size());
List<Email> paged = new ArrayList<>();
for (int i = start; i < end; i++) {
paged.add(emails.get(ids.get(i)));
}
return paged;
}
public List<Email> search(String query) {
List<String> matchedIds = searchIndex.search(query);
List<Email> list = new ArrayList<>();
for (String id : matchedIds) {
list.add(emails.get(id));
}
return list;
}
}
public class Main {
public static void main(String[] args) {
System.out.println("=== STARTING EMAIL CLIENT SIMULATION ===");
EmailClient client = new EmailClient();
// 1. Setup Folder Structure and Filtering Rules
client.createFolder("WORK", "Work-related", null);
client.createFolder("PROMOTION", "Marketing Deals", null);
// Filter: Sender contains "boss" -> WORK folder
client.addFilterRule(new FilterRule(FilterStrategyFactory.createSenderFilter("boss"), "WORK"));
// Filter: Subject contains "discount" -> PROMOTION folder
client.addFilterRule(new FilterRule(FilterStrategyFactory.createSubjectFilter("discount"), "PROMOTION"));
// 2. Receive diverse emails
System.out.println("Receiving incoming emails...");
Email normal = new Email("m1", "friend@gmail.com", List.of("user@me.com"), "Weekend plans", "Hi, are we meeting up?", null, "msg-001", null);
Email work = new Email("m2", "boss@company.com", List.of("user@me.com"), "Urgent Project", "Please review the security audit sheets immediately.", null, "msg-002", null);
Email promo = new Email("m3", "deals@store.com", List.of("user@me.com"), "Big discount inside!", "Get 50% off storewide today only.", null, "msg-003", null);
Email threadReply = new Email("m4", "boss@company.com", List.of("user@me.com"), "Re: Urgent Project", "Thanks for the feedback.", null, "msg-004", "m2");
client.receiveEmail(normal);
client.receiveEmail(work);
client.receiveEmail(promo);
client.receiveEmail(threadReply);
// 3. Verify folders
System.out.println("\n--- Folder Auditing ---");
System.out.println("INBOX Emails: " + client.getFolderEmailsPaginated("INBOX", 0, 10));
System.out.println("WORK Emails: " + client.getFolderEmailsPaginated("WORK", 0, 10));
System.out.println("PROMOTION Emails: " + client.getFolderEmailsPaginated("PROMOTION", 0, 10));
// 4. Verify threading links
System.out.println("\n--- Thread Identification ---");
System.out.println("Parent email (m2) threadId: " + work.getThreadId());
System.out.println("Reply email (m4) threadId (should match parent): " + threadReply.getThreadId());
// 5. Query full text index
System.out.println("\n--- Full Text Search Queries ---");
System.out.println("Search 'security audit' (work matched):");
for (Email e : client.search("security audit")) {
System.out.println(" Matched: " + e);
}
System.out.println("Search 'discount' (promo matched):");
for (Email e : client.search("discount")) {
System.out.println(" Matched: " + e);
}
System.out.println("=== EMAIL CLIENT SIMULATION COMPLETE ===");
}
}