//handle special case departments
        private DepartmentModel GetNormalDepartment(SearchModel criteria)
        {
            int deptId = GetDepartmentIDFromUrlName(criteria.DepartmentName);
            //specific courses...
            DepartmentModel result = GetDepartmentModelBasics(deptId);
            result.HasChildDepartments = false;

            using (HPSADataContext ctx = new HPSADataContext())
            {
                var predicate = PredicateBuilder.True<vw_CLASS_D>();
                bool fPrefixes = false;

                //specify yearquarter
                predicate = predicate.And(s => s.YRQ == criteria.YearQuarterID);

                //handle specifics for this department...
                string[] departmentPrefixes = GetDepartmentPrefixes(deptId);
                if (departmentPrefixes.Count() > 0)
                {
                    predicate = predicate.And(s => departmentPrefixes.Contains(s.CoursePrefix)); //&& !s.CourseNumber.Contains("I"));
                    fPrefixes = true;
                }
                else
                {
                    fPrefixes = false;
                }

                //Get the list of Misc Sort field values that will be used to filter results -
                //so any class offering with these values in the misc sort field will be excluded.
                string[] deptExcludedMiscSort = GetExcludedMiscSort(deptId);
                //exclude the misc sort field value(s) if there are any specified.
                if (deptExcludedMiscSort.Count() > 0)
                {
                    predicate = predicate.And(s => !deptExcludedMiscSort.Contains(s.MISC_SRT.Trim()));
                }

                //if we are not including cancelled classes (such as for the print schedule) we
                //want to exclude them from the search results...
                if (criteria.IncludeCanceledClasses == false)
                {
                    predicate = predicate.And(s => s.SCHD_CHNG != SCHEDULE_CHANGE_CANCELLED);
                }

                //Handles all inclusion and exclusion of MISC_SRT field values...
                //Get the list of Misc Sort field values that will be used to filter results -
                //so any class offering with these values in the misc sort field will be included.
                string[] deptIncludedMiscSort = GetIncludedMiscSort(deptId);

                //
                //Robert.Pan 4/22/2013 - HACK!!!
                //<HACK BEGIN>.
                //Chad's original predicate construction was wrong.  Need to OR this clause to the original clause - not AND it.
                //I.e. Chad's code generated a predicate statement of (A && B && C && D) which is wrong.  Correct predicate statement is: (A && B && C) || (A && D).
                //
                //Also reordered the predicate construction clauses to improve performance.
                //
                if (deptIncludedMiscSort.Count() > 0)
                {
                    var predicate2 = PredicateBuilder.True<vw_CLASS_D>();

                    //specify yearquarter
                    predicate2 = predicate2.And(s => s.YRQ == criteria.YearQuarterID);
                    //include the misc sort field value(s) if there are any specified.
                    predicate2 = predicate2.And(s => deptIncludedMiscSort.Contains(s.MISC_SRT.Trim()));

                    //If there are no prefixes, then the predicate should only be predicate2.  Else, it is
                    //predicate OR predicate2.  See Vic and/or Beth for an explanation of this logic.  Bob does
                    //not understand the logic.  He only coded the fix as per instructions.
                    if (fPrefixes == false)
                    {
                        predicate = predicate2;
                    }
                    else
                    {
                        predicate = predicate.Or(predicate2);
                    }
                }
                //</HACK END>

                //handle excluded admin units
                string[] excludedAu = GetExcludedAdminUnits();

                predicate = predicate.And(s => !excludedAu.Contains(s.ADMIN_UNIT));

                //check to see what instructor criteria has been passed,
                //and include it if a specific instructor has been specified. If not, don't
                //add it as criteria.
                if (criteria.InstructorName != "Any Instructor")
                {
                    predicate = predicate.And(d => d.INSTR_NAME == criteria.InstructorName);
                }

                //If only online courses are specified, include it as a filter.
                if (criteria.OnlineOnly)
                {
                    predicate = predicate.And(s => s.BRANCH == "OL");
                }

                //If only hybrid courses are specified, include it as a filter.
                if (criteria.HybridOnly)
                {
                    predicate = predicate.And(s => s.BRANCH == "HY");
                }

                //If only Cultural Diversity courses are specified, include it as a filter.
                if (criteria.CulturalDiversityOnly)
                {
                    predicate = predicate.And(s => s.COURSE_TITLE.Contains(":CD"));
                }

                //If only evening courses are specified, include it as a filter.
                if(criteria.EveningOnly)
                {
                    DateTime startTime = DateTime.Parse("1900-01-01 17:00:00.000");
                    predicate = predicate.And(s => s.StartTime > startTime);
                }

                //If only late start courses are specified, include it as a filter.
                if (criteria.LateStart)
                {
                    predicate = predicate.And(d => d.STRT_DATE.Value > 0);
                }

                //If only Continuous Enrollment courses are specified, include it as a filter.
                if (criteria.ContinuousEnrollment)
                {
                    predicate = predicate.And(d => d.CONT_SEQ == "C");
                }

                //Handle filters for Start After and End Before criteria if applicable.
                if (criteria.EndBefore != "Anytime")
                {
                    DateTime endBefore = DateTime.Parse("1900-01-01 " + criteria.EndBefore);

                    predicate = predicate.And(d => d.EndTime < endBefore);
                }

                if (criteria.StartAfter != "Anytime")
                {
                    DateTime startAfter = DateTime.Parse("1900-01-01 " + criteria.StartAfter);
                    predicate = predicate.And(d => d.StartTime > startAfter);
                }

                //Handle the days of the week filters if applicable.
                if (criteria.Friday == false)
                {
                    //
                    string[] fridayCodes = GetDayCodesForFriday();
                    predicate = predicate.And(d => !fridayCodes.Contains(d.DAY_CD));
                }

                if (criteria.Hybrid == false)
                {
                    predicate = predicate.And(d => d.BRANCH != "HY");
                }

                if (criteria.Monday == false)
                {
                    string[] mondayCodes = GetDayCodesForMonday();
                    predicate = predicate.And(d => !mondayCodes.Contains(d.DAY_CD));
                }

                if (criteria.Online == false)
                {
                    predicate = predicate.And(d => d.BRANCH != "OL");
                }

                if (criteria.Saturday == false)
                {
                    string[] saturdayCodes = GetDayCodesForSaturday();
                    predicate = predicate.And(d => !saturdayCodes.Contains(d.DAY_CD));
                }

                if (criteria.Sunday == false)
                {
                    string[] sundayCodes = GetDayCodesForSunday();
                    predicate = predicate.And(d => !sundayCodes.Contains(d.DAY_CD));
                }

                if (criteria.Thursday == false)
                {
                    string[] thursdayCodes = GetDayCodesForThursday();
                    predicate = predicate.And(d => !thursdayCodes.Contains(d.DAY_CD));
                }

                if (criteria.Tuesday == false)
                {
                    string[] tuesdayCodes = GetDayCodesForTuesday();
                    predicate = predicate.And(d => !tuesdayCodes.Contains(d.DAY_CD));
                }

                if (criteria.Wednesday == false)
                {
                    string[] wednesdayCodes = GetDayCodesForWednesday();
                    predicate = predicate.And(d => !wednesdayCodes.Contains(d.DAY_CD));
                }

                //Just getting the string for use in testing. This is commented out otherwise. For debugging
                //purposes.
                string sql = ctx.vw_CLASS_Ds.Where(predicate).OrderBy(d => d.CourseNumber).ToString();

                //Get the collection of classes based on all of the above criteria...
                var classes = ctx.vw_CLASS_Ds.Where(predicate).OrderBy(d=>d.CourseNumber).ToList<vw_CLASS_D>();

                //Convert them into usable Course Objects for use by the user interface.
                result.Courses = GetCourseObjectsFromClasses(classes);
            }

            return result;
        }
        /// <summary>
        /// GetSingleDepartment - This function drives an actual search process, using the values
        /// specified in the SearchModel object for a specific single department. 
        /// </summary>
        /// <param name="criteria">A SearchModel object passed by the controller that contains the 
        /// criteria for which the search is to be performed.</param>
        /// <returns>A single instance of a DepartmentModel object, containing the search results.</returns>
        public DepartmentModel GetSingleDepartment(SearchModel criteria)
        {
            //get department ID
            int deptId = GetDepartmentIDFromUrlName(criteria.DepartmentName);

            return GetNormalDepartment(criteria);
        }
        /// <summary>
        /// SearchCourses - This function drives the actual search process, using the values
        /// specified in the SearchModel object. Note that we do not return "Bus Pass" or "Orca"
        /// results.
        /// </summary>
        /// <param name="criteria">A SearchModel object passed by the controller that contains the 
        /// criteria for which the search is to be performed.</param>
        /// <returns>A List of DepartmentModel objects, containing the search results.</returns>
        public List<DepartmentModel> SearchCourses(SearchModel criteria)
        {
            List<DepartmentModel> results = new List<DepartmentModel>();

            List<DepartmentListModel> departments = GetDepartments(criteria.YearQuarterID,false);

            foreach (var dept in departments)
            {
                if (dept.DepartmentID != BUS_PASS && dept.DepartmentID != ORCA_PASS)
                {
                    criteria.DepartmentName = dept.UrlName;
                    DepartmentModel tempModel = GetSingleDepartment(criteria);
                    if (tempModel.Courses.Count() > 0)
                    {
                        results.Add(tempModel);
                    }
                }
            }

            return results;
        }
        /// <summary>
        /// GetSearchResultsXML - This function performs the search process, using the values
        /// specified in the SearchModel object. Note that we DO return "Bus Pass" or "Orca"
        /// results.
        /// </summary>
        /// <param name="criteria">A SearchModel object passed by the controller that contains the 
        /// criteria for which the search is to be performed.</param>
        /// <returns>A List of DepartmentModel objects, containing the search results.</returns>
        public List<DepartmentModel> GetSearchResultsXML(SearchModel criteria)
        {
            List<DepartmentModel> results = new List<DepartmentModel>();

            //get department id if any
            if (criteria.DepartmentName != ANY_DEPARTMENT_VALUE)
            {
                //get department ID
                int deptId = GetDepartmentIDFromUrlName(criteria.DepartmentName);

                results.Add(GetNormalDepartment(criteria));
            }
            else
            {
                var deptList = GetDepartments(criteria.YearQuarterID, false);

                foreach (var dept in deptList)
                {
                    criteria.DepartmentName = dept.UrlName;
                    DepartmentModel temp = GetSingleDepartment(criteria);

                    if (temp.Courses.Count() > 0)
                    {
                        results.Add(temp);
                    }
                }

            }

            return results;
        }
        /// <summary>
        /// GetNewSearchModel - Returns a SearchModel, containing all of the necessary lists, 
        /// parameters, and values that are used to set the initial default search screen.
        /// </summary>
        /// <param name="yrq">The appropriate YearQuarter which the search model is to use.</param>
        /// <returns>A new SearchModel object.</returns>
        public SearchModel GetNewSearchModel(string yrq)
        {
            SearchModel model = new SearchModel();

            model.DepartmentList = GetDepartments(yrq, true);
            model.DisplayTimes = GetDisplayTimes(true);
            model.EndBefore = ANY_TIME_VALUE;
            model.Friday = true;
            model.Hybrid= true;

            model.HybridOnly = false;
            model.OnlineOnly = false;
            model.EveningOnly = false;
            model.CulturalDiversityOnly = false;
            model.Monday = true;
            model.Online = true;

            model.Saturday = true;
            model.StartAfter = ANY_TIME_VALUE;
            model.Sunday = true;
            model.Thursday = true;
            model.Tuesday = true;
            model.Wednesday = true;
            model.YearQuarterID = yrq;
            model.InstructorList = GetInstructorListDefault(yrq);
            model.InstructorName = ANY_INSTRUCTOR_VALUE;
            model.DepartmentName = ANY_DEPARTMENT_VALUE;
            model.IncludeBusPass = false;
            model.IncludeCanceledClasses = true;
            model.FullDownLoad = false;
            return model;
        }
        public ActionResult Search(SearchModel searchOptions)
        {
            ScheduleManager manager = new ScheduleManager();

            ViewBag.YearQuarterCode = searchOptions.YearQuarterID;
            searchOptions.IncludeCanceledClasses = true;
            var yrqItem  = manager.GetQuarterItemFromYRQ(searchOptions.YearQuarterID);
            ViewBag.YearQuarterID = yrqItem.UrlName;
            var model = manager.GetSearchResults(searchOptions);

            return PartialView("_SearchResults", model);
        }
        public FileStreamResult PrintSchedule(SearchModel searchOptions)
        {
            ScheduleManager manager = new ScheduleManager();

            ViewBag.YearQuarterCode = searchOptions.YearQuarterID;
            searchOptions.IncludeCanceledClasses = false;
            var yrqItem = manager.GetQuarterItemFromYRQ(searchOptions.YearQuarterID);
            ViewBag.YearQuarterID = yrqItem.UrlName;
            var model = manager.GetSearchResults(searchOptions);

            string tempResults = manager.GetXMLResults(model, searchOptions.FullDownLoad);

            byte[] byteArray = Encoding.ASCII.GetBytes(tempResults);
            MemoryStream stream = new MemoryStream(byteArray);

            FileStreamResult result = new FileStreamResult(stream, "text/xml");
            result.FileDownloadName = "classschedule.xml";
            return result;
        }
        public ActionResult GenerateXML(SearchModel searchOptions)
        {
            ScheduleManager manager = new ScheduleManager();

            ViewBag.YearQuarterCode = searchOptions.YearQuarterID;
            var yrqItem = manager.GetQuarterItemFromYRQ(searchOptions.YearQuarterID);
            ViewBag.YearQuarterID = yrqItem.UrlName;
            var model = manager.GetSearchResults(searchOptions);

            return PartialView("_SearchResults", model);
        }