private function equalRecurse(ClauseGroup $g1, ClauseGroup $g2, $level)
 {
     if ($g1->getType() != $g2->getType() || $g1->getCount() != $g2->getCount()) {
         return false;
     }
     $subClauses1 = $g1->getSubclauses();
     $subClauses2 = $g2->getSubclauses();
     $ok = true;
     for ($i = 0; $i < count($subClauses1); $i++) {
         $item1 = $subClauses1[$i];
         $item2 = $subClauses2[$i];
         if ($item1 instanceof ClauseGroup) {
             $ok = $this->equalRecurse($item1, $item2, $level + 1);
         } else {
             $ok = $item1 == $item2;
         }
         if (!$ok) {
             break;
         }
     }
     return $ok;
 }
 /**
  * Recursive function to build the code from nested ClauseGroup objects
  */
 private function buildRecursive(ClauseGroup $group, $level, &$cid, $simplifyOpts = null)
 {
     $lines = array();
     $i = 0;
     foreach ($group->getSubclauses() as $subClause) {
         if ($subClause instanceof ClauseGroup) {
             // Pass the simplification options to the ClauseGroup
             $subClause->simplify($simplifyOpts);
             $block = $this->buildRecursive($subClause, $level + 1, $cid, $simplifyOpts);
             $type = $subClause->getType();
             switch ($type) {
                 case ClauseGroup::BOOLEAN_AND:
                     break;
                 case ClauseGroup::BOOLEAN_OR:
                     break;
                 default:
                     throw new Exception('Unrecognised boolean operator found');
             }
             // Copy code into lines
             foreach ($block as $pieces) {
                 array_push($lines, $pieces);
             }
         } else {
             // Build a criterion statement
             SubclauseParser::parse($subClause, $col, $op, $value);
             // This is the name of the criterion object
             $crit = '$' . $this->cPrefix . $cid;
             // Modify the value if required
             $value = $this->valuePostProcess($op, $value);
             // Loop through the operators we presently know about
             $line = null;
             foreach ($this->ops as $thatOp => $syntax) {
                 if ($op == $thatOp) {
                     $cid++;
                     // For the equality operator...
                     if (is_null($syntax)) {
                         $statement = "{$crit} = \$c->getNewCriterion({$col}, {$value});\n";
                     } elseif (is_null($value)) {
                         $statement = "{$crit} = \$c->getNewCriterion({$col}, null, Criteria::{$syntax});\n";
                     } else {
                         $statement = "{$crit} = \$c->getNewCriterion({$col}, {$value}, Criteria::{$syntax});\n";
                     }
                     $line = $this->makeLine($statement, $level, $i == 0, $crit);
                     array_push($lines, $line);
                     break;
                 }
             }
             // Moan if the operator is not found, as it was detected by SubclauseParser!
             if (is_null($line)) {
                 throw new Exception("Unrecognised comparison operator ('{$op}') found");
             }
         }
         $i++;
     }
     // OK, link up the criterions at our current level
     $crits = '';
     $first = null;
     $code = '';
     foreach ($lines as $line) {
         if ($line['level'] == $level) {
             $crit = $line['crit'];
             if (!$first) {
                 $first = $crit;
             } else {
                 $op = $this->boolOpToPropelOp($group->getType());
                 $code .= "{$first}->{$op}({$crit});\n";
             }
             $crits .= $line['crit'] . ' ';
         }
     }
     // Trim off the last \n we've given the code block
     $code = substr($code, 0, strlen($code) - 1);
     $type = $group->getType();
     $str = "{$code}\n";
     if ($this->comments) {
         $str = "// Perform {$type} at level {$level} ({$crits})\n{$str}";
     }
     $str = "\n{$str}";
     $line = $this->makeLine($str, $level - 1, false, $first);
     array_push($lines, $line);
     // Link into $c if last item
     if ($level == 0) {
         // Determine the right select method and loop to use
         if ($this->returnType == self::RETURN_ARRAY) {
             $method = 'doSelect';
             $loop = "foreach (\$result as \$obj)\n{\n\t//\$val = \$obj->getValue();\n}";
             $postOp = "";
         } else {
             // Determine fetch mode
             $fetchMode = $this->resultSetType;
             if ($fetchMode == self::RESULTSET_NUM) {
                 $col1 = '1';
                 $col2 = '2';
             } else {
                 $col1 = "'col1'";
                 $col2 = "'col2'";
             }
             $method = 'doSelectRS';
             $loop = "while (\$result->next())\n{\n\t//\$str = \$result->getString({$col1});\n\t//\$int = \$result->getInt({$col2});\n}";
             $postOp = "\$result->setFetchMode(ResultSet::{$fetchMode});\n";
         }
         // OK, add the select part...
         $statement = "\n";
         if ($this->comments) {
             $statement .= "// Remember to change the peer class here for the correct one in your model\n";
         }
         $statement .= "\$c->add({$first});\n\$result = TablePeer::{$method}(\$c);\n{$postOp}\n";
         // ... now add a demo loop
         if ($this->loop) {
             if ($this->comments) {
                 $statement .= "// This loop will of course need to be edited to work\n";
             }
             $statement .= $loop;
         }
         $line = $this->makeLine($statement, -1);
         array_push($lines, $line);
     }
     return $lines;
 }