private static void addChildren(Set<String> children, ModelValue value, PathAddress address) {
   if (value.getValueType() == ModelValue.ModelValueType.REFERENCE) {
     ModelReference modelRef = value.asValue(ModelReference.class);
     PathAddress ref = modelRef.getValue();
     if (ref.size() > 1 && ref.subAddress(0, ref.size() - 1).equals(address)) {
       children.add(ref.getLastElement());
     }
   } else if (value.getValueType() == ModelValue.ModelValueType.LIST) {
     ModelList list = value.asValue(ModelList.class);
     Set<String> names = new LinkedHashSet<String>(list.size());
     // If the list is a direct child and all items in the list are model references, then we can
     // conclude that
     // these should be added to the children
     for (ModelValue mv : list) {
       if (mv.getValueType() == ModelValue.ModelValueType.REFERENCE) {
         addChildren(names, mv, address);
       } else {
         names.clear();
         break;
       }
     }
     if (!names.isEmpty()) {
       children.addAll(names);
     }
   }
 }
  protected PathAddress getAddress(PathAddress currentAddress, String path) {
    PathAddress pathAddress = currentAddress;
    if (path != null) {
      if (path.charAt(0) == '/') {
        pathAddress = PathAddress.pathAddress(path);
      } else if (path.equals("..")) {
        pathAddress = pathAddress.subAddress(0, pathAddress.size() - 1);
      } else if (path.equals(".")) {
      } else {
        pathAddress = pathAddress.append(path);
      }
    }

    return pathAddress;
  }
  @Override
  public Map<String, Boolean> complete(ParameterDescriptor<?> parameter, String prefix)
      throws Exception {
    try {
      Closure assertConnected = (Closure) getProperty("assertConnected");
      assertConnected.call();
    } catch (ScriptException e) {
      return Collections.emptyMap();
    }

    Closure closure = (Closure) getProperty("begin");
    closure.call();

    try {
      if (String.class == parameter.getJavaType()) {
        ManagementController controller = (ManagementController) getProperty("controller");

        PathAddress address = (PathAddress) getProperty("address");
        PathAddress relative = PathAddress.pathAddress(prefix);

        // Append to current address if not relative
        if (prefix.length() == 0 || prefix.charAt(0) != '/') {
          address = address.append(relative);
        } else // Address is absolute, set address to prefix address
        {
          prefix = prefix.substring(1);
          address = relative;
        }

        // Set the prefix to the last path element
        int index = prefix.lastIndexOf("/");
        if (index != -1) {
          prefix = prefix.substring(index + 1);
        }

        // If prefix is not empty, then remove last element of address, since that is the prefix
        if (prefix.length() > 0
            && address.size() > 0
            && prefix.charAt(prefix.length() - 1) != '/') {
          address = address.subAddress(0, address.size() - 1);
        }

        Set<String> children = getChildren(controller, address);
        Map<String, Boolean> completions = new HashMap<String, Boolean>(children.size());
        for (String child : children) {
          if (child.charAt(0) == '/') child = child.substring(1);

          // Look ahead to see if there are more children
          PathAddress nextAddress = address.append(child);
          boolean more = getChildren(controller, nextAddress).size() > 0;
          if (child.startsWith(prefix)) {
            String suffix = child.substring(prefix.length());
            if (more) {
              completions.put(suffix + "/", false);
            } else {
              completions.put(suffix, true);
            }
          }
        }

        return completions;
      }

      return Collections.emptyMap();
    } catch (Exception e) {
      return Collections.emptyMap();
    } finally {
      closure = (Closure) getProperty("end");
      closure.call();
    }
  }