/// <summary>Saves the assignment.</summary>
        /// <remarks>
        /// <para>
        /// When creating a self-assigned assignment, take care to ensure that
        /// <r>AssignmentProperties.AutoReturn</r> is <n>true</n>, otherwise the learner assignments
        /// will never reach
        /// <a href="Microsoft.SharePointLearningKit.LearnerAssignmentState.Enumeration.htm">LearnerAssignmentState.Final</a>
        /// state.
        /// </para>
        /// <para>
        /// <b>Security:</b>&#160; If <pr>slkRole</pr> is
        /// <a href="Microsoft.SharePointLearningKit.SlkRole.Enumeration.htm">SlkRole.Instructor</a>,
        /// this operation fails if the <a href="SlkApi.htm#AccessingSlkStore">current user</a> doesn't
        /// have SLK
        /// <a href="Microsoft.SharePointLearningKit.SlkSPSiteMapping.InstructorPermission.Property.htm">instructor</a>
        /// permissions on <pr>destinationSPWeb</pr>.  Also fails if the current user doesn't have access to the
        /// package/file.
        /// </para>
        /// </remarks>
        /// <param name="web">The <c>SPWeb</c> to create the assignment in.</param>
        /// <param name="slkRole">The <c>SlkRole</c> to use when creating the assignment.  Use
        ///     <c>SlkRole.Learner</c> to create a self-assigned assignment, i.e. an assignment with
        ///     no instructors for which the current learner is the only learner.  Otherwise, use
        ///     <c>SlkRole.Instructor</c>.</param>
        public void Save(SPWeb web, SlkRole slkRole)
        {
            // Verify that the web is in the site
            if (web.Site.ID != Store.SPSiteGuid)
            {
                throw new InvalidOperationException(SlkCulture.GetResources().SPWebDoesNotMatchSlkSPSite);
            }

            if (Id == null)
            {
                SaveNewAssignment(web, slkRole);
            }
            else
            {
                UpdateAssignment(web);
            }

            if (customPropertiesItem != null)
            {
                customPropertiesItem["Title"] = Id.GetKey().ToString();

                foreach (AssignmentProperty property in Properties)
                {
                    customPropertiesItem[property.Name] = property.Value;
                }

                customPropertiesItem.ParentList.ParentWeb.AllowUnsafeUpdates = true;
                customPropertiesItem.Update();
            }
        }
        void VerifyRole(SPWeb web, SlkRole slkRole)
        {
            if ((slkRole != SlkRole.Instructor) && (slkRole != SlkRole.Learner))
            {
                throw new ArgumentOutOfRangeException("slkRole");
            }

            isSelfAssigned = (slkRole == SlkRole.Learner) ? true : false;

            if (isSelfAssigned)
            {
                VerifyIsValidSelfAssigned();
            }
            else
            {
                Store.EnsureInstructor(web);
            }
        }
        void SaveNewAssignment(SPWeb web, SlkRole slkRole)
        {
            // Security checks: If assigning as an instructor, fails if user isn't an instructor on
            // the web (implemented by calling EnsureInstructor).  Fails if the user doesn't have access to the package/file
            if (web == null)
            {
                throw new ArgumentNullException("web");
            }

            if (PackageFormat == null && Location == null)
            {
                throw new InvalidOperationException(SlkCulture.GetResources().InvalidNewAssignment);
            }

            SPSiteGuid = web.Site.ID;
            SPWebGuid  = web.ID;

            VerifyRole(web, slkRole);
            Id = Store.CreateAssignment(this);

            if (isSelfAssigned == false)
            {
                //Update the MRU list
                Store.AddToUserWebList(web);
            }

            if (IsNonELearning)
            {
                DropBoxManager dropBoxMgr = new DropBoxManager(this);
                Microsoft.SharePoint.Utilities.SPUtility.ValidateFormDigest();
                dropBoxMgr.CreateAssignmentFolder();
            }

            if (EmailChanges)
            {
                using (AssignmentEmailer emailer = new AssignmentEmailer(this, Store.Settings.EmailSettings, web))
                {
                    emailer.SendNewEmail(Learners);
                }
            }
        }
        /// <summary>
        /// Returns an <c>AssignmentProperties</c> object populated with default information for
        /// a new assignment based on a given e-learning package or non-e-learning document.
        /// This method doesn't actually create the assignment -- it just returns information that
        /// can be used as defaults for a form that a user would fill in to create a new assignment.
        /// </summary>
        /// <remarks>
        /// <para>
        /// If <paramref name="slkRole"/> is <c>SlkRole.Learner</c>, default properties for a
        /// self-assigned assignment are returned.  In this case, the returned
        /// <c>AssignmentProperties</c> will contain no users in
        /// <c>AssignmentProperties.Instructors</c>, and <c>AssignmentProperties.Learners</c> will
        /// contain only the current user.
        /// </para>
        /// <para>
        /// <b>Security:</b>&#160; If <pr>slkRole</pr> is
        /// <a href="Microsoft.SharePointLearningKit.SlkRole.Enumeration.htm">SlkRole.Instructor</a>,
        /// this operation fails if the <a href="SlkApi.htm#AccessingSlkStore">current user</a> doesn't
        /// have SLK
        /// <a href="Microsoft.SharePointLearningKit.SlkSPSiteMapping.InstructorPermission.Property.htm">instructor</a>
        /// permissions on <pr>destinationSPWeb</pr>.  Also fails if the current user doesn't have access to the
        /// package/file.
        /// </para>
        /// </remarks>
        /// <param name="store"></param>
        /// <param name="destinationSPWeb">The <c>SPWeb</c> that the assignment would be assigned in.</param>
        /// <param name="slkRole">The <c>SlkRole</c> for which information is to be retrieved.
        ///     Use <c>SlkRole.Learner</c> to get default information for a self-assigned assignment,
        ///     i.e. an assignment with no instructors for which the current learner is the only
        ///     learner.  Otherwise, use <c>SlkRole.Instructor</c>.</param>
        /// <returns></returns>
        public static AssignmentProperties CreateNewAssignmentObject(ISlkStore store, SPWeb destinationSPWeb, SlkRole slkRole)
        {
            // Security checks: Fails if the user isn't an instructor on the web if SlkRole=Instructor
            // (verified by EnsureInstructor).  Fails if the user doesn't have access to the
            // package (verified by calling RegisterPackage or by accessing
            // the properties of the non-elearning file).

            // Check parameters
            if (destinationSPWeb == null)
            {
                throw new ArgumentNullException("destinationSPWeb");
            }

            // Verify that the web is in the site
            if (destinationSPWeb.Site.ID != store.SPSiteGuid)
            {
                throw new InvalidOperationException(SlkCulture.GetResources().SPWebDoesNotMatchSlkSPSite);
            }

            UserItemIdentifier   currentUserId = store.CurrentUserId;
            AssignmentProperties assignment    = new AssignmentProperties(null, store);

            assignment.StartDate    = DateTime.Today; // midnight today
            assignment.DueDate      = null;
            assignment.EmailChanges = store.Settings.EmailSettings.DefaultEmailingOn;
            assignment.CreatedById  = currentUserId;
            store.AddCustomProperties(assignment, destinationSPWeb);

            // Role checking and determine if self assigned
            bool isSelfAssigned;

            if (slkRole == SlkRole.Instructor)
            {
                store.EnsureInstructor(destinationSPWeb);
                isSelfAssigned = false;
            }
            else if (slkRole == SlkRole.Learner)
            {
                isSelfAssigned = true;
            }
            else
            {
                throw new ArgumentException(SlkCulture.GetResources().InvalidSlkRole, "slkRole");
            }

            assignment.ShowAnswersToLearners = isSelfAssigned;
            assignment.AutoReturn            = isSelfAssigned;
            if (isSelfAssigned)
            {
                assignment.Learners.Add(new SlkUser(currentUserId, destinationSPWeb.CurrentUser));
            }
            else
            {
                assignment.Instructors.Add(new SlkUser(currentUserId, destinationSPWeb.CurrentUser));
            }

            return(assignment);
        }