Commits

lfoust committed 823ec5d

Almost done with the .net 3.5 async methods

  • Participants
  • Parent commits 29232b7
  • Branches V2.0

Comments (0)

Files changed (24)

trunk/data/V2.0 Upgrade Checklist.xlsx

Binary file modified.

trunk/source/Stacky.Net35/Options/BadgeByUserOptions.cs

-using System;
-
-namespace Stacky
-{
-    public class BadgeByUserOptions
-    {
-        public int? Page = null;
-        public int? PageSize = null;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-    }
-}

trunk/source/Stacky.Net35/Options/CommentOptions.cs

-using System;
-
-namespace Stacky
-{
-    public class CommentOptions
-    {
-        public CommentSort SortBy = CommentSort.Creation;
-        public SortDirection SortDirection = SortDirection.Descending;
-        public int? ToUserId = null;
-        public int? Page = null;
-        public int? PageSize = null;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-        public int? Min = null;
-        public int? Max = null;
-    }
-}

trunk/source/Stacky.Net35/Options/CommentsByPostOptions.cs

-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Stacky
-{
-    public class CommentsByPostOptions
-    {
-        public CommentSort SortBy = CommentSort.Creation;
-        public SortDirection SortDirection = SortDirection.Descending;
-        public int? Page = null;
-        public int? PageSize = null;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-        public int? Min = null;
-        public int? Max = null;
-    }
-}

trunk/source/Stacky.Net35/Options/FavoriteQuestionOptions.cs

-namespace Stacky
-{
-    public class FavoriteQuestionOptions : QuestionsOptionBase<FavoriteQuestionsSort>
-    {
-        public FavoriteQuestionOptions()
-            : base(FavoriteQuestionsSort.Activity)
-        {
-        }
-    }
-}

trunk/source/Stacky.Net35/Options/QuestionByUserOptions.cs

-namespace Stacky
-{
-    public class QuestionByUserOptions : QuestionsOptionBase<QuestionsByUserSort>
-    {
-        public QuestionByUserOptions()
-            : base(QuestionsByUserSort.Creation)
-        {
-        }
-    }
-}

trunk/source/Stacky.Net35/Options/QuestionTimelineOptions.cs

-using System;
-
-namespace Stacky
-{
-    public class QuestionTimelineOptions
-    {
-        public int? Page = null;
-        public int? PageSize = null;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-    }
-}

trunk/source/Stacky.Net35/Options/QuestionsOptionBase.cs

-using System;
-
-namespace Stacky
-{
-    public abstract class QuestionsOptionBase<T>
-    {
-        public QuestionsOptionBase(T defaultSort)
-        {
-            SortBy = defaultSort;
-        }
-
-        public T SortBy;
-        public SortDirection SortDirection = SortDirection.Descending;
-        public int? Page = null;
-        public int? PageSize = null;
-        public bool IncludeBody = false;
-        public bool IncludeComments = false;
-        public bool IncludeAnswers = false;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-        public string[] Tags = null;
-        public int? Min = null;
-        public int? Max = null;
-    }
-}

trunk/source/Stacky.Net35/Options/QuestionsOptions.cs

-namespace Stacky
-{
-    public class QuestionOptions : QuestionsOptionBase<QuestionSort>
-    {
-        public QuestionOptions()
-            : base(QuestionSort.Activity)
-        {
-        }
-    }
-}

trunk/source/Stacky.Net35/Options/ReputationOptions.cs

-using System;
-
-namespace Stacky
-{
-    public class ReputationOptions
-    {
-        public int? Page = null;
-        public int? PageSize = null;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-    }
-}

trunk/source/Stacky.Net35/Options/UserOptions.cs

-using System;
-
-namespace Stacky
-{
-    public class UserOptions
-    {
-        public UserSort SortBy = UserSort.Reputation;
-        public SortDirection SortDirection = SortDirection.Descending;
-        public int? Page = null;
-        public int? PageSize = null;
-        public string Filter = null;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-        public int? Min = null;
-        public int? Max = null;
-    }
-
-    public class UserMentionsOptions
-    {
-        public UserMentionSort SortBy = UserMentionSort.Creation;
-        public SortDirection SortDirection = SortDirection.Descending;
-        public int? Page = null;
-        public int? PageSize = null;
-        public string Filter = null;
-        public DateTime? FromDate = null;
-        public DateTime? ToDate = null;
-        public int? Min = null;
-        public int? Max = null;
-    }
-}

trunk/source/Stacky.Net35/Stacky.Net35.csproj

     <Compile Include="..\Stacky\Entities\Entity.cs">
       <Link>Entities\Entity.cs</Link>
     </Compile>
+    <Compile Include="..\Stacky\Entities\Error.cs">
+      <Link>Entities\Error.cs</Link>
+    </Compile>
     <Compile Include="..\Stacky\Entities\Filter.cs">
       <Link>Entities\Filter.cs</Link>
     </Compile>
     <Compile Include="..\Stacky\StackyClientAsync\NetworkMethods.cs">
       <Link>StackyClientAsync\NetworkMethods.cs</Link>
     </Compile>
-    <Compile Include="..\Stacky\StackyClientAsync\PostMethods.cs">
-      <Link>StackyClientAsync\PostMethods.cs</Link>
-    </Compile>
     <Compile Include="..\Stacky\StackyClientAsync\PrivilegeMethods.cs">
       <Link>StackyClientAsync\PrivilegeMethods.cs</Link>
     </Compile>
       <Link>UrlClientAsync.cs</Link>
     </Compile>
     <Compile Include="Options\Options.cs" />
-    <Compile Include="Options\BadgeByUserOptions.cs" />
-    <Compile Include="Options\CommentOptions.cs" />
-    <Compile Include="Options\CommentsByPostOptions.cs" />
-    <Compile Include="Options\FavoriteQuestionOptions.cs" />
-    <Compile Include="Options\QuestionByUserOptions.cs" />
     <Compile Include="Options\QuestionSearchOptions.cs" />
-    <Compile Include="Options\QuestionsOptionBase.cs" />
-    <Compile Include="Options\QuestionsOptions.cs" />
-    <Compile Include="Options\QuestionTimelineOptions.cs" />
-    <Compile Include="Options\ReputationOptions.cs" />
     <Compile Include="Options\TagOptions.cs" />
-    <Compile Include="Options\UserOptions.cs" />
     <Compile Include="Options\UserTimelineOptions.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="StackyClientAsync\AnswerMethods.cs" />
     <Compile Include="StackyClientAsync\BadgeMethods.cs" />
     <Compile Include="StackyClientAsync\CommentMethods.cs" />
+    <Compile Include="StackyClientAsync\PostMethods.cs" />
     <Compile Include="StackyClientAsync\QuestionMethods.cs" />
     <Compile Include="StackyClientAsync\RevisionMethods.cs" />
+    <Compile Include="StackyClientAsync\StackyClientWithOptions.cs" />
     <Compile Include="StackyClientAsync\StatsMethods.cs" />
     <Compile Include="StackyClientAsync\TagMethods.cs" />
     <Compile Include="StackyClientAsync\UserMethods.cs" />
     <Compile Include="StackyClient\AnswerMethods.cs" />
     <Compile Include="StackyClient\BadgeMethods.cs" />
     <Compile Include="StackyClient\CommentMethods.cs" />
+    <Compile Include="StackyClient\NetworkMethods.cs" />
     <Compile Include="StackyClient\PostMethods.cs" />
     <Compile Include="StackyClient\QuestionMethods.cs" />
     <Compile Include="StackyClient\RevisionMethods.cs" />

trunk/source/Stacky.Net35/StackyClient/NetworkMethods.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Stacky
+{
+    public partial class StackyClient
+    {
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/invalidate-access-tokens
+        /// </summary>
+        public IPagedList<AccessToken> InvalidateAccessTokens(IEnumerable<string> tokens, Options options)
+        {
+            var response = MakeRequest<AccessToken>("access-tokens", new string[] { tokens.Vectorize(), "invalidate" }, new
+            {
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                filter = options.Filter
+            });
+            return new PagedList<AccessToken>(response);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/invalidate-access-tokens
+        /// </summary>
+        public AccessToken InvalidateAccessToken(string token, Options options)
+        {
+            return InvalidateAccessTokens(new string[] { token }, options).FirstOrDefault();
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/read-access-tokens
+        /// </summary>
+        public IPagedList<AccessToken> ReadAccessTokens(IEnumerable<string> tokens, Options options)
+        {
+            var response = MakeRequest<AccessToken>("access-tokens", new string[] { tokens.Vectorize(), "read" }, new
+            {
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                filter = options.Filter
+            });
+            return new PagedList<AccessToken>(response);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/read-access-tokens
+        /// </summary>
+        public AccessToken ReadAccessToken(string token, Options options)
+        {
+            return ReadAccessTokens(new string[] { token }, options).FirstOrDefault();
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/create-filter
+        /// </summary>
+        public Filter CreateFilter(IEnumerable<string> include, IEnumerable<string> exclude, string baseFilter, bool? isUnsafe)
+        {
+            var response = MakeRequest<Filter>("similar", null, new
+            {
+                include = TryVectorize(include),
+                exclude = TryVectorize(exclude),
+                @base = baseFilter,
+                @unsafe = isUnsafe
+            });
+            return response.Items.FirstOrDefault();
+        }
+
+        private string TryVectorize(IEnumerable<string> items)
+        {
+            if (items == null || items.Count() == 0)
+                return null;
+            return items.Vectorize();
+        }
+
+        /// <summary>
+        /// http://api.stackexchange.com/docs/read-filter
+        /// </summary>
+        public IEnumerable<Filter> GetFilters(IEnumerable<string> filters, string filter)
+        {
+            var response = MakeRequest<Filter>("similar", new string[] { filters.Vectorize() }, new
+            {
+                filter = filter
+            });
+            return response.Items;
+        }
+
+        /// <summary>
+        /// http://api.stackexchange.com/docs/read-filter
+        /// </summary>
+        public Filter GetFilters(string filter)
+        {
+            return GetFilters(new string[] { filter }, null).FirstOrDefault();
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/sites
+        /// </summary>
+        public IPagedList<Site> GetSites()
+        {
+            return GetSites(new Options());
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/sites
+        /// </summary>
+        public IPagedList<Site> GetSites(Options options)
+        {
+            var response = MakeRequest<Site>("sites", null, new
+            {
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                filter = options.Filter
+            });
+            return new PagedList<Site>(response);
+        }
+
+        public IPagedList<NetworkUser> GetAssociatedUsers(IEnumerable<int> ids, Options options)
+        {
+            var response = MakeRequest<NetworkUser>("users", new string[] { ids.Vectorize(), "associated" }, new
+            {
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                filter = options.Filter
+            });
+            return new PagedList<NetworkUser>(response);
+        }
+
+        public IPagedList<NetworkUser> GetAssociatedUsers(int id, string filter)
+        {
+            return GetAssociatedUsers(id.ToArray(), new Options { Filter = filter });
+        }
+    }
+}

trunk/source/Stacky.Net35/StackyClientAsync/AnswerMethods.cs

 using System;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace Stacky
 {
     public partial class StackyClientAsync
 #endif
     {
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/answers
+        /// </summary>
+        public void GetAnswers(Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
+        {
+            Execute<Answer>("answers", null, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/answers-by-ids
+        /// </summary>
+        public void GetAnswers(IEnumerable<int> ids, Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
+        {
+            Execute<Answer>("answers", new string[] { ids.Vectorize() }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/answers-by-ids
+        /// </summary>
+        public void GetAnswer(int id, Action<Answer> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
+        {
+            GetAnswers(id.ToArray(), items => onSuccess(items.FirstOrDefault()), onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/comments-on-answers
+        /// </summary>
+        public void GetAnswerComments(IEnumerable<int> ids, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
+        {
+            Execute<Comment>("answers", new string[] { ids.Vectorize(), "comments" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/comments-on-answers
+        /// </summary>
+        public void GetAnswerComments(int id, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
+        {
+            GetAnswerComments(id.ToArray(), onSuccess, onError, options);
+        }
     }
 }

trunk/source/Stacky.Net35/StackyClientAsync/BadgeMethods.cs

 using System;
+using System.Linq;
 using System.Collections.Generic;
 
 namespace Stacky
     public partial class StackyClientAsync
 #endif
     {
-        public virtual void GetBadges(Action<IEnumerable<Badge>> onSuccess, Action<ApiException> onError)
+        public void GetBadges(Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, Options<BadgeSort, BadgeMinMax> options)
         {
-            GetBadges(onSuccess, onError, "badges", null);
+            Execute<Badge, BadgeMinMax>("badges", null, onSuccess, onError, options);
         }
 
-        private void GetBadges(Action<IEnumerable<Badge>> onSuccess, Action<ApiException> onError, string method, string[] urlArguments)
+        public void GetBadge(int id, Action<Badge> onSuccess, Action<ApiException> onError, string filter)
         {
-            MakeRequest<Badge>(method, urlArguments, new
-            {
-                site = this.SiteUrlName
-            }, (items) => onSuccess(items.Items), onError);
+            GetBadges(id.ToArray(), items => onSuccess(items.FirstOrDefault()), onError, new OptionsWithDates { Filter = filter });
         }
 
-        public virtual void GetUsersByBadge(int userId, Action<IPagedList<User>> onSuccess, Action<ApiException> onError)
+        public void GetBadges(IEnumerable<int> ids, Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
         {
-            GetUsersByBadge(userId, onSuccess, onError, new BadgeByUserOptions());
+            Execute<Badge>("badges", new string[] { ids.Vectorize() }, onSuccess, onError, options);
         }
 
-        public virtual void GetUsersByBadge(int userId, Action<IPagedList<User>> onSuccess, Action<ApiException> onError, BadgeByUserOptions options)
+        public void GetNamedBadges(Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, Options<BadgeSort, BadgeMinMax> options)
         {
-            GetUsersByBadge(userId.ToArray(), onSuccess, onError, options);
+            Execute<Badge, BadgeMinMax>("badges", new string[] { "name" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUsersByBadge(IEnumerable<int> userIds, Action<IPagedList<User>> onSuccess, Action<ApiException> onError = null)
+        public void GetRecentlyAwardedBadges(Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
         {
-            GetUsersByBadge(userIds, onSuccess, onError, new BadgeByUserOptions());
+            Execute<Badge, BadgeMinMax>("badges", new string[] { "recipients" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUsersByBadge(IEnumerable<int> userIds, Action<IPagedList<User>> onSuccess, Action<ApiException> onError, BadgeByUserOptions options)
+        public void GetRecentlyAwardedBadges(int id, Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
         {
-            MakeRequest<User>("badges", new string[] { userIds.Vectorize(), "badges" }, new
-            {
-                site = this.SiteUrlName,
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null,
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-            }, (items) => onSuccess(new PagedList<User>(items)), onError);
+            GetRecentlyAwardedBadges(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetTagBasedBadges(Action<IEnumerable<Badge>> onSuccess, Action<ApiException> onError = null)
+        public void GetRecentlyAwardedBadges(IEnumerable<int> ids, Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
         {
-            GetBadges(onSuccess, onError, "badges", new string[] { "tags" });
+            Execute<Badge, BadgeMinMax>("badges", new string[] { ids.Vectorize(), "recipients" }, onSuccess, onError, options);
+        }
+
+        public void GetTagBasedBadges(Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, Options<BadgeSort, BadgeMinMax> options)
+        {
+            Execute<Badge, BadgeMinMax>("badges", new string[] { "tags" }, onSuccess, onError, options);
         }
     }
 }

trunk/source/Stacky.Net35/StackyClientAsync/CommentMethods.cs

     public partial class StackyClientAsync
 #endif
     {
-        public virtual void GetComments(IEnumerable<int> fromUserIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/comments
+        /// </summary>
+        public void GetComments(Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
         {
-            GetComments(fromUserIds, onSuccess, onError, new CommentOptions());
+            Execute<Comment>("comments", null, onSuccess, onError, options);
         }
 
-        public virtual void GetComments(IEnumerable<int> fromUserIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, CommentOptions options)
+        public void GetComments(int id, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
         {
-            string[] urlParameters = null;
-            if (options.ToUserId.HasValue)
-            {
-                urlParameters = new string[] { fromUserIds.Vectorize(), "comments", options.ToUserId.ToString() };
-            }
-            else
-            {
-                urlParameters = new string[] { fromUserIds.Vectorize(), "comments" };
-            }
-
-            MakeRequest<Comment>("users", urlParameters, new
-            {
-                site = this.SiteUrlName,
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null,
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-                sort = options.SortBy.ToString().ToLower(),
-                order = GetSortDirection(options.SortDirection),
-                min = options.Min ?? null,
-                max = options.Max ?? null
-            }, (items) => onSuccess(new PagedList<Comment>(items)), onError);
+            GetComments(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetComments(int fromUserId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError = null)
+        public void GetComments(IEnumerable<int> ids, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
         {
-            GetComments(fromUserId, onSuccess, onError, new CommentOptions());
-        }
-
-        public virtual void GetComments(int fromUserId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, CommentOptions options)
-        {
-            GetComments(fromUserId.ToArray(), onSuccess, onError, options);
-        }
-
-        public virtual void GetCommentsByPost(int postId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError = null)
-        {
-            GetCommentsByPost(postId, onSuccess, onError, new CommentsByPostOptions());
-        }
-
-        public virtual void GetCommentsByPost(int postId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, CommentsByPostOptions options)
-        {
-            GetCommentsByPost(postId.ToArray(), onSuccess, onError, options);
-        }
-
-        public virtual void GetCommentsByPost(IEnumerable<int> postIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError = null)
-        {
-            GetCommentsByPost(postIds, onSuccess, onError, new CommentsByPostOptions());
-        }
-
-        public virtual void GetCommentsByPost(IEnumerable<int> postIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, CommentsByPostOptions options)
-        {
-            MakeRequest<Comment>("posts", new string[] { postIds.Vectorize(), "comments" }, new
-            {
-                site = this.SiteUrlName,
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null,
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-                sort = options.SortBy.ToString().ToLower(),
-                order = GetSortDirection(options.SortDirection),
-            }, (items) => onSuccess(new PagedList<Comment>(items)), onError);
-        }
-
-        public virtual void GetAnswerComments(int answerId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError = null)
-        {
-            GetAnswerComments(answerId, onSuccess, onError, new CommentsByPostOptions());
-        }
-
-        public virtual void GetAnswerComments(int answerId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, CommentsByPostOptions options)
-        {
-            GetAnswerComments(answerId.ToArray(), onSuccess, onError, options);
-        }
-
-        public virtual void GetAnswerComments(IEnumerable<int> answerIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError = null)
-        {
-            GetAnswerComments(answerIds, onSuccess, onError, new CommentsByPostOptions());
-        }
-
-        public virtual void GetAnswerComments(IEnumerable<int> answerIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, CommentsByPostOptions options)
-        {
-            MakeRequest<Comment>("answers", new string[] { answerIds.Vectorize(), "comments" }, new
-            {
-                site = this.SiteUrlName,
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null,
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-                sort = options.SortBy.ToString().ToLower(),
-                order = GetSortDirection(options.SortDirection),
-                min = options.Min ?? null,
-                max = options.Max ?? null
-            }, response => onSuccess(new PagedList<Comment>(response)), onError);
+            Execute<Comment>("comments", new string[] { ids.Vectorize() }, onSuccess, onError, options);
         }
     }
 }

trunk/source/Stacky.Net35/StackyClientAsync/PostMethods.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Stacky
+{
+#if SILVERLIGHT
+    public partial class StackyClient
+#else
+    public partial class StackyClientAsync
+#endif
+    {
+        public void GetPosts(Action<IPagedList<Post>> onSuccess, Action<ApiException> onError, Options<PostSort> options)
+        {
+            Execute<Post>("posts", null, onSuccess, onError, options);
+        }
+
+        public void GetPosts(IEnumerable<int> ids, Action<IPagedList<Post>> onSuccess, Action<ApiException> onError, Options<PostSort> options)
+        {
+            Execute<Post>("posts", new string[] { ids.Vectorize() }, onSuccess, onError, options);
+        }
+
+        public void GetPosts(int id, Action<Post> onSuccess, Action<ApiException> onError, Options<PostSort> options)
+        {
+            GetPosts(id.ToArray(), items => onSuccess(items.FirstOrDefault()), onError, options);
+        }
+
+        public void GetPostComments(IEnumerable<int> ids, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
+        {
+            Execute<Comment>("posts", new string[] { ids.Vectorize(), "comments" }, onSuccess, onError, options);
+        }
+
+        public void GetPostRevisions(int id, Action<IPagedList<Revision>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
+        {
+            GetPostRevisions(id.ToArray(), onSuccess, onError, options);
+        }
+
+        public void GetPostRevisions(IEnumerable<int> ids, Action<IPagedList<Revision>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
+        {
+            Execute<Revision>("posts", new string[] { ids.Vectorize(), "revisions" }, onSuccess, onError, options);
+        }
+
+        public void GetPostSuggestedEdits(int id, Action<IPagedList<SuggestedEdit>> onSuccess, Action<ApiException> onError, Options<SuggestedEditSort> options)
+        {
+            GetPostSuggestedEdits(id.ToArray(), onSuccess, onError, options);
+        }
+
+        public void GetPostSuggestedEdits(IEnumerable<int> ids, Action<IPagedList<SuggestedEdit>> onSuccess, Action<ApiException> onError, Options<SuggestedEditSort> options)
+        {
+            Execute<SuggestedEdit>("posts", new string[] { ids.Vectorize(), "suggested-edits" }, onSuccess, onError, options);
+        }
+    }
+}

trunk/source/Stacky.Net35/StackyClientAsync/QuestionMethods.cs

     public partial class StackyClientAsync
 #endif
     {
-        private void GetQuestions(Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, string method, string[] urlArgs, string sort, string sortDirection, int? page, int? pageSize, bool includeBody, bool includeComments, bool includeAnswers, DateTime? fromDate, DateTime? toDate, int? min, int? max, params string[] tags)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/questions
+        /// </summary>
+        public void GetQuestions(Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            MakeRequest<Question>(method, urlArgs, new
-            {
-                site = this.SiteUrlName,
-                page = page ?? null,
-                pagesize = pageSize ?? null,
-                body = includeBody ? (bool?)true : null,
-                comments = includeComments ? (bool?)true : null,
-                answers = includeAnswers ? (bool?)true : null,
-                fromdate = GetDateValue(fromDate),
-                todate = GetDateValue(toDate),
-                tagged = tags == null ? (string)null : String.Join(" ", tags),
-                sort = sort,
-                order = sortDirection,
-                min = min ?? null,
-                max = max ?? null
-            }, (items) => onSuccess(new PagedList<Question>(items)), onError);
+            Execute<Question>("questions", null, onSuccess, onError, options);
         }
 
-        public virtual void GetQuestions(Action<IPagedList<Question>> onSuccess, Action<ApiException> onError = null)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/questions-by-ids
+        /// </summary>
+        public void GetQuestion(int id, Action<Question> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            GetQuestions(onSuccess, onError, new QuestionOptions());
+            GetQuestions(id.ToArray(), items => onSuccess(items.FirstOrDefault()), onError, options);
         }
 
-        public virtual void GetQuestions(Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, QuestionOptions options)
+        /// <summary>
+        /// https://api.stackexchange.com/docs/questions-by-ids
+        /// </summary>
+        public void GetQuestions(IEnumerable<int> ids, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            var sortArgs = options.SortBy.GetAttribute<SortArgsAttribute>();
-            GetQuestions(onSuccess, onError, "questions", sortArgs.UrlArgs, sortArgs.Sort, GetSortDirection(options.SortDirection), options.Page, options.PageSize, options.IncludeBody, options.IncludeComments, options.IncludeAnswers, options.FromDate, options.ToDate, options.Min, options.Max, options.Tags);
+            Execute<Question>("questions", new string[] { ids.Vectorize() }, onSuccess, onError, options);
         }
 
-        public virtual void GetQuestionsByUser(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError = null)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/answers-on-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetQuestionAnswers(int id, Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
         {
-            GetQuestionsByUser(userId, onSuccess, onError, new QuestionByUserOptions());
+            GetQuestionAnswers(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetQuestionsByUser(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, QuestionByUserOptions options)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/answers-on-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetQuestionAnswers(IEnumerable<int> ids, Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
         {
-            GetQuestions(onSuccess, onError, "users", new string[] { userId.ToString(), "questions" }, options.SortBy.ToString().ToLower(), GetSortDirection(options.SortDirection), options.Page, options.PageSize, options.IncludeBody, options.IncludeComments, options.IncludeAnswers, options.FromDate, options.ToDate, options.Min, options.Max, options.Tags);
+            Execute<Answer>("questions", new string[] { ids.Vectorize(), "answers" }, onSuccess, onError, options);
         }
 
-        public virtual void GetFavoriteQuestions(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError = null)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/comments-on-questions
+        /// </summary>
+        public void GetQuestionComments(int id, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
         {
-            GetFavoriteQuestions(userId, onSuccess, onError, new FavoriteQuestionOptions());
+            GetQuestionComments(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetFavoriteQuestions(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, FavoriteQuestionOptions options)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/comments-on-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetQuestionComments(IEnumerable<int> ids, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
         {
-            GetQuestions(onSuccess, onError, "users", new string[] { userId.ToString(), "favorites" }, options.SortBy.ToString().ToLower(), GetSortDirection(options.SortDirection), options.Page, options.PageSize, options.IncludeBody, options.IncludeComments, options.IncludeAnswers, options.FromDate, options.ToDate, options.Min, options.Max, options.Tags);
+            Execute<Comment>("questions", new string[] { ids.Vectorize(), "comments" }, onSuccess, onError, options);
         }
 
-        public virtual void GetQuestions(IEnumerable<int> questionIds, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError = null)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/linked-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetLinkedQuestions(int id, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            GetQuestions(questionIds, onSuccess, onError, new QuestionOptions());
+            GetLinkedQuestions(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetQuestions(IEnumerable<int> questionIds, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, QuestionOptions options)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/linked-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetLinkedQuestions(IEnumerable<int> ids, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            var sortArgs = options.SortBy.GetAttribute<SortArgsAttribute>();
-            string[] urlArgs = sortArgs.UrlArgs.Concat(new string[] { questionIds.Vectorize() }).ToArray();
-            GetQuestions(onSuccess, onError, "questions", urlArgs, sortArgs.Sort, GetSortDirection(options.SortDirection), options.Page, options.PageSize, options.IncludeBody, options.IncludeComments, options.IncludeAnswers, options.FromDate, options.ToDate, options.Min, options.Max, options.Tags);
+            Execute<Question>("questions", new string[] { ids.Vectorize(), "linked" }, onSuccess, onError, options);
         }
 
-        public virtual void GetQuestion(int questionId, Action<Question> onSuccess, Action<ApiException> onError, bool? includeBody, bool? includeComments, bool? includeAnswers)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/linked-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetRelatedQuestions(int id, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            GetQuestions(questionId.ToArray(), returnedQuestions => onSuccess(returnedQuestions.FirstOrDefault()), onError, new QuestionOptions
-            {
-                IncludeBody = includeBody ?? false,
-                IncludeComments = includeComments ?? false,
-                IncludeAnswers = includeAnswers ?? false
-            });
+            GetRelatedQuestions(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetQuestionTimeline(IEnumerable<int> questionIds, Action<IPagedList<PostEvent>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/linked-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetRelatedQuestions(IEnumerable<int> ids, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            GetQuestionTimeline(questionIds, onSuccess, onError, new QuestionTimelineOptions());
+            Execute<Question>("questions", new string[] { ids.Vectorize(), "related" }, onSuccess, onError, options);
         }
 
-        public virtual void GetQuestionTimeline(IEnumerable<int> questionIds, Action<IPagedList<PostEvent>> onSuccess, Action<ApiException> onError, QuestionTimelineOptions options)
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/questions-timeline
+        /// </summary>
+        public void GetQuestionTimeline(int id, Action<IPagedList<QuestionTimeline>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
         {
-            MakeRequest<PostEvent>("questions", new string[] { questionIds.Vectorize(), "timeline" }, new
+            GetQuestionTimeline(id.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/questions-timeline
+        /// </summary>
+        public void GetQuestionTimeline(IEnumerable<int> ids, Action<IPagedList<QuestionTimeline>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
+        {
+            Execute<QuestionTimeline>("questions", new string[] { ids.Vectorize(), "timeline" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See https://api.stackexchange.com/docs/unanswered-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUnansweredQuestions(Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, TaggedOptions<QuestionSort> options)
+        {
+            MakeRequest<Question>("questions", new string[] { "unanswered" }, new
             {
                 site = this.SiteUrlName,
                 page = options.Page ?? null,
                 pagesize = options.PageSize ?? null,
                 fromdate = GetDateValue(options.FromDate),
                 todate = GetDateValue(options.ToDate),
-            }, (items) => onSuccess(new PagedList<PostEvent>(items)), onError);
+                sort = GetEnumValue(options.SortBy),
+                order = GetSortDirection(options.SortDirection),
+                min = GetDateValue(options.Min),
+                max = GetDateValue(options.Max),
+                tagged = options.GetListValue(options.Tagged),
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<Question>(response)), onError);
         }
 
-        public virtual void GetQuestionTimeline(int questionId, Action<IPagedList<PostEvent>> onSuccess, Action<ApiException> onError)
+        // <summary>
+        /// See https://api.stackexchange.com/docs/unanswered-questions
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetQuestionsWithNoAnswers(Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, TaggedOptions<QuestionSort> options)
         {
-            GetQuestionTimeline(questionId, onSuccess, onError, new QuestionTimelineOptions());
+            MakeRequest<Question>("questions", new string[] { "no-answers" }, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                fromdate = GetDateValue(options.FromDate),
+                todate = GetDateValue(options.ToDate),
+                sort = GetEnumValue(options.SortBy),
+                order = GetSortDirection(options.SortDirection),
+                min = GetDateValue(options.Min),
+                max = GetDateValue(options.Max),
+                tagged = options.GetListValue(options.Tagged),
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<Question>(response)), onError);
         }
 
-        public virtual void GetQuestionTimeline(int questionId, Action<IPagedList<PostEvent>> onSuccess, Action<ApiException> onError, QuestionTimelineOptions options)
+        // <summary>
+        /// See https://api.stackexchange.com/docs/search
+        /// </summary>
+        /// TODO: Fix Sort
+        public void SearchQuestions(Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, QuestionSearchOptions options)
         {
-            GetQuestionTimeline(questionId.ToArray(), onSuccess, onError, options);
-        }
-
-        public virtual void Search(Action<IEnumerable<Question>> onSuccess, Action<ApiException> onError, QuestionSearchOptions options)
-        {
-            string taggedString = null;
-            if (options.Tagged != null)
-                taggedString = String.Join(" ", options.Tagged.ToArray());
-
-            string notTaggedString = null;
-            if (options.NotTagged != null)
-                notTaggedString = String.Join(" ", options.NotTagged.ToArray());
+            if (((options.Tagged != null && options.Tagged.Count() == 0) || options.Tagged == null) &&
+                String.IsNullOrEmpty(options.InTitle))
+            {
+                throw new ArgumentException("At least one of tagged or intitle must be set on this method");
+            }
 
             MakeRequest<Question>("search", null, new
             {
                 site = this.SiteUrlName,
-                intitle = options.InTitle,
-                tagged = taggedString,
-                nottagged = notTaggedString,
-                sort = options.SortBy.ToString(),
-                order = GetSortDirection(options.SortDirection),
                 page = options.Page ?? null,
                 pagesize = options.PageSize ?? null,
-                min = options.Min ?? null,
-                max = options.Max ?? null
-            }, (items) => onSuccess(new PagedList<Question>(items)), onError);
+                fromdate = GetDateValue(options.FromDate),
+                todate = GetDateValue(options.ToDate),
+                sort = GetEnumValue(options.SortBy),
+                order = GetSortDirection(options.SortDirection),
+                min = GetDateValue(options.Min),
+                max = GetDateValue(options.Max),
+                tagged = options.GetListValue(options.Tagged),
+                nottagged = options.GetListValue(options.NotTagged),
+                intitle = options.InTitle,
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<Question>(response)), onError);
+        }
+
+        // <summary>
+        /// See https://api.stackexchange.com/docs/similar
+        /// </summary>
+        /// TODO: Fix Sort
+        public void SimiliarQuestions(string title, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, SimiliarQuestionsOptions options)
+        {
+            MakeRequest<Question>("similar", null, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                fromdate = GetDateValue(options.FromDate),
+                todate = GetDateValue(options.ToDate),
+                sort = GetEnumValue(options.SortBy),
+                order = GetSortDirection(options.SortDirection),
+                min = GetDateValue(options.Min),
+                max = GetDateValue(options.Max),
+                tagged = options.GetListValue(options.Tagged),
+                nottagged = options.GetListValue(options.NotTagged),
+                title = title,
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<Question>(response)), onError);
         }
     }
 }

trunk/source/Stacky.Net35/StackyClientAsync/StackyClientWithOptions.cs

+using System;
+
+namespace Stacky
+{
+#if SILVERLIGHT
+    public partial class StackyClient : StackyClientBase
+#else
+    public partial class StackyClientAsync : StackyClientBase
+#endif
+    {
+        protected void Execute<TEntity, TMinMax>(string methodName, string[] urlArguments,
+            Action<IPagedList<TEntity>> onSuccess,
+            Action<ApiException> onError,
+            Options options)
+            where TEntity : Entity, new()
+            where TMinMax : struct
+        {
+            MakeRequest<TEntity>(methodName, urlArguments, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                filter = options.Filter
+            }, (response) => onSuccess(new PagedList<TEntity>(response)), onError);
+        }
+
+        protected void Execute<TEntity>(string methodName, string[] urlArguments,
+            Action<IPagedList<TEntity>> onSuccess,
+            Action<ApiException> onError,
+            OptionsWithDates options)
+            where TEntity : Entity, new()
+        {
+            MakeRequest<TEntity>(methodName, urlArguments, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                fromdate = GetDateValue(options.FromDate),
+                todate = GetDateValue(options.ToDate),
+                filter = options.Filter
+            }, (response) => onSuccess(new PagedList<TEntity>(response)), onError);
+        }
+
+        protected void Execute<TEntity, TSort, TMinMax>(string methodName, string[] urlArguments,
+            Action<IPagedList<TEntity>> onSuccess,
+            Action<ApiException> onError,
+            Options<TSort, TMinMax> options)
+            where TEntity : Entity, new()
+            where TSort : struct
+            where TMinMax : struct
+        {
+            MakeRequest<TEntity>(methodName, urlArguments, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                fromdate = GetDateValue(options.FromDate),
+                todate = GetDateValue(options.ToDate),
+                sort = GetEnumValue(options.SortBy),
+                order = GetSortDirection(options.SortDirection),
+                min = options.Min,
+                max = options.Max,
+                filter = options.Filter
+            }, (response) => onSuccess(new PagedList<TEntity>(response)), onError);
+        }
+
+        protected void Execute<TEntity, TSort>(string methodName, string[] urlArguments,
+            Action<IPagedList<TEntity>> onSuccess,
+            Action<ApiException> onError,
+            Options<TSort> options)
+            where TEntity : Entity, new()
+            where TSort : struct
+        {
+            MakeRequest<TEntity>(methodName, urlArguments, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                fromdate = GetDateValue(options.FromDate),
+                todate = GetDateValue(options.ToDate),
+                sort = GetEnumValue(options.SortBy),
+                order = GetSortDirection(options.SortDirection),
+                min = GetDateValue(options.Min),
+                max = GetDateValue(options.Max),
+                filter = options.Filter
+            }, (response) => onSuccess(new PagedList<TEntity>(response)), onError);
+        }
+    }
+}

trunk/source/Stacky.Net35/StackyClientAsync/TagMethods.cs

 namespace Stacky
 {
 #if SILVERLIGHT
-    public partial class StackyClient : StackyClientBase
+    public partial class StackyClient
 #else
-    public partial class StackyClientAsync : StackyClientBase
+    public partial class StackyClientAsync
 #endif
     {
-        private void GetTags(Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError, string method, string[] urlParameters, string filter, string sort, string order, int? page, int? pageSize, DateTime? fromDate, DateTime? toDate, int? min, int? max)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/tags
+        /// </summary>
+        public void GetTags(Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError, TagOptions options)
         {
-            MakeRequest<Tag>(method, urlParameters, new
+            MakeRequest<Tag>("tags", null, new
             {
                 site = this.SiteUrlName,
-                page = page ?? null,
-                pagesize = pageSize ?? null,
-                sort = sort,
-                order = order,
-                fromdate = GetDateValue(fromDate),
-                todate = GetDateValue(toDate),
-                min = min ?? null,
-                max = max ?? null
-            }, (items) => onSuccess(new PagedList<Tag>(items)), onError);
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                fromdate = GetDateValue(options.FromDate),
+                todate = GetDateValue(options.ToDate),
+                sort = GetEnumValue(options.SortBy),
+                order = GetSortDirection(options.SortDirection),
+                min = options.Min ?? null,
+                max = options.Max ?? null,
+                inname = options.InName,
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<Tag>(response)), onError);
         }
 
-        public virtual void GetTags(Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/tag-synonyms
+        /// </summary>
+        public void GetTagSynonyms(Action<IPagedList<TagSynonym>> onSuccess, Action<ApiException> onError, Options<TagSynonymSort> options)
         {
-            GetTags(onSuccess, onError, new TagOptions());
+            Execute<TagSynonym>("tags", new string[] { "synonyms" }, onSuccess, onError, options);
         }
 
-        public virtual void GetTags(Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError, TagOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/synonyms-by-tags
+        /// </summary>
+        public void GetTagSynonyms(IEnumerable<string> tags, Action<IPagedList<TagSynonym>> onSuccess, Action<ApiException> onError, Options<TagSynonymSort> options)
         {
-            GetTags(onSuccess, onError, "tags", null, options.Filter, options.SortBy.ToString().ToLower(), GetSortDirection(options.SortDirection), options.Page, options.PageSize, options.FromDate, options.ToDate, options.Min, options.Max);
+            Execute<TagSynonym>("tags", new string[] { tags.Vectorize(), "synonyms" }, onSuccess, onError, options);
         }
 
-        public virtual void GetTagsByUser(int userId, Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/synonyms-by-tags
+        /// </summary>
+        public void GetTagSynonyms(string tag, Action<IPagedList<TagSynonym>> onSuccess, Action<ApiException> onError, Options<TagSynonymSort> options)
         {
-            GetTagsByUser(userId, onSuccess, onError, new TagOptions());
+            GetTagSynonyms(new string[] { tag }, onSuccess, onError, options);
         }
 
-        public virtual void GetTagsByUser(int userId, Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError, TagOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-answerers-on-tags
+        /// </summary>
+        public void GetTagTopAnswerers(string tag, Action<IPagedList<TagScore>> onSuccess, Action<ApiException> onError, TopAnswerOptions options)
         {
-            GetTagsByUser(userId.ToArray(), onSuccess, onError, options);
+            MakeRequest<TagScore>("tags", new string[] { tag, "top-answerers", GetEnumValue(options.Period) }, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<TagScore>(response)), onError);
         }
 
-        public virtual void GetTagsByUser(IEnumerable<int> userIds, Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-askers-on-tags
+        /// </summary>
+        public void GetTagTopAskers(string tag, Action<IPagedList<TagScore>> onSuccess, Action<ApiException> onError, TopAnswerOptions options)
         {
-            GetTagsByUser(userIds, onSuccess, onError, new TagOptions());
+            MakeRequest<TagScore>("tags", new string[] { tag, "top-askers", GetEnumValue(options.Period) }, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.PageSize ?? null,
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<TagScore>(response)), onError);
         }
 
-        public virtual void GetTagsByUser(IEnumerable<int> userIds, Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError, TagOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/wikis-by-tags
+        /// </summary>
+        public void GetTagWikis(IEnumerable<string> tags, Action<IPagedList<TagWiki>> onSuccess, Action<ApiException> onError, Options options)
         {
-            GetTags(onSuccess, onError, "users", new string[] { userIds.Vectorize(), "tags" }, options.Filter, options.SortBy.ToString(), GetSortDirection(options.SortDirection), options.Page, options.PageSize, options.FromDate, options.ToDate, options.Min, options.Max);
+            MakeRequest<TagWiki>("tags", new string[] { tags.Vectorize(), "wikis" }, new
+            {
+                site = this.SiteUrlName,
+                page = options.Page ?? null,
+                pagesize = options.Page ?? null,
+                filter = options.Filter
+            }, response => onSuccess(new PagedList<TagWiki>(response)), onError);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/wikis-by-tags
+        /// </summary>
+        public void GetTagWikis(string tag, Action<IPagedList<TagWiki>> onSuccess, Action<ApiException> onError, Options options)
+        {
+            GetTagWikis(new string[] { tag }, onSuccess, onError, options);
         }
     }
 }

trunk/source/Stacky.Net35/StackyClientAsync/UserMethods.cs

     public partial class StackyClientAsync
 #endif
     {
-        private void GetUsers(Action<IPagedList<User>> onSuccess, Action<ApiException> onError, string[] urlParameters, UserOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/users
+        /// </summary>
+        public void GetUsers(Action<IPagedList<User>> onSuccess, Action<ApiException> onError, Options<UserSort, int> options)
         {
-            MakeRequest<User>("users", urlParameters, new
-            {
-                site = this.SiteUrlName,
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null,
-                filter = options.Filter,
-                sort = options.SortBy.ToString().ToLower(),
-                order = GetSortDirection(options.SortDirection),
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-                min = options.Min ?? null,
-                max = options.Max ?? null
-            }, (items) => onSuccess(new PagedList<User>(items)), onError);
+            Execute<User, Int32>("users", null, onSuccess, onError, options);
         }
 
-        public virtual void GetUsers(Action<IPagedList<User>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/users-by-ids
+        /// </summary>
+        public void GetUsers(IEnumerable<int> ids, Action<IPagedList<User>> onSuccess, Action<ApiException> onError, Options<UserSort, int> options)
         {
-            GetUsers(onSuccess, onError, new UserOptions());
+            Execute<User, Int32>("users", new string[] { ids.Vectorize() }, onSuccess, onError, options);
         }
 
-        public virtual void GetUsers(Action<IPagedList<User>> onSuccess, Action<ApiException> onError, UserOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/users-by-ids
+        /// </summary>
+        public void GetUser(int id, Action<User> onSuccess, Action<ApiException> onError, Options<UserSort, int> options)
         {
-            GetUsers(onSuccess, onError, null, options);
+            GetUsers(id.ToArray(), items => onSuccess(items.FirstOrDefault()), onError, options);
         }
 
-        public virtual void GetUsers(IEnumerable<int> userIds, Action<IPagedList<User>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/answers-on-users
+        /// </summary>
+        public void GetUserAnswers(IEnumerable<int> ids, Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<UserSort, int> options)
         {
-            GetUsers(userIds, onSuccess, onError, new UserOptions());
+            Execute<Answer>("users", new string[] { ids.Vectorize(), "answers" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUsers(IEnumerable<int> userIds, Action<IPagedList<User>> onSuccess, Action<ApiException> onError, UserOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/answers-on-users
+        /// </summary>
+        public void GetUserAnswers(int id, Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<UserSort, int> options)
         {
-            GetUsers(onSuccess, onError, new string[] { userIds.Vectorize() }, options);
+            GetUserAnswers(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetUser(int userId, Action<User> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/badges-on-users
+        /// </summary>
+        public void GetUserBadges(IEnumerable<int> ids, Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, Options<UserSort, BadgeMinMax> options)
         {
-            GetUsers(new int[] { userId }, results => onSuccess(results.FirstOrDefault()), onError, new UserOptions());
+            Execute<Badge, BadgeMinMax>("users", new string[] { ids.Vectorize(), "badges" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUserMentions(int userId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/badges-on-users
+        /// </summary>
+        public void GetUserBadges(int id, Action<IPagedList<Badge>> onSuccess, Action<ApiException> onError, Options<UserSort, BadgeMinMax> options)
         {
-            GetUserMentions(userId, onSuccess, onError, new UserOptions());
+            GetUserBadges(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetUserMentions(int userId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, UserOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/comments-on-users
+        /// </summary>
+        public void GetUserComments(IEnumerable<int> ids, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<UserSort> options)
         {
-            GetUserMentions(new int[] { userId }, onSuccess, onError, options);
+            Execute<Comment>("users", new string[] { ids.Vectorize(), "comments" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUserMentions(IEnumerable<int> userIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/comments-on-users
+        /// </summary>
+        public void GetUserComments(int id, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<UserSort> options)
         {
-            GetUserMentions(userIds, onSuccess, onError, new UserOptions());
+            GetUserComments(id.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetUserMentions(IEnumerable<int> userIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, UserOptions options)
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/comments-by-users-to-user
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserCommentsTo(IEnumerable<int> fromIds, IEnumerable<int> toIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<UserSort> options)
         {
-            MakeRequest<Comment>("users", new string[] { userIds.Vectorize(), "mentioned" }, new
-            {
-                site = this.SiteUrlName,
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null,
-                filter = options.Filter,
-                sort = options.SortBy.ToString().ToLower(),
-                order = GetSortDirection(options.SortDirection),
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-                min = options.Min ?? null,
-                max = options.Max ?? null
-            }, (items) => onSuccess(new PagedList<Comment>(items)), onError);
+            Execute<Comment>("users", new string[] { fromIds.Vectorize(), "comments", toIds.Vectorize() }, onSuccess, onError, options);
         }
 
-        public virtual void GetUserTimeline(int userId, Action<IPagedList<UserEvent>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/favorites-on-users
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserFavoriteQuestions(IEnumerable<int> userIds, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            GetUserTimeline(userId, onSuccess, onError, new UserTimelineOptions());
+            Execute<Question>("users", new string[] { userIds.Vectorize(), "favorites" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUserTimeline(int userId, Action<IPagedList<UserEvent>> onSuccess, Action<ApiException> onError, UserTimelineOptions options)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/favorites-on-users
+        /// </summary>
+        public void GetUserFavoriteQuestions(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            GetUserTimeline(new int[] { userId }, onSuccess, onError, options);
+            GetUserFavoriteQuestions(userId.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetUserTimeline(IEnumerable<int> userIds, Action<IPagedList<UserEvent>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/mentions-on-users
+        /// </summary>
+        public void GetUserMentions(IEnumerable<int> userIds, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
         {
-            GetUserTimeline(userIds, onSuccess, onError, new UserTimelineOptions());
+            Execute<Comment>("users", new string[] { userIds.Vectorize(), "mentioned" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUserTimeline(IEnumerable<int> userIds, Action<IPagedList<UserEvent>> onSuccess, Action<ApiException> onError, UserTimelineOptions options)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/mentions-on-users
+        /// </summary>
+        public void GetUserMentions(int userId, Action<IPagedList<Comment>> onSuccess, Action<ApiException> onError, Options<CommentSort> options)
         {
-            MakeRequest<UserEvent>("users", new string[] { userIds.Vectorize(), "timeline" }, new
-            {
-                site = this.SiteUrlName,
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null
-            }, (items) => onSuccess(new PagedList<UserEvent>(items)), onError);
+            GetUserMentions(userId.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetUserReputation(int userId, Action<IPagedList<Reputation>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/privileges-on-users
+        /// </summary>
+        public void GetUserPrivileges(IEnumerable<int> userIds, Action<IPagedList<Privilege>> onSuccess, Action<ApiException> onError, Options options)
         {
-            GetUserReputation(userId, onSuccess, onError, new ReputationOptions());
+            Execute<Privilege>("users", new string[] { userIds.Vectorize(), "privileges" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUserReputation(int userId, Action<IPagedList<Reputation>> onSuccess, Action<ApiException> onError, ReputationOptions options)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/privileges-on-users
+        /// </summary>
+        public void GetUserPrivileges(int userId, Action<IPagedList<Privilege>> onSuccess, Action<ApiException> onError, Options options)
         {
-            GetUserReputation(new int[] { userId }, onSuccess, onError, options);
+            GetUserPrivileges(userId.ToArray(), onSuccess, onError, options);
         }
 
-        public virtual void GetUserReputation(IEnumerable<int> userIds, Action<IPagedList<Reputation>> onSuccess, Action<ApiException> onError)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/questions-on-users
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserQuestions(IEnumerable<int> userIds, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            GetUserReputation(userIds, onSuccess, onError, new ReputationOptions());
+            Execute<Question>("users", new string[] { userIds.Vectorize(), "questions" }, onSuccess, onError, options);
         }
 
-        public virtual void GetUserReputation(IEnumerable<int> userIds, Action<IPagedList<Reputation>> onSuccess, Action<ApiException> onError, ReputationOptions options)
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/questions-on-users
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserQuestions(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
         {
-            MakeRequest<Reputation>("users", new string[] { userIds.Vectorize(), "reputation" }, new
-            {
-                site = this.SiteUrlName,
-                fromdate = GetDateValue(options.FromDate),
-                todate = GetDateValue(options.ToDate),
-                page = options.Page ?? null,
-                pagesize = options.PageSize ?? null
-            }, (items) => onSuccess(new PagedList<Reputation>(items)), onError);
+            GetUserQuestions(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/no-answer-questions-on-users
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserQuestionsWithNoAnswers(IEnumerable<int> userIds, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
+        {
+            Execute<Question>("users", new string[] { userIds.Vectorize(), "questions", "no-answers" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/no-answer-questions-on-users    
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserQuestionsWithNoAnswers(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError,  Options<QuestionSort> options)
+        {
+            GetUserQuestionsWithNoAnswers(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/unaccepted-questions-on-users
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserUnacceptedQuestions(IEnumerable<int> userIds, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
+        {
+            Execute<Question>("users", new string[] { userIds.Vectorize(), "questions", "unaccepted" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/unaccepted-questions-on-users    
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserUnacceptedQuestions(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
+        {
+            GetUserUnacceptedQuestions(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/unanswered-questions-on-users
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserUnansweredQuestions(IEnumerable<int> userIds, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
+        {
+            Execute<Question>("users", new string[] { userIds.Vectorize(), "questions", "unanswered" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/unanswered-questions-on-users  
+        /// </summary>
+        /// TODO: Fix Sort
+        public void GetUserUnansweredQuestions(int userId, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
+        {
+            GetUserUnansweredQuestions(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/reputation-on-users
+        /// </summary>
+        public void GetUserReputation(IEnumerable<int> userIds, Action<IPagedList<Reputation>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
+        {
+            Execute<Reputation>("users", new string[] { userIds.Vectorize(), "reputation" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/reputation-on-users 
+        /// </summary>
+        public void GetUserReputation(int userId, Action<IPagedList<Reputation>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
+        {
+            GetUserReputation(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/suggested-edits-on-users
+        /// </summary>
+        public void GetUserSuggestedEdits(IEnumerable<int> userIds, Action<IPagedList<SuggestedEdit>> onSuccess, Action<ApiException> onError, Options<SuggestedEditSort> options)
+        {
+            Execute<SuggestedEdit>("users", new string[] { userIds.Vectorize(), "suggested-edits" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/suggested-edits-on-users 
+        /// </summary>
+        public void GetUserUnansweredQuestions(int userId, Action<IPagedList<SuggestedEdit>> onSuccess, Action<ApiException> onError, Options<SuggestedEditSort> options)
+        {
+            GetUserSuggestedEdits(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/tags-on-users
+        /// </summary>
+        public void GetUserTags(IEnumerable<int> userIds, Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError, Options<TagSort> options)
+        {
+            Execute<Tag>("users", new string[] { userIds.Vectorize(), "tags" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: https://api.stackexchange.com/docs/tags-on-users
+        /// </summary>
+        public void GetUserTags(int userId, Action<IPagedList<Tag>> onSuccess, Action<ApiException> onError, Options<TagSort> options)
+        {
+            GetUserTags(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-user-answers-in-tags
+        /// </summary>
+        public void GetUserTopAnswersByTag(IEnumerable<int> userIds, IEnumerable<string> tags, Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
+        {
+            Execute<Answer>("users", new string[] { userIds.Vectorize(), "tags", tags.Vectorize(), "top-answers" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-user-answers-in-tags
+        /// </summary>
+        public void GetUserTopAnswersByTag(int userId, IEnumerable<string> tags, Action<IPagedList<Answer>> onSuccess, Action<ApiException> onError, Options<AnswerSort> options)
+        {
+            GetUserTopAnswersByTag(userId.ToArray(), tags, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-answer-tags-on-users
+        /// </summary>
+        public void GetUserTopAnswersByTag(IEnumerable<int> userIds, Action<IPagedList<TopTag>> onSuccess, Action<ApiException> onError, Options options)
+        {
+            Execute<TopTag>("users", new string[] { userIds.Vectorize(), "top-answer-tags" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-answer-tags-on-users
+        /// </summary>
+        public void GetUserTopAnswersByTag(int userId, Action<IPagedList<TopTag>> onSuccess, Action<ApiException> onError, Options options)
+        {
+            GetUserTopAnswersByTag(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-user-questions-in-tags
+        /// </summary>
+        public void GetUserTopQuestionsByTag(IEnumerable<int> userIds, IEnumerable<string> tags, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
+        {
+            Execute<Question>("users", new string[] { userIds.Vectorize(), "tags", tags.Vectorize(), "top-questions" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-user-questions-in-tags
+        /// </summary>
+        public void GetUserTopQuestionsByTag(int userId, IEnumerable<string> tags, Action<IPagedList<Question>> onSuccess, Action<ApiException> onError, Options<QuestionSort> options)
+        {
+            GetUserTopQuestionsByTag(userId.ToArray(), tags, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-question-tags-on-users
+        /// </summary>
+        public void GetUserTopQuestionsByTag(IEnumerable<int> userIds, Action<IPagedList<TopTag>> onSuccess, Action<ApiException> onError, Options options)
+        {
+            Execute<TopTag>("users", new string[] { userIds.Vectorize(), "top-question-tags" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/top-question-tags-on-users
+        /// </summary>
+        public void GetUserTopQuestionsByTag(int userId, Action<IPagedList<TopTag>> onSuccess, Action<ApiException> onError, Options options)
+        {
+            GetUserTopQuestionsByTag(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/timeline-on-users
+        /// </summary>
+        public void GetUserTimeline(IEnumerable<int> userIds, Action<IPagedList<UserTimeline>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
+        {
+            Execute<UserTimeline>("users", new string[] { userIds.Vectorize(), "timeline" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/timeline-on-users
+        /// </summary>
+        public void GetUserTimeline(int userId, Action<IPagedList<UserTimeline>> onSuccess, Action<ApiException> onError, OptionsWithDates options)
+        {
+            GetUserTimeline(userId.ToArray(), onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/moderators
+        /// </summary>
+        public void GetModerators(Action<IPagedList<User>> onSuccess, Action<ApiException> onError, Options<UserSort, int> options)
+        {
+            Execute<User, Int32>("users", new string[] { "moderators" }, onSuccess, onError, options);
+        }
+
+        /// <summary>
+        /// See: http://api.stackexchange.com/docs/elected-moderators
+        /// </summary>
+        public void GetElectedModerators(Action<IPagedList<User>> onSuccess, Action<ApiException> onError, Options<UserSort, int> options)
+        {
+            Execute<User, Int32>("users", new string[] { "moderators", "elected" }, onSuccess, onError, options);
         }
     }
 }

trunk/source/Stacky/Entities/Error.cs

+namespace Stacky
+{
+    using Newtonsoft.Json;
+
+    public class Error : Entity
+    {
+        private int id;
+        [JsonProperty("error_id")]
+        public int Id
+        {
+            get { return id; }
+            set { id = value; NotifyOfPropertyChange(() => Id); }
+        }
+
+        private string name;
+        [JsonProperty("error_name")]
+        public string Name
+        {
+            get { return name; }
+            set { name = value; NotifyOfPropertyChange(() => Name); }
+        }
+
+        private string description;
+        [JsonProperty("description")]
+        public string Description
+        {
+            get { return description; }
+            set { description = value; NotifyOfPropertyChange(() => Description); }
+        }
+    }
+}

trunk/source/Stacky/Stacky.csproj

     <Compile Include="Entities\BadgeCounts.cs" />
     <Compile Include="Entities\Comment.cs" />
     <Compile Include="Entities\Entity.cs" />
+    <Compile Include="Entities\Error.cs" />
     <Compile Include="Entities\Filter.cs" />
     <Compile Include="Entities\MigrationInfo.cs" />
     <Compile Include="Entities\NetworkUser.cs" />
     <Compile Include="StackyClient\AnswerMethods.cs" />
     <Compile Include="StackyClient\BadgeMethods.cs" />
     <Compile Include="StackyClient\CommentMethods.cs" />
+    <Compile Include="StackyClient\ErrorMethods.cs" />
     <Compile Include="StackyClient\NetworkMethods.cs" />
     <Compile Include="StackyClient\PostMethods.cs" />
     <Compile Include="StackyClient\PrivilegeMethods.cs" />

trunk/source/Stacky/StackyClient/ErrorMethods.cs

+using System;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace Stacky
+{
+    public partial class StackyClient
+    {
+        public IPagedList<Error> GetErrors(int? page = null, int? pageSize = null)
+        {
+            return Execute<Error>("errors", null, new
+            {
+                page = page ?? null,
+                pagesize = pageSize ?? null
+            });
+        }
+
+        /// <summary>
+        /// https://api.stackexchange.com/docs/simulate-error
+        /// </summary>
+        /// <param name="id"></param>
+        /// <returns></returns>
+        public Error SimulateError(int id)
+        {
+            return Execute<Error>("errors", new string[] { id.ToString() }, null).FirstOrDefault();
+        }
+    }
+}