public LogDeveloperActivityResponse LogDeveloperActivity(string username, string activityType, DateTime timestamp)
        {
            ActivityContract contract = new ActivityContract()
                                          {
                                              ActivityType = activityType,
                                              Timestamp = timestamp,
                                              Username = username,
                                          };

            return LogDeveloperActivity(contract);
        }
        public void ShouldLogAnActivity()
        {
            ActivityContract request = new ActivityContract()
                                           {
                                               ActivityType = "SuccessfulBuild",
                                               Username = "******",
                                           };

            LogDeveloperActivityResponse response = Service.LogDeveloperActivity(request);

            Activity activity = Repository.Get<Activity>(response.ActivityResults[0].Activity);
            Assert.That(activity, Is.Not.Null);
        }
        public LogDeveloperActivityResponse LogDeveloperActivity(ActivityContract activityContract)
        {
            string username = activityContract.Username;
            string activityType = activityContract.ActivityType;
            DateTime timestamp = activityContract.Timestamp.GetValueOrDefault(DateTime.Now);

            Logger.Info("LogDeveloperActivity called for Username: {0}; ActivityType: {1}; Timestamp: {2}",
                        username, activityType, timestamp);

            Type activityTypeInstance = BuildManager.GetType(activityType, false, true);
            if(activityTypeInstance == null || !typeof(Activity).IsAssignableFrom(activityTypeInstance))
            {
                const string messageFormat = "The provided activityType ({0}) is not a known Activity type.";
                Logger.Error(messageFormat, activityType);
                throw new ApplicationException(string.Format(messageFormat, activityType));
            }

            Developer developer = Repository.Get<Developer>(username);
            if (developer == null)
            {
                developer = new Developer() { Username = username };
                Logger.Debug("Developer username {0} does not currently exist - created new user (ID #{1})", username, developer.ID);
            }

            Activity activity;
            try
            {
                activity = (Activity)activityTypeInstance.GetConstructor(Type.EmptyTypes).Invoke(new object[] {});
                activity.Timestamp = timestamp;
                activity.Developer = developer;
            }
            catch (Exception e)
            {
                const string messageFormat = "Unable to create a new instance of {0}.  Perhaps it doesn't have a default constructor or something?";
                Logger.Error(e, messageFormat, activityType);
                throw new ApplicationException(string.Format(messageFormat, activityType), e);
            }

            try
            {
                ApplyActivityParameters(activity, activityContract.ActivityParameters);
            }
            catch (Exception e)
            {
                const string messageFormat = "Unable to populate instance of {0} from parameters provided. Maybe you have a property name wrong?";
                Logger.Error(e, messageFormat, activityType);
                throw new ApplicationException(string.Format(messageFormat, activityType), e);
            }

            // Add and save the history
            developer.History.Add(activity);
            Repository.Save(developer);

            Logger.Debug("Activity added to {0}'s history.", username);

            // Generate any possible achievements
            IEnumerable<AwardedAchievement> generatedAchievements = GenerateAchievements(activity);

            // Update the developers' statistics based on this new information
            IEnumerable<ActivityResult> activityResults = ProcessAchievements(activity, generatedAchievements);

            return new LogDeveloperActivityResponse(activityResults);
        }