private void extractLabels(ExpressionNode node, List<String> labels, List<String> notLabels) {
    if (node.isSingleNode()) {
      if (node instanceof NonLeafExpressionNode) {
        // This is a NOT node.
        LeafExpressionNode lNode =
          (LeafExpressionNode) ((NonLeafExpressionNode) node).getChildExps().get(0);
        notLabels.add(lNode.getIdentifier());
      } else {
        labels.add(((LeafExpressionNode) node).getIdentifier());
      }
    } else {
      // A non leaf expression of labels with & operator.
      NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
      assert nlNode.getOperator() == Operator.AND;
      List<ExpressionNode> childExps = nlNode.getChildExps();
      for (ExpressionNode child : childExps) {
        extractLabels(child, labels, notLabels);
      }
    }
  }
This is a VisibilityLabelService where labels in Mutation's visibility expression will be
persisted as Strings itself rather than ordinals in 'labels' table. Also there is no need to add
labels to the system, prior to using them in Mutations/Authorizations.
hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/ExpAsStringVisibilityLabelServiceImpl.java