@Override
  public void execute(KTraversalActionContext context) {
    if (context.inputObjects() == null || context.inputObjects().length == 0) {
      if (_next != null) {
        _next.execute(context);
      } else {
        context.finalCallback().on(context.inputObjects());
      }
    } else {
      boolean[] selectedIndexes = new boolean[context.inputObjects().length];
      int nbSelected = 0;
      for (int i = 0; i < context.inputObjects().length; i++) {
        try {
          AbstractKObject loopObj = (AbstractKObject) context.inputObjects()[i];
          if (_attributeQuery == null) {
            selectedIndexes[i] = true;
            nbSelected++;
          } else {
            KMeta[] metaElements = loopObj.metaClass().metaElements();
            ArrayStringMap<QueryParam> params = buildParams(_attributeQuery);
            final boolean[] selectedForNext = {true};
            params.each(
                new KStringMapCallBack<QueryParam>() {
                  @Override
                  public void on(String key, QueryParam param) {
                    for (int j = 0; j < metaElements.length; j++) {
                      if (metaElements[j] instanceof MetaAttribute) {
                        KMetaAttribute metaAttribute = (KMetaAttribute) metaElements[j];
                        if (metaAttribute.metaName().matches("^" + param.name() + "$")) {
                          Object o_raw = loopObj.get(metaAttribute);
                          if (o_raw != null) {
                            if (param.value().equals("null")) {
                              if (!param.isNegative()) {
                                selectedForNext[0] = false;
                              }
                            } else if (o_raw.toString().matches("^" + param.value() + "$")) {
                              if (param.isNegative()) {
                                selectedForNext[0] = false;
                              }
                            } else {
                              if (!param.isNegative()) {
                                selectedForNext[0] = false;
                              }
                            }
                          } else {
                            if (param.value().equals("null") || param.value().equals("*")) {
                              if (param.isNegative()) {
                                selectedForNext[0] = false;
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                });
            if (selectedForNext[0]) {
              selectedIndexes[i] = true;
              nbSelected++;
            }
          }

        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      KObject[] nextStepElement = new KObject[nbSelected];
      int inserted = 0;
      for (int i = 0; i < context.inputObjects().length; i++) {
        if (selectedIndexes[i]) {
          nextStepElement[inserted] = context.inputObjects()[i];
          inserted++;
        }
      }
      if (_next == null) {
        context.finalCallback().on(nextStepElement);
      } else {
        context.setInputObjects(nextStepElement);
        _next.execute(context);
      }
    }
  }