docs: public Deferred<List<TSMeta>> getTSMetas() {
      class ResolutionCB implements Callback<Deferred<List<TSMeta>>, Object> {
        @Override
        public Deferred<List<TSMeta>> call(final Object done) throws Exception {
          final Scanner scanner = getScanner();
          scanner.setQualifier(TSMeta.META_QUALIFIER());
          final Deferred<List<TSMeta>> results = new Deferred<List<TSMeta>>();
          final List<TSMeta> tsmetas = new ArrayList<TSMeta>();
          final List<Deferred<TSMeta>> tsmeta_group = new ArrayList<Deferred<TSMeta>>();
          
          final class TSMetaGroupCB implements Callback<Object,
            ArrayList<TSMeta>> {
            @Override
            public List<TSMeta> call(ArrayList<TSMeta> ts) throws Exception {
              for (TSMeta tsm: ts) {
                if (tsm != null) {
                  tsmetas.add(tsm);
                }
              }
              results.callback(tsmetas);
              return null;
            }
            @Override
            public String toString() {
              return "TSMeta callback";
            }
          }
          
          final class ErrBack implements Callback<Object, Exception> {
            @Override
            public Object call(final Exception e) throws Exception {
              results.callback(e);
              return null;
            }
            @Override
            public String toString() {
              return "Error callback";
            }
          }
  
          /**
           * Scanner callback that will call itself while iterating through the 
           * tsdb-meta table.
           * 
           * Keeps track of a Set of Deferred TSMeta calls. When all rows are scanned,
           * will wait for all TSMeta calls to be completed and then create the result 
           * list.
           */
          final class ScannerCB implements Callback<Object,
            ArrayList<ArrayList<KeyValue>>> {
            
            /**
             * Starts the scanner and is called recursively to fetch the next set of
             * rows from the scanner.
             * @return The map of spans if loaded successfully, null if no data was
             * found
             */
            public Object scan() {
              return scanner.nextRows().addCallback(this).addErrback(new ErrBack());
            }
            
            /**
             * Loops through each row of the scanner results and parses out data
             * points and optional meta data
             * @return null if no rows were found, otherwise the TreeMap with spans
             */
            @Override
            public Object call(final ArrayList<ArrayList<KeyValue>> rows)
              throws Exception {
              try {
                if (rows == null) {
                  Deferred.group(tsmeta_group)
                    .addCallback(new TSMetaGroupCB()).addErrback(new ErrBack());
                  return null;
                }
                for (final ArrayList<KeyValue> row : rows) {
                  tsmeta_group.add(TSMeta.parseFromColumn(tsdb, row.get(0), true));
                }
                return scan();
              } catch (Exception e) {
                results.callback(e);
                return null;
              }
            }
          }
          
          new ScannerCB().scan();
          return results;
        }
        @Override
        public String toString() {
          return "TSMeta scan callback";
        }
      }
      
      if (metric_uid == null) {
        return resolveMetric().addCallbackDeferring(new ResolutionCB());
      }
      try {
        return new ResolutionCB().call(null);
      } catch (Exception e) {
        return Deferred.fromError(e);
      }
    }