// rest of javadoc inherited
  public DeviceDefinitionPoliciesSection(Composite parent, int style, DeviceEditorContext context) {
    super(parent, style);

    setMinWidth(DEFAULT_MIN_WIDTH);
    this.context = context;
    DeviceRepositoryAccessorManager dram = context.getDeviceRepositoryAccessorManager();

    Section section = SectionFactory.createSection(this, SWT.NONE, TITLE, MESSAGE);
    GridData data = new GridData(GridData.FILL_BOTH);
    section.setLayoutData(data);

    categoriesComposite = new CategoriesComposite(section, CategoriesComposite.POLICIES, dram);
    section.setClient(categoriesComposite);

    // Set up a focus listener for maintaining global actions.
    categoriesComposite
        .getTreeViewer()
        .getControl()
        .addFocusListener(
            new FocusListener() {
              public void focusGained(FocusEvent event) {
                IActionBars actionBars =
                    DeviceDefinitionPoliciesSection.this.context.getActionBars();
                origDelete = actionBars.getGlobalActionHandler(IWorkbenchActionConstants.DELETE);
                actionBars.setGlobalActionHandler(
                    IWorkbenchActionConstants.DELETE, deletePolicyAction);
                actionBars.updateActionBars();
              }

              public void focusLost(FocusEvent event) {
                IActionBars actionBars =
                    DeviceDefinitionPoliciesSection.this.context.getActionBars();
                actionBars.setGlobalActionHandler(IWorkbenchActionConstants.DELETE, origDelete);
                actionBars.updateActionBars();
              }
            });

    // We use the selection manager for event handling because it allows
    // use to use filters which we need for resolving category elements
    // for use with ODOMAction enablement.
    categoriesComposite.addSelectionChangedListener(context.getODOMSelectionManager());

    data = new GridData(GridData.FILL_BOTH);
    categoriesComposite.setLayoutData(data);

    createActions();
    createContextMenu();

    createButtons(this, SWT.NONE);
  }
  /**
   * Add a new policy to the device repository in use. This will add the policy to the definitions
   * document and to the master device file.
   *
   * @param policyName the name of the new policy. Cannot be null.
   * @param composition the PolicyTypeComposition of the new policy
   * @param type the PolicyType of the new policy
   * @throws IllegalArgumentException if the named policy already exists or if any of the arguments
   *     are null.
   */
  private void addNewPolicyToRepository(
      String policyName, PolicyTypeComposition composition, PolicyType type) {
    if (policyName == null) {
      throw new IllegalArgumentException("Cannot be null: " + policyName);
    }
    if (composition == null) {
      throw new IllegalArgumentException("Cannot be null: " + composition);
    }
    if (type == null) {
      throw new IllegalArgumentException("Cannot be null: " + type);
    }
    String masterDeviceName = context.getDeviceRepositoryAccessorManager().retrieveRootDeviceName();
    boolean policyExists =
        context.getDeviceRepositoryAccessorManager().retrievePolicy(masterDeviceName, policyName)
            != null;

    if (policyExists) {
      throw new IllegalArgumentException(
          "Policy " + policyName + " already exists. Aborting new policy.");
    }

    // Add the policy to the definitions document
    Element category = categoriesComposite.getSelectedCategoryElement();
    Element policy =
        context
            .getODOMFactory()
            .element(DeviceRepositorySchemaConstants.POLICY_ELEMENT_NAME, category.getNamespace());
    policy.setAttribute(DeviceRepositorySchemaConstants.POLICY_NAME_ATTRIBUTE, policyName);
    category.addContent(policy);
    composition.addTypeElement(policy, type, context.getODOMFactory());

    // Add the policy to the master device
    Element masterDevice =
        context.getDeviceRepositoryAccessorManager().retrieveDeviceElement(masterDeviceName);

    StringBuffer xPathBuffer = new StringBuffer();
    xPathBuffer
        .append("//")
        . //$NON-NLS-1$
        append(MCSNamespace.DEVICE.getPrefix())
        .append(':')
        .append(DeviceRepositorySchemaConstants.POLICIES_ELEMENT_NAME);
    XPath policiesXPath = new XPath(xPathBuffer.toString(), new Namespace[] {MCSNamespace.DEVICE});

    try {
      Element policies = policiesXPath.selectSingleElement(masterDevice);
      composition.addDefaultPolicyValue(
          policies,
          policyName,
          type,
          context.getODOMFactory(),
          context.getDeviceRepositoryAccessorManager());
    } catch (XPathException e) {
      EclipseCommonPlugin.handleError(ABPlugin.getDefault(), e);
    }
  }
  /**
   * Creates the context menu that is associated with the tree.
   *
   * <p><strong>The {@link #createActions} method must have been invoked prior to this
   * method</strong>
   */
  private void createContextMenu() {
    // Create menu manager.
    MenuManager menuManager = new MenuManager();
    menuManager.add(newPolicyAction);
    menuManager.add(new Separator());
    menuManager.add(deletePolicyAction);

    // Create the menu and add it to the tree.
    final Tree tree = categoriesComposite.getTreeViewer().getTree();
    Menu menu = menuManager.createContextMenu(tree);
    tree.setMenu(menu);
  }
  /**
   * Select's the new named policy element in the tree.
   *
   * @param newPolicyName the name of the new policy to select.
   */
  private void selectNewPolicy(final String newPolicyName) {
    // Create the XPath for selecting the new policy element just created
    // from the definitions document.
    final StringBuffer newPolicyXPathBuffer = new StringBuffer();
    newPolicyXPathBuffer
        .append("//")
        .append(MCSNamespace.DEVICE_DEFINITIONS.getPrefix())
        .append(':')
        .append(DeviceRepositorySchemaConstants.POLICY_ELEMENT_NAME)
        .append("[@")
        .append(DeviceRepositorySchemaConstants.POLICY_NAME_ATTRIBUTE)
        .append("=\"")
        .append(newPolicyName)
        .append("\"]");
    final XPath newPolicyXPath =
        new XPath(
            newPolicyXPathBuffer.toString(), new Namespace[] {MCSNamespace.DEVICE_DEFINITIONS});

    Element newPolicyElement = null;
    try {
      // Get the definitions root for the XPath search.
      final Element definitionsRoot =
          context
              .getDeviceRepositoryAccessorManager()
              .getDeviceDefinitionsDocument()
              .getRootElement();
      // Retrieve the new policy element.
      newPolicyElement = newPolicyXPath.selectSingleElement(definitionsRoot);
    } catch (XPathException e) {
      EclipseCommonPlugin.handleError(ABPlugin.getDefault(), e);
    }

    TreeViewer treeViewer = categoriesComposite.getTreeViewer();

    // Expand the tree to the new policy element's level and select it.
    treeViewer.expandToLevel(newPolicyElement, 1);
    treeViewer.setSelection(new StructuredSelection(newPolicyElement), true);
  }
 /** Remove a SelectionChange listener that is notified when policy selection changes. */
 public void removeSelectionChangedListener(ISelectionChangedListener listener) {
   categoriesComposite.removeSelectionChangedListener(listener);
 }
 /** Add a SelectionChange listener that is notified when policy selection changes. */
 public void addSelectionChangedListener(ISelectionChangedListener listener) {
   categoriesComposite.addSelectionChangedListener(listener);
 }
 /**
  * Get the name of the selected policy, if any, from this section.
  *
  * @return the selected policy name or null if no policy is selected.
  */
 public String getSelectedPolicy() {
   Element element = categoriesComposite.getSelectedPolicyElement();
   return element == null
       ? null
       : element.getAttributeValue(DeviceRepositorySchemaConstants.POLICY_NAME_ATTRIBUTE);
 }
 /**
  * Get the name of the selected category. If a policy is selected then this method will return the
  * name of the category that the policy belongs to.
  *
  * @return the selected category name or null if no category or policy is selected.
  */
 public String getSelectedCategoryName() {
   Element category = categoriesComposite.getSelectedCategoryElement();
   return (category == null)
       ? null
       : category.getAttributeValue(DeviceRepositorySchemaConstants.CATEGORY_NAME_ATTRIBUTE);
 }
 /**
  * Get the name of the selected policy, if any, from this section.
  *
  * @return the selected policy name or null if no policy is selected.
  */
 public Element getSelectedPolicyElement() {
   return categoriesComposite.getSelectedPolicyElement();
 }