@Override
  public ProtocolFormXmlData creatNewProtocol(ProtocolFormType protocolFormType)
      throws XPathExpressionException, IOException, SAXException {
    Protocol p = new Protocol();
    Date created = new Date();
    p.setCreated(created);
    p.setLocked(false);

    p = protocolDao.saveOrUpdate(p);

    p.setProtocolIdentifier(Long.toString(baseProtocolIdentifier + p.getId()));

    // protocol.metadataxml always start with /protocol/
    // String protocolMetaDataXmlString = "<protocol id=\"" + p.getId() + "\" identifier=\"" +
    // p.getProtocolIdentifier() + "\" type=\""+ protocolFormType.getDescription()
    // +"\"></protocol>";
    String protocolMetaDataXmlString =
        (protocolFormType.equals(ProtocolFormType.NEW_SUBMISSION))
            ? "<protocol id=\""
                + p.getId()
                + "\" identifier=\""
                + p.getProtocolIdentifier()
                + "\"></protocol>"
            : "<protocol id=\""
                + p.getId()
                + "\" identifier=\""
                + p.getProtocolIdentifier()
                + "\" type=\""
                + protocolFormType.getDescription()
                + "\"></protocol>";
    ;

    p.setMetaDataXml(protocolMetaDataXmlString);
    p = protocolDao.saveOrUpdate(p);

    String protocolFormXmlString =
        "<"
            + protocolFormType.getBaseTag()
            + " id=\""
            + p.getId()
            + "\" identifier=\""
            + p.getProtocolIdentifier()
            + "\" type=\""
            + protocolFormType.getDescription()
            + "\"></"
            + protocolFormType.getBaseTag()
            + ">";

    ProtocolForm f = new ProtocolForm();
    f.setProtocolFormType(protocolFormType);
    f.setProtocol(p);
    f.setCreated(created);
    f.setMetaDataXml(protocolFormXmlString);
    f.setParent(f);
    f.setLocked(false);

    f = protocolFormDao.saveOrUpdate(f);

    ProtocolFormXmlData fxd = new ProtocolFormXmlData();
    fxd.setProtocolForm(f);
    fxd.setXmlData(protocolFormXmlString);
    fxd.setProtocolFormXmlDataType(protocolFormType.getDefaultProtocolFormXmlDataType());
    fxd.setParent(fxd);
    fxd.setCreated(created);

    fxd = protocolFormXmlDataDao.saveOrUpdate(fxd);

    Map<ProtocolFormXmlDataType, ProtocolFormXmlData> protocolFormXmlDatas =
        new HashMap<ProtocolFormXmlDataType, ProtocolFormXmlData>(0);
    protocolFormXmlDatas.put(protocolFormType.getDefaultProtocolFormXmlDataType(), fxd);
    f.setTypedProtocolFormXmlDatas(protocolFormXmlDatas);

    User currentUser = userService.getCurrentUser();

    protocolFormService.triggerPIAction("CREATE", f, currentUser, null);

    objectAclService.updateObjectAclByUser(Protocol.class, p.getId(), currentUser);
    return fxd;
  }
  @RequestMapping(
      value =
          "/ajax/protocols/{protocolId}/protocol-forms/{protocolFormId}/reportable-new-information/protocol-form-xml-datas/{protocolFormXmlDataId}/validate",
      method = RequestMethod.GET)
  public @ResponseBody List<ValidationResponse> validateProtocolReportableNewInformationForm(
      @PathVariable("protocolFormXmlDataId") long protocolFormXmlDataId) {

    ProtocolFormXmlData protocolXmlData = protocolFormXmlDataDao.findById(protocolFormXmlDataId);

    String xmldata = protocolXmlData.getXmlData();

    List<ValidationResponse> validationResponses = new ArrayList<ValidationResponse>();
    if (StringUtils.hasText(xmldata)) {

      List<Rule> reportableNewInformationValidationRules =
          getValidationRuleContainer()
              .getValidationRules("reportableNewInformationValidationRules");

      Assert.notNull(reportableNewInformationValidationRules);

      Set<String> valueKeys =
          getValidationRuleContainer()
              .getCachedValueKeys("reportableNewInformationValidationRules");

      Assert.notNull(valueKeys);

      Map<String, List<String>> values = null;

      // setup values
      try {
        values = xmlProcessor.listElementStringValuesByPaths(valueKeys, xmldata);
      } catch (XPathExpressionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }

      validationResponses =
          validationRuleHandler.validate(reportableNewInformationValidationRules, values);
    }

    if (!isReportableOrNot(protocolXmlData)) {
      Constraint notReportableConstraint = new Constraint();
      Map<String, Object> notReportableAdditionalData = new HashMap<String, Object>();

      notReportableConstraint.setConstraintLevel(ConstraintLevel.ERROR);
      notReportableConstraint.setErrorMessage(
          "This event/information does not meet the criteria for an Unanticipated Problem Involving Risk "
              + "to Subjects or Others (UPIRTSO) and does not require immediate reporting to the IRB."
              + "<br/>"
              + "Please submit the information in summary format at Continuing Review."
              + "<br/>"
              + "A suggested summary format is available at:<a href=\"http://www.uams.edu/irb/Reporting%20Events%20and%20Deviations.asp\" target=\"_blank\">http://www.uams.edu/irb/Reporting%20Events%20and%20Deviations.asp</a>"
              + "<br/>"
              + "The IRB recommends that events be compiled throughout the year."
              + "<br/>"
              + "If you need to update documents now, please do so using a Modification.");

      notReportableAdditionalData.put("pagename", "Review");
      notReportableAdditionalData.put("pageref", "review");

      ValidationResponse budgetVP =
          new ValidationResponse(notReportableConstraint, notReportableAdditionalData);

      validationResponses.add(budgetVP);
    }

    return validationResponses;
  }