private void loadCustomProperty(Attributes attrs) {
   String id = attrs.getValue("definition-id");
   String value = attrs.getValue("value");
   List<CustomPropertyDefinition> definitions = myCustomPropertyManager.getDefinitions();
   for (int i = 0; i < definitions.size(); i++) {
     CustomPropertyDefinition nextDefinition = definitions.get(i);
     if (id.equals(nextDefinition.getID())) {
       myCurrentResource.addCustomProperty(nextDefinition, value);
       break;
     }
   }
 }
 private void writeTaskProperties(
     TransformerHandler handler, CustomPropertyManager customPropertyManager) throws SAXException {
   writeTaskProperty(handler, "tpd0", "type", "default", "icon");
   writeTaskProperty(handler, "tpd1", "priority", "default", "icon");
   writeTaskProperty(handler, "tpd2", "info", "default", "icon");
   writeTaskProperty(handler, "tpd3", "name", "default", "text");
   writeTaskProperty(handler, "tpd4", "begindate", "default", "date");
   writeTaskProperty(handler, "tpd5", "enddate", "default", "date");
   writeTaskProperty(handler, "tpd6", "duration", "default", "int");
   writeTaskProperty(handler, "tpd7", "completion", "default", "int");
   writeTaskProperty(handler, "tpd8", "coordinator", "default", "text");
   writeTaskProperty(handler, "tpd9", "predecessorsr", "default", "text");
   for (CustomPropertyDefinition cc : customPropertyManager.getDefinitions()) {
     Object defVal = cc.getDefaultValue();
     final Class<?> cla = cc.getType();
     final String valueType = encodeFieldType(cla);
     if (valueType == null) {
       continue;
     }
     if ("date".equals(valueType) && defVal != null) {
       if (defVal instanceof GanttCalendar) {
         defVal = DateParser.getIsoDate(((GanttCalendar) defVal).getTime());
       } else if (defVal instanceof Date) {
         defVal = DateParser.getIsoDate((Date) defVal);
       } else {
         assert false
             : "Default value is expected to be either GanttCalendar or Date instance, while it is "
                 + defVal.getClass();
       }
     }
     String idcStr = cc.getID();
     writeTaskProperty(
         handler,
         idcStr,
         cc.getName(),
         "custom",
         valueType,
         defVal == null ? null : String.valueOf(defVal));
   }
 }
  private void writeTask(
      TransformerHandler handler, GanttTask task, CustomPropertyManager customPropertyManager)
      throws SAXException, IOException {
    if (task.getTaskID() == -1) {
      throw new IllegalArgumentException("Is it a fake root task? Task=" + task);
    }
    AttributesImpl attrs = new AttributesImpl();
    addAttribute("id", String.valueOf(task.getTaskID()), attrs);
    addAttribute("name", task.getName(), attrs);
    if (task.colorDefined()) {
      addAttribute("color", ColorConvertion.getColor(task.getColor()), attrs);
    }
    if (task.shapeDefined()) {
      addAttribute("shape", task.getShape().getArray(), attrs);
    }
    addAttribute("meeting", Boolean.valueOf(task.isLegacyMilestone()).toString(), attrs);
    if (task.isProjectTask()) {
      addAttribute("project", Boolean.TRUE.toString(), attrs);
    }
    addAttribute("start", task.getStart().toXMLString(), attrs);
    addAttribute("duration", String.valueOf(task.getLength()), attrs);
    addAttribute("complete", String.valueOf(task.getCompletionPercentage()), attrs);
    if (task.getThird() != null) {
      addAttribute("thirdDate", task.getThird().toXMLString(), attrs);
      addAttribute("thirdDate-constraint", String.valueOf(task.getThirdDateConstraint()), attrs);
    }
    if (task.getPriority() != Task.DEFAULT_PRIORITY) {
      addAttribute("priority", task.getPriority().getPersistentValue(), attrs);
    }
    final String sWebLink = task.getWebLink();
    if (sWebLink != null && !sWebLink.equals("") && !sWebLink.equals("http://")) {
      addAttribute("webLink", URLEncoder.encode(sWebLink, "ISO-8859-1"), attrs);
    }
    addAttribute("expand", String.valueOf(task.getExpand()), attrs);

    startElement("task", attrs, handler);

    if (task.getNotes() != null && task.getNotes().length() > 0) {
      cdataElement("notes", task.getNotes(), attrs, handler);
      // fout.write(space2 + "<notes>");
      // fout.write("\n"
      // + space2
      // + s
      // + correct(replaceAll(task.getNotes(), "\n", "\n"
      // + space2 + s)));
      // fout.write("\n" + space2 + "</notes>\n");
    }
    // use successors to write depends information
    final TaskDependency[] depsAsDependee = task.getDependenciesAsDependee().toArray();
    for (int i = 0; i < depsAsDependee.length; i++) {
      TaskDependency next = depsAsDependee[i];
      addAttribute("id", String.valueOf(next.getDependant().getTaskID()), attrs);
      addAttribute("type", next.getConstraint().getType().getPersistentValue(), attrs);
      addAttribute("difference", String.valueOf(next.getDifference()), attrs);
      addAttribute("hardness", next.getHardness().getIdentifier(), attrs);
      emptyElement("depend", attrs, handler);
    }

    CustomColumnsValues ccv = task.getCustomValues();
    for (CustomPropertyDefinition def : customPropertyManager.getDefinitions()) {
      final String idc = def.getID();
      if (ccv.hasOwnValue(def)) {
        Object value = ccv.getValue(def);
        if (GregorianCalendar.class.isAssignableFrom(def.getType()) && value != null) {
          value = DateParser.getIsoDate(((GanttCalendar) value).getTime());
        }
        addAttribute("taskproperty-id", idc, attrs);
        addAttribute("value", value == null ? null : String.valueOf(value), attrs);
        emptyElement("customproperty", attrs, handler);
      }
    }

    // Write the child of the task
    if (task.getManager().getTaskHierarchy().hasNestedTasks(task)) {
      Task[] nestedTasks = task.getManager().getTaskHierarchy().getNestedTasks(task);
      for (int i = 0; i < nestedTasks.length; i++) {
        writeTask(handler, (GanttTask) nestedTasks[i], customPropertyManager);
      }
    }

    // end of task section
    endElement("task", handler);
  }