/**
  * Parses a non-bracketed expression
  *
  * Returns a ClauseGroup for a multi-part expression, or returns a string for an
  * expression containing just one (<col> <test> <value>) part
  */
 private function parse($clause)
 {
     // If the input string is essentially empty then return null
     if (trim($clause) == '') {
         return null;
     }
     // Ensure that ANDs and ORs are not mixed
     $strAnd = ClauseGroup::BOOLEAN_AND;
     $strOr = ClauseGroup::BOOLEAN_OR;
     $boolAnd = strpos($clause, " {$strAnd} ") !== false;
     $boolOr = strpos($clause, " {$strOr} ") !== false;
     if ($boolAnd && $boolOr) {
         throw new SyntaxError("Need to bracket ANDs and ORs to indicate precedence in clause <{$clause}>");
     }
     if ($boolOr) {
         $split = $strOr;
     } elseif ($boolAnd) {
         $split = $strAnd;
     } else {
         $split = null;
     }
     // If applicable, split the clause into subclauses and decide the type
     if ($split) {
         $subClauses = explode(" {$split} ", $clause);
     } else {
         $subClauses = array($clause);
     }
     $group = new ClauseGroup();
     $group->setType($split);
     // Then add all the subclauses in
     foreach ($subClauses as $subClause) {
         if (trim($subClause) != '') {
             QuotedStringParser::insertStrings($subClause, $this->strings);
             $group->addSubclause($subClause);
         }
     }
     // If there is only one subclause, return a string rather than a ClauseGroup
     /*
     		$subClauseArray = $group->getSubclauses();
     		if (count($subClauseArray) == 1)
     		{
     			return $subClauseArray[0];
     		}
     		else
     		{
     			return $group;
     		}*/
     return $group;
 }
$g1->setType(ClauseGroup::BOOLEAN_AND);
$t->ok($result->equal($g1), 'decode a valid bracketed string containing ANDs and ORs');
$clause1 = "person.age IN (17,18,19,20)";
$clause2 = "person.height IN (100, 101)";
$result = $ca->analyse($clause1);
$rClause1 = $result->getFirstSubclause();
$g = new ClauseGroup();
$g->addSubclause($rClause1);
$t->ok($result->equal($g), 'decode a simple IN statement');
try {
    $clause = $clause1 . ' OR ' . $clause2;
    $result = $ca->analyse($clause);
    $clauses = $result->getSubclauses();
    $g->addSubclause($clauses[1]);
    $g->setType(ClauseGroup::BOOLEAN_OR);
    $ok = $result->equal($g);
} catch (Exception $e) {
    $ok = false;
}
$t->ok($ok, 'decode a two IN statements');
$clause = "person.name IN ('person.age IN (1, 2, 3)')";
try {
    $result = $ca->analyse($clause);
    $rClause = $result->getFirstSubclause();
    $g = new ClauseGroup();
    $g->addSubclause($rClause);
    $ok = $result->equal($g);
} catch (Exception $e) {
    $ok = false;
}
$t->ok($ok, 'decode a simple IN statement containing a misleading IN string');