public FindTasksResult FindTasks(string tasktype, string reference, TaskStateEnum? taskState)
        {
            const int MaximumResults = 50;
            const string MethodName = "FindTasks";

            CheckObjectAlreadyDisposed();

            ICollection<Task> result = new HashedSet<Task>();
            int numberOfMatchingTasks = -1;

            if (s_Logger.IsDebugEnabled)
            {
                s_Logger.Debug(
                    string.Format(
                        "{0}({1},{2},{3})",
                        MethodName,
                        tasktype ?? string.Empty,
                        reference,
                        taskState.HasValue
                            ? taskState.ToString()
                            : string.Empty));
            }

            try
            {
                ICriteria criteria = BuildFindTasksQuery(tasktype, reference, taskState, MaximumResults);
                result = criteria.List<Task>();
                if (result.Count < MaximumResults)
                {
                    numberOfMatchingTasks = result.Count;
                }
                else
                {
                    criteria = BuildCountTasksQuery(tasktype, reference, taskState);
                    numberOfMatchingTasks = criteria.UniqueResult<int>();
                }
            }
            catch (HibernateException he)
            {
                // Any hibernate exception is an error
                string message = string.Format(
                    "{0}({1},{2},{3})",
                    MethodName,
                    tasktype ?? string.Empty,
                    reference,
                    taskState.HasValue ?
                                           taskState.ToString()
                        : string.Empty);
                s_Logger.Fatal(message, he);
                StatelessCrudDao.TriageException(he, message);
            }

            if (s_Logger.IsDebugEnabled)
            {
                s_Logger.Debug(
                    string.Format(
                        "{0}({1},{2},{3}) result {4}",
                        MethodName,
                        tasktype ?? string.Empty,
                        reference,
                        taskState.HasValue
                            ? taskState.ToString()
                            : string.Empty, result));
            }

            ICollection<Task> allowedResult = result
                .Where(r => HasSufficientSecurity(r.GetType(), SecurityActionFlag.RETRIEVE))
                .ToList();
            return new FindTasksResult(allowedResult, numberOfMatchingTasks);
        }
        public FindTasksResult FindTasks(IEnumerable<string> taskTypes, IDictionary<string, string> searchAttributes, TaskStateEnum? taskState)
        {
            const int MaximumResults = 50;
            const string MethodName = "FindTasks";

            CheckObjectAlreadyDisposed();

            int numberOfMatchingTasks;

            if (s_Logger.IsDebugEnabled)
            {
                s_Logger.DebugFormat(
                    "{0}({1},{2},{3})",
                    MethodName,
                    string.Join(@",", taskTypes.ToArray()),
                    searchAttributes,
                    taskState != null
                        ? taskState.ToString()
                        : string.Empty);
            }

            // coalesce if nescessary
            searchAttributes = searchAttributes ?? new Dictionary<string, string>();
            taskTypes = taskTypes ?? Enumerable.Empty<string>();
            IList<Task> result;
            try
            {
                IQuery query = BuildFindTasksQuery(taskTypes, searchAttributes, taskState, MaximumResults);
                result = query.List<Task>();
                if (result.Count < MaximumResults)
                {
                    numberOfMatchingTasks = result.Count;
                }
                else
                {
                    query = BuildCountTasksQuery(taskTypes, searchAttributes, taskState);
                    numberOfMatchingTasks = (int)query.UniqueResult<long>();
                }
            }
            catch (HibernateException he)
            {
                // Any hibernate exception is an error
                string message = string.Format(
                    "{0}({1},{2},{3})",
                    MethodName,
                    string.Join(@",", taskTypes.ToArray()),
                    searchAttributes,
                    taskState != null
                        ? taskState.ToString()
                        : string.Empty);
                s_Logger.Fatal(message, he);
                StatelessCrudDao.TriageException(he, message);
                // Line needed to keep resharper happy :) 
                // triageException should give an exception back instead of throwing it already
                throw new Exception();
            }

            if (s_Logger.IsDebugEnabled)
            {
                s_Logger.DebugFormat(
                    "{0}({1},{2},{3}) result {4}",
                    MethodName,
                    string.Join(@",", taskTypes.ToArray()),
                    searchAttributes,
                    taskState.HasValue
                        ? taskState.ToString()
                        : string.Empty, result);
            }

            ICollection<Task> allowedResult = result
                .Where(r => HasSufficientSecurity(r.GetType(), SecurityActionFlag.RETRIEVE))
                .ToArray();
            return new FindTasksResult(allowedResult, numberOfMatchingTasks);
        }