diff --git a/project-plan/.gitignore b/project-plan/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f35f60a357424aa265b3a6c1933c26af537c57ad
--- /dev/null
+++ b/project-plan/.gitignore
@@ -0,0 +1,62 @@
+# Mac file finder metadata
+.DS_Store
+# Windows file metadata
+._*
+# Thumbnail image caches
+Thumbs.db
+ethumbs.db
+# MS Office temporary file
+~*
+# Emacs backup file
+*~
+
+# Common
+[Bb]in/
+[Bb]uild/
+[Oo]bj/
+[Oo]ut/
+[Tt]mp/
+[Xx]86/
+[Ii][Aa]32/
+[Xx]64/
+[Xx]86_64/
+[Xx]86-64/
+[Aa]rm
+[Aa]32
+[Tt]32
+[Aa]64
+*.tmp
+*.bak
+*.bk
+*.swp
+
+# Java files
+*.class
+javadoc/
+
+# Maven
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+
+# JetBrains (IntelliJ IDEA, PyCharm, etc) files
+.idea/
+cmake-build-*/
+*.iml
+*.iws
+*.ipr
+
+# Eclipse files
+.settings/
+.project
+.classpath
+.buildpath
+.loadpath
+.factorypath
+local.properties
diff --git a/project-plan/pom.xml b/project-plan/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..605ee4959f44b81ea93244ec785aa7af58407292
--- /dev/null
+++ b/project-plan/pom.xml
@@ -0,0 +1,36 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>edu.unl.cse.soft160.project_plan</groupId>
+  <artifactId>project_plan</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>project_plan</name>
+  <url>http://maven.apache.org</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Demo.java b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Demo.java
new file mode 100644
index 0000000000000000000000000000000000000000..854a3252018b0111ce115f3913f81486d157ddec
--- /dev/null
+++ b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Demo.java
@@ -0,0 +1,54 @@
+package edu.unl.cse.soft160.project_plan;
+
+public class Demo {
+    public static void main(String... arguments) {
+        Team alpha = new Team("Team Alpha");
+        alpha.addMember(TeamMemberRole.TEAM_LEAD, "Eve", "eve@example.com");
+        alpha.addMember(TeamMemberRole.CODING_LEAD, "Carol", "carol@example.com");
+        alpha.addMember(TeamMemberRole.UX_LEAD, "Bob", "bob@example.com");
+        alpha.addMember(TeamMemberRole.VERIFICATION_LEAD, "Alice", "alice@example.com");
+        for (String name : new String[] { "Alice", "Bob", "Carol", "Dan", "Eve" }) {
+            System.out.print("Email for " + name + ": ");
+            try {
+                System.out.println(alpha.getEmail(name));
+            } catch (IllegalArgumentException exception) {
+                System.out.println(exception.getMessage());
+            }
+        }
+        System.out.println();
+        Project bravo = new Project("Bravo", alpha);
+        Task gatherRequirements = new Task("Gather Requirements");
+        Task implementLogic = new Task("Implement Logic");
+        Task implementBackend = new Task("Implement Backend");
+        Task implementUI = new Task("Implement UI");
+        Task verify = new Task("Verify");
+        verify.addPredecessor(implementLogic);
+        verify.addPredecessor(implementBackend);
+        verify.addPredecessor(implementUI);
+        implementLogic.addPredecessor(gatherRequirements);
+        implementBackend.addPredecessor(gatherRequirements);
+        implementUI.addPredecessor(gatherRequirements);
+        bravo.addTask(gatherRequirements);
+        bravo.addTask(implementLogic);
+        bravo.addTask(implementBackend);
+        bravo.addTask(implementUI);
+        bravo.addTask(verify);
+        System.out.println(bravo);
+        System.out.println();
+        gatherRequirements.complete();
+        System.out.println(bravo);
+        System.out.println();
+        implementLogic.complete();
+        System.out.println(bravo);
+        System.out.println();
+        implementBackend.complete();
+        System.out.println(bravo);
+        System.out.println();
+        implementUI.complete();
+        System.out.println(bravo);
+        System.out.println();
+        verify.complete();
+        System.out.println(bravo);
+        System.out.println();
+    }
+}
diff --git a/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Project.java b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Project.java
new file mode 100644
index 0000000000000000000000000000000000000000..01d04bd57bfc349afaabe3136e659f7a86111aa3
--- /dev/null
+++ b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Project.java
@@ -0,0 +1,41 @@
+package edu.unl.cse.soft160.project_plan;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class Project {
+    private String name;
+    private Team team;
+    private Set<Task> tasks;
+
+    public Project(String name, Team team) {
+        this.name = name;
+        this.team = team;
+        tasks = new HashSet<Task>();
+    }
+
+    public void addTask(Task task) {
+        tasks.add(task);
+    }
+
+    public Set<Task> getTasks(TaskStatus status) {
+        Set<Task> result = new HashSet<Task>();
+        for (Task task : tasks) {
+            if (task.getStatus() == status) {
+                result.add(task);
+            }
+        }
+        return result;
+    }
+
+    public String toString() {
+        String result = "Project " + name + " (assigned to " + team + "):\n";
+        for (TaskStatus status : TaskStatus.values()) {
+            result += " " + status + ":\n";
+            for (Task task : getTasks(status)) {
+                result += "  " + task + "\n";
+            }
+        }
+        return result + "End Project";
+    }
+}
diff --git a/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Task.java b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Task.java
new file mode 100644
index 0000000000000000000000000000000000000000..a74392986ef761140e47c7b6762eef0693c30eae
--- /dev/null
+++ b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Task.java
@@ -0,0 +1,25 @@
+package edu.unl.cse.soft160.project_plan;
+
+public class Task {
+    public Task(String name) {
+        // TODO: replace stub
+    }
+
+    public void addPredecessor(Task other) {
+        // TODO: replace stub
+    }
+
+    public TaskStatus getStatus() {
+        // TODO: replace stub
+        return TaskStatus.BLOCKED;
+    }
+
+    public void complete() {
+        // TODO: replace stub
+    }
+
+    public String toString() {
+        // TODO: replace stub
+        return "〈Placeholder〉";
+    }
+}
diff --git a/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/TaskStatus.java b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/TaskStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..48103543aa0e517205f09cd09e9dbf412d26f3fc
--- /dev/null
+++ b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/TaskStatus.java
@@ -0,0 +1,5 @@
+package edu.unl.cse.soft160.project_plan;
+
+public enum TaskStatus {
+    READY, BLOCKED, COMPLETED,
+}
diff --git a/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Team.java b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Team.java
new file mode 100644
index 0000000000000000000000000000000000000000..f08c8655d71ac95fb5aab9dd3b3c905ba5b5ba45
--- /dev/null
+++ b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/Team.java
@@ -0,0 +1,59 @@
+package edu.unl.cse.soft160.project_plan;
+
+public class Team {
+    private String teamName;
+    private String teamLeadName;
+    private String teamLeadEmail;
+    private String codingLeadName;
+    private String codingLeadEmail;
+    private String UXLeadName;
+    private String UXLeadEmail;
+    private String verificationLeadName;
+    private String verificationLeadEmail;
+
+    public Team(String teamName) {
+        this.teamName = teamName;
+    }
+
+    public void addMember(TeamMemberRole role, String name, String email) {
+        switch (role) {
+        case TEAM_LEAD:
+            teamLeadName = name;
+            teamLeadEmail = email;
+            break;
+        case CODING_LEAD:
+            codingLeadName = name;
+            codingLeadEmail = email;
+            break;
+        case UX_LEAD:
+            UXLeadName = name;
+            UXLeadEmail = email;
+            break;
+        case VERIFICATION_LEAD:
+            verificationLeadName = name;
+            verificationLeadEmail = email;
+            break;
+        }
+    }
+
+    public String getEmail(String name) {
+        if (name.equals(teamLeadName)) {
+            return teamLeadEmail;
+        }
+        if (name.equals(codingLeadName)) {
+            return codingLeadEmail;
+        }
+        if (name.equals(UXLeadName)) {
+            return UXLeadEmail;
+        }
+        if (name.equals(verificationLeadName)) {
+            return verificationLeadEmail;
+        }
+        throw new IllegalArgumentException("Unable to find corresponding email address in \"" + this
+                + "\" because no team member has the name \"" + name + "\".");
+    }
+
+    public String toString() {
+        return teamName;
+    }
+}
diff --git a/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/TeamMemberRole.java b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/TeamMemberRole.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab4ac1b78c10d8b1434d3c1ec1973ff9606fcdce
--- /dev/null
+++ b/project-plan/src/main/java/edu/unl/cse/soft160/project_plan/TeamMemberRole.java
@@ -0,0 +1,5 @@
+package edu.unl.cse.soft160.project_plan;
+
+public enum TeamMemberRole {
+    TEAM_LEAD, CODING_LEAD, UX_LEAD, VERIFICATION_LEAD,
+}
diff --git a/project-plan/src/test/java/edu/unl/cse/soft160/project_plan/.gitkeep b/project-plan/src/test/java/edu/unl/cse/soft160/project_plan/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391