/// <summary>
        /// This static constructor is called only one time, when the application is started. 
        /// It synchronizes the features available for each service with the features available in the database.
        /// </summary>
        static SocialTFSProxy()
        {
            SocialTFSEntities db = new SocialTFSEntities();
            //add the completely new features
            IEnumerable<FeaturesType> features = FeaturesManager.GetFeatures();
            foreach (FeaturesType featureType in features)
            {
                try
                {
                    String strFeatureType = featureType.ToString();
                    Feature fTest = db.Feature.FirstOrDefault<Feature>(f => f.pk_name == strFeatureType);

                    if (fTest == null)
                    {
                        db.Feature.AddObject(new Feature()
                        {
                            pk_name = featureType.ToString(),
                            description = FeaturesManager.GetFeatureDescription(featureType),
                            @public = FeaturesManager.IsPublicFeature(featureType)
                        });
                    }
                }
                catch (Exception)
                {
                }
            }
            db.SaveChanges();
        }
        /// <summary>
        /// Convert a Post (used for the database) in a WPost (used for the web).
        /// </summary>
        /// <param name="db">Database connector data context.</param>
        /// <param name="user">User that requires the conversion.</param>
        /// <param name="post">The Post to convert.</param>
        /// <returns>A WPost.</returns>
        public static WPost PostToWPost(SocialTFSEntities db, User user, Post post)
        {
            WUser author = Converter.UserToWUser(db, user, post.ChosenFeature.Registration.User, false);

            WService service = Converter.ServiceInstanceToWService(db, user, post.ChosenFeature.Registration.ServiceInstance, false);

            WPost result = new WPost()
            {
                Id = post.pk_id,
                User = author,
                Service = service,
                Message = post.message,
                CreateAt = post.createAt
            };

            return result;
        }
        private void UpdateDynamicFriend(User user)
        {
            SocialTFSEntities db = new SocialTFSEntities();

            String str = FeaturesType.IterationNetwork.ToString();
            foreach (ChosenFeature chosenFeature in db.ChosenFeature.Where(cf => cf.fk_user == user.pk_id && cf.fk_feature == str ))
            {
                ChosenFeature temp = db.ChosenFeature.Where(cf => cf.pk_id == chosenFeature.pk_id).Single();
                if (temp.lastDownload > DateTime.UtcNow - _dynamicSpan)
                    continue;
                else
                    temp.lastDownload = DateTime.UtcNow;

                try { db.SaveChanges(); }
                catch { continue; }

                IService service;
                //submit new friendship for the current chosen feature
                if (temp.Registration.ServiceInstance.Service.name.Equals("GitHub"))
                {
                    service = ServiceFactory.getServiceOauth(temp.Registration.ServiceInstance.Service.name, temp.Registration.ServiceInstance.host, temp.Registration.ServiceInstance.consumerKey, temp.Registration.ServiceInstance.consumerSecret, temp.Registration.accessToken, null);
                }
                else
                {

                    service = ServiceFactory.getService(
                        temp.Registration.ServiceInstance.Service.name,
                        temp.Registration.nameOnService,
                        //db.EncDecRc4("key", temp.Registration.accessToken),
                        temp.Registration.accessToken,
                        temp.Registration.accessSecret,
                        temp.Registration.ServiceInstance.host);
                }
                //this line must be before the deleting
                String[] dynamicFriends = (String[])service.Get(FeaturesType.IterationNetwork, null);

                //delete old friendship for the current chosen feature
                var delFriends = db.DynamicFriend.Where(df => df.fk_chosenFeature == temp.pk_id);
                foreach (DynamicFriend s in delFriends)
                {
                    db.DynamicFriend.DeleteObject(s);
                }
                //db.DynamicFriend.DeleteAllOnSubmit(db.DynamicFrien.Where(df => df.chosenFeature == temp.pk_id));
                db.SaveChanges();

                foreach (String dynamicFriend in dynamicFriends)
                {
                    IEnumerable<int> friendsInDb = db.Registration.Where(r => r.nameOnService == dynamicFriend && r.pk_fk_serviceInstance == temp.fk_serviceInstance).Select(r => r.pk_fk_user);
                    foreach (int friendInDb in friendsInDb)
                    {
                        db.DynamicFriend.AddObject(new DynamicFriend()
                        {
                            fk_chosenFeature = temp.pk_id,
                            fk_user = friendInDb
                        });
                    }
                }
                try
                {
                    db.SaveChanges();
                }
                catch { }
            }
        }
        public bool SaveAvatar(string username, string password, Uri avatar)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();
            User user = CheckCredentials(db, username, password);
            if (user == null)
                return false;

            try
            {
                user.avatar = avatar.AbsoluteUri;
                db.SaveChanges();
            }
            catch (Exception)
            {

            }

            return true;
        }
        public bool Authorize(string username, string password, int service, string verifier, string accessToken, string accessSecret)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));
            Contract.Requires(!String.IsNullOrEmpty(accessToken));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return false;

            ServiceInstance si = db.ServiceInstance.Where(s => s.pk_id == service).Single();
            IService iService = ServiceFactory.getService(si.Service.name);

            if (iService.GetPrivateFeatures().Contains(FeaturesType.OAuth1))
            {

                iService = ServiceFactory.getServiceOauth(si.Service.name, si.host, si.consumerKey, si.consumerSecret, accessToken, accessSecret);

                OAuthAccessData oauthData = iService.Get(FeaturesType.OAuth1, OAuth1Phase.Authorize, si.host + si.Service.accessToken, verifier) as OAuthAccessData;

                if (oauthData == null)
                    return false;

                IUser iUser = iService.VerifyCredential();

                return RegisterUserOnAService(db, user, si, iUser, oauthData.AccessToken, oauthData.AccessSecret);

            }
            else if (iService.GetPrivateFeatures().Contains(FeaturesType.OAuth2))
            {

                if (si.Service.name.Equals("GitHub") || si.Service.name.Equals("LinkedIn") || si.Service.name.Equals("StackOverflow"))
                {
                    accessToken = iService.Get(FeaturesType.OAuth2, si.Service.name, si.host, si.consumerKey, si.consumerSecret, accessToken) as string;
                }

                iService = ServiceFactory.getServiceOauth(si.Service.name, si.host, si.consumerKey, si.consumerSecret, accessToken, null);

                IUser iUser = iService.VerifyCredential();
                return RegisterUserOnAService(db, user, si, iUser, accessToken, null);

            }
            return false;
        }
        public bool IsAvailable(String username)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));

            SocialTFSEntities db = new SocialTFSEntities();

            try
            {
                User user = db.User.Where(u => u.username == username && u.active).Single();
                return false;
            }
            catch (InvalidOperationException)
            {
                return true;
            }
        }
        public WHidden GetUserHideSettings(string username, string password, int userId)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();
            User user = CheckCredentials(db, username, password);
            if (user == null)
                return null;

            WHidden result = new WHidden();

            foreach (Hidden item in db.Hidden.Where(h => h.fk_user == user.pk_id && h.fk_friend == userId))
                if (item.timeline == HiddenType.Suggestions.ToString())
                    result.Suggestions = true;
                else if (item.timeline == HiddenType.Dynamic.ToString())
                    result.Dynamic = true;
                else if (item.timeline == HiddenType.Interactive.ToString())
                    result.Interactive = true;

            return result;
        }
        public WUser[] GetSuggestedFriends(string username, string password)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WUser[0];

            List<WUser> suggestedFriends = new List<WUser>();

            foreach (User item in db.User)
            {
                if (item.username != username && item.username != "admin")
                {
                    suggestedFriends.Add(Converter.UserToWUser(db, user, item, false));
                }

            }

            //Incompatibile con ENTITY FRAMEWORK
            // Provides all suggested user not in Hidden or in StaticFriend,
            // ordered by the sum of scores

            //List<User> suggestion =
            //(from s in db.Suggestion
            // join fs in db.FeatureScore
            //     on new { s.chosenFeature.fk_feature, s.ChosenFeature.serviceInstance }
            //     equals new { fs.feature, fs.serviceInstance }
            // where s.ChosenFeature.user == user.pk_id &&
            //     !db.Hidden.Where(h => h.user == s.ChosenFeature.user && h.timeline == HiddenType.Suggestions.ToString()).Select(h => h.friend).Contains(s.user) &&
            //     !db.StaticFriend.Where(sf => sf.user == s.ChosenFeature.user).Select(sf => sf.friend).Contains(s.user)
            // let key = new { s.User }
            // group fs by key into friend
            // orderby friend.Sum(af => af.score) descending
            // select friend.Key.User).ToList();

            new Thread(thread => UpdateSuggestion(user)).Start();

            return suggestedFriends.ToArray();
        }
        public WService[] GetServices(String username, String password)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WService[0];

            List<WService> result = new List<WService>();

            foreach (ServiceInstance item in db.ServiceInstance.Where(si => si.Service.name != "SocialTFS"))
            {
                result.Add(Converter.ServiceInstanceToWService(db, user, item, true));
            }
            return result.ToArray();
        }
        public WEdu[] GetEducations(string username, string password, string ownerName)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WEdu[0];

            User owner;

            try
            {
                owner = db.User.Where(u => u.username == ownerName).Single();
            }
            catch (Exception)
            {
                return new WEdu[0];
            }

            //Inserisce nel db le Edu
            DownloadEducations(owner, db);

            //FIXME prende tutte le tutple, ma deve prendere solo quelle dell'utente
            //attraverso la chiave esterna fk_chosenFeature
            String str = FeaturesType.Educations.ToString();
            ChosenFeature chosenFeature = db.ChosenFeature.FirstOrDefault(cf => cf.fk_user == owner.pk_id &&
                cf.fk_feature == str);

            List<WEdu> ris = new List<WEdu>();
            foreach (var item in db.Educations)
            {
                if (item.fk_chosenFeature == chosenFeature.pk_id)
                {
                    ris.Add(new WEdu()
                    {
                        fieldOfStudy = item.fieldOfStudy,
                        eduId = item.pk_id,
                        schoolName = item.schoolName
                    });
                }
            }

            return ris.ToArray<WEdu>();
        }
        public WUser GetColleagueProfile(String username, String password, int colleagueId)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);

            if (user == null)
                return null;

            User colleague = null;
            try
            {
                colleague = db.User.Where(u => u.pk_id == colleagueId).Single();
            }
            catch
            {
                return null;
            }

            return Converter.UserToWUser(db, user, colleague, true);
        }
        public WFeature[] GetChosenFeatures(string username, string password, int serviceInstanceId)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();
            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WFeature[0];

            List<WFeature> result = new List<WFeature>();

            foreach (FeaturesType item in ServiceFactory.getService(
                db.ServiceInstance.Where(si => si.pk_id == serviceInstanceId).Single().Service.name).GetPublicFeatures())
            {
                WFeature feature = new WFeature()
                {
                    Name = item.ToString(),
                    Description = FeaturesManager.GetFeatureDescription(item),
                    IsChosen = db.ChosenFeature.Where(cf => cf.fk_serviceInstance == serviceInstanceId &&
                        cf.fk_user == user.pk_id).Select(cf => cf.fk_feature).Contains(item.ToString())
                };
                result.Add(feature);
            }

            return result.ToArray();
        }
        public Uri[] GetAvailableAvatars(string username, string password)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();
            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new Uri[0];

            List<Uri> avatars = new List<Uri>();
            String str = FeaturesType.Avatar.ToString();
            foreach (ChosenFeature chosenFeature in db.ChosenFeature.Where(cf => cf.fk_user == user.pk_id && cf.fk_feature == str))
            {
                Registration registration = chosenFeature.Registration;
                IService service = ServiceFactory.getServiceOauth(
                    registration.ServiceInstance.Service.name,
                    registration.ServiceInstance.host,
                    registration.ServiceInstance.consumerKey,
                    registration.ServiceInstance.consumerSecret,
                    registration.accessToken,
                    registration.accessSecret);
                Uri avatar = null;
                try { avatar = (Uri)service.Get(FeaturesType.Avatar); }
                catch (Exception) { }

                if (avatar != null)
                {
                    avatars.Add(avatar);
                }
            }

            return avatars.ToArray();
        }
        public bool Follow(string username, string password, int followId)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return false;

            try
            {
                db.StaticFriend.AddObject(new StaticFriend()
                {
                    fk_user = user.pk_id,
                    fk_friend = followId
                });

                db.SaveChanges();

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        private void UpdateSuggestion(User user)
        {
            SocialTFSEntities db = new SocialTFSEntities();

            String str1 = FeaturesType.Followings.ToString();
            String str2 = FeaturesType.Followers.ToString();
            String str3 = FeaturesType.TFSCollection.ToString();
            String str4 = FeaturesType.TFSTeamProject.ToString();
            IEnumerable<ChosenFeature> chosenFeatures = db.ChosenFeature.Where(
                cf => (cf.fk_feature.Equals(str1) ||
                    cf.fk_feature.Equals(str2) ||
                    cf.fk_feature.Equals(str3) ||
                    cf.fk_feature.Equals(str4)) && cf.fk_user == user.pk_id);

            foreach (ChosenFeature chosenFeature in chosenFeatures)
            {
                ChosenFeature temp = db.ChosenFeature.Where(cf => cf.pk_id == chosenFeature.pk_id).Single();
                if (temp.lastDownload > DateTime.UtcNow - _suggestionSpan)
                    continue;
                else
                    temp.lastDownload = DateTime.UtcNow;

                try { db.SaveChanges(); }
                catch { continue; }

                IService service = null;

                if (chosenFeature.fk_feature.Equals(FeaturesType.Followings.ToString()) ||
                    chosenFeature.fk_feature.Equals(FeaturesType.Followers.ToString()))
                    service = ServiceFactory.getServiceOauth(
                        chosenFeature.Registration.ServiceInstance.Service.name,
                        chosenFeature.Registration.ServiceInstance.host,
                        chosenFeature.Registration.ServiceInstance.consumerKey,
                        chosenFeature.Registration.ServiceInstance.consumerSecret,
                        chosenFeature.Registration.accessToken,
                        chosenFeature.Registration.accessSecret);
                else if (chosenFeature.fk_feature.Equals(FeaturesType.TFSCollection.ToString()) ||
                    chosenFeature.fk_feature.Equals(FeaturesType.TFSTeamProject.ToString()))
                {
                    if (temp.Registration.ServiceInstance.Service.name.Equals("GitHub"))
                    {
                        service = ServiceFactory.getServiceOauth(temp.Registration.ServiceInstance.Service.name, temp.Registration.ServiceInstance.host, temp.Registration.ServiceInstance.consumerKey, temp.Registration.ServiceInstance.consumerSecret, temp.Registration.accessToken, null);
                    }
                    else
                    {
                        service = ServiceFactory.getService(
                            chosenFeature.Registration.ServiceInstance.Service.name,
                            chosenFeature.Registration.nameOnService,
                            //db.EncDecRc4("key", chosenFeature.Registration.accessToken),
                            chosenFeature.Registration.accessToken,
                            chosenFeature.Registration.accessSecret,
                            chosenFeature.Registration.ServiceInstance.host);
                    }
                }

                string[] friends = null;

                if (chosenFeature.fk_feature.Equals(FeaturesType.Followings.ToString()))
                    friends = (string[])service.Get(FeaturesType.Followings, null);
                else if (chosenFeature.fk_feature.Equals(FeaturesType.Followers.ToString()))
                    friends = (string[])service.Get(FeaturesType.Followers, null);
                else if (chosenFeature.fk_feature.Equals(FeaturesType.TFSCollection.ToString()))
                    friends = (string[])service.Get(FeaturesType.TFSCollection, null);
                else if (chosenFeature.fk_feature.Equals(FeaturesType.TFSTeamProject.ToString()))
                    friends = (string[])service.Get(FeaturesType.TFSTeamProject, null);

                if (friends != null)
                {
                    //Delete suggestions for this chosen feature in the database
                    var sug = db.Suggestion.Where(s => s.fk_chosenFeature == chosenFeature.pk_id);
                    foreach (Suggestion s in sug)
                    {
                        db.Suggestion.DeleteObject(s);
                    }

                    //db.Suggestion.DeleteAllOnSubmit(db.Suggestion.Where(s => s.fk_chosenFeature == chosenFeature.pk_id));
                    db.SaveChanges();

                    foreach (string friend in friends)
                    {
                        IEnumerable<User> friendInSocialTfs = db.Registration.Where(r => r.idOnService == friend &&
                            r.pk_fk_serviceInstance == chosenFeature.fk_serviceInstance).Select(r => r.User);

                        if (friendInSocialTfs.Count() == 1)
                        {
                            User suggestedFriend = friendInSocialTfs.First();

                            if (friend != chosenFeature.Registration.idOnService)
                            {
                                db.Suggestion.AddObject(new Suggestion()
                                {
                                    fk_user = suggestedFriend.pk_id,
                                    fk_chosenFeature = chosenFeature.pk_id
                                });
                            }
                        }
                    }
                    try
                    {
                        db.SaveChanges();
                    }
                    catch { }
                }
            }
        }
        private void UpdateInteractiveFriend(User user)
        {
            SocialTFSEntities db = new SocialTFSEntities();
            String str = FeaturesType.InteractiveNetwork.ToString();

            foreach (ChosenFeature chosenFeature in db.ChosenFeature.Where(cf => cf.fk_user == user.pk_id && cf.fk_feature == str))
            {
                ChosenFeature temp = db.ChosenFeature.Where(cf => cf.pk_id == chosenFeature.pk_id).Single();
                if (temp.lastDownload > DateTime.UtcNow - _interactiveSpan)
                    continue;
                else
                    temp.lastDownload = DateTime.UtcNow;

                try { db.SaveChanges(); }
                catch { continue; }

                IService service;
                if (temp.Registration.ServiceInstance.Service.name.Equals("GitHub"))
                {
                    service = ServiceFactory.getServiceOauth(temp.Registration.ServiceInstance.Service.name, temp.Registration.ServiceInstance.host, temp.Registration.ServiceInstance.consumerKey, temp.Registration.ServiceInstance.consumerSecret, temp.Registration.accessToken, null);
                }
                else
                {
                    //submit new friendship for the current chosen feature
                    service = ServiceFactory.getService(
                       temp.Registration.ServiceInstance.Service.name,
                       temp.Registration.nameOnService,
                       //db.EncDecRc4("key", temp.Registration.accessToken),
                       temp.Registration.accessToken,
                       temp.Registration.accessSecret,
                       temp.Registration.ServiceInstance.host);
                }
                //this line must be before the deleting
                SCollection[] collections = (SCollection[])service.Get(FeaturesType.InteractiveNetwork);
                try
                {
                    //delete old friendship for the current chosen feature
                    System.Diagnostics.Debug.WriteLine(" id temp " + temp.pk_id);
                    System.Diagnostics.Debug.WriteLine(" db " + (db.InteractiveFriend == null));
                    System.Diagnostics.Debug.WriteLine(" collections length " + collections.Length);
                    /*
                    foreach (SCollection collection in collections)
                    {
                        System.Diagnostics.Debug.WriteLine(" collection " + collection.Uri);

                        foreach (SFile file in collection.Files)
                        {
                            System.Diagnostics.Debug.WriteLine(" file " + file.Name);

                            foreach (String utente in file.InvolvedUsers)
                            {
                                System.Diagnostics.Debug.WriteLine(" utente " + utente);
                            }
                        }

                    }
                    */
                    /*
                    SocialTFSEntities db2 = new SocialTFSEntities();

                    IQueryable<InteractiveFriend> pr = db2.InteractiveFriends.Where(df => df.chosenFeature == temp.pk_id);

                    try
                    {
                        foreach (InteractiveFriend cf in pr)
                        {
                            System.Diagnostics.Debug.WriteLine(" id selezionato " + cf.pk_id);
                        }
                    }
                    catch
                    {
                        System.Diagnostics.Debug.WriteLine("seconda prova di integrità nulla");

                    }

                    IQueryable<InteractiveFriend> pr3 = db2.InteractiveFriends.Where(u => u.user == 3);
                    IQueryable<ChosenFeature> pr2 = db2.ChosenFeatures.Where(cl => cl.serviceInstance == 2);
                    //prova di integrità CHE FUNZIONA

                    System.Diagnostics.Debug.WriteLine(" righe selezionate chosen feature " + pr2.Count());

                    try
                    {
                        foreach (ChosenFeature cf in pr2)
                        {
                            System.Diagnostics.Debug.WriteLine(" id selezionato " + cf.pk_id);
                        }
                    }
                    catch
                    {
                        System.Diagnostics.Debug.WriteLine(" prova di integrità nulla");
                    }
                    */
                    /*

                    IQueryable<InteractiveFriend> pr3 = db2.InteractiveFriends.Where(u => u.user == 3);

                    //prova di integrità CHE FUNZIONA

                    System.Diagnostics.Debug.WriteLine(" righe selezionate chosen feature " + pr2.Count());

                    try
                    {
                        foreach (ChosenFeature cf in pr2)
                        {
                            System.Diagnostics.Debug.WriteLine(" id selezionato " + cf.pk_id);
                        }
                    }
                    catch
                    {
                        System.Diagnostics.Debug.WriteLine(" prova di integrità nulla");
                    }

                    //prova di integrità 2

                    try
                    {
                        foreach (InteractiveFriend  cf in pr3)
                        {
                            System.Diagnostics.Debug.WriteLine(" id selezionato " + cf.pk_id);
                        }
                    }
                    catch
                    {
                        System.Diagnostics.Debug.WriteLine("seconda prova di integrità nulla");

                    }

                    System.Diagnostics.Debug.WriteLine(" righe selezionate " + pr.Count());

                    try
                    {
                        //1° tentativo
                       foreach(InteractiveFriend fr in pr)
                       {
                            db2.InteractiveFriends.DeleteOnSubmit(fr);
                        }
                    }
                    catch {

                        try
                        {
                            //2° tentativo
                            System.Diagnostics.Debug.WriteLine(" Enum fallito ");
                            List<InteractiveFriend> listfr = pr.ToList<InteractiveFriend>();
                            foreach (InteractiveFriend fr in pr)
                            {
                                db2.InteractiveFriends.DeleteOnSubmit(fr);
                            }
                        }
                        catch
                        {
                            System.Diagnostics.Debug.WriteLine(" List fallito ");

                            try
                            {
                                //3° tentativo
                                var removeItems = (from c in db2.InteractiveFriends where c.chosenFeature == temp.pk_id select c);
                                foreach(var item in removeItems.AsEnumerable())
                                {
                                    db.InteractiveFriend.DeleteOnSubmit(item);
                                }
                            }
                            catch
                            {
                                System.Diagnostics.Debug.WriteLine("Query statica fallita");
                                try
                                {
                                    InteractiveFriend[] fr = pr.ToArray<InteractiveFriend>();
                                    foreach (InteractiveFriend fr1 in pr)
                                    {
                                        db2.InteractiveFriends.DeleteOnSubmit(fr1);
                                    }
                                }
                                catch
                                {
                                    System.Diagnostics.Debug.WriteLine(" Array Fallito");
                                }
                            }

                        }
                    }

                    //ultimo tentativo
                    db2.InteractiveFriends.DeleteAllOnSubmit(pr.AsEnumerable<InteractiveFriend>());
                   //IEnumerable<InteractiveFriend> pr = (from c in db.InteractiveFriend.AsEnumerable()
                    // where c.chosenFeature == temp.pk_id select c).ToList();

                   */

                    //vecchio metodo
                    var inFriends = db.InteractiveFriend.Where(df => df.fk_chosenFeature == temp.pk_id);

                    foreach (InteractiveFriend i in inFriends)
                    {
                        db.InteractiveFriend.DeleteObject(i);
                    }
                    //db.InteractiveFriend.DeleteAllOnSubmit(db.InteractiveFriend.Where(df => df.fk_chosenFeature == temp.pk_id));
                    db.SaveChanges();

                    foreach (SCollection collection in collections)
                    {
                        foreach (SWorkItem workitem in collection.WorkItems)
                        {
                            IEnumerable<int> friendsInDb = db.Registration.Where(r => workitem.InvolvedUsers.Contains(r.nameOnService) || workitem.InvolvedUsers.Contains(r.accessSecret + "\\" + r.nameOnService)).Select(r => r.pk_fk_user);
                            foreach (int friendInDb in friendsInDb)
                                db.InteractiveFriend.AddObject(new InteractiveFriend()
                                {
                                    fk_user = friendInDb,
                                    fk_chosenFeature = temp.pk_id,
                                    collection = collection.Uri,
                                    interactiveObject = workitem.Name,
                                    objectType = "WorkItem"
                                });
                        }
                        foreach (SFile file in collection.Files)
                        {
                            IEnumerable<int> friendsInDb = db.Registration.Where(r => file.InvolvedUsers.Contains(r.nameOnService) || file.InvolvedUsers.Contains(r.accessSecret + "\\" + r.nameOnService)).Select(r => r.pk_fk_user);
                            foreach (int friendInDb in friendsInDb)
                                db.InteractiveFriend.AddObject(new InteractiveFriend()
                                {
                                    fk_user = friendInDb,
                                    fk_chosenFeature = temp.pk_id,
                                    collection = collection.Uri,
                                    interactiveObject = file.Name,
                                    objectType = "File"
                                });
                        }
                    }

                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e.StackTrace);
                }
            }
        }
        public WReputation GetReputations(string username, string password, string ownerName)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WReputation();

            User owner;

            try
            {
                owner = db.User.Where(u => u.username == ownerName).Single();
            }
            catch (Exception)
            {
                return new WReputation();
            }

            //Inserisce nel db le Reputations
            DownloadReputations(owner, db);

            /*
            List<WReputation> ris = new List<WReputation>();
            foreach (var item in db.Reputation)
            {
             * */

            try
            {
                int IDUser = db.User.Where<User>(u => u.username == username).First<User>().pk_id;
                ChosenFeature cf = db.ChosenFeature.Where<ChosenFeature>(c => c.fk_user == IDUser && c.fk_feature == "Reputation").FirstOrDefault<ChosenFeature>();
                Reputation item = db.Reputation.Where<Reputation>(r => r.fk_chosenFeature == cf.pk_id).First<Reputation>();
                return new WReputation()
                {
                    reputationId = item.pk_id,
                    stackAnswer = item.stack_answer,
                    stackQuestion = item.stack_question,
                    stackBronze = item.stack_bronze,
                    stackSilver = item.stack_silver,
                    stackGold = item.stack_gold,
                    stackReputationValue = item.stack_reputationValue,
                    ohlohBigcheese = item.ohloh_bigCheese,
                    ohlohFosser = item.ohloh_fosser,
                    ohlohOrgman = item.ohloh_orgMan,
                    ohlohStacker = item.ohloh_stacker,
                    ohlohKudoRank = item.ohloh_kudorank,
                    ohlohKudoScore = item.ohloh_kudoscore,
                    coderwallEndorsements = item.coderwall_endorsements,
                    linkedinRecommendations = item.linkedin_recommendations,
                    linkedinRecommenders = item.linkedin_recommenders
                };
            }
            catch (Exception)
            {
                return null;
            }

            /*
            Reputation r = db.Reputation.Where<Reputation>(r => r.ChosenFeature

            var rep = from Reputation r in db.Reputation
                      join ChosenFeature cf in db.Reputation on r.fk_chosenFeature equals cf.pk_id

                WReputation rep = new WReputation()
                {
                    reputationId = item.pk_id,
                    stackAnswer = item.stack_answer,
                    stackQuestion = item.stack_question,
                    stackBronze = item.stack_bronze,
                    stackSilver = item.stack_silver,
                    stackGold = item.stack_gold,
                    stackReputationValue = item.stack_reputationValue,
                    ohlohBigcheese = item.ohloh_bigCheese,
                    ohlohFosser = item.ohloh_fosser,
                    ohlohOrgman = item.ohloh_orgMan,
                    ohlohStacker = item.ohloh_stacker,
                    ohlohKudoRank = item.ohloh_kudorank,
                    ohlohKudoScore = item.ohloh_kudoscore,
                    coderwallEndorsements = item.coderwall_endorsements,
                    linkedinRecommendations = item.linkedin_recommendations,
                    linkedinRecommenders = item.linkedin_recommenders
                });
            }

            return ris.FirstOrDefault();
             * */
        }
        public WUser[] GetFollowings(string username, string password)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WUser[0];

            List<WUser> users = new List<WUser>();

            foreach (StaticFriend item in db.StaticFriend.Where(sf => sf.User.pk_id == user.pk_id))
            {
                users.Add(Converter.UserToWUser(db, user, item.Friend, false));
            }

            return users.ToArray();
        }
        public string[] GetSkills(string username, string password, string ownerName)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new string[0];

            User owner;

            try
            {
                owner = db.User.Where(u => u.username == ownerName).Single();
            }
            catch (Exception)
            {
                return new string[0];
            }

            DownloadSkills(owner, db);

            //get the names of the skills from the database
            IEnumerable<string> skills = db.Skills.Where(s => s.ChosenFeature.fk_user == owner.pk_id).Select(s => s.pk_skill_name);

            return skills.Distinct().ToArray<string>();
        }
        public WUser[] GetHiddenUsers(string username, string password)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();
            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WUser[0];

            List<WUser> result = new List<WUser>();

            foreach (User item in db.Hidden.Where(h => h.fk_user == user.pk_id).Select(h => h.Friend).Distinct())
            {
                result.Add(Converter.UserToWUser(db, user, item, false));
            }

            return result.ToArray();
        }
        public WUser GetUser(String username, String password)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);

            if (user == null)
                return null;

            return Converter.UserToWUser(db, user, user, true);
        }
        public WPost[] GetHomeTimeline(string username, string password, long since, long to)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WPost[0];

            List<int> authors = db.StaticFriend.Where(f => f.fk_user == user.pk_id).Select(f => f.fk_friend).ToList();
            authors.Add(user.pk_id);

            return GetTimeline(db, user, authors, since, to);
        }
        public WPost[] GetUserTimeline(string username, string password, string ownerName, long since, long to)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WPost[0];

            List<int> authors = new List<int> { db.User.Where(u => u.username == ownerName).Single().pk_id };

            return GetTimeline(db, user, authors, since, to);
        }
        public WPost[] GetInteractiveTimeline(string username, string password, string collectionUri, string interactiveObject, string objectType, long since, long to)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WPost[0];

            if (String.IsNullOrEmpty(collectionUri))
            {
                collectionUri = FindGithubRepository(user, interactiveObject);
            }

            List<int> hiddenAuthors = db.Hidden.Where(h => h.fk_user == user.pk_id && h.timeline == HiddenType.Interactive.ToString()).Select(h => h.fk_friend).ToList();
            List<int> authors = db.InteractiveFriend.Where(f => f.ChosenFeature.fk_user == user.pk_id && f.collection == collectionUri && f.interactiveObject.EndsWith(interactiveObject) && f.objectType == objectType && !hiddenAuthors.Contains(f.fk_user)).Select(f => f.fk_user).ToList();
            WPost[] timeline = GetTimeline(db, user, authors, since, to);

            new Thread(thread => UpdateInteractiveFriend(user)).Start();

            return timeline;
        }
        public bool Post(String username, String password, String message)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));
            Contract.Requires(!String.IsNullOrEmpty(message));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return false;

            int service = db.ServiceInstance.Where(si => si.Service.name == "SocialTFS").Single().pk_id;

            long chosenFeature = -1;

            try
            {
              String str = FeaturesType.Post.ToString();
              chosenFeature = db.ChosenFeature.Where(cf => cf.fk_user == user.pk_id && cf.fk_serviceInstance == service && cf.fk_feature == str).SingleOrDefault().pk_id;
            }
            catch (InvalidOperationException)
            {
                try
                {
                    db.Registration.Where(r => r.pk_fk_user == user.pk_id && r.pk_fk_serviceInstance == service).Single();
                }
                catch
                {
                    Registration registration = new Registration()
                    {
                        User = user,
                        pk_fk_serviceInstance = db.ServiceInstance.Where(si => si.Service.name == "SocialTFS").Single().pk_id,
                        nameOnService = username,
                        idOnService = username
                    };
                    db.Registration.AddObject(registration);
                    db.SaveChanges();
                }

                ChosenFeature newChoseFeature = new ChosenFeature()
                {
                    Registration = db.Registration.Where(r => r.pk_fk_user == user.pk_id && r.pk_fk_serviceInstance == service).Single(),
                    fk_feature = FeaturesType.Post.ToString(),
                    lastDownload = new DateTime(1900, 1, 1)
                };

                db.ChosenFeature.AddObject(newChoseFeature);
                db.SaveChanges();
                chosenFeature = newChoseFeature.pk_id;
            }

            db.Post.AddObject( new Post
            {
                fk_chosenFeature = chosenFeature,
                message = message,
                createAt = DateTime.UtcNow
            });

            db.SaveChanges();

            return true;
        }
        public WPost[] GetIterationTimeline(string username, string password, long since, long to)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WPost[0];

            String str = HiddenType.Dynamic.ToString();
            List<int> hiddenAuthors = db.Hidden.Where(h => h.fk_user == user.pk_id && h.timeline == str).Select(h => h.fk_friend).ToList();
            List<int> authors = db.DynamicFriend.Where(f => f.ChosenFeature.fk_user == user.pk_id && !hiddenAuthors.Contains(f.fk_user)).Select(f => f.fk_user).ToList();
            WPost[] timeline = GetTimeline(db, user, authors, since, to);

            new Thread(thread => UpdateDynamicFriend(user)).Start();

            return timeline;
        }
        public bool RecordService(string username, string password, int service, string usernameOnService, string passwordOnService, string domain)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));
            Contract.Requires(!String.IsNullOrEmpty(usernameOnService));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return false;

            ServiceInstance serviceInstance = db.ServiceInstance.Where(s => s.pk_id == service).Single();

            IService iService = ServiceFactory.getService(
                serviceInstance.Service.name,
                usernameOnService,
                passwordOnService,
                domain,
                serviceInstance.host);

            IUser iUser = iService.VerifyCredential();

            //return RegisterUserOnAService(db, user, serviceInstance, iUser, db.EncDecRc4("key", passwordOnService), (String)iUser.Get(UserFeaturesType.Domain));
            return RegisterUserOnAService(db, user, serviceInstance, iUser, passwordOnService, (String)iUser.Get(UserFeaturesType.Domain));
        }
        public WOAuthData GetOAuthData(string username, string password, int service)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return null;

            ServiceInstance si = db.ServiceInstance.Where(s => s.pk_id == service).Single();

            IService iService = ServiceFactory.getServiceOauth(si.Service.name, si.host, si.consumerKey, si.consumerSecret, null, null);
            if (iService.GetPrivateFeatures().Contains(FeaturesType.OAuth1))
            {
                OAuthAccessData oauthData = iService.Get(FeaturesType.OAuth1, OAuth1Phase.RequestOAuthData, si.host + si.Service.requestToken, si.host + si.Service.authorize) as OAuthAccessData;
                return new WOAuthData()
                {
                    AuthorizationLink = oauthData.RequestUri,
                    AccessToken = oauthData.AccessToken,
                    AccessSecret = oauthData.AccessSecret
                };
            }
            else if (iService.GetPrivateFeatures().Contains(FeaturesType.OAuth2))
            {
                String authorizationLink = String.Empty;

                if (si.Service.name.Equals("LinkedIn") || si.Service.name.Equals("StackOverflow"))
                {
                    authorizationLink = iService.Get(FeaturesType.OAuth2, si.consumerKey) as String;
                }
                else
                {
                    authorizationLink = iService.Get(FeaturesType.OAuth2) as String;
                }

                return new WOAuthData()
                {
                    AuthorizationLink = authorizationLink
                };
            }
            return null;
        }
        public int SubscribeUser(String email, String password, String username)
        {
            Contract.Requires(!String.IsNullOrEmpty(email));
            Contract.Requires(!String.IsNullOrEmpty(password));
            Contract.Requires(!String.IsNullOrEmpty(username));

            SocialTFSEntities db = new SocialTFSEntities();
            User user;
            try
            {
                user = db.User.Where(u => u.email == email).Single();
            }
            catch (InvalidOperationException)
            {
                return 1;
            }

            if (user.password != (password))
                return 2;

            if (!IsAvailable(username))
                return 3;

            user.username = username;
            user.active = true;

            List<ServiceInstance> tmplst = db.ServiceInstance.ToList<ServiceInstance>();
            ServiceInstance si = db.ServiceInstance.FirstOrDefault( _si => _si.Service.name == "SocialTFS");
            int pk_fk_serviceInstance = si.pk_id;

            Registration registration = new Registration()
            {
                User = user,
                pk_fk_serviceInstance = pk_fk_serviceInstance,
                nameOnService = username,
                idOnService = username
            };

            db.Registration.AddObject(registration);

            ChosenFeature cf = new ChosenFeature()
            {
                Registration = registration,
                fk_feature = FeaturesType.Post.ToString(),
                lastDownload = new DateTime(1900, 1, 1)
            };
            db.ChosenFeature.AddObject(cf);

            db.SaveChanges();

            return 0;
        }
        public WPos[] GetPositions(string username, string password, string ownerName)
        {
            Contract.Requires(!String.IsNullOrEmpty(username));
            Contract.Requires(!String.IsNullOrEmpty(password));

            SocialTFSEntities db = new SocialTFSEntities();

            User user = CheckCredentials(db, username, password);
            if (user == null)
                return new WPos[0];

            User owner;

            try
            {
                owner = db.User.Where(u => u.username == ownerName).Single();
            }
            catch (Exception)
            {
                return new WPos[0];
            }

            DownloadPositions(owner, db);

            String str = FeaturesType.Positions.ToString();
            ChosenFeature chosenFeature = db.ChosenFeature.FirstOrDefault(cf => cf.fk_user == owner.pk_id &&
                cf.fk_feature == str);
            List<WPos> ris = new List<WPos>();
            foreach (var item in db.Positions)
            {
                if (item.fk_chosenFeature == chosenFeature.pk_id)
                {
                    ris.Add(new WPos()
                    {
                        name = item.name,
                        title = item.title,
                        posId = item.pk_id,
                        industry = item.industry
                    });
                }
            }

            return ris.ToArray<WPos>();
        }