diff --git a/src/common/commonUtils.js b/src/common/commonUtils.js
index 5784da1..3e0be66 100644
--- a/src/common/commonUtils.js
+++ b/src/common/commonUtils.js
@@ -32,3 +32,12 @@
   }
   return undefined;
 }
+
+/**
+ * Utility to indicate that a class method should be implemented (similarly to
+ * abstract methods in Java).
+ */
+export function shouldImplement(name) {
+  throw new Error(
+      `The ${name} method should be implemented by the extending class.`);
+}
diff --git a/src/contentScripts/communityConsole/extraInfo.js b/src/contentScripts/communityConsole/extraInfo.js
deleted file mode 100644
index 2efe634..0000000
--- a/src/contentScripts/communityConsole/extraInfo.js
+++ /dev/null
@@ -1,977 +0,0 @@
-import {MDCTooltip} from '@material/tooltip';
-import {waitFor} from 'poll-until-promise';
-
-import {parseUrl} from '../../common/commonUtils.js';
-import OptionsWatcher from '../../common/optionsWatcher.js';
-import {createPlainTooltip} from '../../common/tooltip.js';
-
-import {createExtBadge, getDisplayLanguage} from './utils/common.js';
-import PerForumStatsSection from './utils/PerForumStatsSection.js';
-
-const kViewUnifiedUserResponseEvent = 'TWPT_ViewUnifiedUserResponse';
-const kListCannedResponsesResponse = 'TWPT_ListCannedResponsesResponse';
-const kViewThreadResponse = 'TWPT_ViewThreadResponse';
-const kViewForumRequest = 'TWPT_ViewForumRequest';
-const kViewForumResponse = 'TWPT_ViewForumResponse';
-
-// Used to match each category with the corresponding string.
-const kAbuseCategories = [
-  ['1', 'account'],
-  ['2', 'displayname'],
-  ['3', 'avatar'],
-];
-const kAbuseViolationCategories = {
-  0: 'NO_VIOLATION',
-  1: 'COMMUNITY_POLICY_VIOLATION',
-  2: 'LEGAL_VIOLATION',
-  3: 'CSAI_VIOLATION',
-  4: 'OTHER_VIOLATION',
-};
-const kAbuseViolationCategoriesI18n = {
-  0: 'noviolation',
-  1: 'communitypolicy',
-  2: 'legal',
-  3: 'csai',
-  4: 'other',
-};
-
-// The following array will appear in the interface as is (without being
-// translated).
-const kAbuseViolationTypes = {
-  0: 'UNSPECIFIED',
-  23: 'ACCOUNT_DISABLED',
-  55: 'ACCOUNT_HAS_SERVICES_DISABLED',
-  35: 'ACCOUNT_HIJACKED',
-  96: 'ACCOUNT_LEAKED_CREDENTIALS',
-  92: 'ACCOUNT_NOT_SUPPORTED',
-  81: 'ARTISTIC_NUDITY',
-  66: 'BAD_BEHAVIOR_PATTERN',
-  78: 'BAD_ENGAGEMENT_BEHAVIOR_PATTERN',
-  79: 'BORDERLINE_HARASSMENT',
-  80: 'BORDERLINE_HATE_SPEECH',
-  38: 'BOTNET',
-  32: 'BRANDING_VIOLATION',
-  100: 'CAPITALIZING_TRAGIC_EVENTS',
-  105: 'CLOAKING',
-  49: 'COIN_MINING',
-  7: 'COMMERCIAL_CONTENT',
-  97: 'COPPA_REGULATED',
-  57: 'COPYRIGHT_CIRCUMVENTION',
-  8: 'COPYRIGHTED_CONTENT',
-  58: 'COURT_ORDER',
-  51: 'CSAI',
-  94: 'CSAI_INSPECT',
-  52: 'CSAI_CARTOON_HUMOR',
-  53: 'CSAI_SOLICITATION',
-  108: 'CSAI_NON_APPARENT',
-  67: 'DANGEROUS',
-  37: 'DATA_SCRAPING',
-  86: 'DECEPTIVE_OAUTH_IMPLEMENTATION',
-  46: 'DEFAMATORY_CONTENT',
-  36: 'DELINQUENT_BILLING',
-  30: 'DISRUPTION_ATTEMPT',
-  112: 'DOMESTIC_INTERFERENCE',
-  22: 'DOS',
-  9: 'DUPLICATE_CONTENT',
-  68: 'DUPLICATE_LOCAL_PAGE',
-  121: 'NON_QUALIFYING_ORGANIZATION',
-  115: 'EGREGIOUS_INTERACTION_WITH_MINOR',
-  83: 'ENGAGEMENT_COLLUSION',
-  41: 'EXPLOIT_ATTACKS',
-  65: 'FAKE_USER',
-  2: 'FRAUD',
-  21: 'FREE_TRIAL_VIOLATION',
-  43: 'GIBBERISH',
-  101: 'FOREIGN_INTERFERENCE',
-  59: 'GOVERNMENT_ORDER',
-  10: 'GRAPHICAL_VIOLENCE',
-  11: 'HARASSMENT',
-  12: 'HATE_SPEECH',
-  90: 'IDENTICAL_PRODUCT_NAME',
-  60: 'ILLEGAL_DRUGS',
-  13: 'IMPERSONATION',
-  69: 'IMPERSONATION_WITH_PII',
-  116: 'INAPPROPRIATE_INTERACTION_WITH_MINOR',
-  45: 'INAPPROPRIATE_CONTENT_SPEECH',
-  106: 'INTENTIONAL_THWARTING',
-  27: 'INTRUSION_ATTEMPT',
-  87: 'INVALID_API_USAGE',
-  14: 'INVALID_CONTENT',
-  20: 'INVALID_GCE_USAGE',
-  120: 'INVALID_STORAGE_USAGE',
-  15: 'INVALID_IMAGE_QUALITY',
-  88: 'INVALID_API_PRIVACY_POLICY_DISCLOSURE',
-  54: 'INVALID_USAGE_OF_IP_PROXYING',
-  99: 'KEYWORD_STUFFING',
-  61: 'LEGAL_COUNTERFEIT',
-  62: 'LEGAL_EXPORT',
-  63: 'LEGAL_PRIVACY',
-  33: 'LEGAL_REVIEW',
-  91: 'LEGAL_PROTECTED',
-  70: 'LOW_QUALITY_CONTENT',
-  93: 'LOW_REPUTATION_PHONE_NUMBER',
-  6: 'MALICIOUS_SOFTWARE',
-  40: 'MALWARE',
-  113: 'MISLEADING',
-  114: 'MISREP_OF_ID',
-  89: 'MEMBER_OF_ABUSIVE_GCE_NETWORK',
-  84: 'NON_CONSENSUAL_EXPLICIT_IMAGERY',
-  1: 'NONE',
-  102: 'OFF_TOPIC',
-  31: 'OPEN_PROXY',
-  28: 'PAYMENT_FRAUD',
-  16: 'PEDOPHILIA',
-  71: 'PERSONAL_INFORMATION_CONTENT',
-  25: 'PHISHING',
-  34: 'POLICY_REVIEW',
-  17: 'PORNOGRAPHY',
-  29: 'QUOTA_CIRCUMVENTION',
-  72: 'QUOTA_EXCEEDED',
-  73: 'REGULATED',
-  24: 'REPEATED_POLICY_VIOLATION',
-  104: 'RESOURCE_COMPROMISED',
-  107: 'REWARD_PROGRAMS_ABUSE',
-  74: 'ROGUE_PHARMA',
-  82: 'ESCORT',
-  75: 'SPAMMY_LOCAL_VERTICAL',
-  39: 'SEND_EMAIL_SPAM',
-  117: 'SEXTORTION',
-  118: 'SEX_TRAFFICKING',
-  44: 'SEXUALLY_EXPLICIT_CONTENT',
-  3: 'SHARDING',
-  95: 'SOCIAL_ENGINEERING',
-  109: 'SUSPICIOUS',
-  19: 'TRADEMARK_CONTENT',
-  50: 'TRAFFIC_PUMPING',
-  76: 'UNSAFE_RACY',
-  103: 'UNUSUAL_ACTIVITY_ALERT',
-  64: 'UNWANTED_CONTENT',
-  26: 'UNWANTED_SOFTWARE',
-  77: 'VIOLENT_EXTREMISM',
-  119: 'UNAUTH_IMAGES_OF_MINORS',
-  85: 'UNAUTHORIZED_SERVICE_RESELLING',
-  98: 'CSAI_EXTERNAL',
-  5: 'SPAM',
-  4: 'UNSAFE',
-  47: 'CHILD_PORNOGRAPHY_INCITATION',
-  18: 'TERRORISM_SUPPORT',
-  56: 'CSAI_WORST_OF_WORST',
-};
-
-// These values will be translated
-const kItemMetadataStateI18n = {
-  1: 'published',
-  2: 'draft',
-  3: 'automated_abuse_take_down_hide2',
-  4: 'automated_abuse_take_down_delete2',
-  13: 'automated_abuse_reinstate2',
-  10: 'automated_off_topic_hide2',
-  14: 'automated_flagged_pending_manual_review2',
-  5: 'user_flagged_pending_manual_review',
-  6: 'owner_deleted',
-  7: 'manual_take_down_hide2',
-  17: 'manual_profile_take_down_suspend2',
-  8: 'manual_take_down_delete2',
-  18: 'reinstate_profile_takedown2',
-  9: 'reinstate_abuse_takedown2',
-  11: 'clear_off_topic2',
-  12: 'confirm_off_topic2',
-  15: 'googler_off_topic_hide2',
-  16: 'expert_flagged_pending_manual_review',
-};
-const kItemMetadataState = {
-  0: 'UNDEFINED',
-  1: 'PUBLISHED',
-  2: 'DRAFT',
-  3: 'AUTOMATED_ABUSE_TAKE_DOWN_HIDE',
-  4: 'AUTOMATED_ABUSE_TAKE_DOWN_DELETE',
-  13: 'AUTOMATED_ABUSE_REINSTATE',
-  10: 'AUTOMATED_OFF_TOPIC_HIDE',
-  14: 'AUTOMATED_FLAGGED_PENDING_MANUAL_REVIEW',
-  5: 'USER_FLAGGED_PENDING_MANUAL_REVIEW',
-  6: 'OWNER_DELETED',
-  7: 'MANUAL_TAKE_DOWN_HIDE',
-  17: 'MANUAL_PROFILE_TAKE_DOWN_SUSPEND',
-  8: 'MANUAL_TAKE_DOWN_DELETE',
-  18: 'REINSTATE_PROFILE_TAKEDOWN',
-  9: 'REINSTATE_ABUSE_TAKEDOWN',
-  11: 'CLEAR_OFF_TOPIC',
-  12: 'CONFIRM_OFF_TOPIC',
-  15: 'GOOGLER_OFF_TOPIC_HIDE',
-  16: 'EXPERT_FLAGGED_PENDING_MANUAL_REVIEW',
-};
-
-export default class ExtraInfo {
-  constructor() {
-    this.lastProfile = {
-      body: {},
-      id: -1,
-      timestamp: 0,
-    };
-    this.lastCRsList = {
-      body: {},
-      id: -1,
-      duplicateNames: new Set(),
-    };
-    this.lastThread = {
-      body: {},
-      id: -1,
-      timestamp: 0,
-    };
-    // Threads currently loaded in the thread list
-    this.lastThreadListThreads = [];
-    this.lastThreadListTimestamp = 0;
-    this.lastThreadListIsFirst = null;
-    this.lastThreadListRequestId = -1;
-    this.displayLanguage = getDisplayLanguage();
-    this.optionsWatcher = new OptionsWatcher(['extrainfo', 'perforumstats']);
-    this.setUpHandlers();
-  }
-
-  setUpHandlers() {
-    window.addEventListener(kViewUnifiedUserResponseEvent, e => {
-      if (e.detail.id < this.lastProfile.id) return;
-
-      this.lastProfile = {
-        body: e.detail.body,
-        id: e.detail.id,
-        timestamp: Date.now(),
-      };
-    });
-    window.addEventListener(kListCannedResponsesResponse, e => {
-      if (e.detail.id < this.lastCRsList.id) return;
-
-      // Look if there are duplicate names
-      const crs = e.detail.body?.['1'] ?? [];
-      const names = crs.map(cr => cr?.['7']).slice().sort();
-      let duplicateNames = new Set();
-      for (let i = 1; i < names.length; i++)
-        if (names[i - 1] == names[i]) duplicateNames.add(names[i]);
-
-      this.lastCRsList = {
-        body: e.detail.body,
-        id: e.detail.id,
-        duplicateNames,
-      };
-    });
-    window.addEventListener(kViewThreadResponse, e => {
-      if (e.detail.id < this.lastThread.id) return;
-
-      this.lastThread = {
-        body: e.detail.body,
-        id: e.detail.id,
-        timestamp: Date.now(),
-      };
-    });
-    window.addEventListener(kViewThreadResponse, e => {
-      if (e.detail.id < this.lastThread.id) return;
-
-      this.lastThread = {
-        body: e.detail.body,
-        id: e.detail.id,
-        timestamp: Date.now(),
-      };
-    });
-    window.addEventListener(kViewForumRequest, e => {
-      // Ignore ViewForum requests made by the chat feature and the "Mark as
-      // duplicate" dialog.
-      //
-      // All those requests have |maxNum| set to 10 and 20 respectively, while
-      // the requests that we want to handle are the ones to initially load the
-      // thread list (which currently requests 100 threads) and the ones to load
-      // more threads (which request 50 threads).
-      let maxNum = e.detail.body?.['2']?.['1']?.['2'];
-      if (maxNum != 10 && maxNum != 20) {
-        this.lastThreadListRequestId = e.detail.id;
-        this.lastThreadListIsFirst =
-            !e.detail.body?.['2']?.['1']?.['3']?.['2'];  // Pagination token
-      }
-    });
-    window.addEventListener(kViewForumResponse, e => {
-      if (e.detail.id != this.lastThreadListRequestId) return;
-
-      let threads = e.detail.body?.['1']?.['2'] ?? [];
-      if (this.lastThreadListIsFirst)
-        this.lastThreadListThreads = threads;
-      else
-        this.lastThreadListThreads = this.lastThreadListThreads.concat(threads);
-      this.lastThreadListTimestamp = Date.now();
-    });
-  }
-
-  // Whether |feature| is enabled
-  isEnabled(feature) {
-    return this.optionsWatcher.isEnabled(feature);
-  }
-
-  // Add chips which contain |info| to |node|. If |withContainer| is set to
-  // true, a container will contain all the chips.
-  addExtraInfoElement(info, node, withContainer = false) {
-    // Don't create if there's nothing to show
-    if (info.length == 0) return;
-
-    let container;
-    if (withContainer) {
-      container = document.createElement('div');
-      container.classList.add('TWPT-extrainfo-container');
-    } else {
-      container = node;
-    }
-
-    let tooltips = [];
-
-    for (const i of info) {
-      let chip = document.createElement('material-chip');
-      chip.classList.add('TWPT-extrainfo-chip');
-
-      let chipCont = document.createElement('div');
-      chipCont.classList.add('TWPT-chip-content-container');
-
-      let content = document.createElement('div');
-      content.classList.add('TWPT-content');
-
-      const [badge, badgeTooltip] = createExtBadge();
-
-      let span = document.createElement('span');
-      span.append(i);
-
-      content.append(badge, span);
-      chipCont.append(content);
-      chip.append(chipCont);
-      container.append(chip);
-
-      tooltips.push(badgeTooltip);
-    }
-
-    if (withContainer) node.append(container);
-
-    for (const tooltip of tooltips) new MDCTooltip(tooltip);
-  }
-
-  /**
-   * Profile functionality
-   */
-  injectAtProfile(card) {
-    waitFor(
-        () => {
-          let now = Date.now();
-          if (now - this.lastProfile.timestamp < 15 * 1000)
-            return Promise.resolve(this.lastProfile);
-          return Promise.reject(
-              new Error('Didn\'t receive profile information'));
-        },
-        {
-          interval: 500,
-          timeout: 15 * 1000,
-        })
-        .then(profile => {
-          let info = [];
-          const abuseViolationCategory = profile.body?.['1']?.['6'];
-          if (abuseViolationCategory) {
-            let avCat = document.createElement('span');
-            avCat.textContent = chrome.i18n.getMessage(
-                'inject_extrainfo_profile_abusecategory',
-                [chrome.i18n.getMessage(
-                     'inject_extrainfo_profile_abusecategory_' +
-                     kAbuseViolationCategoriesI18n[abuseViolationCategory]) ??
-                 abuseViolationCategory]);
-            avCat.title = kAbuseViolationCategories[abuseViolationCategory] ??
-                abuseViolationCategory;
-            info.push(avCat);
-          }
-
-          const profileAbuse = profile.body?.['1']?.['1']?.['8'];
-
-          for (const [index, category] of kAbuseCategories) {
-            const violation = profileAbuse?.[index]?.['1']?.['1'];
-            if (violation) {
-              info.push(chrome.i18n.getMessage(
-                  'inject_extrainfo_profile_abuse_' + category,
-                  [kAbuseViolationTypes[violation]]));
-            }
-          }
-
-          const appealCount = profileAbuse?.['4'];
-          if (appealCount !== undefined)
-            info.push(chrome.i18n.getMessage(
-                'inject_extrainfo_profile_appealsnum', [appealCount]));
-
-          this.addExtraInfoElement(info, card, true);
-        })
-        .catch(err => {
-          console.error(
-              'extraInfo: error while injecting profile extra info: ', err);
-        });
-  }
-
-  injectAtProfileIfEnabled(card) {
-    this.isEnabled('extrainfo').then(isEnabled => {
-      if (isEnabled) return this.injectAtProfile(card);
-    });
-  }
-
-  /**
-   * Canned responses (CRs) functionality
-   */
-  getCRName(tags, isExpanded) {
-    if (!isExpanded)
-      return tags.parentNode?.querySelector?.('.text .name')?.textContent;
-
-    // https://www.youtube.com/watch?v=Z6_ZNW1DACE
-    return tags.parentNode?.parentNode?.parentNode?.parentNode?.parentNode
-        ?.parentNode?.parentNode?.querySelector?.('.text .name')
-        ?.textContent;
-  }
-
-  getUsageCountString(num) {
-    if (num == 1)
-      return chrome.i18n.getMessage('inject_extrainfo_crs_used_singular');
-
-    return chrome.i18n.getMessage('inject_extrainfo_crs_used_plural', [num]);
-  }
-
-  // Inject usage stats in the |tags| component of a CR
-  injectAtCR(tags, isExpanded) {
-    waitFor(
-        () => {
-          if (this.lastCRsList.id != -1)
-            return Promise.resolve(this.lastCRsList);
-          return Promise.reject(
-              new Error('Didn\'t receive canned responses list'));
-        },
-        {
-          interval: 500,
-          timeout: 15 * 1000,
-        })
-        .then(crs => {
-          let name = this.getCRName(tags, isExpanded);
-
-          // If another CR has the same name, there's no easy way to distinguish
-          // them, so don't show the usage stats.
-          if (crs.duplicateNames.has(name)) {
-            console.info(
-                'CR "' + name +
-                '" is duplicate, so skipping the injection of usage stats.');
-            return;
-          }
-
-          for (const cr of (crs.body?.['1'] ?? [])) {
-            if (cr['7'] == name) {
-              let tag = document.createElement('material-chip');
-              tag.classList.add('TWPT-tag');
-
-              let container = document.createElement('div');
-              container.classList.add('TWPT-chip-content-container');
-
-              let content = document.createElement('div');
-              content.classList.add('TWPT-content');
-
-              const [badge, badgeTooltip] = createExtBadge();
-
-              let label = document.createElement('span');
-              label.textContent = this.getUsageCountString(cr['8'] ?? '0');
-
-              content.append(badge, label);
-              container.append(content);
-              tag.append(container);
-              tags.append(tag);
-
-              new MDCTooltip(badgeTooltip);
-
-              if (cr['9']) {
-                const lastUsedTime = Math.floor(parseInt(cr['9']) / 1e3);
-                let date = (new Date(lastUsedTime)).toLocaleString();
-                createPlainTooltip(
-                    label,
-                    chrome.i18n.getMessage(
-                        'inject_extrainfo_crs_lastused', [date]));
-              }
-
-              break;
-            }
-          }
-        })
-        .catch(err => {
-          console.error(
-              'extraInfo: error while injecting profile extra info: ', err);
-        });
-  }
-
-  injectAtCRIfEnabled(tags, isExpanded) {
-    // If the tag has already been injected, exit.
-    if (tags.querySelector('.TWPT-tag')) return;
-
-    this.isEnabled('extrainfo').then(isEnabled => {
-      if (isEnabled) return this.injectAtCR(tags, isExpanded);
-    });
-  }
-
-  /**
-   * Thread view functionality
-   */
-
-  getPendingStateInfo(endPendingStateTimestampMicros) {
-    const endPendingStateTimestamp =
-        Math.floor(endPendingStateTimestampMicros / 1e3);
-    const now = Date.now();
-    if (endPendingStateTimestampMicros && endPendingStateTimestamp > now) {
-      let span = document.createElement('span');
-      span.textContent =
-          chrome.i18n.getMessage('inject_extrainfo_message_pendingstate');
-
-      let date = new Date(endPendingStateTimestamp).toLocaleString();
-      let pendingTooltip = createPlainTooltip(
-          span,
-          chrome.i18n.getMessage(
-              'inject_extrainfo_message_pendingstate_tooltip', [date]),
-          false);
-      return [span, pendingTooltip];
-    }
-
-    return [null, null];
-  }
-
-  getMetadataInfo(itemMetadata) {
-    let info = [];
-
-    const state = itemMetadata?.['1'];
-    if (state && state != 1) {
-      let span = document.createElement('span');
-      span.textContent = chrome.i18n.getMessage(
-          'inject_extrainfo_message_state',
-          [chrome.i18n.getMessage(
-               'inject_extrainfo_message_state_' +
-               kItemMetadataStateI18n[state]) ??
-           state]);
-      span.title = kItemMetadataState[state] ?? state;
-      info.push(span);
-    }
-
-    const shadowBlockInfo = itemMetadata?.['10'];
-    const blockedTimestampMicros = shadowBlockInfo?.['2'];
-    if (blockedTimestampMicros) {
-      const isBlocked = shadowBlockInfo?.['1'];
-      let span = document.createElement('span');
-      span.textContent = chrome.i18n.getMessage(
-          'inject_extrainfo_message_shadowblock' +
-          (isBlocked ? 'active' : 'notactive'));
-      if (isBlocked) span.classList.add('TWPT-extrainfo-bad');
-      info.push(span);
-    }
-
-    return info;
-  }
-
-  getLiveReviewStatusInfo(liveReviewStatus) {
-    const verdict = liveReviewStatus?.['1'];
-    if (!verdict) return [null, null];
-    let label, labelClass;
-    switch (verdict) {
-      case 1:  // LIVE_REVIEW_RELEVANT
-        label = 'relevant';
-        labelClass = 'TWPT-extrainfo-good';
-        break;
-
-      case 2:  // LIVE_REVIEW_OFF_TOPIC
-        label = 'offtopic';
-        labelClass = 'TWPT-extrainfo-bad';
-        break;
-
-      case 3:  // LIVE_REVIEW_ABUSE
-        label = 'abuse';
-        labelClass = 'TWPT-extrainfo-bad';
-        break;
-    }
-    const reviewedBy = liveReviewStatus?.['2'];
-    const timestamp = liveReviewStatus?.['3'];
-    const date = (new Date(Math.floor(timestamp / 1e3))).toLocaleString();
-
-    let a = document.createElement('a');
-    a.href = 'https://support.google.com/s/community/user/' + reviewedBy;
-    a.classList.add(labelClass);
-    a.textContent = chrome.i18n.getMessage(
-        'inject_extrainfo_message_livereviewverdict',
-        [chrome.i18n.getMessage(
-            'inject_extrainfo_message_livereviewverdict_' + label)]);
-    let liveReviewTooltip = createPlainTooltip(a, date, false);
-    return [a, liveReviewTooltip];
-  }
-
-  // Get an |info| array with the info related to the thread, and a |tooltips|
-  // array with the corresponding tooltips which should be initialized after the
-  // info is added to the DOM.
-  //
-  // This is used by the injectAtQuestion() and injectAtThreadList() functions.
-  getThreadInfo(thread) {
-    let info = [];
-    let tooltips = [];
-
-    const endPendingStateTimestampMicros = thread?.['2']?.['39'];
-    const [pendingStateInfo, pendingTooltip] =
-        this.getPendingStateInfo(endPendingStateTimestampMicros);
-    if (pendingStateInfo) info.push(pendingStateInfo);
-    if (pendingTooltip) tooltips.push(pendingTooltip);
-
-    const isTrending = thread?.['2']?.['25'];
-    const isTrendingAutoMarked = thread?.['39'];
-    if (isTrendingAutoMarked)
-      info.push(document.createTextNode(
-          chrome.i18n.getMessage('inject_extrainfo_thread_autotrending')));
-    else if (isTrending)
-      info.push(document.createTextNode(
-          chrome.i18n.getMessage('inject_extrainfo_thread_trending')));
-
-    const itemMetadata = thread?.['2']?.['12'];
-    const mdInfo = this.getMetadataInfo(itemMetadata);
-    info.push(...mdInfo);
-
-    const liveReviewStatus = thread?.['2']?.['38'];
-    const [liveReviewInfo, liveReviewTooltip] =
-        this.getLiveReviewStatusInfo(liveReviewStatus);
-    if (liveReviewInfo) info.push(liveReviewInfo);
-    if (liveReviewTooltip) tooltips.push(liveReviewTooltip);
-
-    return [info, tooltips];
-  }
-
-  injectAtQuestion(stateChips) {
-    let currentPage = parseUrl(location.href);
-    if (currentPage === false) {
-      console.error('extraInfo: couldn\'t parse current URL:', location.href);
-      return;
-    }
-
-    waitFor(
-        () => {
-          let now = Date.now();
-          let threadInfo = this.lastThread.body['1']?.['2']?.['1'];
-          if (now - this.lastThread.timestamp < 30 * 1000 &&
-              threadInfo?.['1'] == currentPage.thread &&
-              threadInfo?.['3'] == currentPage.forum)
-            return Promise.resolve(this.lastThread);
-          return Promise.reject(
-              new Error('Didn\'t receive thread information'));
-        },
-        {
-          interval: 500,
-          timeout: 30 * 1000,
-        })
-        .then(thread => {
-          const [info, tooltips] = this.getThreadInfo(thread.body?.['1']);
-          this.addExtraInfoElement(info, stateChips, false);
-          for (const tooltip of tooltips) new MDCTooltip(tooltip);
-        })
-        .catch(err => {
-          console.error(
-              'extraInfo: error while injecting question extra info: ', err);
-        });
-  }
-
-  injectAtQuestionIfEnabled(stateChips) {
-    this.isEnabled('extrainfo').then(isEnabled => {
-      if (isEnabled) return this.injectAtQuestion(stateChips);
-    });
-  }
-
-  getMessagesByType(thread, type) {
-    if (type === 'reply') return thread?.['1']?.['3'];
-    if (type === 'lastMessage') return thread?.['1']?.['17']?.['3'];
-    if (type === 'suggested') return thread?.['1']?.['17']?.['4'];
-    if (type === 'recommended') return thread?.['1']?.['17']?.['1'];
-  }
-
-  getMessageByTypeAndIndex(thread, type, index) {
-    return this.getMessagesByType(thread, type)?.[index];
-  }
-
-  // Returns true if the last message is included in the messages array (in the
-  // extension context, we say those messages are of the type "reply").
-  lastMessageInReplies(thread) {
-    const lastMessageId = thread?.['1']?.['17']?.['3']?.[0]?.['1']?.['1'];
-    if (!lastMessageId) return true;
-
-    // If the last message is included in the lastMessage array, check if it
-    // also exists in the messages/replies array.
-    const replies = thread?.['1']?.['3'];
-    if (!replies?.length) return false;
-    const lastReplyIndex = replies.length - 1;
-    const lastReplyId = replies[lastReplyIndex]?.['1']?.['1'];
-    return lastMessageId && lastMessageId == lastReplyId;
-  }
-
-  getMessageInfo(thread, message) {
-    const section = message.parentNode;
-
-    let type = 'reply';
-    if (section?.querySelector?.('.heading material-icon[icon="auto_awesome"]'))
-      type = 'suggested';
-    if (section?.querySelector?.('.heading material-icon[icon="check_circle"]'))
-      type = 'recommended';
-
-    let index = -1;
-    let messagesInDom = section.querySelectorAll('ec-message');
-
-    // Number of messages in the DOM.
-    const n = messagesInDom.length;
-
-    if (type !== 'reply') {
-      for (let i = 0; i < n; ++i) {
-        if (message.isEqualNode(messagesInDom[i])) {
-          index = i;
-          break;
-        }
-      }
-    } else {
-      // If the type of the message is a reply, things are slightly more
-      // complex, since replies are paginated and the last message should be
-      // treated separately (it is included diferently in the API response).
-      let lastMessageInReplies = this.lastMessageInReplies(thread);
-      if (message.isEqualNode(messagesInDom[n - 1]) && !lastMessageInReplies) {
-        type = 'lastMessage';
-        index = 0
-      } else {
-        // Number of messages in the current API response.
-        const messagesInResponse = this.getMessagesByType(thread, type);
-        const m = messagesInResponse.length;
-        // If the last message is included in the replies array, we also have to
-        // consider the last message in the DOM.
-        let modifier = lastMessageInReplies ? 1 : 0;
-        for (let k = 0; k < m; ++k) {
-          let i = n - 2 - k + modifier;
-          if (message.isEqualNode(messagesInDom[i])) {
-            index = m - 1 - k;
-            break;
-          }
-        }
-      }
-    }
-
-    return [type, index];
-  }
-
-  injectAtMessage(messageNode) {
-    let currentPage = parseUrl(location.href);
-    if (currentPage === false) {
-      console.error('extraInfo: couldn\'t parse current URL:', location.href);
-      return;
-    }
-
-    let footer = messageNode.querySelector('.footer-fill');
-    if (!footer) {
-      console.error('extraInfo: message doesn\'t have a footer:', messageNode);
-      return;
-    }
-
-    const [type, index] =
-        this.getMessageInfo(this.lastThread.body, messageNode);
-    if (index == -1) {
-      console.error('extraInfo: this.getMessageInfo() returned index -1.');
-      return;
-    }
-
-    waitFor(
-        () => {
-          let now = Date.now();
-          let threadInfo = this.lastThread.body['1']?.['2']?.['1'];
-          if (now - this.lastThread.timestamp < 30 * 1000 &&
-              threadInfo?.['1'] == currentPage.thread &&
-              threadInfo?.['3'] == currentPage.forum) {
-            const message = this.getMessageByTypeAndIndex(
-                this.lastThread.body, type, index);
-            if (message) return Promise.resolve(message);
-          }
-
-          return Promise.reject(new Error(
-              'Didn\'t receive thread information (type: ' + type +
-              ', index: ' + index + ')'));
-        },
-        {
-          interval: 1000,
-          timeout: 30 * 1000,
-        })
-        .then(message => {
-          let info = [];
-
-          const endPendingStateTimestampMicros = message['1']?.['17'];
-          const [pendingStateInfo, pendingTooltip] =
-              this.getPendingStateInfo(endPendingStateTimestampMicros);
-          if (pendingStateInfo) info.push(pendingStateInfo);
-
-          const itemMetadata = message['1']?.['5'];
-          const mdInfo = this.getMetadataInfo(itemMetadata);
-          info.push(...mdInfo);
-
-          const liveReviewStatus = message['1']?.['36'];
-          const [liveReviewInfo, liveReviewTooltip] =
-              this.getLiveReviewStatusInfo(liveReviewStatus);
-          if (liveReviewInfo) info.push(liveReviewInfo);
-
-          this.addExtraInfoElement(info, footer, true);
-          if (pendingTooltip) new MDCTooltip(pendingTooltip);
-          if (liveReviewTooltip) new MDCTooltip(liveReviewTooltip);
-        })
-        .catch(err => {
-          console.error(
-              'extraInfo: error while injecting message extra info: ', err);
-        });
-  }
-
-  injectAtMessageIfEnabled(message) {
-    this.isEnabled('extrainfo').then(isEnabled => {
-      if (isEnabled) return this.injectAtMessage(message);
-    });
-  }
-
-  /**
-   * Thread list functionality
-   */
-  injectAtThreadList(li) {
-    waitFor(
-        () => {
-          const headerContent = li.querySelector(
-              'ec-thread-summary .main-header .header a.header-content');
-          if (headerContent === null) {
-            return Promise.reject(new Error(
-                'extraInfo: Header is not present in the thread item\'s DOM.'));
-          }
-
-          const threadInfo = parseUrl(headerContent.href);
-          if (threadInfo === false) {
-            return Promise.reject(
-                new Error('extraInfo: Thread\'s link cannot be parsed.'));
-          }
-
-          let authorLine = li.querySelector(
-              'ec-thread-summary .header-content .top-row .author-line');
-          if (!authorLine) {
-            return Promise.reject(new Error(
-                'extraInfo: Author line is not present in the thread item\'s DOM.'));
-          }
-
-          let thread = this.lastThreadListThreads?.find?.(t => {
-            return t?.['2']?.['1']?.['1'] == threadInfo.thread &&
-                t?.['2']?.['1']?.['3'] == threadInfo.forum;
-          });
-          if (thread) return Promise.resolve([thread, authorLine]);
-          return Promise.reject(
-              new Error('Didn\'t receive thread information'));
-        },
-        {
-          interval: 500,
-          timeout: 7 * 1000,
-        })
-        .then(response => {
-          const [thread, authorLine] = response;
-          const state = thread?.['2']?.['12']?.['1'];
-          if (state && ![1, 13, 18, 9].includes(state)) {
-            let label = document.createElement('div');
-            label.classList.add('TWPT-label');
-
-            const [badge, badgeTooltip] = createExtBadge();
-
-            let span = document.createElement('span');
-            span.textContent = chrome.i18n.getMessage(
-                                   'inject_extrainfo_message_state_' +
-                                   kItemMetadataStateI18n[state]) ??
-                state;
-            span.title = kItemMetadataState[state] ?? state;
-
-            label.append(badge, span);
-            authorLine.prepend(label);
-            new MDCTooltip(badgeTooltip);
-          }
-        })
-        .catch(err => {
-          console.error(
-              'extraInfo: error while injecting thread list extra info: ', err);
-        });
-  }
-
-  injectAtThreadListIfEnabled(li) {
-    this.isEnabled('extrainfo').then(isEnabled => {
-      if (isEnabled) this.injectAtThreadList(li);
-    });
-  }
-
-  injectAtExpandedThreadList(toolbelt) {
-    const headerContent =
-        toolbelt?.parentNode?.parentNode?.parentNode?.querySelector?.(
-            '.main-header .header a.header-content');
-    if (headerContent === null) {
-      console.error(
-          'extraInfo: Header is not present in the thread item\'s DOM.');
-      return;
-    }
-
-    const threadInfo = parseUrl(headerContent.href);
-    if (threadInfo === false) {
-      console.error('extraInfo: Thread\'s link cannot be parsed.');
-      return;
-    }
-
-    waitFor(
-        () => {
-          let thread = this.lastThreadListThreads?.find?.(t => {
-            return t?.['2']?.['1']?.['1'] == threadInfo.thread &&
-                t?.['2']?.['1']?.['3'] == threadInfo.forum;
-          });
-          if (thread) return Promise.resolve(thread);
-          return Promise.reject(
-              new Error('Didn\'t receive thread information'));
-        },
-        {
-          interval: 500,
-          timeout: 7 * 1000,
-        })
-        .then(thread => {
-          const [info, tooltips] = this.getThreadInfo(thread);
-          this.addExtraInfoElement(info, toolbelt, true);
-          for (const tooltip of tooltips) new MDCTooltip(tooltip);
-        })
-        .catch(err => {
-          console.error(
-              'extraInfo: error while injecting thread list extra info: ', err);
-        });
-  }
-
-  injectAtExpandedThreadListIfEnabled(toolbelt) {
-    this.isEnabled('extrainfo').then(isEnabled => {
-      if (isEnabled) this.injectAtExpandedThreadList(toolbelt);
-    });
-  }
-
-  /**
-   * Per-forum stats in user profiles.
-   */
-
-  injectPerForumStats(chart) {
-    waitFor(
-        () => {
-          let now = Date.now();
-          if (now - this.lastProfile.timestamp < 15 * 1000)
-            return Promise.resolve(this.lastProfile);
-          return Promise.reject(new Error(
-              'Didn\'t receive profile information (for per-profile stats)'));
-        },
-        {
-          interval: 500,
-          timeout: 15 * 1000,
-        })
-        .then(profile => {
-          new PerForumStatsSection(
-              chart?.parentNode, profile.body, this.displayLanguage,
-              /* isCommunityConsole = */ true);
-        })
-        .catch(err => {
-          console.error(
-              'extraInfo: error while preparing to inject per-forum stats: ',
-              err);
-        });
-  }
-
-  injectPerForumStatsIfEnabled(chart) {
-    this.isEnabled('perforumstats').then(isEnabled => {
-      if (isEnabled) this.injectPerForumStats(chart);
-    });
-  }
-}
diff --git a/src/contentScripts/communityConsole/extraInfo/consts.js b/src/contentScripts/communityConsole/extraInfo/consts.js
new file mode 100644
index 0000000..d2f2122
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/consts.js
@@ -0,0 +1,192 @@
+export const kViewUnifiedUserResponseEvent = 'TWPT_ViewUnifiedUserResponse';
+export const kViewThreadResponse = 'TWPT_ViewThreadResponse';
+export const kViewForumRequest = 'TWPT_ViewForumRequest';
+export const kViewForumResponse = 'TWPT_ViewForumResponse';
+
+// Used to match each category with the corresponding string.
+export const kAbuseCategories = [
+  ['1', 'account'],
+  ['2', 'displayname'],
+  ['3', 'avatar'],
+];
+export const kAbuseViolationCategories = {
+  0: 'NO_VIOLATION',
+  1: 'COMMUNITY_POLICY_VIOLATION',
+  2: 'LEGAL_VIOLATION',
+  3: 'CSAI_VIOLATION',
+  4: 'OTHER_VIOLATION',
+};
+export const kAbuseViolationCategoriesI18n = {
+  0: 'noviolation',
+  1: 'communitypolicy',
+  2: 'legal',
+  3: 'csai',
+  4: 'other',
+};
+
+// The following array will appear in the interface as is (without being
+// translated).
+export const kAbuseViolationTypes = {
+  0: 'UNSPECIFIED',
+  23: 'ACCOUNT_DISABLED',
+  55: 'ACCOUNT_HAS_SERVICES_DISABLED',
+  35: 'ACCOUNT_HIJACKED',
+  96: 'ACCOUNT_LEAKED_CREDENTIALS',
+  92: 'ACCOUNT_NOT_SUPPORTED',
+  81: 'ARTISTIC_NUDITY',
+  66: 'BAD_BEHAVIOR_PATTERN',
+  78: 'BAD_ENGAGEMENT_BEHAVIOR_PATTERN',
+  79: 'BORDERLINE_HARASSMENT',
+  80: 'BORDERLINE_HATE_SPEECH',
+  38: 'BOTNET',
+  32: 'BRANDING_VIOLATION',
+  100: 'CAPITALIZING_TRAGIC_EVENTS',
+  105: 'CLOAKING',
+  49: 'COIN_MINING',
+  7: 'COMMERCIAL_CONTENT',
+  97: 'COPPA_REGULATED',
+  57: 'COPYRIGHT_CIRCUMVENTION',
+  8: 'COPYRIGHTED_CONTENT',
+  58: 'COURT_ORDER',
+  51: 'CSAI',
+  94: 'CSAI_INSPECT',
+  52: 'CSAI_CARTOON_HUMOR',
+  53: 'CSAI_SOLICITATION',
+  108: 'CSAI_NON_APPARENT',
+  67: 'DANGEROUS',
+  37: 'DATA_SCRAPING',
+  86: 'DECEPTIVE_OAUTH_IMPLEMENTATION',
+  46: 'DEFAMATORY_CONTENT',
+  36: 'DELINQUENT_BILLING',
+  30: 'DISRUPTION_ATTEMPT',
+  112: 'DOMESTIC_INTERFERENCE',
+  22: 'DOS',
+  9: 'DUPLICATE_CONTENT',
+  68: 'DUPLICATE_LOCAL_PAGE',
+  121: 'NON_QUALIFYING_ORGANIZATION',
+  115: 'EGREGIOUS_INTERACTION_WITH_MINOR',
+  83: 'ENGAGEMENT_COLLUSION',
+  41: 'EXPLOIT_ATTACKS',
+  65: 'FAKE_USER',
+  2: 'FRAUD',
+  21: 'FREE_TRIAL_VIOLATION',
+  43: 'GIBBERISH',
+  101: 'FOREIGN_INTERFERENCE',
+  59: 'GOVERNMENT_ORDER',
+  10: 'GRAPHICAL_VIOLENCE',
+  11: 'HARASSMENT',
+  12: 'HATE_SPEECH',
+  90: 'IDENTICAL_PRODUCT_NAME',
+  60: 'ILLEGAL_DRUGS',
+  13: 'IMPERSONATION',
+  69: 'IMPERSONATION_WITH_PII',
+  116: 'INAPPROPRIATE_INTERACTION_WITH_MINOR',
+  45: 'INAPPROPRIATE_CONTENT_SPEECH',
+  106: 'INTENTIONAL_THWARTING',
+  27: 'INTRUSION_ATTEMPT',
+  87: 'INVALID_API_USAGE',
+  14: 'INVALID_CONTENT',
+  20: 'INVALID_GCE_USAGE',
+  120: 'INVALID_STORAGE_USAGE',
+  15: 'INVALID_IMAGE_QUALITY',
+  88: 'INVALID_API_PRIVACY_POLICY_DISCLOSURE',
+  54: 'INVALID_USAGE_OF_IP_PROXYING',
+  99: 'KEYWORD_STUFFING',
+  61: 'LEGAL_COUNTERFEIT',
+  62: 'LEGAL_EXPORT',
+  63: 'LEGAL_PRIVACY',
+  33: 'LEGAL_REVIEW',
+  91: 'LEGAL_PROTECTED',
+  70: 'LOW_QUALITY_CONTENT',
+  93: 'LOW_REPUTATION_PHONE_NUMBER',
+  6: 'MALICIOUS_SOFTWARE',
+  40: 'MALWARE',
+  113: 'MISLEADING',
+  114: 'MISREP_OF_ID',
+  89: 'MEMBER_OF_ABUSIVE_GCE_NETWORK',
+  84: 'NON_CONSENSUAL_EXPLICIT_IMAGERY',
+  1: 'NONE',
+  102: 'OFF_TOPIC',
+  31: 'OPEN_PROXY',
+  28: 'PAYMENT_FRAUD',
+  16: 'PEDOPHILIA',
+  71: 'PERSONAL_INFORMATION_CONTENT',
+  25: 'PHISHING',
+  34: 'POLICY_REVIEW',
+  17: 'PORNOGRAPHY',
+  29: 'QUOTA_CIRCUMVENTION',
+  72: 'QUOTA_EXCEEDED',
+  73: 'REGULATED',
+  24: 'REPEATED_POLICY_VIOLATION',
+  104: 'RESOURCE_COMPROMISED',
+  107: 'REWARD_PROGRAMS_ABUSE',
+  74: 'ROGUE_PHARMA',
+  82: 'ESCORT',
+  75: 'SPAMMY_LOCAL_VERTICAL',
+  39: 'SEND_EMAIL_SPAM',
+  117: 'SEXTORTION',
+  118: 'SEX_TRAFFICKING',
+  44: 'SEXUALLY_EXPLICIT_CONTENT',
+  3: 'SHARDING',
+  95: 'SOCIAL_ENGINEERING',
+  109: 'SUSPICIOUS',
+  19: 'TRADEMARK_CONTENT',
+  50: 'TRAFFIC_PUMPING',
+  76: 'UNSAFE_RACY',
+  103: 'UNUSUAL_ACTIVITY_ALERT',
+  64: 'UNWANTED_CONTENT',
+  26: 'UNWANTED_SOFTWARE',
+  77: 'VIOLENT_EXTREMISM',
+  119: 'UNAUTH_IMAGES_OF_MINORS',
+  85: 'UNAUTHORIZED_SERVICE_RESELLING',
+  98: 'CSAI_EXTERNAL',
+  5: 'SPAM',
+  4: 'UNSAFE',
+  47: 'CHILD_PORNOGRAPHY_INCITATION',
+  18: 'TERRORISM_SUPPORT',
+  56: 'CSAI_WORST_OF_WORST',
+};
+
+// These values will be translated
+export const kItemMetadataStateI18n = {
+  1: 'published',
+  2: 'draft',
+  3: 'automated_abuse_take_down_hide2',
+  4: 'automated_abuse_take_down_delete2',
+  13: 'automated_abuse_reinstate2',
+  10: 'automated_off_topic_hide2',
+  14: 'automated_flagged_pending_manual_review2',
+  5: 'user_flagged_pending_manual_review',
+  6: 'owner_deleted',
+  7: 'manual_take_down_hide2',
+  17: 'manual_profile_take_down_suspend2',
+  8: 'manual_take_down_delete2',
+  18: 'reinstate_profile_takedown2',
+  9: 'reinstate_abuse_takedown2',
+  11: 'clear_off_topic2',
+  12: 'confirm_off_topic2',
+  15: 'googler_off_topic_hide2',
+  16: 'expert_flagged_pending_manual_review',
+};
+export const kItemMetadataState = {
+  0: 'UNDEFINED',
+  1: 'PUBLISHED',
+  2: 'DRAFT',
+  3: 'AUTOMATED_ABUSE_TAKE_DOWN_HIDE',
+  4: 'AUTOMATED_ABUSE_TAKE_DOWN_DELETE',
+  13: 'AUTOMATED_ABUSE_REINSTATE',
+  10: 'AUTOMATED_OFF_TOPIC_HIDE',
+  14: 'AUTOMATED_FLAGGED_PENDING_MANUAL_REVIEW',
+  5: 'USER_FLAGGED_PENDING_MANUAL_REVIEW',
+  6: 'OWNER_DELETED',
+  7: 'MANUAL_TAKE_DOWN_HIDE',
+  17: 'MANUAL_PROFILE_TAKE_DOWN_SUSPEND',
+  8: 'MANUAL_TAKE_DOWN_DELETE',
+  18: 'REINSTATE_PROFILE_TAKEDOWN',
+  9: 'REINSTATE_ABUSE_TAKEDOWN',
+  11: 'CLEAR_OFF_TOPIC',
+  12: 'CONFIRM_OFF_TOPIC',
+  15: 'GOOGLER_OFF_TOPIC_HIDE',
+  16: 'EXPERT_FLAGGED_PENDING_MANUAL_REVIEW',
+};
+
diff --git a/src/contentScripts/communityConsole/extraInfo/handlers/base.js b/src/contentScripts/communityConsole/extraInfo/handlers/base.js
new file mode 100644
index 0000000..732ccee
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/handlers/base.js
@@ -0,0 +1,17 @@
+import {shouldImplement} from '../../../../common/commonUtils.js';
+
+export default class BaseInfoHandler {
+  constructor() {
+    if (this.constructor == BaseInfoHandler) {
+      throw new Error('The base class cannot be instantiated.');
+    }
+  }
+
+  /**
+   * Should return a promise which resolves to the current info in a best-effort
+   * manner (if it can't retrieve the current info it is allowed to fail).
+   */
+  async getCurrentInfo(_injectionDetails) {
+    shouldImplement('getCurrentInfo');
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/handlers/basedOnResponseEvent.js b/src/contentScripts/communityConsole/extraInfo/handlers/basedOnResponseEvent.js
new file mode 100644
index 0000000..881356c
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/handlers/basedOnResponseEvent.js
@@ -0,0 +1,76 @@
+import {waitFor} from 'poll-until-promise';
+
+import {shouldImplement} from '../../../../common/commonUtils.js';
+
+import BaseInfoHandler from './base.js';
+
+export default class ResponseEventBasedInfoHandler extends BaseInfoHandler {
+  constructor() {
+    super();
+
+    if (this.constructor == ResponseEventBasedInfoHandler) {
+      throw new Error('The base class cannot be instantiated.');
+    }
+
+    this.setUpDefaultInfoValue();
+    this.setUpEventHandler();
+  }
+
+  /**
+   * Should return the name of the XHR interceptor event for the API response
+   * which has the information being handled.
+   */
+  getEvent() {
+    shouldImplement('getEvent');
+  }
+
+  /**
+   * This function should return a promise which resolves to a boolean
+   * specifying whether this.info is the information related to the view that
+   * the user is currently on.
+   */
+  async isInfoCurrent(_injectionDetails) {
+    shouldImplement('isInfoCurrent');
+  }
+
+  /**
+   * Should return the options for the waitFor function which is called when
+   * checking whether the information is current or not.
+   */
+  getWaitForCurrentInfoOptions() {
+    shouldImplement('getWaitForCurrentInfoOptions');
+  }
+
+  setUpDefaultInfoValue() {
+    this.info = {
+      body: {},
+      id: -1,
+      timestamp: 0,
+    };
+  }
+
+  setUpEventHandler() {
+    window.addEventListener(this.getEvent(), e => {
+      if (e.detail.id < this.info.id) return;
+
+      this.info = {
+        body: e.detail.body,
+        id: e.detail.id,
+        timestamp: Date.now(),
+      };
+    });
+  }
+
+  async getCurrentInfo(injectionDetails) {
+    const options = this.getWaitForCurrentInfoOptions();
+    return waitFor(
+        () => this.attemptToGetCurrentInfo(injectionDetails), options);
+  }
+
+  async attemptToGetCurrentInfo(injectionDetails) {
+    const isInfoCurrent = await this.isInfoCurrent(injectionDetails);
+    if (!isInfoCurrent) throw new Error('Didn\'t receive current information');
+
+    return this.info;
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/handlers/profile.js b/src/contentScripts/communityConsole/extraInfo/handlers/profile.js
new file mode 100644
index 0000000..28e8309
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/handlers/profile.js
@@ -0,0 +1,20 @@
+import {kViewUnifiedUserResponseEvent} from '../consts.js';
+
+import ResponseEventBasedInfoHandler from './basedOnResponseEvent.js';
+
+export default class ProfileInfoHandler extends ResponseEventBasedInfoHandler {
+  getEvent() {
+    return kViewUnifiedUserResponseEvent;
+  }
+
+  async isInfoCurrent() {
+    return Date.now() - this.info.timestamp < 15 * 1000;
+  }
+
+  getWaitForCurrentInfoOptions() {
+    return {
+      interval: 500,
+      timeout: 15 * 1000,
+    };
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/handlers/threadList.js b/src/contentScripts/communityConsole/extraInfo/handlers/threadList.js
new file mode 100644
index 0000000..47d7e65
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/handlers/threadList.js
@@ -0,0 +1,100 @@
+import {waitFor} from 'poll-until-promise';
+
+import {kViewForumRequest, kViewForumResponse} from '../consts.js';
+import ThreadExtraInfoService from '../services/thread.js';
+
+import BaseInfoHandler from './base.js';
+
+const kCheckIntervalInMs = 450;
+const kTimeoutInMs = 2 * 1000;
+
+export default class ThreadListInfoHandler extends BaseInfoHandler {
+  constructor() {
+    super();
+
+    this.setUpDefaultValues();
+    this.setUpEventHandlers();
+  }
+
+  setUpDefaultValues() {
+    this.threads = [];
+    this.isFirstBatch = null;
+    this.requestId = -1;
+    this.timestamp = 0;
+  }
+
+  setUpEventHandlers() {
+    window.addEventListener(kViewForumRequest, e => this.onThreadRequest(e));
+    window.addEventListener(kViewForumResponse, e => this.onThreadResponse(e));
+  }
+
+  onThreadRequest(e) {
+    // Ignore ViewForum requests made by the chat feature and the "Mark as
+    // duplicate" dialog.
+    //
+    // All those requests have |maxNum| set to 10 and 20 respectively, while
+    // the requests that we want to handle are the ones to initially load the
+    // thread list (which currently requests 100 threads) and the ones to load
+    // more threads (which request 50 threads).
+    const maxNum = e.detail.body?.['2']?.['1']?.['2'];
+    if (maxNum == 10 || maxNum == 20) return;
+
+    this.requestId = e.detail.id;
+    this.isFirstBatch =
+        !e.detail.body?.['2']?.['1']?.['3']?.['2'];  // Pagination token
+  }
+
+  onThreadResponse(e) {
+    if (e.detail.id != this.requestId) return;
+
+    const threads = e.detail.body?.['1']?.['2'] ?? [];
+    if (this.isFirstBatch)
+      this.threads = threads;
+    else
+      this.threads = this.threads.concat(threads);
+
+    this.timestamp = Date.now();
+  }
+
+  async getCurrentInfo(injectionDetails) {
+    const currentThreadInfo = injectionDetails.threadInfo;
+    const checkRecentTimestamp = !injectionDetails.isExpanded;
+
+    return this.getCurrentThreads(currentThreadInfo, checkRecentTimestamp)
+        .catch(err => {
+          if (checkRecentTimestamp) {
+            return this.getCurrentThreads(
+                currentThreadInfo, /* checkRecentTimestamp = */ false);
+          } else {
+            throw err;
+          }
+        });
+  }
+
+  async getCurrentThreads(currentThreadInfo, checkRecentTimestamp) {
+    const options = {
+      interval: kCheckIntervalInMs,
+      timeout: kTimeoutInMs,
+    };
+    return waitFor(
+        () => this.attemptToGetCurrentThreads(
+            currentThreadInfo, checkRecentTimestamp),
+        options);
+  }
+
+  async attemptToGetCurrentThreads(currentThreadInfo, checkRecentTimestamp) {
+    if (!this.isThreadListCurrent(currentThreadInfo, checkRecentTimestamp))
+      throw new Error('Didn\'t receive current information');
+
+    return this.threads;
+  }
+
+  isThreadListCurrent(currentThreadInfo, checkRecentTimestamp) {
+    if (checkRecentTimestamp && Date.now() - this.timestamp > kTimeoutInMs)
+      return false;
+
+    const thread = ThreadExtraInfoService.getThreadFromThreadList(
+        this.threads, currentThreadInfo);
+    return thread !== undefined;
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/index.js b/src/contentScripts/communityConsole/extraInfo/index.js
new file mode 100644
index 0000000..21e7546
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/index.js
@@ -0,0 +1,192 @@
+import {MDCTooltip} from '@material/tooltip';
+import {waitFor} from 'poll-until-promise';
+
+import {parseUrl} from '../../../common/commonUtils.js';
+import OptionsWatcher from '../../../common/optionsWatcher.js';
+
+import {kViewThreadResponse} from './consts.js';
+import ProfileInfoHandler from './handlers/profile.js';
+import ThreadListInfoHandler from './handlers/threadList.js';
+import ExpandedThreadListExtraInfoInjection from './injections/expandedThreadList.js';
+import ProfileAbuseExtraInfoInjection from './injections/profileAbuse.js';
+import ProfilePerForumStatsExtraInfoInjection from './injections/profilePerForumStats.js';
+import ThreadListExtraInfoInjection from './injections/threadList.js';
+import ThreadExtraInfoService from './services/thread.js';
+
+export default class ExtraInfo {
+  constructor() {
+    this.optionsWatcher = new OptionsWatcher(['extrainfo', 'perforumstats']);
+
+    const profileInfoHandler = new ProfileInfoHandler();
+    const threadListInfoHandler = new ThreadListInfoHandler();
+
+    this.profileAbuse = new ProfileAbuseExtraInfoInjection(
+        profileInfoHandler, this.optionsWatcher);
+    this.profilePerForumStats = new ProfilePerForumStatsExtraInfoInjection(
+        profileInfoHandler, this.optionsWatcher);
+    this.expandedThreadList = new ExpandedThreadListExtraInfoInjection(
+        threadListInfoHandler, this.optionsWatcher);
+    this.threadList = new ThreadListExtraInfoInjection(
+        threadListInfoHandler, this.optionsWatcher);
+
+    this.lastThread = {
+      body: {},
+      id: -1,
+      timestamp: 0,
+    };
+
+    this.setUpHandlers();
+  }
+
+  setUpHandlers() {
+    window.addEventListener(kViewThreadResponse, e => {
+      if (e.detail.id < this.lastThread.id) return;
+
+      this.lastThread = {
+        body: e.detail.body,
+        id: e.detail.id,
+        timestamp: Date.now(),
+      };
+    });
+  }
+
+  injectAbuseChipsAtProfileIfEnabled(card) {
+    this.profileAbuse.injectIfEnabled({card});
+  }
+
+  injectAtThreadListIfEnabled(li) {
+    const injectionDetails = this.threadList.getInjectionDetails(li);
+    this.threadList.injectIfEnabled(injectionDetails);
+  }
+
+  injectAtExpandedThreadListIfEnabled(toolbelt) {
+    const injectionDetails =
+        this.expandedThreadList.getInjectionDetails(toolbelt);
+    this.expandedThreadList.injectIfEnabled(injectionDetails);
+  }
+
+  injectPerForumStatsIfEnabled(chart) {
+    this.profilePerForumStats.injectIfEnabled({chart});
+  }
+
+  // Whether |feature| is enabled
+  isEnabled(feature) {
+    return this.optionsWatcher.isEnabled(feature);
+  }
+
+  /**
+   * Thread view functionality
+   */
+  injectAtQuestion(stateChips) {
+    let currentPage = parseUrl(location.href);
+    if (currentPage === false) {
+      console.error('extraInfo: couldn\'t parse current URL:', location.href);
+      return;
+    }
+
+    waitFor(
+        () => {
+          let now = Date.now();
+          let threadInfo = this.lastThread.body['1']?.['2']?.['1'];
+          if (now - this.lastThread.timestamp < 30 * 1000 &&
+              threadInfo?.['1'] == currentPage.thread &&
+              threadInfo?.['3'] == currentPage.forum)
+            return Promise.resolve(this.lastThread);
+          return Promise.reject(
+              new Error('Didn\'t receive thread information'));
+        },
+        {
+          interval: 500,
+          timeout: 30 * 1000,
+        })
+        .then(thread => {
+          const [info, tooltips] =
+              ThreadExtraInfoService.getThreadChips(thread.body?.['1']);
+          this.addExtraInfoElement(info, stateChips, false);
+          for (const tooltip of tooltips) new MDCTooltip(tooltip);
+        })
+        .catch(err => {
+          console.error(
+              'extraInfo: error while injecting question extra info: ', err);
+        });
+  }
+
+  injectAtQuestionIfEnabled(stateChips) {
+    this.isEnabled('extrainfo').then(isEnabled => {
+      if (isEnabled) return this.injectAtQuestion(stateChips);
+    });
+  }
+
+  injectAtMessage(messageNode) {
+    let currentPage = parseUrl(location.href);
+    if (currentPage === false) {
+      console.error('extraInfo: couldn\'t parse current URL:', location.href);
+      return;
+    }
+
+    let footer = messageNode.querySelector('.footer-fill');
+    if (!footer) {
+      console.error('extraInfo: message doesn\'t have a footer:', messageNode);
+      return;
+    }
+
+    const [type, index] =
+        this.getMessageInfo(this.lastThread.body, messageNode);
+    if (index == -1) {
+      console.error('extraInfo: this.getMessageInfo() returned index -1.');
+      return;
+    }
+
+    waitFor(
+        () => {
+          let now = Date.now();
+          let threadInfo = this.lastThread.body['1']?.['2']?.['1'];
+          if (now - this.lastThread.timestamp < 30 * 1000 &&
+              threadInfo?.['1'] == currentPage.thread &&
+              threadInfo?.['3'] == currentPage.forum) {
+            const message = this.getMessageByTypeAndIndex(
+                this.lastThread.body, type, index);
+            if (message) return Promise.resolve(message);
+          }
+
+          return Promise.reject(new Error(
+              'Didn\'t receive thread information (type: ' + type +
+              ', index: ' + index + ')'));
+        },
+        {
+          interval: 1000,
+          timeout: 30 * 1000,
+        })
+        .then(message => {
+          let info = [];
+
+          const endPendingStateTimestampMicros = message['1']?.['17'];
+          const [pendingStateInfo, pendingTooltip] =
+              this.getPendingStateInfo(endPendingStateTimestampMicros);
+          if (pendingStateInfo) info.push(pendingStateInfo);
+
+          const itemMetadata = message['1']?.['5'];
+          const mdInfo = ThreadExtraInfoService.getMetadataInfo(itemMetadata);
+          info.push(...mdInfo);
+
+          const liveReviewStatus = message['1']?.['36'];
+          const [liveReviewInfo, liveReviewTooltip] =
+              this.getLiveReviewStatusChip(liveReviewStatus);
+          if (liveReviewInfo) info.push(liveReviewInfo);
+
+          this.addExtraInfoElement(info, footer, true);
+          if (pendingTooltip) new MDCTooltip(pendingTooltip);
+          if (liveReviewTooltip) new MDCTooltip(liveReviewTooltip);
+        })
+        .catch(err => {
+          console.error(
+              'extraInfo: error while injecting message extra info: ', err);
+        });
+  }
+
+  injectAtMessageIfEnabled(message) {
+    this.isEnabled('extrainfo').then(isEnabled => {
+      if (isEnabled) return this.injectAtMessage(message);
+    });
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/injections/base.js b/src/contentScripts/communityConsole/extraInfo/injections/base.js
new file mode 100644
index 0000000..1498efd
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/injections/base.js
@@ -0,0 +1,97 @@
+import {MDCTooltip} from '@material/tooltip';
+
+import {shouldImplement} from '../../../../common/commonUtils.js';
+import {createExtBadge} from '../../utils/common.js';
+
+export default class BaseExtraInfoInjection {
+  constructor(infoHandler, optionsWatcher) {
+    if (this.constructor == BaseExtraInfoInjection) {
+      throw new Error('The base class cannot be instantiated.');
+    }
+
+    this.infoHandler = infoHandler;
+    this.optionsWatcher = optionsWatcher;
+  }
+
+  /**
+   * Method which actually injects the extra information. It should be
+   * implemented by the extending class.
+   */
+  inject() {
+    shouldImplement('inject');
+  }
+
+  async isEnabled() {
+    return await this.optionsWatcher.isEnabled('extrainfo');
+  }
+
+  /**
+   * This is the method which should be called when injecting extra information.
+   */
+  async injectIfEnabled(injectionDetails) {
+    const isEnabled = await this.isEnabled();
+    if (!isEnabled) return;
+
+    return this.infoHandler.getCurrentInfo(injectionDetails)
+        .then(info => this.inject(info, injectionDetails))
+        .catch(err => {
+          console.error(
+              `${this.constructor.name}: error while injecting extra info: `,
+              err);
+        });
+  }
+
+  /**
+   * Add chips which contain |chipContentList| to |node|. If |withContainer| is
+   * set to true, a container will contain all the chips.
+   */
+  addExtraInfoChips(chipContentList, node, withContainer = false) {
+    if (chipContentList.length == 0) return;
+
+    let container;
+    if (withContainer) {
+      container = document.createElement('div');
+      container.classList.add('TWPT-extrainfo-container');
+    } else {
+      container = node;
+    }
+
+    let tooltips = [];
+
+    for (const content of chipContentList) {
+      const tooltip = this.addChipToContainer(content, container);
+      tooltips.push(tooltip);
+    }
+
+    if (withContainer) node.append(container);
+
+    for (const tooltip of tooltips) new MDCTooltip(tooltip);
+  }
+
+  /**
+   * Adds a chip to the container and returns a tooltip element to be
+   * instantiated.
+   */
+  addChipToContainer(chipContent, container) {
+    let chip = document.createElement('material-chip');
+    chip.classList.add('TWPT-extrainfo-chip');
+
+    let chipContentContainer = document.createElement('div');
+    chipContentContainer.classList.add('TWPT-chip-content-container');
+
+    let content = document.createElement('div');
+    content.classList.add('TWPT-content');
+
+    const [badge, badgeTooltip] = createExtBadge();
+
+    let span = document.createElement('span');
+    span.append(chipContent);
+
+    content.append(badge, span);
+    chipContentContainer.append(content);
+    chip.append(chipContentContainer);
+    container.append(chip);
+
+    return badgeTooltip;
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/injections/expandedThreadList.js b/src/contentScripts/communityConsole/extraInfo/injections/expandedThreadList.js
new file mode 100644
index 0000000..f5a6874
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/injections/expandedThreadList.js
@@ -0,0 +1,39 @@
+import {MDCTooltip} from '@material/tooltip';
+
+import {parseUrl} from '../../../../common/commonUtils.js';
+import ThreadExtraInfoService from '../services/thread.js';
+
+import BaseExtraInfoInjection from './base.js';
+
+export default class ExpandedThreadListExtraInfoInjection extends
+    BaseExtraInfoInjection {
+  getInjectionDetails(toolbelt) {
+    const headerContent =
+        toolbelt?.parentNode?.parentNode?.parentNode?.querySelector?.(
+            '.main-header .header a.header-content');
+    if (headerContent === null) {
+      throw new Error(
+          `extraInfo: Header is not present in the thread item's DOM.`);
+    }
+
+    const threadInfo = parseUrl(headerContent.href);
+    if (threadInfo === false)
+      throw new Error(`extraInfo: Thread's link cannot be parsed.`);
+
+    return {
+      toolbelt,
+      threadInfo,
+      isExpanded: true,
+    };
+  }
+
+  inject(threads, injectionDetails) {
+    const thread = ThreadExtraInfoService.getThreadFromThreadList(
+        threads, injectionDetails.threadInfo);
+    const [chipContentList, tooltips] =
+        ThreadExtraInfoService.getThreadChips(thread);
+    this.addExtraInfoChips(
+        chipContentList, injectionDetails.toolbelt, /* withContainer = */ true);
+    for (const tooltip of tooltips) new MDCTooltip(tooltip);
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/injections/profileAbuse.js b/src/contentScripts/communityConsole/extraInfo/injections/profileAbuse.js
new file mode 100644
index 0000000..2ba911c
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/injections/profileAbuse.js
@@ -0,0 +1,78 @@
+import {kAbuseCategories, kAbuseViolationCategories, kAbuseViolationCategoriesI18n, kAbuseViolationTypes} from '../consts.js';
+
+import BaseExtraInfoInjection from './base.js';
+
+export default class ProfileAbuseExtraInfoInjection extends
+    BaseExtraInfoInjection {
+  constructor(infoHandler, optionsWatcher) {
+    super(infoHandler, optionsWatcher);
+    this.unifiedUserView = undefined;
+  }
+
+  inject(profileInfo, injectionDetails) {
+    this.unifiedUserView = profileInfo.body?.['1'];
+    const chips = this.getChips();
+    this.addExtraInfoChips(
+        chips, injectionDetails.card, /* withContainer = */ true);
+  }
+
+  getChips() {
+    const chips = [
+      this.getGeneralAbuseViolationCategoryChip(),
+      ...this.getProfileAbuseChips(),
+      this.getAppealCountChip(),
+    ];
+
+    return chips.filter(chip => chip !== null);
+  }
+
+  getGeneralAbuseViolationCategoryChip() {
+    const abuseViolationCategory = this.unifiedUserView?.['6'];
+    if (!abuseViolationCategory) return null;
+    return this.getAbuseViolationCategoryChipContent(abuseViolationCategory);
+  }
+
+  getProfileAbuseChips() {
+    return kAbuseCategories
+        .map(category => {
+          return this.getProfileAbuseCategoryChip(category);
+        })
+        .filter(chip => chip !== null);
+  }
+
+  getAppealCountChip() {
+    const profileAbuse = this.unifiedUserView?.['1']?.['8'];
+    const appealCount = profileAbuse?.['4'];
+    if (appealCount === undefined) return null;
+
+    return chrome.i18n.getMessage(
+        'inject_extrainfo_profile_appealsnum', [appealCount]);
+  }
+
+  getAbuseViolationCategoryChipContent(abuseViolationCategory) {
+    const content = document.createElement('span');
+
+    const categoryI18nKey = 'inject_extrainfo_profile_abusecategory_' +
+        kAbuseViolationCategoriesI18n[abuseViolationCategory];
+    const categoryLocalized =
+        chrome.i18n.getMessage(categoryI18nKey) ?? abuseViolationCategory;
+    content.textContent = chrome.i18n.getMessage(
+        'inject_extrainfo_profile_abusecategory', [categoryLocalized]);
+
+    content.title = kAbuseViolationCategories[abuseViolationCategory] ??
+        abuseViolationCategory;
+
+    return content;
+  }
+
+  getProfileAbuseCategoryChip(abuseCategory) {
+    const [protoIndex, category] = abuseCategory;
+    const profileAbuse = this.unifiedUserView?.['1']?.['8'];
+    const violation = profileAbuse?.[protoIndex]?.['1']?.['1'];
+    if (!violation) return null;
+
+    return chrome.i18n.getMessage(
+        'inject_extrainfo_profile_abuse_' + category,
+        [kAbuseViolationTypes[violation]]);
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/injections/profilePerForumStats.js b/src/contentScripts/communityConsole/extraInfo/injections/profilePerForumStats.js
new file mode 100644
index 0000000..57278ee
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/injections/profilePerForumStats.js
@@ -0,0 +1,22 @@
+import {getDisplayLanguage} from '../../utils/common.js';
+import PerForumStatsSection from '../../utils/PerForumStatsSection.js';
+
+import BaseExtraInfoInjection from './base.js';
+
+export default class ProfilePerForumStatsExtraInfoInjection extends
+    BaseExtraInfoInjection {
+  constructor(infoHandler, optionsWatcher) {
+    super(infoHandler, optionsWatcher);
+    this.displayLanguage = getDisplayLanguage();
+  }
+
+  async isEnabled() {
+    return await this.optionsWatcher.isEnabled('perforumstats');
+  }
+
+  inject(profileInfo, injectionDetails) {
+    new PerForumStatsSection(
+        injectionDetails.chart?.parentNode, profileInfo.body,
+        this.displayLanguage, /* isCommunityConsole = */ true);
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/injections/threadList.js b/src/contentScripts/communityConsole/extraInfo/injections/threadList.js
new file mode 100644
index 0000000..c4e807c
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/injections/threadList.js
@@ -0,0 +1,71 @@
+import {MDCTooltip} from '@material/tooltip';
+
+import {parseUrl} from '../../../../common/commonUtils.js';
+import {createExtBadge} from '../../utils/common.js';
+import {kItemMetadataState, kItemMetadataStateI18n} from '../consts.js';
+import ThreadExtraInfoService from '../services/thread.js';
+
+import BaseExtraInfoInjection from './base.js';
+
+export default class ThreadListExtraInfoInjection extends
+    BaseExtraInfoInjection {
+  getInjectionDetails(li) {
+    const headerContent = li.querySelector(
+        'ec-thread-summary .main-header .header a.header-content');
+    if (headerContent === null) {
+      throw new Error(
+          `extraInfo: Header is not present in the thread item's DOM.`);
+    }
+
+    const threadInfo = parseUrl(headerContent.href);
+    if (threadInfo === false)
+      throw new Error(`extraInfo: Thread's link cannot be parsed.`);
+
+    return {
+      li,
+      threadInfo,
+      isExpanded: false,
+    };
+  }
+
+  inject(threads, injectionDetails) {
+    const thread = ThreadExtraInfoService.getThreadFromThreadList(
+        threads, injectionDetails.threadInfo);
+
+    const state = thread?.['2']?.['12']?.['1'];
+    if (!state || [1, 13, 18, 9].includes(state)) return;
+
+    const [label, badgeTooltip] = this.createLabelElement(state);
+    const authorLine = this.getAuthorLine(injectionDetails.li);
+    authorLine.prepend(label);
+
+    new MDCTooltip(badgeTooltip);
+  }
+
+  createLabelElement(state) {
+    const label = document.createElement('div');
+    label.classList.add('TWPT-label');
+
+    const [badge, badgeTooltip] = createExtBadge();
+
+    let span = document.createElement('span');
+    const stateI18nKey =
+        'inject_extrainfo_message_state_' + kItemMetadataStateI18n[state];
+    span.textContent = chrome.i18n.getMessage(stateI18nKey) ?? state;
+    span.title = kItemMetadataState[state] ?? state;
+
+    label.append(badge, span);
+
+    return [label, badgeTooltip];
+  }
+
+  getAuthorLine(li) {
+    const authorLine = li.querySelector(
+        'ec-thread-summary .header-content .top-row .author-line');
+    if (!authorLine) {
+      throw new Error(
+          `extraInfo: Author line is not present in the thread item's DOM.`);
+    }
+    return authorLine;
+  }
+}
diff --git a/src/contentScripts/communityConsole/extraInfo/services/thread.js b/src/contentScripts/communityConsole/extraInfo/services/thread.js
new file mode 100644
index 0000000..357ed3d
--- /dev/null
+++ b/src/contentScripts/communityConsole/extraInfo/services/thread.js
@@ -0,0 +1,159 @@
+import {createPlainTooltip} from '../../../../common/tooltip.js';
+import {kItemMetadataState, kItemMetadataStateI18n} from '../consts.js';
+
+export default class ThreadExtraInfoService {
+  /**
+   * Get a |chipContentList| array with the chips related to the thread, and a
+   * |tooltips| array with the corresponding tooltips which should be
+   * initialized after the chips are added to the DOM.
+   */
+  static getThreadChips(thread) {
+    let chips = [];
+    let tooltips = [];
+
+    const [pendingStateInfo, pendingTooltip] = this.getPendingStateChip(thread);
+    if (pendingStateInfo) chips.push(pendingStateInfo);
+    if (pendingTooltip) tooltips.push(pendingTooltip);
+
+    chips.push(...this.getTrendingChips(thread));
+    chips.push(...this.getMetadataChips(thread));
+
+    const [liveReviewInfo, liveReviewTooltip] =
+        this.getLiveReviewStatusChip(thread);
+    if (liveReviewInfo) chips.push(liveReviewInfo);
+    if (liveReviewTooltip) tooltips.push(liveReviewTooltip);
+
+    return [chips, tooltips];
+  }
+
+  static getPendingStateChip(thread) {
+    const endPendingStateTimestampMicros = thread?.['2']?.['39'];
+    const endPendingStateTimestamp =
+        Math.floor(endPendingStateTimestampMicros / 1e3);
+    const now = Date.now();
+    if (!endPendingStateTimestampMicros || endPendingStateTimestamp < now)
+      return [null, null];
+
+    const span = document.createElement('span');
+    span.textContent =
+        chrome.i18n.getMessage('inject_extrainfo_message_pendingstate');
+
+    const date = new Date(endPendingStateTimestamp).toLocaleString();
+    const pendingTooltip = createPlainTooltip(
+        span,
+        chrome.i18n.getMessage(
+            'inject_extrainfo_message_pendingstate_tooltip', [date]),
+        false);
+    return [span, pendingTooltip];
+  }
+
+  static getTrendingChips(thread) {
+    const chips = [];
+
+    const isTrending = thread?.['2']?.['25'];
+    const isTrendingAutoMarked = thread?.['39'];
+    if (isTrendingAutoMarked)
+      chips.push(document.createTextNode(
+          chrome.i18n.getMessage('inject_extrainfo_thread_autotrending')));
+    else if (isTrending)
+      chips.push(document.createTextNode(
+          chrome.i18n.getMessage('inject_extrainfo_thread_trending')));
+
+    return chips;
+  }
+
+  static getMetadataChips(thread) {
+    const itemMetadata = thread?.['2']?.['12'];
+
+    return [
+      this.getStateChip(itemMetadata),
+      this.getShadowBlockChip(itemMetadata),
+    ].filter(chip => chip !== null);
+  }
+
+  static getLiveReviewStatusChip(thread) {
+    const liveReviewStatus = thread?.['2']?.['38'];
+    const verdict = liveReviewStatus?.['1'];
+    if (!verdict) return [null, null];
+
+    const [label, labelClass] = this.getLiveReviewStatusLabel(verdict);
+    if (!label || !labelClass) return [null, null];
+
+    const reviewedBy = liveReviewStatus?.['2'];
+    const timestamp = liveReviewStatus?.['3'];
+    const date = (new Date(Math.floor(timestamp / 1e3))).toLocaleString();
+
+    let a = document.createElement('a');
+    a.href = 'https://support.google.com/s/community/user/' + reviewedBy;
+    a.classList.add(labelClass);
+    a.textContent = chrome.i18n.getMessage(
+        'inject_extrainfo_message_livereviewverdict',
+        [chrome.i18n.getMessage(
+            'inject_extrainfo_message_livereviewverdict_' + label)]);
+    let liveReviewTooltip = createPlainTooltip(a, date, false);
+    return [a, liveReviewTooltip];
+  }
+
+  static getStateChip(itemMetadata) {
+    const state = itemMetadata?.['1'];
+    if (!state || state == 1) return null;
+
+    const stateI18nKey =
+        'inject_extrainfo_message_state_' + kItemMetadataStateI18n[state];
+    const stateLocalized = chrome.i18n.getMessage(stateI18nKey) ?? state;
+
+    const span = document.createElement('span');
+    span.textContent = chrome.i18n.getMessage(
+        'inject_extrainfo_message_state', [stateLocalized]);
+    span.title = kItemMetadataState[state] ?? state;
+    return span;
+  }
+
+  static getLiveReviewStatusLabel(verdict) {
+    let label, labelClass;
+    switch (verdict) {
+      case 1:  // LIVE_REVIEW_RELEVANT
+        label = 'relevant';
+        labelClass = 'TWPT-extrainfo-good';
+        break;
+
+      case 2:  // LIVE_REVIEW_OFF_TOPIC
+        label = 'offtopic';
+        labelClass = 'TWPT-extrainfo-bad';
+        break;
+
+      case 3:  // LIVE_REVIEW_ABUSE
+        label = 'abuse';
+        labelClass = 'TWPT-extrainfo-bad';
+        break;
+
+      default:
+        return [null, null];
+    }
+    return [label, labelClass];
+  }
+
+  static getShadowBlockChip(itemMetadata) {
+    const shadowBlockInfo = itemMetadata?.['10'];
+    const blockedTimestampMicros = shadowBlockInfo?.['2'];
+    if (!blockedTimestampMicros) return null;
+
+    const isBlocked = shadowBlockInfo?.['1'];
+    let span = document.createElement('span');
+    span.textContent = chrome.i18n.getMessage(
+        'inject_extrainfo_message_shadowblock' +
+        (isBlocked ? 'active' : 'notactive'));
+    if (isBlocked) span.classList.add('TWPT-extrainfo-bad');
+    return span;
+  }
+
+  static getThreadFromThreadList(threadList, currentThreadInfo) {
+    return threadList?.find?.(thread => {
+      const threadInfo = thread?.['2']?.['1'];
+      const threadId = threadInfo?.['1'];
+      const forumId = threadInfo?.['3'];
+      return threadId == currentThreadInfo.thread &&
+          forumId == currentThreadInfo.forum;
+    });
+  }
+}
diff --git a/src/contentScripts/communityConsole/main.js b/src/contentScripts/communityConsole/main.js
index b16b42f..3729937 100644
--- a/src/contentScripts/communityConsole/main.js
+++ b/src/contentScripts/communityConsole/main.js
@@ -114,7 +114,7 @@
 
     // Show additional details in the profile view.
     if (node.matches('ec-unified-user .scTailwindUser_profileUsercardmain')) {
-      window.TWPTExtraInfo.injectAtProfileIfEnabled(node);
+      window.TWPTExtraInfo.injectAbuseChipsAtProfileIfEnabled(node);
     }
 
     // Show the "previous posts" links if the option is currently enabled.
diff --git a/src/contentScripts/communityConsole/start.js b/src/contentScripts/communityConsole/start.js
index a597aaa..294c6cd 100644
--- a/src/contentScripts/communityConsole/start.js
+++ b/src/contentScripts/communityConsole/start.js
@@ -5,7 +5,7 @@
 import {kCSTarget, kMWTarget} from '../../xhrInterceptor/responseModifiers/index.js';
 
 import AutoRefresh from './autoRefresh.js';
-import ExtraInfo from './extraInfo.js';
+import ExtraInfo from './extraInfo/index.js';
 import ThreadPageDesignWarning from './threadPageDesignWarning.js';
 import WorkflowsImport from './workflows/import.js';
 
