/// <summary>
 /// Performs validation and business logic checks on the CopyCourseSectionAndContentRequest values
 /// </summary>
 /// <param name="request"><see cref="CopyCourseSectionAndContentRequest">object</see></param>
 /// <exception cref="ArgumentNullException">Thrown when a required value is not set in the <see cref="CopyCourseSectionAndContentRequest">object</see></exception>
 /// <exception cref="ArgumentException">Thrown when there is a conflict between the values in the <see cref="CopyCourseSectionAndContentRequest">object</see></exception>
 /// <exception cref="ArgumentOutOfRangeException">Thrown when a value in the <see cref="CopyCourseSectionAndContentRequest">object</see> is invalid.</exception>
 private static void ValidateCopyCourseSectionAndContentRequest(CopyCourseSectionAndContentRequest request)
 {
     // Perform a Parameter Validation and Business Logic Check on the Request
     if (request.ClientString == null)
         throw new ArgumentNullException("The ClientString value is required.  Please correct and try the reqeust again.");
     else if (request.DestinationClientSortString == null)
         throw new ArgumentNullException("The DestinationClientSortString value is required.  Please correct and try the request again.");
     else if (request.DestinationCourseCallNumbers == null)
         throw new ArgumentNullException("The DestinationCourseCallNumbers value is required.  Please correct and try the request again.");
     else if (request.DestinationTermId == null && request.DestinationTermSourcedId == null)
         throw new ArgumentNullException("Either a DestinationTermId or DestinationTermSourcedId value is required.  Please correct and try the request again.");
     else if (request.SourceCourseCallNumber == null && request.SourceCourseId == null)
         throw new ArgumentNullException("Either a SourceCourseCallNumber or SourceCourseId value is required.  Please correct and try the request again.");
     else if (request.DestinationTermId != null && request.DestinationTermSourcedId != null)
         throw new ArgumentException("The DestinationTermId and DestinationTermSourcedId values are mutually exclusive.  Only set one of the values for a given Destination Term.  Please correct and try the request again.");
     else if (request.SourceClientSortString == null)
         throw new ArgumentNullException("The SourceClientSortString value is required.  Please correct and try the request again.");
     else if (request.SourceCourseCallNumber != null && request.SourceCourseId != null)
         throw new ArgumentException("The SourceCourseCallNumber and SourceCourseId values are mutually exclusive.  Only set one of the values for a given Source Coruse.  Please correct and try the request again.");
     else if (request.DestinationSectionNumber > 255)
         throw new ArgumentOutOfRangeException("The DestinationSectionNumber has a Maximum allowed Value of 255.  Please correct and try the request again.");
     else if (request.DestinationTermSourcedId != null)
         if (!request.DestinationTermSourcedId.Contains(":"))
             throw new ArgumentOutOfRangeException("The DestinationTermSourcedId should have a format of \"{Source}:{Id}\".  Note the colon delimiter that seperates the two concatenated values.  " +
                 "In addition, please use your ClientString as the {Source} portion of this concatenated value.  Please correct and try the request again.");
 }
        /// <summary>
        /// Creates the XML payload for the CopyCourseSectionAndContent Course API Request
        /// </summary>
        /// <param name="request"><see cref="CopyCourseSectionAndContentRequest">object</see></param>
        /// <returns><see cref="API.CopyCourseRequestEx"/>object</returns>
        private API.CopyCourseRequestEx SetCopyCourseSectionAndContentRequest(CopyCourseSectionAndContentRequest request)
        {
            API.CopyCourseRequestEx copyCourse = new API.CopyCourseRequestEx();
            copyCourse.ClientString = request.ClientString;
            copyCourse.CopyContentOptions = CONTENT_COPY_OPTIONS;
            copyCourse.DestinationClientSortString = request.DestinationClientSortString;
            copyCourse.DestinationCourseIdentifiers = new API.CourseIdentifier[1];
            copyCourse.DestinationCourseIdentifiers[0] = new API.CourseIdentifier();

            // If more then 1 Call Number is used set them accordingly
            if (request.DestinationCourseCallNumbers.Length > 1)
            {
                // Initialize the CourseCallNumbers Object
                copyCourse.DestinationCourseIdentifiers[0].CourseCallNumbers = new API.CourseCallNumber[request.DestinationCourseCallNumbers.Length - 1];

                // Loop through the Call Numbers in the Request; the 1st is set in the DestinationCoruseIdentifier
                // the remainder, 2nd through n, are set in the CourseCallNumbers Object
                for (int i = 0; i < request.DestinationCourseCallNumbers.Length; i++)
                {
                    // Set the 1st Call Number accordingly, the rest are set in the CourseCallNumbers Object
                    if (i == 0)
                    {
                        copyCourse.DestinationCourseIdentifiers[0].ID = request.DestinationCourseCallNumbers[i];
                        copyCourse.DestinationCourseIdentifiers[0].MappingType = API.MappedIDType.CallNumber;
                    }
                    else
                    {
                        copyCourse.DestinationCourseIdentifiers[0].CourseCallNumbers[i - 1] = new API.CourseCallNumber();
                        copyCourse.DestinationCourseIdentifiers[0].CourseCallNumbers[i - 1].ClientCallNumber = request.DestinationCourseCallNumbers[i];
                    }
                }
            }
            else
            {
                copyCourse.DestinationCourseIdentifiers[0].ID = request.DestinationCourseCallNumbers[0];
                copyCourse.DestinationCourseIdentifiers[0].MappingType = API.MappedIDType.CallNumber;
            }

            copyCourse.DestinationDisplayCourseCode = request.DestinationDisplayCourseCode;
            copyCourse.DestinationSectionDescription = request.DestinationSectionDescription;
            copyCourse.DestinationSectionNumber = request.DestinationSectionNumber;
            copyCourse.DestinationSectionTitle = request.DestinationSectionTitle;
            copyCourse.DestinationTermID = 0;
            copyCourse.DestinationTermIdentifier = new API.TermIdentifier();

            // Set the Destination Term Identifier accordingly
            if (request.DestinationTermId != null)
            {
                copyCourse.DestinationTermIdentifier.ID = INTERNAL_IDENTIFIER + request.DestinationTermId;
                copyCourse.DestinationTermIdentifier.MappingType = API.MappedTermIDType.TermID;
            }
            else
            {
                copyCourse.DestinationTermIdentifier.ID = request.DestinationTermSourcedId;
                copyCourse.DestinationTermIdentifier.MappingType = API.MappedTermIDType.SourcedID;
            }

            copyCourse.SourceClientSortString = request.SourceClientSortString;
            copyCourse.SourceCourseIdentifier = new API.CourseIdentifier();

            // Set the Source Coruse Identifier accordingly
            if (request.SourceCourseId != null)
            {
                copyCourse.SourceCourseIdentifier.ID = request.SourceCourseId;
                copyCourse.SourceCourseIdentifier.MappingType = API.MappedIDType.CourseID;
            }
            else
            {
                copyCourse.SourceCourseIdentifier.ID = request.SourceCourseCallNumber;
                copyCourse.SourceCourseIdentifier.MappingType = API.MappedIDType.CallNumber;
            }

            return copyCourse;
        }
        /// <summary>
        /// Generates a CopyCourseSectionAndContent Course API Request
        /// </summary>
        /// <param name="request"><see cref="CopyCourseSectionAndContentRequest">object</see></param>
        /// <returns><see cref="Response"/>object</returns>
        public Response CopyCourseSectionAndContent(CopyCourseSectionAndContentRequest request)
        {
            API.CopyCourseRequestEx copyCourse = null;
            Response response = null;

            try
            {
                // Validate the Request Object
                ValidateCopyCourseSectionAndContentRequest(request);

                // Intialize and Set the CopyCourseSectionAndContentRequest
                copyCourse = SetCopyCourseSectionAndContentRequest(request);

                // Build the Response Object from the SOAP Response
                response = ReadCopyCourseSectionAndContentResponse(copyCourse);
            }
            catch (Exception ex)
            {
                Logger.Error("Exception from CopyCourseSectionAndContent: ", ex);
                throw;
            }
            finally
            {
                if (this.courseAPI != null)
                    this.courseAPI.Close();
            }

            return response;
        }