public DrillDownProfile edit(final DrillDownProfile profile) {
    final AbstractDrillDownEditor drillDownEditor;
    if (PatternLinkCustomizer.class.isAssignableFrom(profile.getLinkCustomizerType())) {
      drillDownEditor = new PatternDrillDownEditor(this);
    } else if (FormulaLinkCustomizer.class.isAssignableFrom(profile.getLinkCustomizerType())) {
      drillDownEditor = new FormulaDrillDownEditor(this);
    } else {
      return profile;
    }

    return drillDownEditor.performEdit(profile);
  }
  public void save(final File file) {
    try {
      final DefaultTagDescription tags = new DefaultTagDescription();
      tags.setDefaultNamespace(DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE);
      tags.setNamespaceHasCData(DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE, false);
      tags.setElementHasCData(DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE, "attribute", true);

      final XmlWriter w =
          new XmlWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"), tags);
      w.writeXmlDeclaration("UTF-8");

      final AttributeList rootList = new AttributeList();
      rootList.addNamespaceDeclaration("", DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE);
      w.writeTag(
          DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
          "drilldown-profiles",
          rootList,
          XmlWriter.OPEN);

      final Object[] objects = drillDownProfiles.toArray();
      for (int i = 0; i < objects.length; i++) {
        final DrillDownProfile object = (DrillDownProfile) objects[i];

        final AttributeList profileAttrs = new AttributeList();
        profileAttrs.setAttribute(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE, "name", object.getName());
        profileAttrs.setAttribute(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
            "class",
            object.getLinkCustomizerType().getName());
        profileAttrs.setAttribute(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE, "bundle-name", object.getBundleLocation());
        profileAttrs.setAttribute(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
            "expert",
            String.valueOf(object.isExpert()));
        profileAttrs.setAttribute(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
            "hidden",
            String.valueOf(object.isHidden()));
        profileAttrs.setAttribute(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
            "deprecated",
            String.valueOf(object.isDeprecated()));
        profileAttrs.setAttribute(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
            "preferred",
            String.valueOf(object.isPreferred()));

        w.writeTag(
            DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
            "drilldown-profile",
            profileAttrs,
            XmlWriter.OPEN);

        final String[] attrNames = object.getAttributes();
        for (int j = 0; j < attrNames.length; j++) {
          final String attrName = attrNames[j];
          final String attrValue = object.getAttribute(attrName);

          w.writeTag(
              DrillDownModule.DRILLDOWN_PROFILE_NAMESPACE,
              "attribute",
              "name",
              attrName,
              XmlWriter.OPEN);
          w.writeTextNormalized(attrValue, false);
          w.writeCloseTag();
        }

        w.writeCloseTag();
      }

      w.writeCloseTag();
      w.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }