Added a test for issue #52 that currently fails.
Changed the signature of getStudent(id) in GradeBook to return an Optional<Student>.  This had a number of ripples in the codebase.  I also added a Stream<Student> API to GradeBook to make it easier to iterate over the students in a GradeBook (which was one of the primary uses of getStudent(id)).  I resisted the urge to do further cleanup in some of these ancient classes.
To address issue #52, if a student submits a project under a different student id than the one that he/she used when filling out the Survey, then the submissions processor will consider the student's full name (first and last) when looking for the student in the grade book.
Refactored test to make it easier to add more tests.
When looking for students who submitting a project, match using the nick name and last name.
Cleaned up tests some more.
When looking for which student submitted a project, match based on email address.
Test that a SubmissionException is thrown when the student information in the submission matches no student in the grade book.
Refactored implementation to use fewer Streams and Lambdas.
Merge pull request #95 from DavidWhitlock/issue-52-student-id-different-in-submission

Match submissions to students using criteria other than just student id.

To address issue #52, I augmented the ProjectSubmissionsProcessor to use the name and email address of the student who submitted the project (in addition to the student id) to locate the student in the grade book. Along the way, I did a pretty major refactor that involved changing the signature of GradeBook's getStudent method to return an Optional<Student> and I added a Stream API to work with all of the Students in a GradeBook.