diff --git a/final-exam-fullsheets.tex b/final-exam-fullsheets.tex
new file mode 100644
index 0000000000000000000000000000000000000000..1b5b6c5bd6388f9f905a7fb26ad1fdee7125010e
--- /dev/null
+++ b/final-exam-fullsheets.tex
@@ -0,0 +1,23 @@
+\documentclass[11pt, portrait]{article}
+\usepackage{multicol}
+\usepackage{listings}
+\usepackage{layout}
+\lstset{basicstyle=\ttfamily,tabsize=4,texcl=true,escapechar=\^,keepspaces,showstringspaces=false,commentstyle=\ttfamily}
+\input{preamble}
+\renewcommand{\exam}{Final~exam}
+
+\begin{document}
+%    \renewcommand{\arraystretch}{2}
+    \Large
+    \begin{enumerate}
+        \item \setlength{\hoffset}{-0.5cm} \input{final-exam/program-state-diagram} \newpage
+        \item \setlength{\hoffset}{0cm} \input{final-exam/code-reading} \newpage
+        \item \setlength{\hoffset}{-1cm} \input{final-exam/class-diagram} \newpage
+        \item \setlength{\hoffset}{0cm} \input{final-exam/testing} \newpage
+        \item \input{final-exam/object-orientation} \newpage
+        \item \input{final-exam/loop-code-writing} \newpage
+        \item \input{final-exam/design-an-algorithm_3-grades} \newpage
+        \item \input{final-exam/unit-testing} \newpage
+        \item \input{final-exam/control-flow-graph}
+    \end{enumerate}
+\end{document}
\ No newline at end of file
diff --git a/final-exam-halfsheets.tex b/final-exam-halfsheets.tex
new file mode 100644
index 0000000000000000000000000000000000000000..8cd577d775821c68ad924dc66646c0b413cb0b7d
--- /dev/null
+++ b/final-exam-halfsheets.tex
@@ -0,0 +1,22 @@
+\documentclass[11pt, portrait]{article}
+\usepackage{multicol}
+\usepackage{listings}
+\lstset{basicstyle=\ttfamily,tabsize=4,texcl=true,escapechar=\^,keepspaces,showstringspaces=false,commentstyle=\ttfamily}
+\input{preamble}
+\renewcommand{\exam}{Final~exam}
+
+\begin{document}
+%    \renewcommand{\arraystretch}{2}
+    \linespread{0.9}
+    \begin{enumerate}
+        \item \input{final-exam/program-state-diagram} \vspace{1cm}
+        \item \input{final-exam/code-reading} \newpage
+        \item \input{final-exam/class-diagram} %\vspace{1cm}
+        \item \input{final-exam/testing} \newpage
+        \item \input{final-exam/object-orientation} \vspace{4cm}
+        \item \input{final-exam/loop-code-writing} \newpage
+        \item \input{final-exam/design-an-algorithm_3-grades} \vspace{4cm}
+        \item \input{final-exam/unit-testing} \newpage
+        \item \input{final-exam/control-flow-graph}
+    \end{enumerate}
+\end{document}
\ No newline at end of file
diff --git a/final-exam/class-diagram.tex b/final-exam/class-diagram.tex
new file mode 100644
index 0000000000000000000000000000000000000000..4bccda249e996d465c42ae8dc285560059aabea7
--- /dev/null
+++ b/final-exam/class-diagram.tex
@@ -0,0 +1,35 @@
+Consider the following class:
+
+\begin{quote}
+    \begin{lstlisting}
+public class Pay {
+  private double hours, amount;
+  public Pay(double hours, double amount) {
+    this.hours = hours;
+    this.amount = amount;
+  }
+  public double getHourlyRate() {
+    return amount / hours;
+  }
+  public boolean isOvertime() {
+    return hours > 40;
+  }
+  public String toString() {
+    String result = "$" + getHourlyRate() + " per hour";
+    if (isOvertime()) {
+      return result + " (overtime)";
+    }
+    return result;
+  }
+}
+    \end{lstlisting}
+\end{quote}
+
+Draw a class diagram for \lstinline{Pay}.
+
+Evaluate the code below to determine the value of \lstinline{myPay}:
+\begin{quote}
+    \begin{lstlisting}
+String myPay = new Pay(10.0,5.0).toString();
+    \end{lstlisting}
+\end{quote}
\ No newline at end of file
diff --git a/final-exam/code-reading.tex b/final-exam/code-reading.tex
new file mode 100644
index 0000000000000000000000000000000000000000..08894d5c0b7b43b143c47396367a4cc787278bbb
--- /dev/null
+++ b/final-exam/code-reading.tex
@@ -0,0 +1,32 @@
+Consider the following class:
+
+\begin{quote}
+    \begin{lstlisting}
+public class Point {
+  private int x, y;
+  public Point(int x, int y) {
+    this.x = x;
+    this.y = y;
+  }
+  public Point translate(int dx, int dy) {
+    this.x += dx;
+    this.y += dy;
+    return this;
+  }
+  public Point mystery() {
+    return translate(-2 * x, -2 * y);
+  }
+  public String toString() {
+    return "(" + x + ", " + y + ")";
+  }
+}
+    \end{lstlisting}
+\end{quote}
+
+Determine what would be printed by the following statement
+
+\begin{quote}
+    \begin{lstlisting}
+System.out.println(new Point(4, 6).mystery());
+    \end{lstlisting}
+\end{quote}
\ No newline at end of file
diff --git a/final-exam/control-flow-graph.tex b/final-exam/control-flow-graph.tex
new file mode 100644
index 0000000000000000000000000000000000000000..e0eb3bfc82714a99ac15ec0d85915aa9a3e02de8
--- /dev/null
+++ b/final-exam/control-flow-graph.tex
@@ -0,0 +1,21 @@
+Draw a control-flow graph for the code listed below.
+
+\begin{quote}
+    \begin{lstlisting}[numbers=left]
+int[] data = new int[] { 2, 11, 18, 4 };
+int size = data.length;
+int[] moreData = new int[size];
+for (int i = 0; i < size; ++i) {
+  if (i > 0) {
+    moreData[i] = data[i - 1];
+  } else {
+    moreData[i] = data[i] - 1;
+  }
+}
+for (int i = size - 1; i >= 0; --i) {
+  System.out.println(moreData[i]);
+}
+    \end{lstlisting}
+\end{quote}
+
+Write the values printed by this code in the order they are printed.
\ No newline at end of file
diff --git a/final-exam/design-an-algorithm_3-grades.tex b/final-exam/design-an-algorithm_3-grades.tex
new file mode 100644
index 0000000000000000000000000000000000000000..e3999f8743ca83beabdf368b6dc3829d6694b656
--- /dev/null
+++ b/final-exam/design-an-algorithm_3-grades.tex
@@ -0,0 +1,8 @@
+Suppose you are designing an algorithm to find the best grade among
+three exam grades given as integer percentages.
+
+\begin{enumerate}
+    \item Give a detailed restatement of the problem as an outline of subproblems (you do not need to include the subproblem of getting the three grades as inputs).
+    \item Give a solution to the problem as a sequence of steps.
+    \item Show, with arrows, the mapping from subproblems to the parts of your solution that solve those subproblems.
+\end{enumerate}
diff --git a/final-exam/loop-code-writing.tex b/final-exam/loop-code-writing.tex
new file mode 100644
index 0000000000000000000000000000000000000000..4005d3937186128079f5a33ff1a0b8462035938a
--- /dev/null
+++ b/final-exam/loop-code-writing.tex
@@ -0,0 +1,4 @@
+Suppose the function \lstinline{hasCross} takes two arguments, an \(x\)~coordinate and a \(y\)~coordinate, and returns \lstinline{true} if that position on a certain tic-tac-toe board is occupied by an `X', \lstinline{false} otherwise.
+Similarly, the function \lstinline{hasNaught} takes two coordinates and returns \lstinline{true} if the position is occupied by an `O'.
+Tic-tac-toe boards are usually \(3\times 3\), so both coordinates range from 0 to~2.
+Write code to set the variable \lstinline{empty} to \lstinline{true} if the entire board is blank (no square is occupied by either symbol), but to \lstinline{false} otherwise.
\ No newline at end of file
diff --git a/final-exam/object-orientation.tex b/final-exam/object-orientation.tex
new file mode 100644
index 0000000000000000000000000000000000000000..251034e67e29ab529ee3c05fbb3c0d167aaca5e3
--- /dev/null
+++ b/final-exam/object-orientation.tex
@@ -0,0 +1,20 @@
+Given the following class diagram, write the class in Java:
+
+%\illustration{0}
+    \begin{center}
+        \begin{tabular}{|c@{}l|}
+            \hline
+            \multicolumn{2}{|c|}{Course} \\ \hline
+            + & title : String                               \\
+            - & corequisites : List$\langle$Course$\rangle$  \\
+            - & prerequisites : List$\langle$Course$\rangle$ \\ \hline
+        \end{tabular}
+    \end{center}
+
+Add the code for a constructor that takes one argument, \lstinline{title}.
+The constructor should also set \lstinline{corequisites} to a new, empty \lstinline{ArrayList} and \lstinline{prerequisites} to a new, empty \lstinline{ArrayList}.
+You do not need to write getters and setters.
+
+\vspace{1cm}
+
+Write a line of Java code to create a course titled \lstinline{"Software Engineering I"} and store that course in a newly declared variable named \lstinline{soft160}.
diff --git a/final-exam/program-state-diagram.tex b/final-exam/program-state-diagram.tex
new file mode 100644
index 0000000000000000000000000000000000000000..202ddbeae3ce42508d64c4c58480881e552ea88b
--- /dev/null
+++ b/final-exam/program-state-diagram.tex
@@ -0,0 +1,23 @@
+Draw a program state diagram (showing all contexts) for the
+program state just after line 9 executes. What is the output of the program?
+
+\begin{quote}
+    \begin{lstlisting}[numbers=left]
+private static boolean fie(int fum) {
+  for (int i=0; i<2; ++i){
+    fum++;
+  }
+  if (fum > 3) {return true;}
+  return false;
+}
+private static int baz(int fum) {
+  boolean result = fie(fum+1);
+  if (result) {return fum;}
+  return -fum;
+}
+public static void main(String... arguments) {
+  int fum = baz(1);
+  System.out.println(fum + " " + (0 < fum && fum < 5));
+}
+    \end{lstlisting}
+\end{quote}
\ No newline at end of file
diff --git a/final-exam/testing.tex b/final-exam/testing.tex
new file mode 100644
index 0000000000000000000000000000000000000000..871bc4b94611b3f403736f523038f442d45989a3
--- /dev/null
+++ b/final-exam/testing.tex
@@ -0,0 +1,26 @@
+Consider category-partition testing of a method.
+
+\begin{enumerate}
+    \item What artifacts would a software engineer consult to design such tests?
+    \item What artifacts would be analyzed by running such tests?
+    \item What metrics would be measured by running such tests?
+    \item Which of the following quality dimensions from the list below would each of those metrics speak to?
+        \begin{quote}
+            \begin{multicols}{2}
+                \begin{itemize}
+                    \item{Functional correctness}
+                    \item{Code complexity}
+                    \item{Readability}
+                    \item{Testability}
+                    \item{Testedness}
+                    \item{Scalability}
+                    \item{Compatibility}
+                    \item{Portability}
+                    \item{Usability}
+                \end{itemize}
+            \end{multicols}
+        \end{quote}
+    \item How do your answers change if coverage information is collected while testing?
+    \item Is category-partition testing a white-box or black-box testing technique?
+        Justify your response.
+\end{enumerate}
diff --git a/final-exam/unit-testing.tex b/final-exam/unit-testing.tex
new file mode 100644
index 0000000000000000000000000000000000000000..131c487228478cee73e5709a836141f843ea02b6
--- /dev/null
+++ b/final-exam/unit-testing.tex
@@ -0,0 +1,34 @@
+You are using the category-partition method to unit test a method \lstinline{countWords} with the parameter \lstinline{identifier} of type \lstinline{String}.
+The \lstinline{countWords} method has the following specification:
+
+\begin{quote}
+    The \lstinline{countWords} method shall take a camel-case string called \lstinline{identifier} and return the number of nonempty pieces \lstinline{identifier} would be divided into if it were broken just before every capital letter~(\lstinline{A}--\lstinline{Z}).
+    For example, if
+    \lstinline{identifier} were the string \lstinline{"AlphaBCharlie"}, \lstinline{countWords} would return~\lstinline{3} because the string would break into three words:
+    \lstinline{"Alpha"}, \lstinline{"B"}, and \lstinline{"Charlie"}.
+\end{quote}
+
+\begin{quote}
+    \begin{itemize}
+        \item{\lstinline{identifier}'s length:}
+        \item{number of words in \lstinline{identifier}:}
+        \item{\lstinline{identifier} starts with a capital letter:}
+        \item{\lstinline{identifier} contains a one-letter word:}
+        \item{return value:}
+    \end{itemize}
+\end{quote}
+
+\begin{enumerate}
+    \item Given the specification above, identify a partition for each category and the return value.
+    \item Identify a representative value for each choice.
+    \item Write a set of test frames that achieve 1-way coverage of your partitions.
+    \item Using your partitions from above and the following JUnit test template, create a JUnit test that matches the test name.
+
+        \begin{lstlisting}
+@Test
+public void countWords() {
+  int result = Editor.countWords(^\codeblank^);
+  assertEquals(^\codeblank^, result);
+}
+        \end{lstlisting}
+\end{enumerate}
diff --git a/preamble.tex b/preamble.tex
index b8bbd7ac481de33590f3c2b4598d06c11ed8530e..0cf9436b37e2a0bce055da472f228f45b27a8be4 100644
--- a/preamble.tex
+++ b/preamble.tex
@@ -40,6 +40,9 @@
 \newcommand{\Let}[2]{\KwLet{#1\({\null}\leftarrow{\null}\)#2}\;}
 \SetKwFor{Function}{function}{}{end}
 
+% fill-in-the-blanks in code
+\newcommand{\codeblank}{\ensuremath{\underbar{\vphantom{\raisebox{12pt}{Yy}}\qquad\qquad\qquad\qquad}}}
+
 % graphics
 \usepackage{graphicx}