public function findBy(array $criteria = array(), array $options = array())
    {
        // Check the identity map first.
        if (array_key_exists($this->getUserColumns('id'), $criteria) 
            && array_key_exists($criteria[$this->getUserColumns('id')], $this->identityMap)) {
            return array($this->identityMap[$criteria[$this->getUserColumns('id')]]);
        }

        list ($common_sql, $params) = $this->createCommonFindSql($criteria);

        $sql = 'SELECT * ' . $common_sql;

        if (array_key_exists('order_by', $options)) {
            list ($order_by, $order_dir) = is_array($options['order_by']) ? $options['order_by'] : array($options['order_by']);
            $sql .= 'ORDER BY ' . $this->conn->quoteIdentifier($order_by) . ' ' . ($order_dir == 'DESC' ? 'DESC' : 'ASC') . ' ';
        }
        if (array_key_exists('limit', $options)) {
            list ($offset, $limit) = is_array($options['limit']) ? $options['limit'] : array(0, $options['limit']);
            $sql .=   ' LIMIT ' . (int) $limit . ' ' .' OFFSET ' . (int) $offset ;
        }

        $data = $this->conn->fetchAll($sql, $params);

        $users = array();
        foreach ($data as $userData) {
            if (array_key_exists($userData[$this->getUserColumns('id')], $this->identityMap)) {
                $user = $this->identityMap[$userData[$this->getUserColumns('id')]];
            } else {
                $userData['customFields'] = $this->getUserCustomFields($userData[$this->getUserColumns('id')]);
                $user = $this->hydrateUser($userData);
                $this->identityMap[$user->getId()] = $user;
            }
            $users[] = $user;
        }

        return $users;
    }