/**
   * Write exception transfer report
   *
   * @return NodeRef the node ref of the new transfer report
   */
  public NodeRef createTransferReport(
      Exception e,
      TransferTarget target,
      TransferDefinition definition,
      List<TransferEvent> events,
      File snapshotFile) {
    Map<QName, Serializable> properties = new HashMap<QName, Serializable>();

    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssSSSZ");
    String timeNow = format.format(new Date());

    String title = "Transfer report, error,  " + timeNow;
    String description = "Transfer error report";
    String name = "Transfer error report, " + timeNow;

    properties.put(ContentModel.PROP_NAME, name);
    properties.put(ContentModel.PROP_TITLE, title);
    properties.put(ContentModel.PROP_DESCRIPTION, description);
    ChildAssociationRef ref =
        nodeService.createNode(
            target.getNodeRef(),
            ContentModel.ASSOC_CONTAINS,
            QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
            TransferModel.TYPE_TRANSFER_REPORT,
            properties);
    ContentWriter writer =
        contentService.getWriter(ref.getChildRef(), ContentModel.PROP_CONTENT, true);
    writer.setLocale(Locale.getDefault());
    writer.setMimetype(MimetypeMap.MIMETYPE_XML);
    writer.setEncoding(DEFAULT_ENCODING);

    //
    XMLTransferReportWriter reportWriter = new XMLTransferReportWriter();

    BufferedWriter bufferedWriter =
        new BufferedWriter(new OutputStreamWriter(writer.getContentOutputStream()));

    try {
      reportWriter.startTransferReport(DEFAULT_ENCODING, bufferedWriter);

      // Header
      reportWriter.writeTarget(target);

      reportWriter.writeDefinition(definition);

      reportWriter.writeException(e);

      // Detail
      reportWriter.writeTransferEvents(events);

      reportWriter.endTransferReport();

      return ref.getChildRef();
    } catch (SAXException se) {
      return null;
    } finally {
      try {
        bufferedWriter.close();
      } catch (IOException error) {
        error.printStackTrace();
      }
    }
  }
  /**
   * Create a new transfer report of success
   *
   * @return NodeRef the node ref of the new transfer report
   */
  public NodeRef createTransferReport(
      Transfer transfer,
      TransferTarget target,
      TransferDefinition definition,
      List<TransferEvent> events,
      File snapshotFile) {
    Map<QName, Serializable> properties = new HashMap<QName, Serializable>();

    SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssSSSZ");
    String timeNow = format.format(new Date());

    String title = "Transfer report, " + timeNow + "success";
    String description = "Transfer report success targetName : " + target.getName();
    String name = "Transfer report, " + timeNow;

    properties.put(ContentModel.PROP_NAME, name);
    properties.put(ContentModel.PROP_TITLE, title);
    properties.put(ContentModel.PROP_DESCRIPTION, description);
    ChildAssociationRef ref =
        nodeService.createNode(
            target.getNodeRef(),
            ContentModel.ASSOC_CONTAINS,
            QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
            TransferModel.TYPE_TRANSFER_REPORT,
            properties);
    ContentWriter writer =
        contentService.getWriter(ref.getChildRef(), ContentModel.PROP_CONTENT, true);
    writer.setLocale(Locale.getDefault());
    writer.setMimetype(MimetypeMap.MIMETYPE_XML);
    writer.setEncoding(DEFAULT_ENCODING);

    //
    final XMLTransferReportWriter reportWriter = new XMLTransferReportWriter();

    BufferedWriter bufferedWriter =
        new BufferedWriter(new OutputStreamWriter(writer.getContentOutputStream()));

    try {
      reportWriter.startTransferReport(DEFAULT_ENCODING, bufferedWriter);

      // Header
      reportWriter.writeTarget(target);

      reportWriter.writeDefinition(definition);

      /** Write the node summary details to the transfer report */
      TransferManifestProcessor processor =
          new TransferManifestProcessor() {
            public void processTransferManifestNode(TransferManifestNormalNode node) {

              try {
                reportWriter.writeNodeSummary(node);
              } catch (SAXException error) {
                error.printStackTrace();
              }
            }

            public void processTransferManifestNode(TransferManifestDeletedNode node) {
              try {
                reportWriter.writeNodeSummary(node);
              } catch (SAXException error) {
                error.printStackTrace();
              }
            }

            public void processTransferManifiestHeader(TransferManifestHeader header) {
              /* NO-OP */
            }

            public void startTransferManifest() {
              /* NO-OP */
            }

            public void endTransferManifest() {
              /* NO-OP */
            }
          };

      /** Step 3: wire up the manifest reader to a manifest processor */
      SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
      SAXParser parser;
      parser = saxParserFactory.newSAXParser();
      XMLTransferManifestReader reader = new XMLTransferManifestReader(processor);

      /** Step 4: start the magic Give the manifest file to the manifest reader */
      try {
        parser.parse(snapshotFile, reader);
      } catch (IOException error) {
        // TODO temp code
        error.printStackTrace();
        return null;
      }

      // Detail Events
      reportWriter.writeTransferEvents(events);

      reportWriter.endTransferReport();

      return ref.getChildRef();
    } catch (SAXException se) {
      // TODO Temp code
      return null;
    } catch (ParserConfigurationException error) {
      // TODO temp code
      error.printStackTrace();
      return null;
    } finally {
      try {
        bufferedWriter.close();
      } catch (IOException error) {
        error.printStackTrace();
      }
    }
  }