Medical Clinic

Implement a system to manage patients of a medical clinic. The classes are hosted in package clinic. The system must meet the following requirements.

R1: Patients

The main class of the program is class Clinic.

Patients are characterized by the first name, the last name, and the unique social security number (SSN). New patients can be added to the system by means of method addPatient().
The information about a patient can be retrieved by means of method getPatient() that given an SSN returns an object of class Person. Such class provides the getter methods for SSN, first and last names. If the patient does not exist, exception NoSuchPatient is thrown.

R2: Doctors

Doctors are characterized by the first name, last name, SSN, unique badge ID, and the specialization (e.g. "cardiologist", "dentist", etc.). New doctors can be added to the system by means of method addDoctor().
Method getDoctor(), given a badge ID, returns an object of class Doctor. Such class that extends class Person and provide the getter methods for the id and specialization.
If the doctor does not exist, exception NoSuchDoctor is thrown.

Keep in mind that doctors can be patients of the same clinic they work in.

R3: Patient registration

When accepted, a patient is assigned to one of the clinic doctors. To this aim, method assignPatientToDoctor() is provided. Patient is identified by means of her SSN, and doctor is identified by means of her badge ID. If the doctor does not exist, exception NoSuchDoctor is thrown. Further, if the patient does not exist, exception NoSuchPatient is thrown.
By means of method getDoctor() of class Person, it is possible to obtain the Doctor assigned to that person.

By means of method getPatients() of class Doctor returns the list of all patients of that doctor.

R4: Loading

The method loadData() of class Clinic accepts a file path as a parameter and loads from it the information about patients and doctors.
The file is a text file organized by rows; each row contains info about either a patient or a doctor.
Rows containing a person's info begin with letter "P" followed by first name, last name, and SSN. Rows containing doctor's info start with letter "M", followed by badge ID, first name, last name, SSN, and specialization.
The elements on a line are separated by the ";" character.

In case of error in the data present on a line, the method should be able to ignore the row and skip to the next one.
In case of IO errors the method propagates an IOException.

R5: Statistics

The method idleDoctors() returns the collection of doctors that have no patient at all, sorted in alphabetic order.

The method busyDoctors() returns the collection of doctors that are assigned a number of patients larger than the average.

The method doctorsByNumPatients() returns list of strings containing the name of the doctor and the relative number of patients with the relative number of patients, sorted by decreasing number.
The string must be formatted as "### : ID SURNAME NAME" where ### represent the number of patients (printed on three characters).

The method countPatientsPerSpecialization() computes the number of patients per (their doctor's) specialization. The elements are sorted first by decreasing count and then by alphabetic specialization.
The strings are structured as "### - SPECIALITY" where ### represent the number of patients (printed on three characters).

Hint: