/// <summary>
        /// Create user (including extension attributes).  Foreach loop adds extension properties to object before calling CreateUserJSON.
        /// </summary>
        /// <param name="user">User object containing values to be set on new object.</param>
        /// <param name="strErrors">Error return value.</param>
        /// <returns>created user</returns>
        public JObject CreateUser(JObject user, ref string strErrors)
        {
            // setup AadUser with standard attributes, accountEnabled, and password profile
            AadUser aadUser = new AadUser();
            aadUser.userPrincipalName = (string)user["userPrincipalName"];
            aadUser.displayName = (string)user["displayName"];
            aadUser.mailNickname = (string)user["mailNickname"];
            aadUser.jobTitle = (string)user["jobTitle"];
            aadUser.passwordProfile = new passwordProfile();
            aadUser.accountEnabled = true;
            aadUser.passwordProfile.forceChangePasswordNextLogin = true;
            aadUser.passwordProfile.password = "******";

            // convert to JObject
            JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
            jsonSettings.NullValueHandling = NullValueHandling.Ignore;
            jsonSettings.DefaultValueHandling = DefaultValueHandling.Ignore;
            JsonSerializer serializer = JsonSerializer.CreateDefault(jsonSettings);
            JObject newUser = JObject.FromObject(aadUser, serializer);

            // add supported extension values
            foreach (JProperty property in user.Properties())
            {
                // exclude unsupported attributes added by application logic
                if (property.Name == "isManager" || property.Name == "managerUserPrincipalName")
                {
                    // skip
                }
                else if (property.Name.StartsWith(DirectoryExtensions.ExtensionPropertyPrefix))
                {
                    newUser[property.Name] = property.Value;
                }
            }

            // create user
            newUser = this.graphCall.CreateUserJSON(newUser, ref strErrors);

            // set manager
            if (newUser != null)
            {
                newUser["managerUserPrincipalName"] = user["managerUserPrincipalName"];
                newUser = this.SetUser(newUser, ref strErrors);
            }

            return newUser;
        }
        public AadUser CreateUser(AadUser user, ref string strErrors)
        {
            if (!this.ValidateAndRenewTokenIfRequired(ref strErrors))
            {
                return null;
            }

            string authnHeader = "Authorization: " + this.aadAuthentication.AadAuthenticationResult.AccessToken;

            string uri = this.BaseGraphUri + "/users" + "?" + this.ApiVersion;

            //Setup AadUser object
            JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
            jsonSettings.NullValueHandling = NullValueHandling.Ignore;
            string body = "";
            body = JsonConvert.SerializeObject(user, jsonSettings);

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

                request.Headers.Add(authnHeader);
                request.Method = "POST";
                request.ContentType = "application/json";
                byte[] data = encoding.GetBytes(body);
                request.ContentLength = data.Length;
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    if (response.StatusCode != HttpStatusCode.Created)
                    {
                        throw new Exception(String.Format(
                        "Server error (HTTP {0}: {1}).",
                        response.StatusCode,
                        response.StatusDescription));
                    }
                    else
                        using (var stream = response.GetResponseStream())
                        {
                          DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(AadUser));
                          AadUser newUser = ser.ReadObject(stream) as AadUser;
                          return newUser;
                       }
                }
            }

            catch (WebException webException)
            {
                GraphHelperEventSourceLogger.Log(webException, ref strErrors);
                return null;
            }
        }
        public bool licenseUser(AadUser user, string skuToAddOrUpdate, string skuToRemove, string[] disabledPlans, ref string strErrors)
        {
            // if incorrect parameters are passed in, return null
            if (user == null || (skuToAddOrUpdate == skuToRemove))
                return false;

            // create the addLicense object
            addLicense licenseObjectToAdd = new addLicense();

            // assign the subscriptionId to the addLicense object
            licenseObjectToAdd.skuId = skuToAddOrUpdate;

            //get the list of plans to remove and assign to the addLicense Object
            licenseObjectToAdd.disabledPlans = disabledPlans;

            //create a List of addLicense objects, and add the addLicense object
            List<addLicense> addLicensesList = new List<addLicense>();

            // if skuToAddOrUpdate is not empty, then add the license object, else remove the license Object
            if (skuToAddOrUpdate != "")
                addLicensesList.Add(licenseObjectToAdd);
            else
                addLicensesList.Clear();

            // assign addLicense and removeLicense objects to license object
            userLicense license = new userLicense();
            license.addLicenses = addLicensesList;

            // check to see if there's a skue to remove
            if (skuToRemove != "")
            {
                string[] licenseToRemove = new string[1] { skuToRemove };
                license.removeLicenses = licenseToRemove;
            }
            else
                license.removeLicenses = new string[0] { };

            AadUser returnedUser = this.licenseUser(user, license, ref strErrors);

            if (returnedUser != null)
               return true;
            else
               return false;
        }
        public bool modifyUser(string method, AadUser user, ref string strErrors)
        {
            // check if token is expired or about to expire in 2 minutes
            if (this.aadAuthentication.AadAuthenticationResult.IsExpired() ||
                           this.aadAuthentication.AadAuthenticationResult.WillExpireIn(2))
                this.aadAuthentication.AadAuthenticationResult = this.aadAuthentication.GetNewAuthenticationResult(ref strErrors);

            if (this.aadAuthentication.AadAuthenticationResult == null)
                return false;

            string authnHeader = "Authorization: " + this.aadAuthentication.AadAuthenticationResult.AccessToken;
            string uri = "";

             if (method == "POST")
                uri = this.BaseGraphUri + "/users" + "?" + this.ApiVersion;
             else
               uri = this.BaseGraphUri + "/users/" + user.userPrincipalName + "?" + this.ApiVersion;

            //Setup AadUser object
            JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
            jsonSettings.NullValueHandling = NullValueHandling.Ignore;
            string body = "";
            if (uri.Contains("/users"))
                body = JsonConvert.SerializeObject(user, jsonSettings);

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

                request.Headers.Add(authnHeader);
                request.Method = method.ToUpper();

                if (method == "POST" || method == "PATCH" || method == "PUT")
                {
                    byte[] data = encoding.GetBytes(body);
                    request.Method = method;
                    request.ContentType = "application/json";
                    request.ContentLength = data.Length;
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                }

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    if ((method == "GET" && response.StatusCode != HttpStatusCode.OK) ||
                        (method == "POST" && response.StatusCode != HttpStatusCode.Created) ||
                        (method == "PATCH" && response.StatusCode != HttpStatusCode.NoContent) ||
                        (method == "DELETE" && response.StatusCode != HttpStatusCode.NoContent))
                    {
                        throw new Exception(String.Format(
                        "Server error (HTTP {0}: {1}).",
                        response.StatusCode,
                        response.StatusDescription));
                    }
                    else
                        return true;
                }
            }

            catch (WebException webException)
            {
                GraphHelperEventSourceLogger.Log(webException, ref strErrors);
                return false;
            }
        }
        public AadUser licenseUser(AadUser user, userLicense license, ref string strErrors)
        {
            // return null, if the user's location location is not populated, then we can't assign a license
            if (user.usageLocation == null)
                return null;

            // check if token is expired or about to expire in 2 minutes
            if (this.aadAuthentication.AadAuthenticationResult.IsExpired() ||
                           this.aadAuthentication.AadAuthenticationResult.WillExpireIn(2))
                this.aadAuthentication.AadAuthenticationResult = this.aadAuthentication.GetNewAuthenticationResult(ref strErrors);

            if (this.aadAuthentication.AadAuthenticationResult == null)
                return null;

            //Setup AadUser object
            JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
            jsonSettings.NullValueHandling = NullValueHandling.Ignore;
            string body = JsonConvert.SerializeObject(license, jsonSettings);
            //Console.WriteLine(body);

            string method = "POST";

            string authnHeader = "Authorization: " + this.aadAuthentication.AadAuthenticationResult.AccessToken;

            string uri = this.BaseGraphUri + "/users/" + user.userPrincipalName + "/assignLicense" + "?" + StringConstants.ApiVersionPreview;

            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

                request.Headers.Add(authnHeader);
                request.Method = method;

                if (method == "POST" || method == "PATCH" || method == "PUT")
                {
                    byte[] data = encoding.GetBytes(body);
                    request.Method = method;
                    request.ContentType = "application/json";
                    request.ContentLength = data.Length;
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                }

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    if ( (method == "POST" && response.StatusCode != HttpStatusCode.Created) && response.StatusCode != HttpStatusCode.OK )
                    {
                        throw new Exception(String.Format(
                        "Server error (HTTP {0}: {1}).",
                        response.StatusCode,
                        response.StatusDescription));
                    }
                    else if ((method == "PATCH") || (method == "PUT") || (method == "POST") )
                        using (var stream = response.GetResponseStream())
                        {
                            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(AadUser));
                            AadUser newUser = ser.ReadObject(stream) as AadUser;
                            return newUser;
                        }
                    else
                       return null;
                }
            }

            catch (WebException webException)
            {
                GraphHelperEventSourceLogger.Log(webException, ref strErrors);
                return null;
            }
        }