/**
  * @param s the JSON representation of the filter
  * @return the filter
  * @throws Exception
  */
 public static Filter buildFilter(String s) throws Exception {
   JSONJAXBContext context =
       new JSONJAXBContext(JSONConfiguration.natural().build(), FilterModel.class);
   JSONUnmarshaller unmarshaller = context.createJSONUnmarshaller();
   FilterModel model = unmarshaller.unmarshalFromJSON(new StringReader(s), FilterModel.class);
   return model.build();
 }
 public Filter build() {
   Filter filter;
   switch (FilterType.valueOf(type)) {
     case ColumnCountGetFilter:
       filter = new ColumnCountGetFilter(limit);
       break;
     case ColumnPaginationFilter:
       filter = new ColumnPaginationFilter(limit, offset);
       break;
     case ColumnPrefixFilter:
       filter = new ColumnPrefixFilter(Base64.decode(value));
       break;
     case ColumnRangeFilter:
       filter =
           new ColumnRangeFilter(
               Base64.decode(minColumn),
               minColumnInclusive,
               Base64.decode(maxColumn),
               maxColumnInclusive);
       break;
     case DependentColumnFilter:
       filter =
           new DependentColumnFilter(
               Base64.decode(family),
               qualifier != null ? Base64.decode(qualifier) : null,
               dropDependentColumn,
               CompareOp.valueOf(op),
               comparator.build());
       break;
     case FamilyFilter:
       filter = new FamilyFilter(CompareOp.valueOf(op), comparator.build());
       break;
     case FilterList:
       {
         List<Filter> list = new ArrayList<Filter>();
         for (FilterModel model : filters) {
           list.add(model.build());
         }
         filter = new FilterList(FilterList.Operator.valueOf(op), list);
       }
       break;
     case FirstKeyOnlyFilter:
       filter = new FirstKeyOnlyFilter();
       break;
     case InclusiveStopFilter:
       filter = new InclusiveStopFilter(Base64.decode(value));
       break;
     case KeyOnlyFilter:
       filter = new KeyOnlyFilter();
       break;
     case MultipleColumnPrefixFilter:
       {
         byte[][] values = new byte[prefixes.size()][];
         for (int i = 0; i < prefixes.size(); i++) {
           values[i] = Base64.decode(prefixes.get(i));
         }
         filter = new MultipleColumnPrefixFilter(values);
       }
       break;
     case PageFilter:
       filter = new PageFilter(Long.valueOf(value));
       break;
     case PrefixFilter:
       filter = new PrefixFilter(Base64.decode(value));
       break;
     case QualifierFilter:
       filter = new QualifierFilter(CompareOp.valueOf(op), comparator.build());
       break;
     case RandomRowFilter:
       filter = new RandomRowFilter(chance);
       break;
     case RowFilter:
       filter = new RowFilter(CompareOp.valueOf(op), comparator.build());
       break;
     case SingleColumnValueFilter:
       filter =
           new SingleColumnValueFilter(
               Base64.decode(family),
               qualifier != null ? Base64.decode(qualifier) : null,
               CompareOp.valueOf(op),
               comparator.build());
       if (ifMissing != null) {
         ((SingleColumnValueFilter) filter).setFilterIfMissing(ifMissing);
       }
       if (latestVersion != null) {
         ((SingleColumnValueFilter) filter).setLatestVersionOnly(latestVersion);
       }
       break;
     case SingleColumnValueExcludeFilter:
       filter =
           new SingleColumnValueExcludeFilter(
               Base64.decode(family),
               qualifier != null ? Base64.decode(qualifier) : null,
               CompareOp.valueOf(op),
               comparator.build());
       if (ifMissing != null) {
         ((SingleColumnValueExcludeFilter) filter).setFilterIfMissing(ifMissing);
       }
       if (latestVersion != null) {
         ((SingleColumnValueExcludeFilter) filter).setLatestVersionOnly(latestVersion);
       }
       break;
     case SkipFilter:
       filter = new SkipFilter(filters.get(0).build());
       break;
     case TimestampsFilter:
       filter = new TimestampsFilter(timestamps);
       break;
     case ValueFilter:
       filter = new ValueFilter(CompareOp.valueOf(op), comparator.build());
       break;
     case WhileMatchFilter:
       filter = new WhileMatchFilter(filters.get(0).build());
       break;
     default:
       throw new RuntimeException("unhandled filter type: " + type);
   }
   return filter;
 }