public static AbstractElement getPredicatedElement(AbstractElement element) {
    if (element.isPredicated()) {
      return element;
    }
    if (element instanceof Assignment) {
      return getPredicatedElement(((Assignment) element).getTerminal());
    }
    if (element instanceof RuleCall) {
      final RuleCall ruleCall = (RuleCall) element;
      final AbstractRule calledRule = ruleCall.getRule();
      Group group = (Group) calledRule.getAlternatives();
      AbstractElement first = group.getElements().get(0);
      AbstractElement result = getPredicatedElement(first);
      if (ruleCall.getArguments().isEmpty()) {
        return result;
      }
      EcoreUtil.Copier copier =
          new EcoreUtil.Copier() {
            private static final long serialVersionUID = 1L;

            @Override
            public EObject copy(EObject eObject) {
              if (eObject instanceof ParameterReference) {
                ParameterReference paramRef = (ParameterReference) eObject;
                Parameter parameter = paramRef.getParameter();
                if (calledRule == GrammarUtil.containingRule(parameter)) {
                  for (NamedArgument givenArgument : ruleCall.getArguments()) {
                    if (givenArgument.getParameter() == parameter) {
                      EObject result = copy(givenArgument.getValue());
                      return result;
                    }
                  }
                  throw new IllegalStateException();
                }
              }
              return super.copy(eObject);
            }
          };
      AbstractElement clone = (AbstractElement) copier.copy(result);
      copier.copyReferences();
      return clone;
    }
    return element;
  }
 protected boolean _predicated(final AbstractElement it) {
   return it.isPredicated();
 }