docs: function( conditions, fieldPrefix, selectorWithoutBells ){
  
      //consolelog("FILTERS IN MONGO MIXIN: " );
      //consolelog( require('util').inspect( filters, {depth: 10 }) );
  
      var self = this;
      var a, aWithPrefix, aIsSearchableAsString, b;
  
      // If there is no condition, return an empty filter
      if( ! conditions.type ) return {};
  
      // Scan filters recursively, making up the mongo query
      if( conditions.type == 'and' || conditions.type == 'or' ){
  
        // For 'and', it will return { $and: [ ... ] }
        var mongoName = '$' + conditions.type;
  
        // The content of the $and key will be the result of makeMongo
        var r = {};
        r[ mongoName ] = conditions.args.map( function( item ){
          return self._makeMongoConditions( item, fieldPrefix, selectorWithoutBells );
        });
        return r;
  
      } else {
  
        // Otherwise, run the operator encoutered
        // (But, remember to fixup the field name (paths, etc.) and possibly the checked value (uppercase)
        var operator = this._operators[ conditions.type ];
        if( ! operator ) throw( new Error( "Could not find operator: " + conditions.type ) );
  
        // Save this for later
        a = conditions.args[ 0 ];
        b = conditions.args[ 1 ];
  
        // Making up aWithPrefix, useful to check if it's searchable, if
        // b should be converted to upperCase(), etc.
  
        // Create aWithPrefix, which is simply `a` with the prefix prepended
        // to it
        aWithPrefix = this._addPrefix( a, fieldPrefix );
  
        // Check that aWithPrefix is indeed searchable
        if( !self._searchableHash[ aWithPrefix ] ){
          throw( new Error("Field " + aWithPrefix + " is not searchable" ) );
        }
  
        // Cast the field to the right type in the schema
  
        //console.log("Type of b before the cure:" , a, conditions, typeof b );
        var definition = self._searchableHash[ aWithPrefix ];
        var definitionSchema = self._searchableHashSchema[ aWithPrefix ];      
        var type = definition.type;
        var castFunction = type && definitionSchema[ type + 'TypeCast'];
        var failedCasts = {};
        var errors = [];
        //console.log( type, castFunction, definitionSchema );
        if( type &&  castFunction ){
          b = castFunction.call( definitionSchema, definition, b, aWithPrefix, {}, failedCasts );
        }
        Object.keys( failedCasts ).forEach( function( fieldName ){
          errors.push( { field: aWithPrefix, message: "Error during casting" } );
        });
        // TODO: See what to do about error
        //console.log("Type of b after the cure:" , typeof b );
        //console.log("Errors: " , errors );
    
        // Create aIsSearchableAsString. Saving the result as I will need the result
        // if this check later on, to determine whether to add __uc__ to `a`
        aIsSearchableAsString = this._isSearchableAsString( aWithPrefix );
  
        // `upperCase()` `b` if a is of type 'string', since it will be compared to
        // the __uc__ equivalent field
        b = aIsSearchableAsString ? b.toUpperCase() : b;
  
        // Unless we want a selector without path (only used when `$pull`ing an array in `deleteMany`),
        // `a` needs to become `aWithPrefix`.
        a = selectorWithoutBells ? a : aWithPrefix;
  
        // Add __uc__ (if field is 'string') to path
        if( aIsSearchableAsString ) a = self._addUcPrefixToPath( a );
  
        // Add _children to `a` (unless a selector without bells was required)
        a = selectorWithoutBells ? a : self._addChildrenPrefixToPath( a );
  
        // Call the operator on the two values
        return operator.call( this, a, b, fieldPrefix, selectorWithoutBells );
      }
  
    }