private void addIntroductionElement(PersonElementWrapper person, Element rapSheetElement) {

    Element e;
    e = appendElement(rapSheetElement, OjbcNamespaceContext.NS_RAPSHEET_41, "Introduction");
    e = appendElement(e, OjbcNamespaceContext.NS_RAPSHEET_41, "RapSheetRequest");
    Element rsr = e;

    e = appendElement(rsr, OjbcNamespaceContext.NS_RAPSHEET_41, "PurposeCode");
    e.setTextContent("A");

    e = appendElement(rsr, OjbcNamespaceContext.NS_RAPSHEET_41, "Attention");
    e.setTextContent("**CONFIDENTIAL INFORMATION FOR CRIMINAL JUSTICE AGENCIES ONLY**");

    e = appendElement(rsr, OjbcNamespaceContext.NS_RAPSHEET_41, "RapSheetPerson");
    Element rsp = e;

    e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonBirthDate");
    e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
    e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(person.birthdate));

    e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonName");
    Element pn = e;
    e = appendElement(pn, OjbcNamespaceContext.NS_NC, "PersonGivenName");
    e.setTextContent(person.firstName);
    e = appendElement(pn, OjbcNamespaceContext.NS_NC, "PersonMiddleName");
    e.setTextContent(person.middleName);
    e = appendElement(pn, OjbcNamespaceContext.NS_NC, "PersonSurName");
    e.setTextContent(person.lastName);
  }
  private void addProtectionOrderElements(
      Element rapSheetElement, PersonElementWrapper person, DateTime baseDate) {

    int orderCount = generatePoissonInt(.3, false);

    for (int i = 0; i < orderCount; i++) {

      Element orderElement =
          appendElement(rapSheetElement, OjbcNamespaceContext.NS_CH_EXT, "Order");
      Element activityElement =
          appendElement(orderElement, OjbcNamespaceContext.NS_NC, "ActivityIdentification");
      Element e = appendElement(activityElement, OjbcNamespaceContext.NS_NC, "IdentificationID");
      e.setTextContent(generateRandomID("ORDER", 10));
      e = appendElement(activityElement, OjbcNamespaceContext.NS_NC, "IdentificationCategoryText");
      e.setTextContent("TRO DOCUMENT ID");
      e = appendElement(orderElement, OjbcNamespaceContext.NS_NC, "ActivityCategoryText");
      e.setTextContent("TRO");
      e = appendElement(orderElement, OjbcNamespaceContext.NS_NC, "ActivityDate");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
      DateTime orderDate = generateUniformRandomDateBetween(baseDate, baseDate.minusYears(5));
      e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(orderDate));
      e = appendElement(orderElement, OjbcNamespaceContext.NS_JXDM_41, "CourtOrderIssuingCourt");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "OrganizationName");
      e.setTextContent(getRandomCounty(person.state) + " District Court");
      e =
          appendElement(
              orderElement, OjbcNamespaceContext.NS_JXDM_41, "CourtOrderServiceDescriptionText");
      e.setTextContent(generateRandomCodeFromList("PENDING", "SERVED"));
      e = appendElement(orderElement, OjbcNamespaceContext.NS_CH_EXT, "CourtCase");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "ActivityIdentification");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "IdentificationID");
      e.setTextContent("TRO-" + baseDate.getYear() + generateRandomID("-", 8));
      e =
          appendElement(
              orderElement, OjbcNamespaceContext.NS_CH_EXT, "ProtectionOrderExpirationDate");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
      e.setTextContent(
          DATE_FORMATTER_YYYY_MM_DD.print(orderDate.plusDays(randomGenerator.nextInt(5, 365))));
    }
  }
  private void addPersonElement(
      Document parentDocument, PersonElementWrapper person, Element rapSheetElement) {

    Element rsp =
        appendElement(rapSheetElement, OjbcNamespaceContext.NS_RAPSHEET_41, "RapSheetPerson");
    Element e;

    XmlUtils.addAttribute(rsp, OjbcNamespaceContext.NS_STRUCTURES, "id", person.personId);

    if (coinFlip(.7)) {
      e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonAlternateName");
      Element alternateName = e;
      e = appendElement(alternateName, OjbcNamespaceContext.NS_NC, "PersonGivenName");
      e.setTextContent(person.firstName + " " + generateRandomLetter());
      e = appendElement(alternateName, OjbcNamespaceContext.NS_NC, "PersonSurName");
      e.setTextContent(person.lastName);
    }

    if (coinFlip(.1)) {
      e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonAlternateName");
      Element alternateName = e;
      e = appendElement(alternateName, OjbcNamespaceContext.NS_NC, "PersonGivenName");
      e.setTextContent(person.firstName);
      e = appendElement(alternateName, OjbcNamespaceContext.NS_NC, "PersonSurName");
      e.setTextContent(
          person.lastName
              + "-"
              + generateRandomCodeFromList(
                  "Washington", "Adams", "Jefferson", "Madison", "Monroe"));
    }

    e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonBirthDate");
    e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
    e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(person.birthdate));
    e = appendElement(rsp, OjbcNamespaceContext.NS_RAPSHEET_41, "PersonEyeColorText");
    e.setTextContent(generateRandomCodeFromList("Brown", "Black", "Blue", "Hazel"));
    e = appendElement(rsp, OjbcNamespaceContext.NS_RAPSHEET_41, "PersonHairColorText");
    e.setTextContent(
        generateRandomCodeFromList("Brown", "Black", "Red Or Auburn", "Blonde Or Strawberry"));

    if (coinFlip(.4)) {
      e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonHeightMeasure");
      Element phm = e;
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "MeasurePointValue");
      e.setTextContent(String.valueOf(Math.round(Integer.parseInt(person.centimeters) * .39)));
      e = appendElement(phm, OjbcNamespaceContext.NS_NC, "LengthUnitCode");
      e.setTextContent("INH");
    }

    e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonName");
    Element pn = e;
    e = appendElement(pn, OjbcNamespaceContext.NS_NC, "PersonGivenName");
    e.setTextContent(person.firstName);
    e = appendElement(pn, OjbcNamespaceContext.NS_NC, "PersonMiddleName");
    e.setTextContent(person.middleName);
    e = appendElement(pn, OjbcNamespaceContext.NS_NC, "PersonSurName");
    e.setTextContent(person.lastName);

    e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonRaceCode");
    e.setTextContent(generateRandomCodeFromList("B", "A", "W", "U", "I"));
    e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonSexCode");
    e.setTextContent(person.sex.substring(0, 1).toUpperCase());

    if (coinFlip(.8)) {
      e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonSSNIdentification");
      Element ssn = e;
      e = appendElement(ssn, OjbcNamespaceContext.NS_NC, "IdentificationID");
      e.setTextContent(person.nationalID);
      e = appendElement(ssn, OjbcNamespaceContext.NS_NC, "IdentificationJurisdictionText");
      e.setTextContent("SSA");
    }

    if (coinFlip(.4)) {
      e = appendElement(rsp, OjbcNamespaceContext.NS_NC, "PersonWeightMeasure");
      Element pwm = e;
      e = appendElement(pwm, OjbcNamespaceContext.NS_NC, "MeasurePointValue");
      e.setTextContent(person.pounds);
      e = appendElement(pwm, OjbcNamespaceContext.NS_NC, "WeightUnitCode");
      e.setTextContent("LBR");
    }

    e = appendElement(rsp, OjbcNamespaceContext.NS_JXDM_41, "PersonAugmentation");
    Element pa = e;
    if (coinFlip(.7)) {
      e = appendElement(pa, OjbcNamespaceContext.NS_JXDM_41, "PersonFBIIdentification");
      Element fbi = e;
      e = appendElement(fbi, OjbcNamespaceContext.NS_NC, "IdentificationID");
      e.setTextContent(
          generateRandomID("", 6)
              + generateRandomLetter()
              + generateRandomLetter()
              + generateRandomID("", 1));
      e = appendElement(fbi, OjbcNamespaceContext.NS_NC, "IdentificationJurisdictionText");
    }
    e = appendElement(pa, OjbcNamespaceContext.NS_JXDM_41, "PersonStateFingerprintIdentification");
    Element sid = e;
    e = appendElement(sid, OjbcNamespaceContext.NS_NC, "IdentificationID");
    e.setTextContent(generateRandomID("A", 7));
    e = appendElement(sid, OjbcNamespaceContext.NS_NC, "IdentificationJurisdictionText");
  }
  private void addSupervisionCycleElements(
      Document parentDocument, Element rapSheetElement, List<Arrest> arrests) {
    Element e;
    for (Arrest arrest : arrests) {

      if (arrest.custodyEndDate != null) {
        Element rapSheetCycle =
            appendElement(rapSheetElement, OjbcNamespaceContext.NS_CH_EXT, "RapSheetCycle");
        e = appendElement(rapSheetCycle, OjbcNamespaceContext.NS_RAPSHEET_41, "CycleEarliestDate");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
        e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.dispoDate));
        Element supervisionElement =
            appendElement(rapSheetCycle, OjbcNamespaceContext.NS_RAPSHEET_41, "Supervision");
        XmlUtils.addAttribute(
            supervisionElement,
            OjbcNamespaceContext.NS_STRUCTURES,
            "id",
            arrest.custodySupervisionId);
        e = appendElement(supervisionElement, OjbcNamespaceContext.NS_NC, "ActivityCategoryText");
        e.setTextContent("CUSTODY");
        e = appendElement(supervisionElement, OjbcNamespaceContext.NS_NC, "ActivityDate");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
        e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.dispoDate));
        e =
            appendElement(
                supervisionElement, OjbcNamespaceContext.NS_NC, "SupervisionCustodyStatus");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "StatusDescriptionText");
        e.setTextContent(arrest.felonyConviction ? "SENT FELON" : "SENT MISD");
        e = appendElement(supervisionElement, OjbcNamespaceContext.NS_NC, "SupervisionRelease");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "ActivityDate");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
        e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.custodyEndDate));
      }

      if (arrest.probationEndDate != null) {
        Element rapSheetCycle =
            appendElement(rapSheetElement, OjbcNamespaceContext.NS_CH_EXT, "RapSheetCycle");
        e = appendElement(rapSheetCycle, OjbcNamespaceContext.NS_RAPSHEET_41, "CycleEarliestDate");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
        e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.dispoDate));
        Element supervisionElement =
            appendElement(rapSheetCycle, OjbcNamespaceContext.NS_RAPSHEET_41, "Supervision");
        XmlUtils.addAttribute(
            supervisionElement,
            OjbcNamespaceContext.NS_STRUCTURES,
            "id",
            arrest.probationSupervisionId);
        e = appendElement(supervisionElement, OjbcNamespaceContext.NS_NC, "ActivityCategoryText");
        e.setTextContent("PROBATION");
        e = appendElement(supervisionElement, OjbcNamespaceContext.NS_NC, "ActivityDate");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
        e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.dispoDate));
        e =
            appendElement(
                supervisionElement, OjbcNamespaceContext.NS_NC, "SupervisionCustodyStatus");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "StatusDescriptionText");
        e.setTextContent(arrest.felonyConviction ? "SENT FELON" : "SENT MISD");
        e = appendElement(supervisionElement, OjbcNamespaceContext.NS_NC, "SupervisionRelease");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "ActivityDate");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
        e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.probationEndDate));
      }
    }
  }
  private void addMainCycleElements(
      Document parentDocument, Element rapSheetElement, List<Arrest> arrests) {
    Element e;
    for (Arrest arrest : arrests) {
      boolean courtAction = false;
      Element rapSheetCycle =
          appendElement(rapSheetElement, OjbcNamespaceContext.NS_CH_EXT, "RapSheetCycle");
      e = appendElement(rapSheetCycle, OjbcNamespaceContext.NS_RAPSHEET_41, "CycleEarliestDate");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
      e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.date));
      Element arrestElement =
          appendElement(rapSheetCycle, OjbcNamespaceContext.NS_RAPSHEET_41, "Arrest");
      XmlUtils.addAttribute(arrestElement, OjbcNamespaceContext.NS_STRUCTURES, "id", arrest.id);
      e = appendElement(arrestElement, OjbcNamespaceContext.NS_NC, "ActivityDate");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
      e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.date));
      e =
          appendElement(
              arrestElement, OjbcNamespaceContext.NS_JXDM_41, "ArrestAgencyRecordIdentification");
      e = appendElement(e, OjbcNamespaceContext.NS_NC, "IdentificationID");
      e.setTextContent(arrest.recordId);
      for (ArrestCharge arrestCharge : arrest.charges) {
        Element arrestChargeElement =
            appendElement(arrestElement, OjbcNamespaceContext.NS_RAPSHEET_41, "ArrestCharge");
        e =
            appendElement(
                arrestChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeDescriptionText");
        e.setTextContent(arrestCharge.description);
        if (!arrestCharge.prosecuted) {
          e =
              appendElement(
                  arrestChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeDisposition");
          e = appendElement(e, OjbcNamespaceContext.NS_NC, "DispositionDescriptionText");
          e.setTextContent("LACK OF PROS");
        } else {
          courtAction = true;
        }
        e =
            appendElement(
                arrestChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeIdentification");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "IdentificationID");
        e.setTextContent(arrestCharge.id);
        e =
            appendElement(
                arrestChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeSeverityText");
        e.setTextContent(arrestCharge.severity);
        e =
            appendElement(
                arrestChargeElement,
                OjbcNamespaceContext.NS_JXDM_41,
                "ChargeTrackingIdentification");
        e = appendElement(e, OjbcNamespaceContext.NS_NC, "IdentificationID");
        e.setTextContent(arrestCharge.trackingId);
      }

      boolean sentenced = false;

      if (courtAction && arrest.dispoDate != null) {

        Element courtActionElement =
            appendElement(rapSheetCycle, OjbcNamespaceContext.NS_RAPSHEET_41, "CourtAction");
        for (ArrestCharge arrestCharge : arrest.charges) {
          if (arrestCharge.prosecuted) {
            Element courtChargeElement =
                appendElement(
                    courtActionElement, OjbcNamespaceContext.NS_RAPSHEET_41, "CourtCharge");
            e =
                appendElement(
                    courtChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeDescriptionText");
            e.setTextContent(arrestCharge.description);
            e =
                appendElement(
                    courtChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeDisposition");
            Element dispoElement = e;
            e = appendElement(dispoElement, OjbcNamespaceContext.NS_NC, "DispositionDate");
            e = appendElement(e, OjbcNamespaceContext.NS_NC, "Date");
            e.setTextContent(DATE_FORMATTER_YYYY_MM_DD.print(arrest.dispoDate));
            e =
                appendElement(
                    dispoElement, OjbcNamespaceContext.NS_NC, "DispositionDescriptionText");
            if (arrestCharge.guilty) {
              e.setTextContent("GUILTY");
              sentenced = true;
            } else {
              e.setTextContent("NOT GUILTY");
            }
            e =
                appendElement(
                    courtChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeIdentification");
            e = appendElement(e, OjbcNamespaceContext.NS_NC, "IdentificationID");
            e.setTextContent(arrestCharge.id);
            e =
                appendElement(
                    courtChargeElement, OjbcNamespaceContext.NS_JXDM_41, "ChargeSeverityText");
            e.setTextContent(arrestCharge.severity);
            e =
                appendElement(
                    courtChargeElement,
                    OjbcNamespaceContext.NS_JXDM_41,
                    "ChargeTrackingIdentification");
            e = appendElement(e, OjbcNamespaceContext.NS_NC, "IdentificationID");
            e.setTextContent(arrestCharge.trackingId);
          }
        }
      }

      if (sentenced) {

        Element sentencingElement =
            appendElement(rapSheetCycle, OjbcNamespaceContext.NS_CH_EXT, "Sentencing");

        for (ArrestCharge arrestCharge : arrest.charges) {
          if (arrestCharge.guilty) {
            Element sentenceElement =
                appendElement(sentencingElement, OjbcNamespaceContext.NS_CH_EXT, "Sentence");
            e =
                appendElement(
                    sentenceElement, OjbcNamespaceContext.NS_JXDM_41, "SentenceDescriptionText");
            String termPeriod = " DAYS";
            String sentenceType = " CONFINEMENT ";
            int termLength = arrestCharge.offense.daysInJail;
            if (termLength > 365 * 2) {
              termLength = (int) Math.round(termLength / 365.0);
              termPeriod = " YEARS";
            } else if (termLength == 0) {
              termLength = (int) Math.round(arrestCharge.offense.daysOfProbation / 30.0);
              termPeriod = " MONTHS";
              sentenceType = " PROBATION ";
            }
            e.setTextContent(
                "ON "
                    + DATE_FORMATTER_MM_DD_YYYY.print(arrest.dispoDate)
                    + " SUBJECT SENTENCED TO "
                    + termLength
                    + termPeriod
                    + sentenceType
                    + "AND "
                    + "A FINE OF "
                    + NumberFormat.getCurrencyInstance().format(arrestCharge.offense.fine));

            e =
                appendElement(
                    sentenceElement, OjbcNamespaceContext.NS_RAPSHEET_41, "SentenceCharge");
            e = appendElement(e, OjbcNamespaceContext.NS_JXDM_41, "ChargeTrackingIdentification");
            e = appendElement(e, OjbcNamespaceContext.NS_NC, "IdentificationID");
            e.setTextContent(arrestCharge.trackingId);
          }
        }
      }
    }
  }