@Override
  public ReportDefinition getReportDefinition() {

    String nullString = null;
    ObjectFormatter nullStringConverter = new ObjectFormatter();
    MohCoreService service = Context.getService(MohCoreService.class);

    ReportDefinition report = new PeriodIndicatorReportDefinition();
    report.setName("MOH 361A Report");

    // set up the DSD
    PatientDataSetDefinition dsd = new PatientDataSetDefinition();
    dsd.setName("allPatients");

    // set up parameters
    Parameter facility = new Parameter();
    facility.setName("facility");
    facility.setType(MOHFacility.class);

    // add to report and data set definition
    report.addParameter(facility);
    dsd.addParameter(facility);

    // sort by serial number, then by date
    dsd.addSortCriteria("Transfer Status", SortCriteria.SortDirection.ASC);
    dsd.addSortCriteria("Date Chronic HIV Care Started", SortCriteria.SortDirection.ASC);
    dsd.addSortCriteria("Serial Number", SortCriteria.SortDirection.ASC);

    // set up the columns ...

    // patient id ... until we get this thing working proper
    dsd.addColumn("Person ID", new PersonIdDataDefinition(), nullString);

    // a. serial number
    dsd.addColumn("Serial Number", new SerialNumberDataDefinition(), "facility=${facility}");

    // b. date chronic HIV+ care started
    EnrollmentDateDataDefinition enrollmentDate = new EnrollmentDateDataDefinition();
    dsd.addColumn("Date Chronic HIV Care Started", enrollmentDate, nullString);

    // extra column to help understand reason for including in this cohort
    dsd.addColumn(
        "First Encounter Date At Facility",
        new FirstEncounterAtFacilityDataDefinition(),
        "facility=${facility}",
        new EncounterDatetimeConverter());

    // c. Unique Patient Number
    PatientIdentifierType pit = service.getCCCNumberIdentifierType();
    CohortRestrictedPatientIdentifierDataDefinition cccColumn =
        new CohortRestrictedPatientIdentifierDataDefinition("CCC", pit);
    cccColumn.setIncludeFirstNonNullOnly(true);
    dsd.addColumn("Unique Patient Number", cccColumn, nullString);

    // AMRS Universal ID
    CohortRestrictedPatientIdentifierDataDefinition uidColumn =
        new CohortRestrictedPatientIdentifierDataDefinition(
            "AMRS Universal ID", Context.getPatientService().getPatientIdentifierType(8));
    uidColumn.setIncludeFirstNonNullOnly(true);
    dsd.addColumn("AMRS Universal ID", uidColumn, nullString);

    // AMRS Medical Record Number
    CohortRestrictedPatientIdentifierDataDefinition mrnColumn =
        new CohortRestrictedPatientIdentifierDataDefinition(
            "AMRS Medical Record Number", Context.getPatientService().getPatientIdentifierType(3));
    mrnColumn.setIncludeFirstNonNullOnly(true);
    dsd.addColumn("AMRS Medical Record Number", mrnColumn, nullString);

    // d. Patient's Name
    dsd.addColumn("Name", new CohortRestrictedPreferredNameDataDefinition(), nullString);

    // e1. Date of Birth
    dsd.addColumn(
        "Date of Birth",
        new CohortRestrictedBirthdateDataDefinition(),
        nullString,
        new BirthdateConverter(MOHReportUtil.DATE_FORMAT));

    // e2. Age at Enrollment

    MappedData<EnrollmentDateDataDefinition> mappedDef =
        new MappedData<EnrollmentDateDataDefinition>();
    mappedDef.setParameterizable(enrollmentDate);
    mappedDef.addConverter(new DateConverter());
    CohortRestrictedAgeAtDateOfOtherDataDefinition ageAtEnrollment =
        new CohortRestrictedAgeAtDateOfOtherDataDefinition();
    ageAtEnrollment.setEffectiveDateDefinition(mappedDef);
    dsd.addColumn("Age at Enrollment", ageAtEnrollment, nullString, new DecimalAgeConverter(2));

    // f. Sex
    dsd.addColumn("Sex", new CohortRestrictedGenderDataDefinition(), nullString);

    // g. Entry point: From where?
    PersonAttributeType pat =
        Context.getPersonService()
            .getPersonAttributeTypeByName(MohEvaluableNameConstants.POINT_OF_HIV_TESTING);
    dsd.addColumn(
        "Entry Point",
        new CohortRestrictedPersonAttributeDataDefinition("entryPoint", pat),
        nullString,
        new EntryPointConverter());

    // h. Confirmed HIV+ Date
    dsd.addColumn("Confirmed HIV Date", enrollmentDate, nullString);

    //		// i. PEP Start / Stop Date
    //		LogicDataDefinition columnI = new LogicDataDefinition();
    //		columnI.setLogicQuery("\"MOH PEP Start Stop Date\"");
    //		dsd.addColumn("PEP Start / Stop Date", columnI, nullString);
    //
    //		// j. Reasons for PEP use:
    //		LogicDataDefinition columnJ = new LogicDataDefinition();
    //		columnJ.setLogicQuery("\"MOH Reasons For PEP\"");
    //		dsd.addColumn("Reasons for PEP Use", columnJ, nullString);

    // k. CTX startdate and stopdate:
    dsd.addColumn("CTX Start Stop Date", new CtxStartStopDataDefinition(), nullString);

    // l. Fluconazole startdate and stopdate
    dsd.addColumn(
        "Fluconazole Start Stop Date", new FluconazoleStartStopDataDefinition(), nullString);

    // m. TB treatment startdate and stopdate
    dsd.addColumn("TB Treatment Start Stop Date", new TbStartStopDataDefinition(), nullString);

    // n. Pregnancy Yes?, Due date, PMTCT refer
    dsd.addColumn(
        "Pregnancy EDD and Referral",
        new PmtctPregnancyDataDefinition(),
        nullString,
        new PMTCTDatesConverter());

    // o. LTFU / TO / Dead and date when the event occurred
    dsd.addColumn("LTFU TO DEAD", new LTFUTODeadDataDefinition(), nullString, nullStringConverter);

    // p. WHO clinical Stage and date
    dsd.addColumn(
        "WHO Clinical Stage",
        new FirstWHOStageDataDefinition(),
        nullString,
        new WHOStageAndDateConverter());

    // q. Date medically eligible for ART
    EligibilityForARTDataDefinition eligibility = new EligibilityForARTDataDefinition();
    dsd.addColumn(
        "Date Medically Eligible for ART",
        eligibility,
        nullString,
        new ARVPatientSnapshotDateConverter());

    // r. Reason Medically Eligible for ART
    dsd.addColumn(
        "Reason Medically Eligible for ART",
        eligibility,
        nullString,
        new ARVPatientSnapshotReasonConverter());

    // s. Date ART started (Transfer to ART register)
    dsd.addColumn("Date ART Started", new DateARTStartedDataDefinition(), nullString);

    // additional columns for troubleshooting
    LastHIVEncounterDataDefinition lastHIVEncounter = new LastHIVEncounterDataDefinition();
    dsd.addColumn(
        "Last HIV Encounter Date", lastHIVEncounter, nullString, new EncounterDatetimeConverter());
    dsd.addColumn(
        "Last HIV Encounter Location",
        lastHIVEncounter,
        nullString,
        new EncounterLocationConverter());

    // informative column for the destination clinics
    dsd.addColumn(
        "Last Return to Clinic Date",
        new LastRTCDateDataDefinition(),
        nullString,
        new ObsValueDatetimeConverter());

    // transfer status column (used for sorting, not needed in output)
    dsd.addColumn("Transfer Status", new TransferStatusDataDefinition(), nullString);

    Map<String, Object> mappings = new HashMap<String, Object>();
    mappings.put("facility", "${facility}");
    report.addDataSetDefinition(dsd, mappings);

    return report;
  }