private static DescribedOp getDescribedOp(
      OperationContext context, String operationName, ModelNode operation, boolean lenient)
      throws OperationFailedException {
    DescribedOp result = null;
    OperationEntry operationEntry;
    // First try to get the current resource registration to give authz a chance to reject this
    // request
    ImmutableManagementResourceRegistration registry = context.getResourceRegistration();
    if (registry != null) {
      operationEntry = registry.getOperationEntry(PathAddress.EMPTY_ADDRESS, operationName);
    } else {
      // We know the user is authorized to read this address.
      // There's no MRR at that address, but see if the MRR tree can resolve an operation entry
      // (e.g. an inherited one)
      operationEntry =
          context
              .getRootResourceRegistration()
              .getOperationEntry(context.getCurrentAddress(), operationName);
    }

    if (operationEntry != null) {
      Locale locale = GlobalOperationHandlers.getLocale(context, operation);
      result = new DescribedOp(operationEntry, locale);
    } else if (lenient) {
      // For wildcard elements, check specific registrations where the same OSH is used
      // for all such registrations
      PathAddress address = context.getCurrentAddress();
      if (address.size() > 0) {
        PathElement pe = address.getLastElement();
        if (pe.isWildcard()) {
          ImmutableManagementResourceRegistration rootRegistration =
              context.getRootResourceRegistration();
          String type = pe.getKey();
          PathAddress parent = address.subAddress(0, address.size() - 1);
          Set<PathElement> children = rootRegistration.getChildAddresses(parent);
          if (children != null) {
            Locale locale = GlobalOperationHandlers.getLocale(context, operation);
            DescribedOp found = null;
            for (PathElement child : children) {
              if (type.equals(child.getKey())) {
                OperationEntry oe =
                    rootRegistration.getOperationEntry(parent.append(child), operationName);
                DescribedOp describedOp = oe == null ? null : new DescribedOp(oe, locale);
                if (describedOp == null || (found != null && !found.equals(describedOp))) {
                  // Not all children have the same handler; give up
                  found = null;
                  break;
                }
                // We have a candidate OSH
                found = describedOp;
              }
            }
            result = found;
          }
        }
      }
    }
    return result;
  }
 @Override
 void getProxyControllers(ListIterator<PathElement> iterator, Set<ProxyController> controllers) {
   if (iterator.hasNext()) {
     final PathElement next = iterator.next();
     final NodeSubregistry subregistry = children.get(next.getKey());
     if (subregistry == null) {
       return;
     }
     if (next.isWildcard()) {
       subregistry.getProxyControllers(iterator, null, controllers);
     } else if (next.isMultiTarget()) {
       for (final String value : next.getSegments()) {
         subregistry.getProxyControllers(iterator, value, controllers);
       }
     } else {
       subregistry.getProxyControllers(iterator, next.getValue(), controllers);
     }
   } else {
     final Map<String, NodeSubregistry> snapshot = childrenUpdater.get(this);
     for (NodeSubregistry subregistry : snapshot.values()) {
       subregistry.getProxyControllers(iterator, null, controllers);
     }
   }
 }
  Object invoke(ObjectName name, String operationName, Object[] params, String[] signature)
      throws InstanceNotFoundException, MBeanException, ReflectionException {
    if (operationName == null) {
      throw MESSAGES.nullVar("operationName");
    }
    if (params == null) {
      params = new Object[0];
    }
    if (signature == null) {
      signature = new String[0];
    }
    if (params.length != signature.length) {
      throw MESSAGES.differentLengths("params", "signature");
    }

    final ResourceAndRegistration reg = getRootResourceAndRegistration();
    final PathAddress address = resolvePathAddress(name, reg);
    if (address == null) {
      throw MESSAGES.mbeanNotFound(name);
    }
    final ImmutableManagementResourceRegistration registration = getMBeanRegistration(address, reg);

    String realOperationName = null;
    OperationEntry opEntry =
        registration.getOperationEntry(PathAddress.EMPTY_ADDRESS, operationName);
    if (opEntry != null) {
      realOperationName = operationName;
    } else {
      String opName = NameConverter.convertFromCamelCase(operationName);
      opEntry = registration.getOperationEntry(PathAddress.EMPTY_ADDRESS, opName);
      if (opEntry != null) {
        realOperationName = opName;
      }
    }

    if (opEntry == null) {
      // Brute force search in case the operation name is not standard format
      Map<String, OperationEntry> ops =
          registration.getOperationDescriptions(PathAddress.EMPTY_ADDRESS, false);
      for (Map.Entry<String, OperationEntry> entry : ops.entrySet()) {
        if (operationName.equals(NameConverter.convertToCamelCase(entry.getKey()))) {
          opEntry = entry.getValue();
          realOperationName = entry.getKey();
          break;
        }
      }
    }

    if (opEntry == null) {
      ChildAddOperationEntry entry =
          ChildAddOperationFinder.findAddChildOperation(
              reg.getRegistration().getSubModel(address), operationName);
      if (entry == null) {
        throw MESSAGES.noOperationCalled(null, operationName, address);
      }
      PathElement element = entry.getElement();
      if (element.isWildcard()) {
        if (params.length == 0) {
          throw MESSAGES.wildcardNameParameterRequired();
        }
        element = PathElement.pathElement(element.getKey(), (String) params[0]);
        Object[] newParams = new Object[params.length - 1];
        System.arraycopy(params, 1, newParams, 0, newParams.length);
        params = newParams;
      }

      return invoke(entry.getOperationEntry(), ADD, address.append(element), params);
    }
    return invoke(opEntry, realOperationName, address, params);
  }