diff --git a/src/Storm/Model/Loader.php b/src/Storm/Model/Loader.php
index 1a7a96607c64d280bd5468d33be2e551916374ec..0d7ba1ddf118726444a5cef3015dd232dacb3020 100644
--- a/src/Storm/Model/Loader.php
+++ b/src/Storm/Model/Loader.php
@@ -474,4 +474,77 @@ class Storm_Model_Loader {
   public function fetchAllBy($fields, $params) {
     return $this->getPersistenceStrategy()->fetchAllBy($fields, $params);
   }
+
+
+  public function clauseLike(string $key, string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseLike($key, $value);
+  }
+
+
+  public function clauseNotLike(string $key, string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseNotLike($key, $value);
+  }
+
+
+  public function clauseGreater(string $key, string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseGreater($key, $value);
+  }
+
+
+  public function clauseGreaterEqual(string $key, string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseGreaterEqual($key, $value);
+  }
+
+
+  public function clauseLesser(string $key, string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseLesser($key, $value);
+  }
+
+
+  public function clauseLesserEqual(string $key, string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseLesserEqual($key, $value);
+  }
+
+
+  public function clauseIs(string $key) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseIs($key);
+  }
+
+
+  public function clauseNotIs(string $key) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseNotIs($key);
+  }
+
+
+  public function clauseIn(string $key, array $array) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseIn($key, $array);
+  }
+
+
+  public function clauseNotIn(string $key, array $array) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseNotIn($key, $array);
+  }
+
+
+  public function clauseEqual(string $key,
+                              string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseEqual($key, $value);
+  }
+
+
+  public function clauseNotEqual(string $key, string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseNotEqual($key, $value);
+  }
+
+
+  public function clauseStart(string $key,
+                              string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseStart($key, $value);
+  }
+
+
+  public function clauseEnd(string $key,
+                            string $value) : Storm_Model_PersistenceStrategy_Clause {
+    return Storm_Model_PersistenceStrategy_Clause::clauseEnd($key, $value);
+  }
 }
diff --git a/src/Storm/Model/PersistenceStrategy/Clause.php b/src/Storm/Model/PersistenceStrategy/Clause.php
new file mode 100644
index 0000000000000000000000000000000000000000..b1db63ec7e60f8cde186de2f3f47de72bfce3f7d
--- /dev/null
+++ b/src/Storm/Model/PersistenceStrategy/Clause.php
@@ -0,0 +1,234 @@
+<?php
+/*
+STORM is under the MIT License (MIT)
+
+Copyright (c) 2010-2022 Agence Française Informatique http://www.afi-sa.fr
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+
+class Storm_Model_PersistenceStrategy_Clause {
+
+  protected
+    $_key,
+    $_operator,
+    $_value,
+    $_array,
+    $_negated,
+    $_is_array;
+
+  const
+    CLAUSE_WHERE = 'where',
+    CLAUSE_LIKE = 'like',
+    CLAUSE_EQUAL = '=',
+    CLAUSE_IN = 'in',
+    CLAUSE_IS = 'is',
+    CLAUSE_GREATER = '>',
+    CLAUSE_GREATER_EQUAL = '>=',
+    CLAUSE_LESSER = '<',
+    CLAUSE_LESSER_EQUAL = '<=',
+    PERCENT = '%';
+
+
+  public function __construct(string $key, string $operator, $value_or_array) {
+    $this->_negated = false;
+    $this->_key = $key;
+    $this->_operator = $operator;
+    $this->_is_array = is_array($value_or_array);
+
+    if ($this->_is_array)
+      $this->_array = $value_or_array;
+
+    if (!$this->_is_array)
+      $this->_value = $value_or_array;
+  }
+
+
+  public static function clauseIs(string $key) : self {
+    return new static($key, static::CLAUSE_IS, null);
+  }
+
+
+  public static function clauseNotIs(string $key) : self {
+    return static::clauseIs($key)->_setNegated(true);
+  }
+
+
+  public static function clauseIn(string $key, array $array) : self {
+    return new static($key, static::CLAUSE_IN, $array);
+  }
+
+
+  public static function clauseNotIn(string $key, array $array) : self {
+    return static::clauseIn($key, $array)->_setNegated(true);
+  }
+
+
+  public static function clauseEqual(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_EQUAL, $value);
+  }
+
+
+  public static function clauseNotEqual(string $key, string $value) : self {
+    return static::clauseEqual($key, $value)->_setNegated(true);
+  }
+
+
+  public static function clauseLike(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_LIKE, $value);
+  }
+
+
+  public static function clauseNotLike(string $key, string $value) : self {
+    return static::clauseLike($key, $value)->_setNegated(true);
+  }
+
+
+  public static function clauseStart(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_LIKE, $value . static::PERCENT);
+  }
+
+
+  public static function clauseEnd(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_LIKE, static::PERCENT . $value);
+  }
+
+
+  public static function clauseGreater(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_GREATER, $value);
+  }
+
+
+  public static function clauseGreaterEqual(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_GREATER_EQUAL, $value);
+  }
+
+
+  public static function clauseLesser(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_LESSER, $value);
+  }
+
+
+  public static function clauseLesserEqual(string $key, string $value) : self {
+    return new static($key, static::CLAUSE_LESSER_EQUAL, $value);
+  }
+
+
+  public static function newWith(string $key, $value_or_array) : self {
+    $operator = static::CLAUSE_EQUAL;
+    if (static::CLAUSE_WHERE === $key)
+      $operator = static::CLAUSE_WHERE;
+
+    $is_like = ' like' === substr($key, -5);
+    $key = $is_like ? substr($key, 0, strlen($key) - 5) : $key;
+    $negated = (' not' === substr($key, -4));
+    $key = $negated ? substr($key, 0, strlen($key) - 4) : $key;
+
+    if ($is_like)
+      $operator = static::CLAUSE_LIKE;
+
+    if (null === $value_or_array)
+      $operator = static::CLAUSE_IS;
+
+    if (is_array($value_or_array))
+      $operator = static::CLAUSE_IN;
+
+    return (new static($key, $operator, $value_or_array))->_setNegated($negated);
+  }
+
+
+  protected function _setNegated(bool $negated) : self {
+    $this->_negated = $negated;
+    return $this;
+  }
+
+
+  protected function _getValueOrArray() {
+    return $this->_is_array
+      ? ($this->_array ?? [])
+      : ($this->_value ?? '');
+  }
+
+
+  public function getFormatDb($table) : string {
+    if (static::CLAUSE_WHERE === $this->_operator)
+      return '(' . $this->_getValueOrArray() . ')';
+    if (static::CLAUSE_IS === $this->_operator)
+      return $this->_key . ' ' . $this->_getOperator() . ' null';
+
+    return $table->getAdapter()
+                 ->quoteInto($this->_clauseFormatDb(),
+                             $this->_getValueOrArray(), null, null);
+  }
+
+
+  protected function _clauseFormatDb() : string {
+    if (static::CLAUSE_IN === $this->_operator)
+      return $this->_key . ' ' . $this->_getOperator() . ' (?)';
+    if (static::CLAUSE_LIKE === $this->_operator)
+      return $this->_key . ' ' . $this->_getOperator() . ' ?';
+
+    return $this->_key . $this->_getOperator() . '?';
+  }
+
+
+  protected function _getOperator() : string {
+    if (static::CLAUSE_EQUAL === $this->_operator)
+      return ($this->_negated ? '!' : '') . $this->_operator;
+    if (static::CLAUSE_IS === $this->_operator)
+      return $this->_operator . ($this->_negated ? ' not' : '');
+
+    return ($this->_negated ? 'not ' : '') . $this->_operator;
+  }
+
+
+  public function containAttibuteInVolatile($model) : bool {
+    if (!array_key_exists($this->_key, $model))
+      return $this->_negated;
+
+    if ($this->_is_array && 0 === count($this->_getValueOrArray()))
+      throw new Storm_Model_Exception(sprintf('array given for %s is empty',
+                                              $this->_key));
+
+    if ($this->_is_array && in_array($model[$this->_key], $this->_getValueOrArray()))
+      return !$this->_negated;
+
+    if (static::CLAUSE_LIKE === $this->_operator) {
+      $matches = preg_match(('/^' . str_replace('%', '.*',
+                                                $this->_getValueOrArray()) . '$/i'),
+                            $model[$this->_key]);
+      return $this->_negated ? !$matches : $matches;
+    }
+
+    if (static::CLAUSE_GREATER === $this->_operator)
+      return $model[$this->_key] > $this->_getValueOrArray();
+
+    if (static::CLAUSE_GREATER_EQUAL === $this->_operator)
+      return $model[$this->_key] >= $this->_getValueOrArray();
+
+    if (static::CLAUSE_LESSER === $this->_operator)
+      return $model[$this->_key] < $this->_getValueOrArray();
+
+    if (static::CLAUSE_LESSER_EQUAL === $this->_operator)
+      return $model[$this->_key] <= $this->_getValueOrArray();
+
+    return ($this->_negated !== ($model[$this->_key] == $this->_getValueOrArray()));
+  }
+}
diff --git a/src/Storm/Model/PersistenceStrategy/Db.php b/src/Storm/Model/PersistenceStrategy/Db.php
index 4dad81e9fda43345fd34a80246107cf7d3067e93..17890faef779dfac86b446126cfe228c0b9c5de6 100644
--- a/src/Storm/Model/PersistenceStrategy/Db.php
+++ b/src/Storm/Model/PersistenceStrategy/Db.php
@@ -25,7 +25,8 @@ THE SOFTWARE.
 */
 
 
-class Storm_Model_PersistenceStrategy_Db extends Storm_Model_PersistenceStrategy_Abstract {
+class Storm_Model_PersistenceStrategy_Db
+  extends Storm_Model_PersistenceStrategy_Abstract {
 
   protected $_table;
 
@@ -90,27 +91,17 @@ class Storm_Model_PersistenceStrategy_Db extends Storm_Model_PersistenceStrategy
     $where = [];
     foreach($where_or_clauses as $key => $value)
       $where []= $this->_generateWhereClauseForKeyAndValue($key, $value);
+
     return implode(' and ', $where);
   }
 
 
-  protected function _generateWhereClauseForKeyAndValue(string $key, $value_or_array) : string {
-    if ('where' == $key)
-      return '(' . $value_or_array . ')';
-
-    if (' like' == substr($key, -5))
-      return $this->quoteInto($key . ' ?', $value_or_array);
-
-    $negated = (' not' == substr($key, -4));
-    $key = $negated ? substr($key, 0, strlen($key) - 4) : $key;
-
-    if (is_array($value_or_array))
-      return $this->quoteInto($key . ($negated ? ' not': '') . ' in (?)', $value_or_array);
+  protected function _generateWhereClauseForKeyAndValue(string $key, $value) : string {
+    $clause = ($value instanceof Storm_Model_PersistenceStrategy_Clause)
+      ? $value
+      : Storm_Model_PersistenceStrategy_Clause::newWith($key, $value);
 
-    if (null === $value_or_array)
-      return $key . ' is' . ($negated ? ' not' : '') . ' null';
-
-    return $this->quoteInto($key . ($negated ? '!': '') . '=?', $value_or_array);
+    return $clause->getFormatDb($this->getTable());
   }
 
 
@@ -164,14 +155,17 @@ class Storm_Model_PersistenceStrategy_Db extends Storm_Model_PersistenceStrategy
     return $rows[0]['numberof'];
   }
 
+
   public function insert($data) {
     return $this->getTable()->insert($data);
   }
 
+
   public function lastInsertId() {
     return $this->getTable()->getAdapter()->lastInsertId();
   }
 
+
   /**
    * @see findAllBy
    */
@@ -192,12 +186,12 @@ class Storm_Model_PersistenceStrategy_Db extends Storm_Model_PersistenceStrategy
       $select = $this->getTable()->select();
 
     foreach ($args as $field => $value) {
-      if (in_array($field, ['order', 'limit', 'where'])) {
+      if (in_array($field, ['order', 'limit', 'where'], true)) {
         $select->$field($value);
         continue;
       }
 
-      if (in_array($field, ['limitPage', 'scope'])) {
+      if (in_array($field, ['limitPage', 'scope'], true)) {
         $this->$field($select, $value);
         continue;
       }
diff --git a/src/Storm/Model/PersistenceStrategy/Volatile.php b/src/Storm/Model/PersistenceStrategy/Volatile.php
index b64668099eeba68d1fdea78ce36b03e7fd4277d2..0f160bac24089fd782244c924405588f55308922 100644
--- a/src/Storm/Model/PersistenceStrategy/Volatile.php
+++ b/src/Storm/Model/PersistenceStrategy/Volatile.php
@@ -193,45 +193,19 @@ class Storm_Model_PersistenceStrategy_Volatile  extends Storm_Model_PersistenceS
   }
 
 
-  public function containsNoneAttributes(array $model, array $select) : bool {
-    foreach ($select as $key => $value)
-      if ($this->containsAttribute($model, $key, $value))
-        return false;
-
-    return true;
-  }
-
-
   public function containsAttribute(array $model, string $key, $value) : bool {
-    if (preg_match('/left\((.+),(.+)\)/', $key, $matches)) {
-      $key = trim($matches[1]);
-      $left_len = (int)$matches[2];
-    }
-
-    if (preg_match('/(.+)( not)? like/', $key, $matches)) {
-      $key = trim($matches[1]);
-      $like = '/^' . str_replace('%', '.*', $value) . '$/i';
-    }
-
-    if (!array_key_exists($key, $model))
-      return false;
-
-    if (is_array($value) && count($value) == 0)
-      throw new Storm_Model_Exception(sprintf('array given for %s is empty',
-                                              $key));
+    $clause = ($value instanceof Storm_Model_PersistenceStrategy_Clause)
+      ? $value
+      : null;
 
-    if (is_array($value) && in_array($model[$key], $value))
-      return true;
+    if (!$clause && preg_match('/left\((.+),(.+)\)/', $key, $matches))
+      $clause = Storm_Model_PersistenceStrategy_Clause::clauseLike(trim($matches[1]),
+                                                                   (substr($value, 0, (int)$matches[2]) . '%'));
 
-    if (isset($left_len)
-        && is_string($value)
-        && substr($model[$key], 0, $left_len) === substr($value, 0, $left_len))
-      return true;
+    if (!$clause)
+      $clause = Storm_Model_PersistenceStrategy_Clause::newWith($key, $value);
 
-    if (isset($like))
-      return preg_match($like, $model[$key]);
-
-    return $model[$key] == $value;
+    return $clause->containAttibuteInVolatile($model);
   }
 
 
@@ -301,28 +275,17 @@ class Storm_Model_PersistenceStrategy_Volatile  extends Storm_Model_PersistenceS
 
 
   protected function _allMatchingInstancesDo(array $clauses, callable $callback) : int {
-    $negations = [];
-
-    foreach($clauses as $k => $v) {
-      if (false !== strpos($k, ' not')) {
-        $negations[str_replace(' not', '', $k)] = $v;
-        unset($clauses[$k]);
-      }
-    }
-
     $matching_instances = array_filter($this->getInstancesArray(),
-                                       function($model) use ($clauses, $negations) {
-                                         return $this->_modelMatchesClausesAndNegations($model, $clauses, $negations);
+                                       function ($model) use ($clauses) {
+                                         return $this->_modelMatchesClauses($model, $clauses);
                                        });
 
     return count(array_map($callback, $matching_instances));
   }
 
 
-  protected function _modelMatchesClausesAndNegations(array $model, array $clauses, array $negations) : bool {
-    return
-      $this->containsAllAttributes($model, $clauses)
-      && (empty($negations) || $this->containsNoneAttributes($model, $negations));
+  protected function _modelMatchesClauses(array $model, array $clauses) : bool {
+    return $this->containsAllAttributes($model, $clauses);
   }
 
 
@@ -335,5 +298,3 @@ class Storm_Model_PersistenceStrategy_Volatile  extends Storm_Model_PersistenceS
     return true;
   }
 }
-
-?>
diff --git a/tests/Storm/Test/LoaderTest.php b/tests/Storm/Test/LoaderTest.php
index 30b515301f1691c7f04a0023b5e4512b371dc877..29650d4721337b214f9a786e63b3807cf20fea40 100644
--- a/tests/Storm/Test/LoaderTest.php
+++ b/tests/Storm/Test/LoaderTest.php
@@ -157,11 +157,42 @@ class Storm_Test_LoaderBasicTest extends Storm_Test_LoaderTestCase {
   public function findAllByGeneratedSelects() {
     return
       [
-       [ ['name not' => 'Harlock'] , ['name!=\'Harlock\''] ],
-       [ ['name not' => ['Harlock', 'Nausicaa']] , ['name not in (\'Harlock\',\'Nausicaa\')'] ],
-       [ ['name not' => null] , ['name is not null'] ],
-       [ ['login like' => '%aus%'] , ['login like \'%aus%\''] ],
-       [ ['login not like' => '%aus%'] , ['login not like \'%aus%\''] ]
+       [ ['name' => null] , ['name is null'] ],
+       [ ['name' => ['Harlock', 'Nausicaa']], ['name in (\'Harlock\',\'Nausicaa\')'] ],
+       [ ['name not' => 'Harlock'], ['name!=\'Harlock\''] ],
+       [ ['name not' => ['Harlock', 'Nausicaa']],
+        ['name not in (\'Harlock\',\'Nausicaa\')'] ],
+       [ ['name not' => null], ['name is not null'] ],
+       [ ['login like' => '%aus%'], ['login like \'%aus%\''] ],
+       [ ['login not like' => '%aus%'], ['login not like \'%aus%\''] ],
+       [ ['where' => 'id=\'29\' and name=\'lp\''], ['id=\'29\' and name=\'lp\''] ],
+       [ ['left(name, 5)' => 'ganda'], ['left(name, 5)=\'ganda\''] ],
+       [ ['id' => '29'], ['id=\'29\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseGreater('id', '30') ],
+        ['id>\'30\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseGreaterEqual('id', '30') ],
+        ['id>=\'30\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseLesser('id', '30') ],
+        ['id<\'30\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseLesserEqual('id', '30') ],
+        ['id<=\'30\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseIs('name') ], ['name is null'] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseIn('name', ['Harlock', 'Nausicaa']) ],
+        ['name in (\'Harlock\',\'Nausicaa\')'] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseNotEqual('name', 'Harlock') ],
+        ['name!=\'Harlock\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseNotIn('name', ['Harlock', 'Nausicaa']) ],
+        ['name not in (\'Harlock\',\'Nausicaa\')'] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseLike('login', '%aus%') ],
+        ['login like \'%aus%\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseNotLike('login', '%aus%') ],
+        ['login not like \'%aus%\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseEqual('left(name, 5)', 'ganda') ],
+        ['left(name, 5)=\'ganda\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseStart('login', 'aus') ],
+        ['login like \'aus%\''] ],
+       [ [ Storm_Model_PersistenceStrategy_Clause::clauseEnd('login', 'aus') ],
+        ['login like \'%aus\''] ],
       ];
   }
 
diff --git a/tests/Storm/Test/LoaderVolatileTest.php b/tests/Storm/Test/LoaderVolatileTest.php
index a42e61b95d74cdfa94b3df2aa6b80d5a840ba103..87e553715454546c7df8dc3282981ce28778b627 100644
--- a/tests/Storm/Test/LoaderVolatileTest.php
+++ b/tests/Storm/Test/LoaderVolatileTest.php
@@ -179,7 +179,7 @@ class Storm_Test_LoaderVolatileTest extends Storm_Test_ModelTestCase {
   /** @test */
   public function changingAlbertBrainShouldUpdateItsReferenceInBrainId() {
     $better_brain = $this->fixture(Storm_Test_VolatileBrain::class, ['id' => 3,
-                                                                'weight' => 150]);
+                                                                     'weight' => 150]);
     $this->albert->setBrain($better_brain);
     $this->assertEquals(3, $this->albert->getBrainId());
   }
@@ -777,5 +777,76 @@ class Storm_Test_LoaderVolatileTest extends Storm_Test_ModelTestCase {
                         ->collect('login')
                         ->getArrayCopy());
   }
+
+
+  /** @test */
+  public function selectAllCatsWhereIdMoreThanThreeShouldAnswersFifiAndLoulou() {
+    $this->assertEquals(['fifi', 'loulou'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileCat::findAllBy([Storm_Test_VolatileCat::clauseGreater('id', 3)])))
+                        ->collect('name')
+                        ->getArrayCopy());
+  }
+
+
+  /** @test */
+  public function selectAllCatsWhereIdMoreOrEqualThanForShouldAnswersFifiAndLoulou() {
+    $this->assertEquals(['fifi', 'loulou'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileCat::findAllBy([Storm_Test_VolatileCat::clauseGreaterEqual('id', 4)])))
+                        ->collect('name')
+                        ->getArrayCopy());
+  }
+
+
+  /** @test */
+  public function selectAllCatsWhereIdLesserThanFiveShouldAnswersRiriAndFifi() {
+    $this->assertEquals(['riri', 'fifi'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileCat::findAllBy([Storm_Test_VolatileCat::clauseLesser('id', 5)])))
+                        ->collect('name')
+                        ->getArrayCopy());
+  }
+
+
+  /** @test */
+  public function selectAllCatsWhereIdLesserOrEqualThanForShouldAnswersRiriAndFifi() {
+    $this->assertEquals(['riri', 'fifi'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileCat::findAllBy([Storm_Test_VolatileCat::clauseLesserEqual('id', 4)])))
+                        ->collect('name')
+                        ->getArrayCopy());
+  }
+
+
+  /** @test */
+  public function selectUserLoginNotHubertShouldReturnAlbertAndZoe() {
+    $this->assertEquals(['albert', 'zoe'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileUser::findAllBy([Storm_Test_VolatileUser::clauseNotEqual('login', 'hubert')])))
+                        ->collect('login')
+                        ->getArrayCopy());
+  }
+
+
+  /** @test */
+  public function selectUserLoginInAlbertZoeAndFooNotLikeSnafuShouldReturnAlbert() {
+    $this->assertEquals(['albert'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileUser::findAllBy([Storm_Test_VolatileUser::clauseIn('login', ['albert', 'zoe']), Storm_Test_VolatileUser::clauseNotLike('foo', '%naf%')])))
+                        ->collect('login')
+                        ->getArrayCopy());
+  }
+
+
+  /** @test */
+  public function selectUserLoginInAlbertZoeAndFooStartSnaShouldReturnZoe() {
+    $this->assertEquals(['zoe'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileUser::findAllBy([Storm_Test_VolatileUser::clauseIn('login', ['albert', 'zoe']), Storm_Test_VolatileUser::clauseStart('foo', 'sna')])))
+                        ->collect('login')
+                        ->getArrayCopy());
+  }
+
+
+  /** @test */
+  public function selectUserLoginInAlbertZoeAndFooEndAfuShouldReturnZoe() {
+    $this->assertEquals(['zoe'],
+                        (new Storm_Model_Collection(Storm_Test_VolatileUser::findAllBy([Storm_Test_VolatileUser::clauseIn('login', ['albert', 'zoe']), Storm_Test_VolatileUser::clauseEnd('foo', 'afu')])))
+                        ->collect('login')
+                        ->getArrayCopy());
+  }
 }
-?>