docs: public void compile() {
      if (LOG.isDebugEnabled()) {
        LOG.debug("Compiling " + this);
      }
      if (results.size() < 1) {
        throw new IllegalArgumentException("No results for any variables in "
            + "the expression: " + this);
      }
      if (results.size() < names.size()) {
        throw new IllegalArgumentException("Not enough query results [" 
            + results.size() + " total results found] for the expression variables [" 
            + names.size() + " expected] " + this);
      }
      
      // don't care if we have extra results, but we had darned well better make
      // sure we have a result set for each variable    
      for (final String variable : names) {
        // validation
        final ITimeSyncedIterator it = results.get(variable.toLowerCase());
        if (it == null) {
          throw new IllegalArgumentException("Missing results for variable " + variable);
        }
  
        if (it instanceof ExpressionIterator) {
          ((ExpressionIterator)it).compile();
        }
        if (LOG.isDebugEnabled()) {
          LOG.debug("Matched variable " + variable + " to " + it);
        }
      }
      
      // TODO implement other set functions
      switch (set_operator) {
      case INTERSECTION:
        iterator = new IntersectionIterator(id, results, intersect_on_query_tagks, 
            include_agg_tags);
        break;
      case UNION:
        iterator = new UnionIterator(id, results, intersect_on_query_tagks, 
            include_agg_tags);
      }
      iteration_results = iterator.getResults();
      
      dps = new ExpressionDataPoint[iterator.getSeriesSize()];
      for (int i = 0; i < iterator.getSeriesSize(); i++) {
        final Iterator<Entry<String, ExpressionDataPoint[]>> it = 
            iteration_results.entrySet().iterator();
        Entry<String, ExpressionDataPoint[]> entry = it.next();
        
        if (entry.getValue() == null || entry.getValue()[i] == null) {
          dps[i] = new ExpressionDataPoint();
        } else {
          dps[i] = new ExpressionDataPoint(entry.getValue()[i]);
        }
        while (it.hasNext()) {
          entry = it.next();
          if (entry.getValue() != null && entry.getValue()[i] != null) {
            dps[i].add(entry.getValue()[i]);
          }
        }
      }
      
      if (LOG.isDebugEnabled()) {
        LOG.debug("Finished compiling " + this);
      }
    }