diff --git a/common_functions.py b/common_functions.py
index d0dc86cd5cf6d1777ce36e2f7570d320e5f0ca1a..dc4cbac0fa2959b2608a6f5e30416f8f832543d6 100644
--- a/common_functions.py
+++ b/common_functions.py
@@ -1,6 +1,10 @@
 import datetime
+import json
 import re
-from typing import List, Optional, TypeVar
+import ssl
+from typing import Dict, List, Any, Optional, TypeVar
+from urllib import request
+from urllib.error import HTTPError
 
 ChoiceType = TypeVar("ChoiceType")
 
@@ -51,3 +55,17 @@ def semester_stamp() -> str:
     else:
         month = 8
     return f'{year}-0{month}'
+
+
+def finger(login: str, directory: str = 'https://directory.unl.edu/people/') -> Dict[str, Any]:
+    finger_url: str = f'{directory}{login}.json'
+    self_signed_ssl_okay: ssl.SSLContext = ssl.create_default_context()
+    self_signed_ssl_okay.check_hostname = False
+    self_signed_ssl_okay.verify_mode = ssl.CERT_NONE
+    data: str
+    try:
+        with request.urlopen(finger_url, context=self_signed_ssl_okay) as response:
+            data = str(response.read(), 'UTF=8')
+    except HTTPError:
+        data = f'{{"cn":"{login}", "unlSISClassLevel":["Unknown"], "unlSISMajor":["Unknown"]}}'
+    return json.loads(data)
diff --git a/majors.py b/majors.py
index 4df8d5c551553d0507184b98e64cfcb61b08f384..74c391bb2caf067059014a3d7ceb1a74397c3f40 100644
--- a/majors.py
+++ b/majors.py
@@ -1,16 +1,48 @@
-from typing import Set
+from typing import Dict, Set, Any, Optional
+
+from common_functions import finger
 
 
 class Major:
     majors: Set["Major"] = set()
 
-    def __init__(self, name: str, abbreviations: Set[str]):
+    def __init__(self, name: str, alternate_names: Set[str] = None,
+                 abbreviations: Optional[Set[str]] = None, is_cse_major: bool = True):
         self.name: str = name
-        self.abbreviations: Set[str] = abbreviations
+        self.alternate_names: Set[str] = alternate_names if alternate_names is not None else set()
+        self.abbreviations: Set[str] = abbreviations if abbreviations is not None else set()
+        self.is_cse_major: bool = is_cse_major
         Major.majors.add(self)
 
+    @classmethod
+    def get_major(cls, name: str) -> "Major":
+        candidate = [major for major in cls.majors if name == major.name or name in major.alternate_names]
+        if candidate:
+            return candidate[0]
+        else:
+            return Major(name, is_cse_major=False)
+
+    @staticmethod
+    def get_student_majors(login: str) -> Set["Major"]:
+        student_data: Dict[str, Any] = finger(login)
+        if student_data['unlSISClassLevel'] == 'GR':
+            return {Major.get_major('Graduate Student')}
+        else:
+            majors: Optional[Set[str]] = student_data['unlSISMajor']
+            return {Major.get_major(major) for major in majors} if majors is not None else Major.get_major('None')
+
+    def __str__(self) -> str:
+        return self.name
+
+    def __repr__(self) -> str:
+        return f'Name: "{self.name}";\tAlternate Names: {self.alternate_names if self.alternate_names else "{}"};\t' \
+               f'CSE Major: {self.is_cse_major};\tAbbreviations: {self.abbreviations if self.abbreviations else "{}"}'
+
 
-Major('Computer Science', {'COMP-BS', 'COMP-BA', 'COMP-MAJ', 'COMP-BSCS',   # we don't yet have BSCS
-                           'JECS-BS', 'JECS-BA', 'JECS-MAJ', 'JECS-BSCS'})  # but I expect we soon will
-Major('Computer Engineering', {'CENG-BSCP', 'JECE-BSCP'})
-Major('Software Engineering', {'SOFT-BSSE', 'JESE-BSSE'})
+Major('Computer Science', alternate_names={'Computer Science (Raikes)'},
+      abbreviations={'COMP-BS', 'COMP-BA', 'COMP-MAJ', 'COMP-BSCS',  # we don't yet have BSCS
+                     'JECS-BS', 'JECS-BA', 'JECS-MAJ', 'JECS-BSCS'})  # but I expect we soon will
+Major('Computer Engineering', alternate_names={'Computer Engineering (Raikes)'},
+      abbreviations={'CENG-BSCP', 'JECE-BSCP'})
+Major('Software Engineering', alternate_names={'Software Engineering (Raikes)'},
+      abbreviations={'SOFT-BSSE', 'JESE-BSSE'})