class ModifyClinician implements Runnable {

    @Override
    public void run() {
        Optional<Clinician> clinician = manager.getClinicianByStaffId(id);

        if (!clinician.isPresent()) {
            outputStream.println("No clinician exists with that staff ID");
            return;
        }

        if (!RegionValidator.isValid(country == null ? clinician.get().getCountry() : country, region)) {
            outputStream.printf("%s is not a valid NZ region%n", region);
            return;
        }

        ModifyClinicianAction action = new ModifyClinicianAction(clinician.get(), manager);

        Map<String, Object[]> updates = new HashMap<>();
        updates.put("setFirstName", new String[]{clinician.get().getFirstName(), firstName});
        updates.put("setMiddleName", new String[]{clinician.get().getMiddleName(), middleNames});
        updates.put("setLastName", new String[]{clinician.get().getLastName(), lastName});
        updates.put("setWorkAddress", new String[]{clinician.get().getWorkAddress(), workAddress});
        updates.put("setRegion", new String[]{clinician.get().getRegion(), region});
        updates.put("setCountry", new Country[]{clinician.get().getCountry(), country});
        updates.put("setPassword", new String[]{clinician.get().getPassword(), password});

        for (Entry<String, Object[]> entry : updates.entrySet()) {
            if (entry.getValue()[1] == null) {
                continue;
            }
            try {
                action.addChange(entry.getKey(), entry.getValue()[0], entry.getValue()[1]);
            } catch (ReflectiveOperationException e) {
                LOGGER.log(Level.WARNING, e.getMessage(), e);
            }
        }

        outputStream.println(invoker.execute(action));

    }

    public  ModifyClinician(PrintStream outputStream, ActionInvoker invoker);
    public  ModifyClinician(ClinicianManager manager, ActionInvoker invoker);

}