/// <summary>
        /// Method for updating secondary motivation Aspect ( != attention/satisfaction/confidence)
        /// </summary>
        ///
        /// <param name="ms"> Motivation state for storing the new values. </param>
        internal void updateSecondaryMotivationAspects(MotivationState ms)
        {
            MotivationModel mm = ms.getMotivationModel();

            foreach (MotivationAspect ma in mm.motivationAspects.motivationAspectList)
            {
                if (!primaryMotivationAspects.Contains(ma.name))
                {
                    if (ms.getMotivation().ContainsKey(ma.name))
                    {
                        try
                        {
                            double sol = FormulaInterpreter.eval(ma.rule);
                            ms.updateMotivationAspect(ma.name, sol);
                        }
                        catch (Exception e)
                        {
                            loggingMAs("Warning: Update for secondary motivation aspects not done.", Severity.Warning);
                            loggingMAs("Exception caught: " + e.Message);
                        }
                    }
                    else
                    {
                        loggingMAs("Warning: Motivation aspect not found!", Severity.Warning);
                    }
                }
            }
        }
 /// <summary>
 /// Method for storing new calculated motivation state
 /// </summary>
 /// <param name="newMs"> state to store</param>
 internal void storeNewMotivationState(MotivationState newMs)
 {
     setMotivationState(newMs);
     updateSecondaryMotivationAspects(newMs);
     newMs.print();
     setMotivationState(newMs);
 }
        /// <summary>
        /// Method downgrading satisfaction, if needed
        /// </summary>
        public void updateSatisfaction()
        {
            MotivationState currentMs = getMotivationState();
            MotivationState newMs     = currentMs.getCopy();

            if (checkSatisfactionDowngrade(newMs))
            {
                storeNewMotivationState(newMs);
            }
        }
        /// <summary>
        /// Generates a copy of the motivation state.
        /// </summary>
        ///
        /// <returns> A copy of the motivation state. </returns>
        internal MotivationState getCopy()
        {
            MotivationState ms = new MotivationState(this.motivationModel);

            foreach (KeyValuePair <String, double> entry in this.motivation)
            {
                ms.updateMotivationAspect(entry.Key, entry.Value);
            }

            return(ms);
        }
        /// <summary>
        /// Method for replacing motivation component variables with the current values.
        /// </summary>
        ///
        /// <param name="expression"> String for which replacement should happen. </param>
        ///
        /// <returns> String without any motivation component variables. </returns>
        private static String replaceVariables(String expression)
        {
            MotivationState ms = MotivationAssessmentAsset.Handler.getMotivationState();
            MotivationModel mm = ms.getMotivationModel();

            foreach (MotivationAspect ma in mm.motivationAspects.motivationAspectList)
            {
                expression = expression.Replace(ma.name, ms.getMotivationAspectValue(ma.name).ToString());
            }
            MotivationAssessmentAsset.Handler.loggingMAs("FormulaInterpreter: expression to evaluate without variables=" + expression);
            return(expression);
        }
        /// <summary>
        /// Updates the motivation state of a player with an motivation evidence.
        /// </summary>
        ///
        /// <param name="me"> Motivation evidence for the update. </param>
        internal void updateMotivationState(MotivationEvidence me)
        {
            loggingMAs("Start updating motivation state.");

            MotivationState currentMs = getMotivationState();
            MotivationState newMs     = currentMs.getCopy();

            MotivationAssessmentAssetSettings maas = (MotivationAssessmentAssetSettings)getMAsA().Settings;

            if (me.EvidenceType == EvidenceType.LevelReached)
            {
                updatePrimaryMotivationAspect(newMs, "satisfaction", true);
                lastTimeUpdated = DateTime.Now;
            }
            else if (me.EvidenceType == EvidenceType.ProblemSolved)
            {
                if (me.FirstTryDuration < maas.FirstTryMinDuration)
                {
                    updatePrimaryMotivationAspect(newMs, "attention", false);
                }
                else
                {
                    if (me.SolvingDuration > maas.SolutionMaxDuration)
                    {
                        updatePrimaryMotivationAspect(newMs, "attention", false);
                    }
                    else
                    {
                        updatePrimaryMotivationAspect(newMs, "attention", true);
                    }

                    if (me.NoOfErrors > maas.MaxNoErrors || me.NoOfHelpRequests > maas.MaxNoHelpRequests)
                    {
                        updatePrimaryMotivationAspect(newMs, "confidence", false);
                    }
                    else
                    {
                        updatePrimaryMotivationAspect(newMs, "confidence", true);
                    }
                }
            }
            else
            {
                loggingMAs("Warning: Evidence Type unknown!", Severity.Warning);
            }

            //downgrade satisfaction, if too much time passed by
            checkSatisfactionDowngrade(newMs);

            //Method for storing changes
            storeNewMotivationState(newMs);
        }
        /// <summary>
        /// Method for updating the motivation state aspect satisfaction due to 'too much time no new level'
        /// </summary>
        /// <param name="newMs"> the new motivation state</param>
        private bool checkSatisfactionDowngrade(MotivationState newMs)
        {
            MotivationAssessmentAssetSettings maas = (MotivationAssessmentAssetSettings)getMAsA().Settings;

            if (lastTimeUpdated.AddSeconds(maas.SatisfactionDowngradeTime) < DateTime.Now)
            {
                updatePrimaryMotivationAspect(newMs, "satisfaction", false);
                lastTimeUpdated = DateTime.Now;
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Returns the Motivation State of the player
        /// </summary>
        ///
        ///
        /// <returns> Motivation state of the specified player. </returns>
        public MotivationState getMotivationState()
        {
            MotivationState ms;

            if (motivationState != null)
            {
                return(motivationState);
            }
            else
            {
                ms = new MotivationState(getMotivationModel());
            }

            return(ms);
        }
        /// <summary>
        /// Method for updating primary motivation Aspect (attention/satisfaction/confidence)
        /// </summary>
        ///
        ///<param name="ms"> Motivation state for storing the new values. </param>
        ///<param name="aspect"> String containing "attention","satisfaction" or "confidence". Describes which component gets updated. </param>
        ///<param name="direction"> Boolean - if true upgrade, else downgrade is done. </param>
        ///<param name="playerId"> Identification of the player. </param>
        internal void updatePrimaryMotivationAspect(MotivationState ms, String aspect, Boolean direction)
        {
            MotivationModel  mm         = ms.getMotivationModel();
            MotivationAspect ma         = mm.motivationAspects.getMotivationAspectByName(aspect);
            String           expression = direction ? ma.up : ma.down;

            try
            {
                double sol = FormulaInterpreter.eval(expression);
                ms.updateMotivationAspect(aspect, sol);
            }
            catch (Exception e)
            {
                loggingMAs("Warning: Update for primary motivation aspects not done.", Severity.Warning);
                loggingMAs("Exception caught: " + e.Message);
            }
        }
 /// <summary>
 /// Method for saving a updated motivation state.
 /// </summary>
 ///
 /// <param name="ms"> MotivationState to be stored. </param>
 public void setMotivationState(MotivationState ms)
 {
     motivationState = ms;
 }
        /// <summary>
        /// Returns the Motivation State of a player when provided with player-Id.
        /// </summary>
        ///
        /// <param name="playerId"> Identifier of the player. </param>
        ///
        /// <returns> Motivation state of the specified player. </returns>
        public Dictionary <string, double> getMotivationState()
        {
            MotivationState ms = Handler.getMotivationState();

            return(ms.getMotivation());;
        }