The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 029
MANIFEST 15
META.json 61133
META.yml 61113
Makefile.PL 1114
README 22
dist.ini 313
examples/gitdata_commit.pl 22
lib/Pithub/Base.pm 96112
lib/Pithub/Events.pm 53
lib/Pithub/Gists/Comments.pm 2040
lib/Pithub/Gists.pm 64
lib/Pithub/GitData/Blobs.pm 53
lib/Pithub/GitData/Commits.pm 53
lib/Pithub/GitData/References.pm 53
lib/Pithub/GitData/Tags.pm 53
lib/Pithub/GitData/Trees.pm 53
lib/Pithub/GitData.pm 108
lib/Pithub/Issues/Assignees.pm 53
lib/Pithub/Issues/Comments.pm 53
lib/Pithub/Issues/Events.pm 53
lib/Pithub/Issues/Labels.pm 53
lib/Pithub/Issues/Milestones.pm 53
lib/Pithub/Issues.pm 108
lib/Pithub/Orgs/Members.pm 53
lib/Pithub/Orgs/Teams.pm 53
lib/Pithub/Orgs.pm 75
lib/Pithub/PullRequests/Comments.pm 53
lib/Pithub/PullRequests.pm 64
lib/Pithub/Repos/Collaborators.pm 53
lib/Pithub/Repos/Commits.pm 53
lib/Pithub/Repos/Contents.pm 77
lib/Pithub/Repos/Downloads.pm 53
lib/Pithub/Repos/Forks.pm 53
lib/Pithub/Repos/Hooks.pm 53
lib/Pithub/Repos/Keys.pm 403
lib/Pithub/Repos/Releases/Assets.pm 53
lib/Pithub/Repos/Releases.pm 64
lib/Pithub/Repos/Starring.pm 53
lib/Pithub/Repos/Stats.pm 53
lib/Pithub/Repos/Statuses.pm 53
lib/Pithub/Repos/Watching.pm 53
lib/Pithub/Repos.pm 1766
lib/Pithub/Result/SharedCache.pm 072
lib/Pithub/Result.pm 1051
lib/Pithub/Search.pm 53
lib/Pithub/Users/Emails.pm 53
lib/Pithub/Users/Followers.pm 53
lib/Pithub/Users/Keys.pm 403
lib/Pithub/Users.pm 86
lib/Pithub.pm 1412
t/basic.t 3361
t/events.t 22
t/gists.t 3437
t/git_data.t 1615
t/issues.t 2929
t/lib/Pithub/Test/Factory.pm 022
t/lib/Pithub/Test/UA.pm 1316
t/lib/Pithub/Test.pm 1549
t/live/basic.t 436
t/live/cache.t 046
t/live/events.t 55
t/live/gists.t 1212
t/live/git_data.t 811
t/live/issues.t 55
t/live/orgs.t 712
t/live/pull_requests.t 55
t/live/repos.t 1920
t/live/users.t 167
t/multi.t 3131
t/orgs.t 2525
t/pull_requests.t 1414
t/repos.t 8498
t/search.t 66
t/test.t 016
t/users.t 3318
76 files changed (This is a version diff) 9891395
@@ -1,5 +1,34 @@
 Revision history for Pithub
 
+0.01028   2014-11-19 16:50:32-08:00 America/Los_Angeles
+          - #178 Fixed the minimum version of Moo.
+          - #176 Using JSON::MaybeXS instead of JSON to allow
+            alternatives to JSON::XS such as CPanel::JSON::XS.
+          - #177 Using Path::Tiny instead of File::Slurp to simplify file
+            access and avoid File::Slurp unicode bugs.
+          - #175 Now using Github for issue tracking.
+
+0.01027   2014-11-04 10:55:03-08:00 America/Los_Angeles
+          - Forgot to update the change log last release.
+
+0.01026   2014-11-04 10:28:22-08:00 America/Los_Angeles
+          - #173 Document Pithub::Result->code, raw_content, request,
+            etag and success.
+          - #171 Add Pithub::Repos->branch to get information about a
+            branch.
+          - #169 Add Pithub::Repos->delete to delete a repository.
+          - #168 Allow inherited attributes to be changed when making
+            a sub-object.  $p->repos( per_page => 100 )
+          - #163 The default per_page is now 100, the maximum allowed
+            by Github, for more efficient pagination.
+          - #162 Requests are now cached (aka Conditional Requests)
+            for more efficient use of the API.
+          - Pithub::Repos::Keys->update and Pithub::Users::Keys->update
+            have been removed.  Deploy and public keys are immutable.
+            removed.  If you need to update a key, remove it and create
+            a new one.
+          - Gist comments have been fixed.
+
 0.01025   2014-05-18 16:16:38+02:00 Europe/Berlin
           - Fix #159 - forking repo into organization
 
@@ -1,4 +1,4 @@
-# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.015.
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.020.
 Changes
 LICENSE
 MANIFEST
@@ -50,6 +50,7 @@ lib/Pithub/Repos/Stats.pm
 lib/Pithub/Repos/Statuses.pm
 lib/Pithub/Repos/Watching.pm
 lib/Pithub/Result.pm
+lib/Pithub/Result/SharedCache.pm
 lib/Pithub/Search.pm
 lib/Pithub/Users.pm
 lib/Pithub/Users/Emails.pm
@@ -61,6 +62,7 @@ t/gists.t
 t/git_data.t
 t/issues.t
 t/lib/Pithub/Test.pm
+t/lib/Pithub/Test/Factory.pm
 t/lib/Pithub/Test/UA.pm
 t/lib/Pithub/Test/http_response/api.github.com/error/notfound.GET
 t/lib/Pithub/Test/http_response/api.github.com/orgs/CPAN-API/repos.GET
@@ -78,6 +80,7 @@ t/lib/Pithub/Test/http_response/api.github.com/users/plu/followers.GET.page-4.pe
 t/lib/Pithub/Test/http_response/api.github.com/users/plu/followers.GET.per_page-15
 t/lib/Pithub/Test/http_response/api.github.com/users/plu/repos.GET
 t/live/basic.t
+t/live/cache.t
 t/live/events.t
 t/live/gists.t
 t/live/git_data.t
@@ -92,4 +95,5 @@ t/pull_requests.t
 t/release-pod-syntax.t
 t/repos.t
 t/search.t
+t/test.t
 t/users.t
@@ -4,7 +4,7 @@
       "Johannes Plunien <plu@cpan.org>"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "Dist::Zilla version 5.015, CPAN::Meta::Converter version 2.140640",
+   "generated_by" : "Dist::Zilla version 5.020, CPAN::Meta::Converter version 2.142060",
    "license" : [
       "perl_5"
    ],
@@ -16,7 +16,7 @@
    "prereqs" : {
       "configure" : {
          "requires" : {
-            "ExtUtils::MakeMaker" : "6.30"
+            "ExtUtils::MakeMaker" : "0"
          }
       },
       "develop" : {
@@ -27,23 +27,28 @@
       "runtime" : {
          "requires" : {
             "Array::Iterator" : "0",
+            "Cache::LRU" : "0.04",
             "HTTP::Message" : "0",
-            "JSON" : "0",
+            "JSON::MaybeXS" : "1.002000",
             "LWP::Protocol::https" : "0",
             "LWP::UserAgent" : "0",
-            "Moo" : "0"
+            "Moo" : "1.001000"
          }
       },
       "test" : {
          "requires" : {
-            "File::Slurp" : "0",
+            "Import::Into" : "1.002004",
             "MIME::Base64" : "0",
+            "Path::Tiny" : "0.037",
             "Test::Most" : "0"
          }
       }
    },
    "release_status" : "stable",
    "resources" : {
+      "bugtracker" : {
+         "web" : "https://github.com/plu/Pithub/issues"
+      },
       "homepage" : "https://github.com/plu/Pithub",
       "repository" : {
          "type" : "git",
@@ -51,56 +56,56 @@
          "web" : "https://github.com/plu/Pithub"
       }
    },
-   "version" : "0.01025",
+   "version" : "0.01028",
    "x_Dist_Zilla" : {
       "perl" : {
-         "version" : "5.018002"
+         "version" : "5.018001"
       },
       "plugins" : [
          {
             "class" : "Dist::Zilla::Plugin::GatherDir",
             "name" : "@Basic/GatherDir",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::PruneCruft",
             "name" : "@Basic/PruneCruft",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::ManifestSkip",
             "name" : "@Basic/ManifestSkip",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::MetaYAML",
             "name" : "@Basic/MetaYAML",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::License",
             "name" : "@Basic/License",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::Readme",
             "name" : "@Basic/Readme",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::ExtraTests",
             "name" : "@Basic/ExtraTests",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::ExecDir",
             "name" : "@Basic/ExecDir",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::ShareDir",
             "name" : "@Basic/ShareDir",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::MakeMaker",
@@ -110,57 +115,62 @@
                }
             },
             "name" : "@Basic/MakeMaker",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::Manifest",
             "name" : "@Basic/Manifest",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::TestRelease",
             "name" : "@Basic/TestRelease",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::ConfirmRelease",
             "name" : "@Basic/ConfirmRelease",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::UploadToCPAN",
             "name" : "@Basic/UploadToCPAN",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::Authority",
             "name" : "Authority",
-            "version" : "1.006"
+            "version" : "1.009"
+         },
+         {
+            "class" : "Dist::Zilla::Plugin::CheckChangesHasContent",
+            "name" : "CheckChangesHasContent",
+            "version" : "0.007"
          },
          {
             "class" : "Dist::Zilla::Plugin::MetaConfig",
             "name" : "MetaConfig",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::MetaJSON",
             "name" : "MetaJSON",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::NextRelease",
             "name" : "NextRelease",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::PkgVersion",
             "name" : "PkgVersion",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::PodSyntaxTests",
             "name" : "PodSyntaxTests",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::PodWeaver",
@@ -174,118 +184,180 @@
                      {
                         "class" : "Pod::Weaver::Plugin::EnsurePod5",
                         "name" : "@CorePrep/EnsurePod5",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Plugin::H1Nester",
                         "name" : "@CorePrep/H1Nester",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Plugin::SingleEncoding",
                         "name" : "@Default/SingleEncoding",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Name",
                         "name" : "@Default/Name",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Version",
                         "name" : "@Default/Version",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Region",
                         "name" : "@Default/prelude",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Generic",
                         "name" : "SYNOPSIS",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Generic",
                         "name" : "DESCRIPTION",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Generic",
                         "name" : "OVERVIEW",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Collect",
                         "name" : "ATTRIBUTES",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Collect",
                         "name" : "METHODS",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Collect",
                         "name" : "FUNCTIONS",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Leftovers",
                         "name" : "@Default/Leftovers",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Region",
                         "name" : "@Default/postlude",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Authors",
                         "name" : "@Default/Authors",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      },
                      {
                         "class" : "Pod::Weaver::Section::Legal",
                         "name" : "@Default/Legal",
-                        "version" : "4.006"
+                        "version" : "4.007"
                      }
                   ]
                }
             },
             "name" : "PodWeaver",
-            "version" : "4.005"
+            "version" : "4.006"
          },
          {
             "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod",
             "name" : "ReadmeAnyFromPod",
-            "version" : "0.133360"
+            "version" : "0.142470"
          },
          {
             "class" : "Dist::Zilla::Plugin::GithubMeta",
             "name" : "GithubMeta",
-            "version" : "0.42"
+            "version" : "0.46"
+         },
+         {
+            "class" : "Dist::Zilla::Plugin::GitHubREADME::Badge",
+            "name" : "GitHubREADME::Badge",
+            "version" : "0.03"
          },
          {
             "class" : "Dist::Zilla::Plugin::Git::NextVersion",
+            "config" : {
+               "Dist::Zilla::Plugin::Git::NextVersion" : {
+                  "first_version" : "0.01000",
+                  "version_by_branch" : "0",
+                  "version_regexp" : "(?^:^v(.+)$)"
+               },
+               "Dist::Zilla::Role::Git::Repo" : {
+                  "repo_root" : "."
+               }
+            },
             "name" : "Git::NextVersion",
-            "version" : "2.020"
+            "version" : "2.023"
          },
          {
             "class" : "Dist::Zilla::Plugin::Git::Check",
+            "config" : {
+               "Dist::Zilla::Plugin::Git::Check" : {
+                  "untracked_files" : "die"
+               },
+               "Dist::Zilla::Role::Git::DirtyFiles" : {
+                  "allow_dirty" : [
+                     "dist.ini",
+                     "Changes"
+                  ],
+                  "allow_dirty_match" : [],
+                  "changelog" : "Changes"
+               },
+               "Dist::Zilla::Role::Git::Repo" : {
+                  "repo_root" : "."
+               }
+            },
             "name" : "Git::Check",
-            "version" : "2.020"
+            "version" : "2.023"
          },
          {
             "class" : "Dist::Zilla::Plugin::Git::Commit",
+            "config" : {
+               "Dist::Zilla::Plugin::Git::Commit" : {
+                  "add_files_in" : [],
+                  "commit_msg" : "v%v%n%n%c",
+                  "time_zone" : "local"
+               },
+               "Dist::Zilla::Role::Git::DirtyFiles" : {
+                  "allow_dirty" : [
+                     "dist.ini",
+                     "Changes"
+                  ],
+                  "allow_dirty_match" : [],
+                  "changelog" : "Changes"
+               },
+               "Dist::Zilla::Role::Git::Repo" : {
+                  "repo_root" : "."
+               }
+            },
             "name" : "Git::Commit",
-            "version" : "2.020"
+            "version" : "2.023"
          },
          {
             "class" : "Dist::Zilla::Plugin::Git::Tag",
+            "config" : {
+               "Dist::Zilla::Plugin::Git::Tag" : {
+                  "branch" : null,
+                  "signed" : 0,
+                  "tag" : "v0.01028",
+                  "tag_format" : "v%v",
+                  "tag_message" : "v%v",
+                  "time_zone" : "local"
+               },
+               "Dist::Zilla::Role::Git::Repo" : {
+                  "repo_root" : "."
+               }
+            },
             "name" : "Git::Tag",
-            "version" : "2.020"
+            "version" : "2.023"
          },
          {
             "class" : "Dist::Zilla::Plugin::Prereqs",
@@ -296,7 +368,7 @@
                }
             },
             "name" : "TestRequires",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::Prereqs",
@@ -307,47 +379,47 @@
                }
             },
             "name" : "Prereqs",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":InstallModules",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":IncModules",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":TestFiles",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":ExecFiles",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":ShareFiles",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":MainModule",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":AllFiles",
-            "version" : "5.015"
+            "version" : "5.020"
          },
          {
             "class" : "Dist::Zilla::Plugin::FinderCode",
             "name" : ":NoFiles",
-            "version" : "5.015"
+            "version" : "5.020"
          }
       ],
       "zilla" : {
@@ -355,7 +427,7 @@
          "config" : {
             "is_trial" : "0"
          },
-         "version" : "5.015"
+         "version" : "5.020"
       }
    },
    "x_authority" : "cpan:PLU"
@@ -3,13 +3,14 @@ abstract: 'Github v3 API'
 author:
   - 'Johannes Plunien <plu@cpan.org>'
 build_requires:
-  File::Slurp: '0'
+  Import::Into: '1.002004'
   MIME::Base64: '0'
+  Path::Tiny: '0.037'
   Test::Most: '0'
 configure_requires:
-  ExtUtils::MakeMaker: '6.30'
+  ExtUtils::MakeMaker: '0'
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.015, CPAN::Meta::Converter version 2.140640'
+generated_by: 'Dist::Zilla version 5.020, CPAN::Meta::Converter version 2.142060'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -17,102 +18,108 @@ meta-spec:
 name: Pithub
 requires:
   Array::Iterator: '0'
+  Cache::LRU: '0.04'
   HTTP::Message: '0'
-  JSON: '0'
+  JSON::MaybeXS: '1.002000'
   LWP::Protocol::https: '0'
   LWP::UserAgent: '0'
-  Moo: '0'
+  Moo: '1.001000'
 resources:
+  bugtracker: https://github.com/plu/Pithub/issues
   homepage: https://github.com/plu/Pithub
   repository: https://github.com/plu/Pithub.git
-version: '0.01025'
+version: '0.01028'
 x_Dist_Zilla:
   perl:
-    version: '5.018002'
+    version: '5.018001'
   plugins:
     -
       class: Dist::Zilla::Plugin::GatherDir
       name: '@Basic/GatherDir'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::PruneCruft
       name: '@Basic/PruneCruft'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::ManifestSkip
       name: '@Basic/ManifestSkip'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::MetaYAML
       name: '@Basic/MetaYAML'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::License
       name: '@Basic/License'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::Readme
       name: '@Basic/Readme'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::ExtraTests
       name: '@Basic/ExtraTests'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::ExecDir
       name: '@Basic/ExecDir'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::ShareDir
       name: '@Basic/ShareDir'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::MakeMaker
       config:
         Dist::Zilla::Role::TestRunner:
           default_jobs: 1
       name: '@Basic/MakeMaker'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::Manifest
       name: '@Basic/Manifest'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::TestRelease
       name: '@Basic/TestRelease'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::ConfirmRelease
       name: '@Basic/ConfirmRelease'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::UploadToCPAN
       name: '@Basic/UploadToCPAN'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::Authority
       name: Authority
-      version: '1.006'
+      version: '1.009'
+    -
+      class: Dist::Zilla::Plugin::CheckChangesHasContent
+      name: CheckChangesHasContent
+      version: '0.007'
     -
       class: Dist::Zilla::Plugin::MetaConfig
       name: MetaConfig
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::MetaJSON
       name: MetaJSON
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::NextRelease
       name: NextRelease
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::PkgVersion
       name: PkgVersion
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::PodSyntaxTests
       name: PodSyntaxTests
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::PodWeaver
       config:
@@ -124,93 +131,138 @@ x_Dist_Zilla:
             -
               class: Pod::Weaver::Plugin::EnsurePod5
               name: '@CorePrep/EnsurePod5'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Plugin::H1Nester
               name: '@CorePrep/H1Nester'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Plugin::SingleEncoding
               name: '@Default/SingleEncoding'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Name
               name: '@Default/Name'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Version
               name: '@Default/Version'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Region
               name: '@Default/prelude'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Generic
               name: SYNOPSIS
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Generic
               name: DESCRIPTION
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Generic
               name: OVERVIEW
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Collect
               name: ATTRIBUTES
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Collect
               name: METHODS
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Collect
               name: FUNCTIONS
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Leftovers
               name: '@Default/Leftovers'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Region
               name: '@Default/postlude'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Authors
               name: '@Default/Authors'
-              version: '4.006'
+              version: '4.007'
             -
               class: Pod::Weaver::Section::Legal
               name: '@Default/Legal'
-              version: '4.006'
+              version: '4.007'
       name: PodWeaver
-      version: '4.005'
+      version: '4.006'
     -
       class: Dist::Zilla::Plugin::ReadmeAnyFromPod
       name: ReadmeAnyFromPod
-      version: '0.133360'
+      version: '0.142470'
     -
       class: Dist::Zilla::Plugin::GithubMeta
       name: GithubMeta
-      version: '0.42'
+      version: '0.46'
+    -
+      class: Dist::Zilla::Plugin::GitHubREADME::Badge
+      name: GitHubREADME::Badge
+      version: '0.03'
     -
       class: Dist::Zilla::Plugin::Git::NextVersion
+      config:
+        Dist::Zilla::Plugin::Git::NextVersion:
+          first_version: '0.01000'
+          version_by_branch: '0'
+          version_regexp: (?^:^v(.+)$)
+        Dist::Zilla::Role::Git::Repo:
+          repo_root: .
       name: Git::NextVersion
-      version: '2.020'
+      version: '2.023'
     -
       class: Dist::Zilla::Plugin::Git::Check
+      config:
+        Dist::Zilla::Plugin::Git::Check:
+          untracked_files: die
+        Dist::Zilla::Role::Git::DirtyFiles:
+          allow_dirty:
+            - dist.ini
+            - Changes
+          allow_dirty_match: []
+          changelog: Changes
+        Dist::Zilla::Role::Git::Repo:
+          repo_root: .
       name: Git::Check
-      version: '2.020'
+      version: '2.023'
     -
       class: Dist::Zilla::Plugin::Git::Commit
+      config:
+        Dist::Zilla::Plugin::Git::Commit:
+          add_files_in: []
+          commit_msg: v%v%n%n%c
+          time_zone: local
+        Dist::Zilla::Role::Git::DirtyFiles:
+          allow_dirty:
+            - dist.ini
+            - Changes
+          allow_dirty_match: []
+          changelog: Changes
+        Dist::Zilla::Role::Git::Repo:
+          repo_root: .
       name: Git::Commit
-      version: '2.020'
+      version: '2.023'
     -
       class: Dist::Zilla::Plugin::Git::Tag
+      config:
+        Dist::Zilla::Plugin::Git::Tag:
+          branch: ~
+          signed: 0
+          tag: v0.01028
+          tag_format: v%v
+          tag_message: v%v
+          time_zone: local
+        Dist::Zilla::Role::Git::Repo:
+          repo_root: .
       name: Git::Tag
-      version: '2.020'
+      version: '2.023'
     -
       class: Dist::Zilla::Plugin::Prereqs
       config:
@@ -218,7 +270,7 @@ x_Dist_Zilla:
           phase: test
           type: requires
       name: TestRequires
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::Prereqs
       config:
@@ -226,42 +278,42 @@ x_Dist_Zilla:
           phase: runtime
           type: requires
       name: Prereqs
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':InstallModules'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':IncModules'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':TestFiles'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':ExecFiles'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':ShareFiles'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':MainModule'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':AllFiles'
-      version: '5.015'
+      version: '5.020'
     -
       class: Dist::Zilla::Plugin::FinderCode
       name: ':NoFiles'
-      version: '5.015'
+      version: '5.020'
   zilla:
     class: Dist::Zilla::Dist::Builder
     config:
       is_trial: '0'
-    version: '5.015'
+    version: '5.020'
 x_authority: cpan:PLU
@@ -1,20 +1,19 @@
 
-# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.015.
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.020.
 use strict;
 use warnings;
 
 
 
-use ExtUtils::MakeMaker 6.30;
+use ExtUtils::MakeMaker ;
 
 
 
 my %WriteMakefileArgs = (
   "ABSTRACT" => "Github v3 API",
   "AUTHOR" => "Johannes Plunien <plu\@cpan.org>",
-  "BUILD_REQUIRES" => {},
   "CONFIGURE_REQUIRES" => {
-    "ExtUtils::MakeMaker" => "6.30"
+    "ExtUtils::MakeMaker" => 0
   },
   "DISTNAME" => "Pithub",
   "EXE_FILES" => [],
@@ -22,18 +21,20 @@ my %WriteMakefileArgs = (
   "NAME" => "Pithub",
   "PREREQ_PM" => {
     "Array::Iterator" => 0,
+    "Cache::LRU" => "0.04",
     "HTTP::Message" => 0,
-    "JSON" => 0,
+    "JSON::MaybeXS" => "1.002000",
     "LWP::Protocol::https" => 0,
     "LWP::UserAgent" => 0,
-    "Moo" => 0
+    "Moo" => "1.001000"
   },
   "TEST_REQUIRES" => {
-    "File::Slurp" => 0,
+    "Import::Into" => "1.002004",
     "MIME::Base64" => 0,
+    "Path::Tiny" => "0.037",
     "Test::Most" => 0
   },
-  "VERSION" => "0.01025",
+  "VERSION" => "0.01028",
   "test" => {
     "TESTS" => "t/*.t t/live/*.t"
   }
@@ -42,13 +43,15 @@ my %WriteMakefileArgs = (
 
 my %FallbackPrereqs = (
   "Array::Iterator" => 0,
-  "File::Slurp" => 0,
+  "Cache::LRU" => "0.04",
   "HTTP::Message" => 0,
-  "JSON" => 0,
+  "Import::Into" => "1.002004",
+  "JSON::MaybeXS" => "1.002000",
   "LWP::Protocol::https" => 0,
   "LWP::UserAgent" => 0,
   "MIME::Base64" => 0,
-  "Moo" => 0,
+  "Moo" => "1.001000",
+  "Path::Tiny" => "0.037",
   "Test::Most" => 0
 );
 
@@ -1,7 +1,7 @@
 
 
 This archive contains the distribution Pithub,
-version 0.01025:
+version 0.01028:
 
   Github v3 API
 
@@ -11,5 +11,5 @@ This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 
-This README file was generated by Dist::Zilla::Plugin::Readme v5.015.
+This README file was generated by Dist::Zilla::Plugin::Readme v5.020.
 
@@ -8,6 +8,7 @@ name = Pithub
 [Authority]
 authority = cpan:PLU
 
+[CheckChangesHasContent]
 [MetaConfig]
 [MetaJSON]
 [NextRelease]
@@ -18,10 +19,17 @@ authority = cpan:PLU
 [ReadmeAnyFromPod]
 type = markdown
 location = root
+filename = README.md
 
 [GithubMeta]
 user = plu
 remote = origin
+issues = 1
+
+[GitHubREADME::Badge]
+badges = travis
+badges = coveralls
+place  = top
 
 [Git::NextVersion]
 first_version = 0.01000
@@ -31,14 +39,16 @@ first_version = 0.01000
 [Git::Tag]
 
 [Prereqs / TestRequires]
-File::Slurp = 0
+Path::Tiny = 0.037
 Test::Most = 0
 MIME::Base64 = 0
+Import::Into = 1.002004
 
 [Prereqs]
 Array::Iterator = 0
+Cache::LRU = 0.04
 HTTP::Message = 0
-JSON = 0
+JSON::MaybeXS = 1.002000
 LWP::Protocol::https = 0
 LWP::UserAgent = 0
-Moo = 0
+Moo = 1.001000
@@ -1,7 +1,7 @@
 #!/usr/bin/env perl
 use strict;
 use warnings;
-use File::Slurp;
+use Path::Tiny;
 use Pithub::GitData;
 
 my $git = Pithub::GitData->new(
@@ -10,7 +10,7 @@ my $git = Pithub::GitData->new(
     user  => 'plu',
 );
 
-my $content = File::Slurp::read_file(__FILE__);
+my $content = path(__FILE__)->slurp;
 
 # the encoding can also be 'base64', if necessary
 my $blob = $git->blobs->create(
@@ -1,8 +1,6 @@
 package Pithub::Base;
-$Pithub::Base::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Base::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Base::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 base class for all Pithub modules
 
@@ -10,11 +8,13 @@ use Moo;
 use Carp qw(croak);
 use HTTP::Headers;
 use HTTP::Request;
-use JSON;
+use JSON::MaybeXS;
 use LWP::UserAgent;
 use Pithub::Result;
 use URI;
 
+with 'Pithub::Result::SharedCache';
+
 
 has 'auto_pagination' => (
     default => sub { 0 },
@@ -44,6 +44,7 @@ has 'per_page' => (
     clearer   => 'clear_per_page',
     is        => 'rw',
     predicate => 'has_per_page',
+    default   => 100,
     required  => 0,
 );
 
@@ -107,73 +108,49 @@ my @TOKEN_REQUIRED = (
 );
 
 my @TOKEN_REQUIRED_REGEXP = (
-    qr{^DELETE /gists/.*?$},
-    qr{^DELETE /gists/comments/.*?$},
-    qr{^DELETE /gists/[^/]+/star$},
-    qr{^DELETE /orgs/[^/]+/members/.*?$},
-    qr{^DELETE /orgs/[^/]+/public_members/.*?},
-    qr{^DELETE /repos/[^/]+/[^/]+/collaborators/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/comments/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/downloads/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/hooks/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/issues/comments/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/issues/[^/]+/labels$},
-    qr{^DELETE /repos/[^/]+/[^/]+/issues/[^/]+/labels/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/keys/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/labels/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/milestones/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/pulls/comments/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/releases/.*?$},
-    qr{^DELETE /repos/[^/]+/[^/]+/releases/assets/.*?$},
-    qr{^DELETE /teams/.*?$},
-    qr{^DELETE /teams/[^/]+/members/.*?$},
-    qr{^DELETE /teams/[^/]+/repos/.*?$},
-    qr{^DELETE /user/following/.*?$},
-    qr{^DELETE /user/keys/.*?$},
-    qr{^DELETE /user/starred/[^/]+/.*?$},
-    qr{^DELETE /user/watched/[^/]+/.*?$},
+    qr{^DELETE },
     qr{^GET /gists/starred$},
     qr{^GET /gists/[^/]+/star$},
     qr{^GET /issues$},
-    qr{^GET /orgs/[^/]+/members/.*?$},
+    qr{^GET /orgs/[^/]+/members/.*$},
     qr{^GET /orgs/[^/]+/teams$},
     qr{^GET /repos/[^/]+/[^/]+/collaborators$},
-    qr{^GET /repos/[^/]+/[^/]+/collaborators/.*?$},
+    qr{^GET /repos/[^/]+/[^/]+/collaborators/.*$},
     qr{^GET /repos/[^/]+/[^/]+/hooks$},
-    qr{^GET /repos/[^/]+/[^/]+/hooks/.*?$},
+    qr{^GET /repos/[^/]+/[^/]+/hooks/.*$},
     qr{^GET /repos/[^/]+/[^/]+/keys$},
-    qr{^GET /repos/[^/]+/[^/]+/keys/.*?$},
-    qr{^GET /teams/.*?$},
+    qr{^GET /repos/[^/]+/[^/]+/keys/.*$},
+    qr{^GET /teams/.*$},
     qr{^GET /teams/[^/]+/members$},
-    qr{^GET /teams/[^/]+/members/.*?$},
+    qr{^GET /teams/[^/]+/members/.*$},
     qr{^GET /teams/[^/]+/repos$},
-    qr{^GET /teams/[^/]+/repos/.*?$},
-    qr{^GET /user/following/.*?$},
-    qr{^GET /user/keys/.*?$},
+    qr{^GET /teams/[^/]+/repos/.*$},
+    qr{^GET /user/following/.*$},
+    qr{^GET /user/keys/.*$},
     qr{^GET /user/orgs$},
-    qr{^GET /user/starred/[^/]+/.*?$},
+    qr{^GET /user/starred/[^/]+/.*$},
     qr{^GET /user/watched$},
-    qr{^GET /user/watched/[^/]+/.*?$},
-    qr{^GET /users/[^/]+/events/orgs/.*?$},
-    qr{^PATCH /gists/.*?$},
-    qr{^PATCH /gists/comments/.*?$},
-    qr{^PATCH /orgs/.*?$},
-    qr{^PATCH /repos/[^/]+/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/comments/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/git/refs/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/hooks/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/issues/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/issues/comments/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/keys/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/labels/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/milestones/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/pulls/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/releases/.*?$},
-    qr{^PATCH /repos/[^/]+/[^/]+/pulls/comments/.*?$},
-    qr{^PATCH /teams/.*?$},
-    qr{^PATCH /user/keys/.*?$},
-    qr{^PATCH /user/repos/.*?$},
-    qr{^POST /repos/[^/]+/[^/]+/releases/[^/]+/assets.*?$},
+    qr{^GET /user/watched/[^/]+/.*$},
+    qr{^GET /users/[^/]+/events/orgs/.*$},
+    qr{^PATCH /gists/.*$},
+    qr{^PATCH /gists/[^/]+/comments/.*$},
+    qr{^PATCH /orgs/.*$},
+    qr{^PATCH /repos/[^/]+/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/comments/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/git/refs/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/hooks/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/issues/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/issues/comments/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/keys/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/labels/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/milestones/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/pulls/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/releases/.*$},
+    qr{^PATCH /repos/[^/]+/[^/]+/pulls/comments/.*$},
+    qr{^PATCH /teams/.*$},
+    qr{^PATCH /user/keys/.*$},
+    qr{^PATCH /user/repos/.*$},
+    qr{^POST /repos/[^/]+/[^/]+/releases/[^/]+/assets.*$},
     qr{^POST /gists/[^/]+/comments$},
     qr{^POST /orgs/[^/]+/repos$},
     qr{^POST /orgs/[^/]+/teams$},
@@ -197,15 +174,15 @@ my @TOKEN_REQUIRED_REGEXP = (
     qr{^POST /repos/[^/]+/[^/]+/releases$},
     qr{^POST /repos/[^/]+/[^/]+/pulls/[^/]+/comments$},
     qr{^PUT /gists/[^/]+/star$},
-    qr{^PUT /orgs/[^/]+/public_members/.*?$},
-    qr{^PUT /repos/[^/]+/[^/]+/collaborators/.*?$},
+    qr{^PUT /orgs/[^/]+/public_members/.*$},
+    qr{^PUT /repos/[^/]+/[^/]+/collaborators/.*$},
     qr{^PUT /repos/[^/]+/[^/]+/issues/[^/]+/labels$},
     qr{^PUT /repos/[^/]+/[^/]+/pulls/[^/]+/merge$},
-    qr{^PUT /teams/[^/]+/members/.*?$},
-    qr{^PUT /teams/[^/]+/repos/.*?$},
-    qr{^PUT /user/following/.*?$},
-    qr{^PUT /user/starred/[^/]+/.*?$},
-    qr{^PUT /user/watched/[^/]+/.*?$},
+    qr{^PUT /teams/[^/]+/members/.*$},
+    qr{^PUT /teams/[^/]+/repos/.*$},
+    qr{^PUT /user/following/.*$},
+    qr{^PUT /user/starred/[^/]+/.*$},
+    qr{^PUT /user/watched/[^/]+/.*$},
 );
 
 
@@ -256,7 +233,8 @@ sub request {
         my %query = ( $request->uri->query_form, %$params );
         $request->uri->query_form(%query);
     }
-    my $response = $self->ua->request($request);
+
+    my $response = $self->_make_request($request);
 
     return Pithub::Result->new(
         auto_pagination => $self->auto_pagination,
@@ -266,6 +244,31 @@ sub request {
 }
 
 
+sub _make_request {
+    my($self, $request) = @_;
+
+    if( my $cached_response = $self->shared_cache->get($request->uri) ) {
+        # Add the If-None-Match header from the cache's ETag
+        # and make the request
+        $request->header( "If-None-Match" => $cached_response->header("ETag") );
+        my $response = $self->ua->request($request);
+
+        # Got 304 Not Modified, cache is still valid
+        return $cached_response if ($response->code || 0) == 304;
+
+        # The response changed, cache it and return it.
+        $self->shared_cache->set( $request->uri, $response );
+        return $response;
+    }
+    else {
+        my $response = $self->ua->request($request);
+        $self->shared_cache->set( $request->uri, $response );
+        return $response;
+    }
+}
+
+
+
 sub has_token {
     my ($self, $request) = @_;
 
@@ -296,30 +299,23 @@ sub _get_user_repo_args {
 }
 
 sub _create_instance {
-    my ( $self, $class ) = @_;
+    my ( $self, $class, @args ) = @_;
+
     my %args = (
         api_uri         => $self->api_uri,
         auto_pagination => $self->auto_pagination,
         ua              => $self->ua,
+        @args
     );
-    if ( $self->has_repo ) {
-        $args{repo} = $self->repo;
-    }
-    if ( $self->has_token ) {
-        $args{token} = $self->token;
-    }
-    if ( $self->has_user ) {
-        $args{user} = $self->user;
-    }
-    if ( $self->has_per_page ) {
-        $args{per_page} = $self->per_page;
-    }
-    if ( $self->has_jsonp_callback ) {
-        $args{jsonp_callback} = $self->jsonp_callback;
-    }
-    if ( $self->has_prepare_request ) {
-        $args{prepare_request} = $self->prepare_request;
+
+    for my $attr (qw(repo token user per_page jsonp_callback prepare_request)) {
+        # Allow overrides to set attributes to undef
+        next if exists $args{$attr};
+
+        my $has_attr = "has_$attr";
+        $args{$attr} = $self->$attr if $self->$has_attr;
     }
+
     return $class->new(%args);
 }
 
@@ -348,12 +344,18 @@ sub _request_for {
     return $request;
 }
 
+my %TOKEN_REQUIRED = map { ($_ => 1) } @TOKEN_REQUIRED;
 sub _token_required {
     my ( $self, $method, $path ) = @_;
-    return 1 if grep $_ eq "${method} ${path}", @TOKEN_REQUIRED;
+
+    my $key = "${method} ${path}";
+
+    return 1 if $TOKEN_REQUIRED{$key};
+
     foreach my $regexp (@TOKEN_REQUIRED_REGEXP) {
-        return 1 if "${method} ${path}" =~ /$regexp/;
+        return 1 if $key =~ /$regexp/;
     }
+
     return 0;
 }
 
@@ -402,7 +404,7 @@ Pithub::Base - Github v3 base class for all Pithub modules
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 DESCRIPTION
 
@@ -411,8 +413,8 @@ L<Pithub::Base>, even L<Pithub> itself. So all
 L<attributes|/ATTRIBUTES> listed here can either be set in the
 constructor or via the setter on the objects.
 
-If any attribute is set on a L<Pithub> object, it gets
-automatically set on objects, that get created by a method call on
+If any attribute is set on a L<Pithub> object it gets
+automatically set on objects that get created by a method call on
 the L<Pithub> object. This is very convenient for attributes like
 the L</token> or the L</user> and L</repo> attributes.
 
@@ -424,6 +426,13 @@ object of L<Pithub::Repos> where you set the L</user> and L</repo>
 attribute in the constructor, this will also be set once you
 get to the L<Pithub::Repos::Keys> object via the C<< keys >> method.
 
+Attributes passed along from the parent can be changed in the method
+call.
+
+    my $p = Pithub->new( per_page => 50 );
+    my $r1 = $p->repos;                         # $r->per_page == 50
+    my $r2 = $p->repos( per_page => 100 );      # $r->per_page == 100
+
 Examples:
 
     # just to demonstrate the "magic"
@@ -454,6 +463,8 @@ Examples:
 
 =head2 auto_pagination
 
+Off by default.
+
 See also: L<Pithub::Result/auto_pagination>.
 
 =head2 api_uri
@@ -527,17 +538,22 @@ B<has_jsonp_callback>: check if the jsonp_callback attribute is set
 
 =head2 per_page
 
-By default undef, so it defaults to Github's default. See also:
-L<http://developer.github.com/v3/#pagination>.
+Controls how many items are fetched per API call, aka "page".  See
+also: L<http://developer.github.com/v3/#pagination> and
+L</auto_pagination>.
+
+To minimize the number of API calls to get a complete listing, this
+defaults to the maximum allowed by Github, which is currently 100.
+This may change in the future if Github changes their maximum.
 
 Examples:
 
-    my $users = Pithub::Users->new( per_page => 100 );
+    my $users = Pithub::Users->new( per_page => 30 );
 
     # ... is the same as ...
 
     my $users = Pithub::Users->new;
-    $users->per_page(100);
+    $users->per_page(30);
 
 There are two helper methods:
 
@@ -1,8 +1,6 @@
 package Pithub::Events;
-$Pithub::Events::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Events::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Events::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Events API
 
@@ -120,7 +118,7 @@ Pithub::Events - Github v3 Events API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Gists::Comments;
-$Pithub::Gists::Comments::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Gists::Comments::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Gists::Comments::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Gist Comments API
 
@@ -25,10 +23,11 @@ sub create {
 
 sub delete {
     my ( $self, %args ) = @_;
+    croak 'Missing key in parameters: gist_id' unless $args{gist_id};
     croak 'Missing key in parameters: comment_id' unless $args{comment_id};
     return $self->request(
         method => 'DELETE',
-        path   => sprintf( '/gists/comments/%s', delete $args{comment_id} ),
+        path   => sprintf( '/gists/%s/comments/%s', delete $args{gist_id}, delete $args{comment_id} ),
         %args,
     );
 }
@@ -36,10 +35,11 @@ sub delete {
 
 sub get {
     my ( $self, %args ) = @_;
+    croak 'Missing key in parameters: gist_id' unless $args{gist_id};
     croak 'Missing key in parameters: comment_id' unless $args{comment_id};
     return $self->request(
         method => 'GET',
-        path   => sprintf( '/gists/comments/%s', delete $args{comment_id} ),
+        path   => sprintf( '/gists/%s/comments/%s', delete $args{gist_id}, delete $args{comment_id} ),
         %args,
     );
 }
@@ -58,11 +58,12 @@ sub list {
 
 sub update {
     my ( $self, %args ) = @_;
+    croak 'Missing key in parameters: gist_id' unless $args{gist_id};
     croak 'Missing key in parameters: comment_id' unless $args{comment_id};
     croak 'Missing key in parameters: data (hashref)' unless ref $args{data} eq 'HASH';
     return $self->request(
         method => 'PATCH',
-        path   => sprintf( '/gists/comments/%s', delete $args{comment_id} ),
+        path   => sprintf( '/gists/%s/comments/%s', delete $args{gist_id}, delete $args{comment_id} ),
         %args,
     );
 }
@@ -81,7 +82,7 @@ Pithub::Gists::Comments - Github v3 Gist Comments API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -101,7 +102,7 @@ Parameters:
 
 =item *
 
-B<gist_id>: mandatory integer
+B<gist_id>: mandatory string
 
 =item *
 
@@ -121,7 +122,7 @@ Examples:
 
     my $c = Pithub::Gists::Comments->new;
     my $result = $c->create(
-        gist_id => 1,
+        gist_id => 'c0ff33',
         data    => { body => 'Just commenting for the sake of commenting' },
     );
 
@@ -129,7 +130,7 @@ Response: B<Status: 201 Created>
 
     {
         "id": 1,
-        "url": "https://api.github.com/gists/comments/1",
+        "url": "https://api.github.com/gists/c0ff33/comments/1",
         "body": "Just commenting for the sake of commenting",
         "user": {
             "login": "octocat",
@@ -150,7 +151,7 @@ Response: B<Status: 201 Created>
 
 Delete a comment
 
-    DELETE /gists/comments/:id
+    DELETE /gists/:gist_id/comments/:id
 
 Parameters:
 
@@ -158,6 +159,10 @@ Parameters:
 
 =item *
 
+B<gist_id>: mandatory string
+
+=item *
+
 B<comment_id>: mandatory integer
 
 =back
@@ -165,7 +170,10 @@ B<comment_id>: mandatory integer
 Examples:
 
     my $c = Pithub::Gists::Comments->new;
-    my $result = $c->delete( comment_id => 1 );
+    my $result = $c->delete(
+        gist_id    => 'c0ff33',
+        comment_id => 1
+    );
 
 Response: B<Status: 204 No Content>
 
@@ -179,7 +187,7 @@ Response: B<Status: 204 No Content>
 
 Get a single comment
 
-    GET /gists/comments/:id
+    GET /gists/:gist_id/comments/:id
 
 Parameters:
 
@@ -187,6 +195,10 @@ Parameters:
 
 =item *
 
+B<gist_id>: mandatory string
+
+=item *
+
 B<comment_id>: mandatory integer
 
 =back
@@ -194,13 +206,16 @@ B<comment_id>: mandatory integer
 Examples:
 
     my $c = Pithub::Gists::Comments->new;
-    my $result = $c->get( comment_id => 1 );
+    my $result = $c->get(
+        gist_id    => 'c0ff33',
+        comment_id => 1
+    );
 
 Response: B<Status: 200 OK>
 
     {
         "id": 1,
-        "url": "https://api.github.com/gists/comments/1",
+        "url": "https://api.github.com/gists/c0ff33/comments/1",
         "body": "Just commenting for the sake of commenting",
         "user": {
             "login": "octocat",
@@ -229,7 +244,7 @@ Parameters:
 
 =item *
 
-B<gist_id>: mandatory integer
+B<gist_id>: mandatory string
 
 =back
 
@@ -243,7 +258,7 @@ Response: B<Status: 200 OK>
     [
         {
             "id": 1,
-            "url": "https://api.github.com/gists/comments/1",
+            "url": "https://api.github.com/gists/c0ff33/comments/1",
             "body": "Just commenting for the sake of commenting",
             "user": {
                 "login": "octocat",
@@ -265,7 +280,7 @@ Response: B<Status: 200 OK>
 
 Edit a comment
 
-    PATCH /gists/comments/:id
+    PATCH /gists/:gist_id/comments/:id
 
 Parameters:
 
@@ -273,6 +288,10 @@ Parameters:
 
 =item *
 
+B<gist_id>: mandatory string
+
+=item *
+
 B<comment_id>: mandatory integer
 
 =item *
@@ -293,6 +312,7 @@ Examples:
 
     my $c = Pithub::Gists::Comments->new;
     my $result = $c->update(
+        gist_id    => 'c0ff33',
         comment_id => 1,
         data       => { body => 'some comment' }
     );
@@ -301,7 +321,7 @@ Response: B<Status: 200 OK>
 
     {
         "id": 1,
-        "url": "https://api.github.com/gists/comments/1",
+        "url": "https://api.github.com/gists/c0ff33/comments/1",
         "body": "Just commenting for the sake of commenting",
         "user": {
             "login": "octocat",
@@ -1,8 +1,6 @@
 package Pithub::Gists;
-$Pithub::Gists::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Gists::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Gists::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Gists API
 
@@ -13,7 +11,7 @@ extends 'Pithub::Base';
 
 
 sub comments {
-    return shift->_create_instance('Pithub::Gists::Comments');
+    return shift->_create_instance('Pithub::Gists::Comments', @_);
 }
 
 
@@ -150,7 +148,7 @@ Pithub::Gists - Github v3 Gists API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::GitData::Blobs;
-$Pithub::GitData::Blobs::VERSION = '0.01025';
-BEGIN {
-  $Pithub::GitData::Blobs::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::GitData::Blobs::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Git Data Blobs API
 
@@ -48,7 +46,7 @@ Pithub::GitData::Blobs - Github v3 Git Data Blobs API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,6 @@
 package Pithub::GitData::Commits;
-$Pithub::GitData::Commits::VERSION = '0.01025';
-BEGIN {
-  $Pithub::GitData::Commits::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::GitData::Commits::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Git Data Commits API
 
@@ -48,7 +46,7 @@ Pithub::GitData::Commits - Github v3 Git Data Commits API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::GitData::References;
-$Pithub::GitData::References::VERSION = '0.01025';
-BEGIN {
-  $Pithub::GitData::References::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::GitData::References::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Git Data References API
 
@@ -79,7 +77,7 @@ Pithub::GitData::References - Github v3 Git Data References API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::GitData::Tags;
-$Pithub::GitData::Tags::VERSION = '0.01025';
-BEGIN {
-  $Pithub::GitData::Tags::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::GitData::Tags::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Git Data Tags API
 
@@ -48,7 +46,7 @@ Pithub::GitData::Tags - Github v3 Git Data Tags API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 DESCRIPTION
 
@@ -1,8 +1,6 @@
 package Pithub::GitData::Trees;
-$Pithub::GitData::Trees::VERSION = '0.01025';
-BEGIN {
-  $Pithub::GitData::Trees::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::GitData::Trees::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Git Data Trees API
 
@@ -54,7 +52,7 @@ Pithub::GitData::Trees - Github v3 Git Data Trees API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::GitData;
-$Pithub::GitData::VERSION = '0.01025';
-BEGIN {
-  $Pithub::GitData::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::GitData::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Git Data API
 
@@ -17,27 +15,27 @@ extends 'Pithub::Base';
 
 
 sub blobs {
-    return shift->_create_instance('Pithub::GitData::Blobs');
+    return shift->_create_instance('Pithub::GitData::Blobs', @_);
 }
 
 
 sub commits {
-    return shift->_create_instance('Pithub::GitData::Commits');
+    return shift->_create_instance('Pithub::GitData::Commits', @_);
 }
 
 
 sub references {
-    return shift->_create_instance('Pithub::GitData::References');
+    return shift->_create_instance('Pithub::GitData::References', @_);
 }
 
 
 sub tags {
-    return shift->_create_instance('Pithub::GitData::Tags');
+    return shift->_create_instance('Pithub::GitData::Tags', @_);
 }
 
 
 sub trees {
-    return shift->_create_instance('Pithub::GitData::Trees');
+    return shift->_create_instance('Pithub::GitData::Trees', @_);
 }
 
 1;
@@ -54,7 +52,7 @@ Pithub::GitData - Github v3 Git Data API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Issues::Assignees;
-$Pithub::Issues::Assignees::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Issues::Assignees::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Issues::Assignees::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Issue Assignees API
 
@@ -47,7 +45,7 @@ Pithub::Issues::Assignees - Github v3 Issue Assignees API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Issues::Comments;
-$Pithub::Issues::Comments::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Issues::Comments::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Issues::Comments::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Issue Comments API
 
@@ -86,7 +84,7 @@ Pithub::Issues::Comments - Github v3 Issue Comments API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Issues::Events;
-$Pithub::Issues::Events::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Issues::Events::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Issues::Events::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Issue Events API
 
@@ -54,7 +52,7 @@ Pithub::Issues::Events - Github v3 Issue Events API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Issues::Labels;
-$Pithub::Issues::Labels::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Issues::Labels::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Issues::Labels::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Issue Labels API
 
@@ -143,7 +141,7 @@ Pithub::Issues::Labels - Github v3 Issue Labels API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Issues::Milestones;
-$Pithub::Issues::Milestones::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Issues::Milestones::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Issues::Milestones::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Issue Milestones API
 
@@ -84,7 +82,7 @@ Pithub::Issues::Milestones - Github v3 Issue Milestones API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Issues;
-$Pithub::Issues::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Issues::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Issues::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Issues API
 
@@ -17,12 +15,12 @@ extends 'Pithub::Base';
 
 
 sub assignees {
-    return shift->_create_instance('Pithub::Issues::Assignees');
+    return shift->_create_instance('Pithub::Issues::Assignees', @_);
 }
 
 
 sub comments {
-    return shift->_create_instance('Pithub::Issues::Comments');
+    return shift->_create_instance('Pithub::Issues::Comments', @_);
 }
 
 
@@ -39,7 +37,7 @@ sub create {
 
 
 sub events {
-    return shift->_create_instance('Pithub::Issues::Events');
+    return shift->_create_instance('Pithub::Issues::Events', @_);
 }
 
 
@@ -56,7 +54,7 @@ sub get {
 
 
 sub labels {
-    return shift->_create_instance('Pithub::Issues::Labels');
+    return shift->_create_instance('Pithub::Issues::Labels', @_);
 }
 
 
@@ -79,7 +77,7 @@ sub list {
 
 
 sub milestones {
-    return shift->_create_instance('Pithub::Issues::Milestones');
+    return shift->_create_instance('Pithub::Issues::Milestones', @_);
 }
 
 
@@ -109,7 +107,7 @@ Pithub::Issues - Github v3 Issues API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Orgs::Members;
-$Pithub::Orgs::Members::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Orgs::Members::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Orgs::Members::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Org Members API
 
@@ -106,7 +104,7 @@ Pithub::Orgs::Members - Github v3 Org Members API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Orgs::Teams;
-$Pithub::Orgs::Teams::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Orgs::Teams::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Orgs::Teams::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Org Teams API
 
@@ -179,7 +177,7 @@ Pithub::Orgs::Teams - Github v3 Org Teams API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Orgs;
-$Pithub::Orgs::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Orgs::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Orgs::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Orgs API
 
@@ -42,12 +40,12 @@ sub list {
 
 
 sub members {
-    return shift->_create_instance('Pithub::Orgs::Members');
+    return shift->_create_instance('Pithub::Orgs::Members', @_);
 }
 
 
 sub teams {
-    return shift->_create_instance('Pithub::Orgs::Teams');
+    return shift->_create_instance('Pithub::Orgs::Teams', @_);
 }
 
 
@@ -76,7 +74,7 @@ Pithub::Orgs - Github v3 Orgs API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::PullRequests::Comments;
-$Pithub::PullRequests::Comments::VERSION = '0.01025';
-BEGIN {
-  $Pithub::PullRequests::Comments::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::PullRequests::Comments::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Pull Request Comments API
 
@@ -86,7 +84,7 @@ Pithub::PullRequests::Comments - Github v3 Pull Request Comments API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::PullRequests;
-$Pithub::PullRequests::VERSION = '0.01025';
-BEGIN {
-  $Pithub::PullRequests::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::PullRequests::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Pull Requests API
 
@@ -13,7 +11,7 @@ extends 'Pithub::Base';
 
 
 sub comments {
-    return shift->_create_instance('Pithub::PullRequests::Comments');
+    return shift->_create_instance('Pithub::PullRequests::Comments', @_);
 }
 
 
@@ -126,7 +124,7 @@ Pithub::PullRequests - Github v3 Pull Requests API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Collaborators;
-$Pithub::Repos::Collaborators::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Collaborators::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Collaborators::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Collaborators API
 
@@ -71,7 +69,7 @@ Pithub::Repos::Collaborators - Github v3 Repo Collaborators API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Commits;
-$Pithub::Repos::Commits::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Commits::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Commits::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Commits API
 
@@ -128,7 +126,7 @@ Pithub::Repos::Commits - Github v3 Repo Commits API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Contents;
-$Pithub::Repos::Contents::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Contents::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Contents::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Contents API
 
@@ -66,7 +64,7 @@ Pithub::Repos::Contents - Github v3 Repo Contents API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -89,6 +87,8 @@ C<< master >>.
 
 Examples:
 
+    use Path::Tiny;
+
     my $c = Pithub::Repos::Contents->new(
         repo => 'Pithub',
         user => 'plu'
@@ -96,12 +96,12 @@ Examples:
 
     my $result = $c->archive( archive_format => 'tarball' );
     if ( $result->success ) {
-        File::Slurp::write_file('Pithub-master.tgz', $result->raw_content);
+        path('Pithub-master.tgz')->spew($result->raw_content);
     }
 
     $result = $c->archive( archive_format => 'tarball', ref => 'other_branch' );
     if ( $result->success ) {
-        File::Slurp::write_file('Pithub-other_branch.tgz', $result->raw_content);
+        path('Pithub-other_branch.tgz')->spew($result->raw_content);
     }
 
 =back
@@ -1,8 +1,6 @@
 package Pithub::Repos::Downloads;
-$Pithub::Repos::Downloads::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Downloads::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Downloads::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Downloads API
 
@@ -99,7 +97,7 @@ Pithub::Repos::Downloads - Github v3 Repo Downloads API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Forks;
-$Pithub::Repos::Forks::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Forks::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Forks::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Forks API
 
@@ -54,7 +52,7 @@ Pithub::Repos::Forks - Github v3 Repo Forks API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Hooks;
-$Pithub::Repos::Hooks::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Hooks::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Hooks::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Hooks API
 
@@ -96,7 +94,7 @@ Pithub::Repos::Hooks - Github v3 Repo Hooks API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Keys;
-$Pithub::Repos::Keys::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Keys::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Keys::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Keys API
 
@@ -57,19 +55,6 @@ sub list {
     );
 }
 
-
-sub update {
-    my ( $self, %args ) = @_;
-    croak 'Missing key in parameters: key_id' unless $args{key_id};
-    croak 'Missing key in parameters: data (hashref)' unless ref $args{data} eq 'HASH';
-    $self->_validate_user_repo_args( \%args );
-    return $self->request(
-        method => 'PATCH',
-        path   => sprintf( '/repos/%s/%s/keys/%s', delete $args{user}, delete $args{repo}, delete $args{key_id} ),
-        %args,
-    );
-}
-
 1;
 
 __END__
@@ -84,7 +69,7 @@ Pithub::Repos::Keys - Github v3 Repo Keys API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -174,28 +159,6 @@ Examples:
 
 =back
 
-=head2 update
-
-=over
-
-=item *
-
-Edit
-
-    PATCH /repos/:user/:repo/keys/:id
-
-Examples:
-
-    my $k = Pithub::Repos::Keys->new;
-    my $result = $k->update(
-        user   => 'plu',
-        repo   => 'Pithub',
-        key_id => 1,
-        data   => { title => 'some new title' },
-    );
-
-=back
-
 =head1 AUTHOR
 
 Johannes Plunien <plu@cpan.org>
@@ -1,8 +1,6 @@
 package Pithub::Repos::Releases::Assets;
-$Pithub::Repos::Releases::Assets::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Releases::Assets::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Releases::Assets::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Releases Assets API
 
@@ -93,7 +91,7 @@ Pithub::Repos::Releases::Assets - Github v3 Repo Releases Assets API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Releases;
-$Pithub::Repos::Releases::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Releases::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Releases::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Releases API
 
@@ -13,7 +11,7 @@ extends 'Pithub::Base';
 
 
 sub assets {
-    return shift->_create_instance('Pithub::Repos::Releases::Assets');
+    return shift->_create_instance('Pithub::Repos::Releases::Assets', @_);
 }
 
 
@@ -90,7 +88,7 @@ Pithub::Repos::Releases - Github v3 Repo Releases API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Starring;
-$Pithub::Repos::Starring::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Starring::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Starring::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Starring API
 
@@ -85,7 +83,7 @@ Pithub::Repos::Starring - Github v3 Repo Starring API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Stats;
-$Pithub::Repos::Stats::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Stats::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Stats::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 repos / stats API
 
@@ -53,7 +51,7 @@ Pithub::Repos::Stats - Github v3 repos / stats API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Statuses;
-$Pithub::Repos::Statuses::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Statuses::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Statuses::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT:  Github v3 repos / statuses API
 
@@ -66,7 +64,7 @@ Pithub::Repos::Statuses - Github v3 repos / statuses API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos::Watching;
-$Pithub::Repos::Watching::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::Watching::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::Watching::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repo Watching API
 
@@ -85,7 +83,7 @@ Pithub::Repos::Watching - Github v3 Repo Watching API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Repos;
-$Pithub::Repos::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Repos::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Repos::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Repos API
 
@@ -23,6 +21,22 @@ use Pithub::Repos::Watching;
 extends 'Pithub::Base';
 
 
+sub branch {
+    my ( $self, %args ) = @_;
+    croak 'Missing key in parameters: branch (string)' unless defined $args{branch};
+    $self->_validate_user_repo_args( \%args );
+    return $self->request(
+        method => 'GET',
+        path   => sprintf(
+            '/repos/%s/%s/branches/%s', delete $args{user},
+                                        delete $args{repo},
+                                        delete $args{branch},
+        ),
+        %args,
+    );
+}
+
+
 sub branches {
     my ( $self, %args ) = @_;
     $self->_validate_user_repo_args( \%args );
@@ -35,17 +49,17 @@ sub branches {
 
 
 sub collaborators {
-    return shift->_create_instance('Pithub::Repos::Collaborators');
+    return shift->_create_instance('Pithub::Repos::Collaborators', @_);
 }
 
 
 sub commits {
-    return shift->_create_instance('Pithub::Repos::Commits');
+    return shift->_create_instance('Pithub::Repos::Commits', @_);
 }
 
 
 sub contents {
-    return shift->_create_instance('Pithub::Repos::Contents');
+    return shift->_create_instance('Pithub::Repos::Contents', @_);
 }
 
 
@@ -80,13 +94,24 @@ sub create {
 }
 
 
+sub delete {
+    my( $self, %args ) = @_;
+    $self->_validate_user_repo_args( \%args );
+    return $self->request(
+        method => 'DELETE',
+        path   => sprintf( '/repos/%s/%s', delete $args{user}, delete $args{repo} ),
+        %args,
+    );
+}
+
+
 sub downloads {
-    return shift->_create_instance('Pithub::Repos::Downloads');
+    return shift->_create_instance('Pithub::Repos::Downloads', @_);
 }
 
 
 sub forks {
-    return shift->_create_instance('Pithub::Repos::Forks');
+    return shift->_create_instance('Pithub::Repos::Forks', @_);
 }
 
 
@@ -102,12 +127,12 @@ sub get {
 
 
 sub hooks {
-    return shift->_create_instance('Pithub::Repos::Hooks');
+    return shift->_create_instance('Pithub::Repos::Hooks', @_);
 }
 
 
 sub keys {
-    return shift->_create_instance('Pithub::Repos::Keys');
+    return shift->_create_instance('Pithub::Repos::Keys', @_);
 }
 
 
@@ -149,22 +174,22 @@ sub list {
 
 
 sub releases {
-    return shift->_create_instance('Pithub::Repos::Releases');
+    return shift->_create_instance('Pithub::Repos::Releases', @_);
 }
 
 
 sub starring {
-    return shift->_create_instance('Pithub::Repos::Starring');
+    return shift->_create_instance('Pithub::Repos::Starring', @_);
 }
 
 
 sub stats {
-    return shift->_create_instance('Pithub::Repos::Stats');
+    return shift->_create_instance('Pithub::Repos::Stats', @_);
 }
 
 
 sub statuses {
-    return shift->_create_instance('Pithub::Repos::Statuses');
+    return shift->_create_instance('Pithub::Repos::Statuses', @_);
 }
 
 
@@ -203,7 +228,7 @@ sub update {
 
 
 sub watching {
-    return shift->_create_instance('Pithub::Repos::Watching');
+    return shift->_create_instance('Pithub::Repos::Watching', @_);
 }
 
 1;
@@ -220,10 +245,26 @@ Pithub::Repos - Github v3 Repos API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
+=head2 branch
+
+Get information about a single branch.
+
+    GET /repos/:owner/:repo/branches/:branch
+
+Example:
+
+    my $result = Pithub->new->branch(
+        user => 'plu',
+        repo => 'Pithub',
+        branch => "master"
+    );
+
+See also L<branches> to get a list of all branches.
+
 =head2 branches
 
 =over
@@ -239,6 +280,8 @@ Examples:
     my $repos  = Pithub::Repos->new;
     my $result = $repos->branches( user => 'plu', repo => 'Pithub' );
 
+See also L<branch> to get information about a single branch.
+
 =back
 
 =head2 collaborators
@@ -302,6 +345,12 @@ Examples:
 
 =back
 
+=head2 delete
+
+Delete a repository.
+
+    DELETE /repos/:owner/:repo
+
 =head2 downloads
 
 Provides access to L<Pithub::Repos::Downloads>.
@@ -0,0 +1,72 @@
+package Pithub::Result::SharedCache;
+$Pithub::Result::SharedCache::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
+
+# ABSTRACT: A role to share the LRU cache with all Pithub objects
+
+use Moo::Role;
+use Cache::LRU;
+
+my $Shared_Cache = Cache::LRU->new(
+    size        => 200
+);
+
+
+sub shared_cache {
+    return $Shared_Cache;
+}
+
+
+sub set_shared_cache {
+    my($self, $cache) = @_;
+
+    $Shared_Cache = $cache;
+
+    return;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Pithub::Result::SharedCache - A role to share the LRU cache with all Pithub objects
+
+=head1 VERSION
+
+version 0.01028
+
+=head1 DESCRIPTION
+
+A role to share the least recently used cache with all Pithub objects.
+
+=head1 METHODS
+
+=head2 shared_cache
+
+Returns the Cache::LRU object shared by all Pithub objects.
+
+=head2 set_shared_cache
+
+Sets the Cache::LRU object shared by all Pithub objects.
+
+This should only be necessary for testing or to change the
+size of the cache.
+
+=head1 AUTHOR
+
+Johannes Plunien <plu@cpan.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2011 by Johannes Plunien.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -1,15 +1,23 @@
 package Pithub::Result;
-$Pithub::Result::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Result::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Result::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 result object
 
 use Moo;
 use Array::Iterator;
-use JSON;
+use JSON::MaybeXS;
 use URI;
+use Carp;
+
+sub _isa_isa_maker {
+    my $class = shift;
+    return sub {
+        confess "must be an instance of $class but isn't a reference" if !ref $_[0];
+        confess "must be an instance of $class, but is a ".ref $_[0]
+          unless eval { $_[0]->isa($class) };
+    };
+}
 
 
 has 'auto_pagination' => (
@@ -66,14 +74,17 @@ has 'response' => (
         success     => 'is_success',
     },
     is       => 'ro',
-    isa      => sub { die 'must be a HTTP::Response, but is ' . ref $_[0] unless ref $_[0] eq 'HTTP::Response' },
+    isa      => _isa_isa_maker('HTTP::Response'),
     required => 1,
 );
 
+
 # required for next_page etc
 has '_request' => (
     is       => 'ro',
-    isa      => sub { die 'must be a coderef, but is ' . ref $_[0] unless ref $_[0] eq 'CODE' },
+    isa      => sub {
+        croak 'must be a coderef, but is ' . ref $_[0] unless ref $_[0] eq 'CODE'
+    },
     required => 1,
 );
 
@@ -82,14 +93,17 @@ has '_iterator' => (
     builder => '_build__iterator',
     clearer => '_clear_iterator',
     is      => 'ro',
-    isa     => sub { die 'must be a Array::Iterator, but is ' . ref $_[0] unless ref $_[0] eq 'Array::Iterator' },
+    isa     => _isa_isa_maker('Array::Iterator'),
     lazy    => 1,
 );
 
 has '_json' => (
     builder => '_build__json',
     is      => 'ro',
-    isa     => sub { die 'must be a JSON, but is ' . ref $_[0] unless ref $_[0] eq 'JSON' },
+    isa     => sub {
+        confess "$_[0] is not a suitable JSON object"
+          unless eval { $_[0]->can("decode") };
+    },
     lazy    => 1,
 );
 
@@ -189,6 +203,12 @@ sub prev_page {
 }
 
 
+sub etag {
+    my ($self) = @_;
+    return $self->response->header('ETag');
+}
+
+
 sub ratelimit {
     my ($self) = @_;
     return $self->response->header('X-RateLimit-Limit');
@@ -292,7 +312,7 @@ Pithub::Result - Github v3 result object
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 DESCRIPTION
 
@@ -366,6 +386,23 @@ The L<HTTP::Response> object.
 
 =head1 METHODS
 
+=head2 raw_content
+
+Returns the content of the API response as a string, it will probably
+be JSON.
+
+=head2 request
+
+Returns the L<HTTP::Request> object used to make the API call.
+
+=head2 code
+
+Returns the HTTP code from the API call.
+
+=head2 success
+
+Returns whether the API call was successful.
+
 =head2 count
 
 Returns the count of the elements in L</content>. If the result is
@@ -471,6 +508,10 @@ L</auto_pagination>.
 
 =back
 
+=head2 etag
+
+Returns the value of the C<< ETag >> http header.
+
 =head2 ratelimit
 
 Returns the value of the C<< X-Ratelimit-Limit >> http header.
@@ -1,8 +1,6 @@
 package Pithub::Search;
-$Pithub::Search::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Search::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Search::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Search API
 
@@ -70,7 +68,7 @@ Pithub::Search - Github v3 Search API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Users::Emails;
-$Pithub::Users::Emails::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Users::Emails::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Users::Emails::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 User Emails API
 
@@ -56,7 +54,7 @@ Pithub::Users::Emails - Github v3 User Emails API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Users::Followers;
-$Pithub::Users::Followers::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Users::Followers::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Users::Followers::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 User Followers API
 
@@ -91,7 +89,7 @@ Pithub::Users::Followers - Github v3 User Followers API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub::Users::Keys;
-$Pithub::Users::Keys::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Users::Keys::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Users::Keys::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 User Keys API
 
@@ -53,18 +51,6 @@ sub list {
     );
 }
 
-
-sub update {
-    my ( $self, %args ) = @_;
-    croak 'Missing key in parameters: key_id' unless $args{key_id};
-    croak 'Missing key in parameters: data (hashref)' unless ref $args{data} eq 'HASH';
-    return $self->request(
-        method => 'PATCH',
-        path   => sprintf( '/user/keys/%s', delete $args{key_id} ),
-        %args,
-    );
-}
-
 1;
 
 __END__
@@ -79,7 +65,7 @@ Pithub::Users::Keys - Github v3 User Keys API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -156,29 +142,6 @@ Examples:
 
 =back
 
-=head2 update
-
-=over
-
-=item *
-
-Update a public key
-
-    PATCH /user/keys/:id
-
-Examples:
-
-    my $k = Pithub::Users::Keys->new( token => 'b3c62c6' );
-    my $result = $k->update(
-        key_id => 123,
-        data => {
-            title => 'plu@localhost',
-            key   => 'ssh-rsa AAA...',
-        }
-    );
-
-=back
-
 =head1 AUTHOR
 
 Johannes Plunien <plu@cpan.org>
@@ -1,8 +1,6 @@
 package Pithub::Users;
-$Pithub::Users::VERSION = '0.01025';
-BEGIN {
-  $Pithub::Users::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::Users::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 Users API
 
@@ -15,12 +13,12 @@ extends 'Pithub::Base';
 
 
 sub emails {
-    return shift->_create_instance('Pithub::Users::Emails');
+    return shift->_create_instance('Pithub::Users::Emails', @_);
 }
 
 
 sub followers {
-    return shift->_create_instance('Pithub::Users::Followers');
+    return shift->_create_instance('Pithub::Users::Followers', @_);
 }
 
 
@@ -42,7 +40,7 @@ sub get {
 
 
 sub keys {
-    return shift->_create_instance('Pithub::Users::Keys');
+    return shift->_create_instance('Pithub::Users::Keys', @_);
 }
 
 
@@ -70,7 +68,7 @@ Pithub::Users - Github v3 Users API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 METHODS
 
@@ -1,8 +1,6 @@
 package Pithub;
-$Pithub::VERSION = '0.01025';
-BEGIN {
-  $Pithub::AUTHORITY = 'cpan:PLU';
-}
+$Pithub::VERSION = '0.01028';
+our $AUTHORITY = 'cpan:PLU';
 
 # ABSTRACT: Github v3 API
 
@@ -21,47 +19,47 @@ extends 'Pithub::Base';
 
 
 sub events {
-    return shift->_create_instance('Pithub::Events');
+    return shift->_create_instance('Pithub::Events', @_);
 }
 
 
 sub gists {
-    return shift->_create_instance('Pithub::Gists');
+    return shift->_create_instance('Pithub::Gists', @_);
 }
 
 
 sub git_data {
-    return shift->_create_instance('Pithub::GitData');
+    return shift->_create_instance('Pithub::GitData', @_);
 }
 
 
 sub issues {
-    return shift->_create_instance('Pithub::Issues');
+    return shift->_create_instance('Pithub::Issues', @_);
 }
 
 
 sub orgs {
-    return shift->_create_instance('Pithub::Orgs');
+    return shift->_create_instance('Pithub::Orgs', @_);
 }
 
 
 sub pull_requests {
-    return shift->_create_instance('Pithub::PullRequests');
+    return shift->_create_instance('Pithub::PullRequests', @_);
 }
 
 
 sub repos {
-    return shift->_create_instance('Pithub::Repos');
+    return shift->_create_instance('Pithub::Repos', @_);
 }
 
 
 sub search {
-    return shift->_create_instance('Pithub::Search');
+    return shift->_create_instance('Pithub::Search', @_);
 }
 
 
 sub users {
-    return shift->_create_instance('Pithub::Users');
+    return shift->_create_instance('Pithub::Users', @_);
 }
 
 
@@ -79,7 +77,7 @@ Pithub - Github v3 API
 
 =head1 VERSION
 
-version 0.01025
+version 0.01028
 
 =head1 SYNOPSIS
 
@@ -1,9 +1,9 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
-use Pithub::Test;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Pithub::Test::UA;
-use Test::Most;
+use Pithub::Test;
 
 BEGIN {
     use_ok('Pithub');
@@ -159,7 +159,7 @@ my @tree = (
             {
                 accessor => 'keys',
                 isa      => 'Pithub::Repos::Keys',
-                methods  => [qw(create delete get list update)],
+                methods  => [qw(create delete get list)],
             },
             {
                 accessor => 'releases',
@@ -213,7 +213,7 @@ my @tree = (
             {
                 accessor => 'keys',
                 isa      => 'Pithub::Users::Keys',
-                methods  => [qw(create delete get list update)],
+                methods  => [qw(create delete get list)],
             },
         ],
     },
@@ -342,7 +342,7 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
 
     isa_ok $p, 'Pithub';
 
@@ -379,7 +379,7 @@ sub validate_tree {
 
 {
     my $json = JSON->new;
-    my $p    = Pithub::Test->create('Pithub');
+    my $p    = Pithub::Test::Factory->create('Pithub');
     $p->token('123');
     my $request = $p->request( method => 'POST', path => '/foo', data => { some => 'data' } )->request;
     eq_or_diff $json->decode( $request->content ), { some => 'data' }, 'The JSON content was set in the request object';
@@ -391,7 +391,8 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
+    $p->ua->add_response('error/notfound.GET');
     my $result = $p->request( method => 'GET', path => '/error/notfound' );
 
     is $result->code,    404, 'HTTP status is 404';
@@ -409,7 +410,8 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
+    $p->ua->add_response('users/miyagawa/followers.GET');
     my $result = $p->users->followers->list( user => 'miyagawa' );
 
     is $result->count,          30,                                                        'Count accessor';
@@ -420,15 +422,17 @@ sub validate_tree {
 
     is $result->first_page, undef, 'We are on first page already';
     is $result->prev_page,  undef, 'No prev page on the first page';
-    is $result->next_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=2',  'Next page call';
-    is $result->last_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=26', 'Last page call';
+    uri_is $result->next_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=2&per_page=100',  'Next page call';
+    uri_is $result->last_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=26&per_page=100', 'Last page call';
 
-    is $result->get_page(42)->request->uri, 'https://api.github.com/users/miyagawa/followers?page=42',
+    uri_is $result->get_page(42)->request->uri, 'https://api.github.com/users/miyagawa/followers?page=42&per_page=100',
       'URI for get_page is generated, no matter if it exists or not';
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
+    $p->ua->add_response('users/miyagawa/followers.GET');
+    $p->ua->add_response('users/miyagawa/followers.GET.page-3');
     my $result = $p->users->followers->list( user => 'miyagawa' )->get_page(3);
 
     is $result->first_page_uri, 'https://api.github.com/users/miyagawa/followers?page=1',  'First page link on third page';
@@ -436,27 +440,30 @@ sub validate_tree {
     is $result->next_page_uri,  'https://api.github.com/users/miyagawa/followers?page=4',  'Next page link no third page';
     is $result->last_page_uri,  'https://api.github.com/users/miyagawa/followers?page=26', 'Last page link no third page';
 
-    is $result->first_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=1',  'First page call';
-    is $result->prev_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=2',  'Prev page call';
-    is $result->next_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=4',  'Next page call';
-    is $result->last_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=26', 'Last page call';
+    uri_is $result->first_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=1&per_page=100',  'First page call';
+    uri_is $result->prev_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=2&per_page=100',  'Prev page call';
+    uri_is $result->next_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=4&per_page=100',  'Next page call';
+    uri_is $result->last_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=26&per_page=100', 'Last page call';
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
+    $p->ua->add_response('users/miyagawa/followers.GET');
+    $p->ua->add_response('users/miyagawa/followers.GET.page-26');
     my $result = $p->users->followers->list( user => 'miyagawa' )->get_page(26);
 
-    is $result->first_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=1',  'First page call';
-    is $result->prev_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=25', 'Prev page call';
+    uri_is $result->first_page->request->uri, 'https://api.github.com/users/miyagawa/followers?page=1&per_page=100',  'First page call';
+    uri_is $result->prev_page->request->uri,  'https://api.github.com/users/miyagawa/followers?page=25&per_page=100', 'Prev page call';
     is $result->next_page, undef, 'No next page on the last page';
     is $result->last_page, undef, 'We are on last page already';
 
-    is $result->get_page(42)->request->uri, 'https://api.github.com/users/miyagawa/followers?page=42',
+    uri_is $result->get_page(42)->request->uri, 'https://api.github.com/users/miyagawa/followers?page=42&per_page=100',
       'URI for get_page is generated, no matter if it exists or not';
 }
 
 {
-    my $p = Pithub::Test->create( 'Pithub', per_page => 1 );
+    my $p = Pithub::Test::Factory->create( 'Pithub', per_page => 1 );
+    $p->ua->add_response('users/miyagawa/followers.GET.per_page-1');
     my $result = $p->users->followers->list( user => 'miyagawa' );
 
     eq_or_diff { $result->next_page->request->uri->query_form }, { page => 2,   per_page => 1 }, 'Next page call';
@@ -469,7 +476,8 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
+    $p->ua->add_response('users/plu.GET');
     my $result = $p->users->get( user => 'plu' );
 
     is $result->first_page, undef, 'First page call';
@@ -482,13 +490,14 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create( 'Pithub', jsonp_callback => 'foo' );
+    my $p = Pithub::Test::Factory->create( 'Pithub', jsonp_callback => 'foo' );
     my $result = $p->request( method => 'GET', path => '/foo' );
-    is $result->request->uri->query, 'callback=foo', 'The callback parameter was set';
+    eq_or_diff {$result->request->uri->query_form}, { callback => 'foo', per_page => 100 }, 'The callback parameter was set';
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
+    $p->ua->add_response('orgs/CPAN-API/repos.GET');
     my $result = $p->request( method => 'GET', path => '/orgs/CPAN-API/repos' );
 
     my @expectations = (
@@ -507,7 +516,8 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
+    $p->ua->add_response('users/plu.GET');
     my $result = $p->request( method => 'GET', path => '/users/plu' );
 
     my $row = $result->next;
@@ -519,7 +529,11 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create( 'Pithub', per_page => 15 );
+    my $p = Pithub::Test::Factory->create( 'Pithub', per_page => 15 );
+    $p->ua->add_response('users/plu/followers.GET.per_page-15');
+    $p->ua->add_response('users/plu/followers.GET.page-2.per_page-15');
+    $p->ua->add_response('users/plu/followers.GET.page-3.per_page-15');
+    $p->ua->add_response('users/plu/followers.GET.page-4.per_page-15');
     my $result = $p->users->followers->list( user => 'plu' );
     $result->auto_pagination(1);
     my @followers = ();
@@ -530,7 +544,11 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create( 'Pithub', per_page => 15, auto_pagination => 1 );
+    my $p = Pithub::Test::Factory->create( 'Pithub', per_page => 15, auto_pagination => 1 );
+    $p->ua->add_response('users/plu/followers.GET.per_page-15');
+    $p->ua->add_response('users/plu/followers.GET.page-2.per_page-15');
+    $p->ua->add_response('users/plu/followers.GET.page-3.per_page-15');
+    $p->ua->add_response('users/plu/followers.GET.page-4.per_page-15');
     my $result = $p->users->followers->list( user => 'plu' );
     my @followers = ();
     while ( my $row = $result->next ) {
@@ -540,7 +558,7 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create(
+    my $p = Pithub::Test::Factory->create(
         'Pithub',
         prepare_request => sub {
             my ($request) = @_;
@@ -552,7 +570,7 @@ sub validate_tree {
 }
 
 {
-    my $p      = Pithub::Test->create('Pithub');
+    my $p      = Pithub::Test::Factory->create('Pithub');
     my $result = $p->users->followers->list(
         user    => 'plu',
         options => {
@@ -566,7 +584,7 @@ sub validate_tree {
 }
 
 {
-    my $p = Pithub::Test->create('Pithub');
+    my $p = Pithub::Test::Factory->create('Pithub');
     throws_ok {
         $p->users->get( user => 'foo', params => 5 );
     }
@@ -574,7 +592,17 @@ sub validate_tree {
 
     my $result = $p->users->get( user => 'foo', params => { direction => 'asc' } );
     my %query = $result->request->uri->query_form;
-    eq_or_diff \%query, { direction => 'asc' }, 'The params were set';
+    eq_or_diff \%query, { direction => 'asc', per_page => 100 }, 'The params were set';
 }
 
+subtest "_create_instance passes attributes" => sub {
+    my $p = Pithub::Test::Factory->create("Pithub", per_page => 10);
+
+    is $p->repos->per_page, 10;
+    is $p->repos( per_page => 5 )->per_page, 5;
+    is $p->issues->comments( per_page => 3 )->per_page, 3;
+
+    is $p->repos( per_page => undef )->per_page, undef, "undef is allowed";
+};
+
 done_testing;
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -8,7 +8,7 @@ BEGIN {
 }
 
 {
-    my $obj = Pithub::Test->create( 'Pithub::Events', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Events', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Events';
 
@@ -1,7 +1,7 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
-use Pithub::Test;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -12,7 +12,7 @@ BEGIN {
 # Pithub::Gists->create
 {
     my $json = JSON->new;
-    my $obj  = Pithub::Test->create('Pithub::Gists');
+    my $obj  = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -37,7 +37,7 @@ BEGIN {
 
 # Pithub::Gists->delete
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -57,7 +57,7 @@ BEGIN {
 
 # Pithub::Gists->fork
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -74,7 +74,7 @@ BEGIN {
 
 # Pithub::Gists->get
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -91,7 +91,7 @@ BEGIN {
 
 # Pithub::Gists->is_starred
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -111,7 +111,7 @@ BEGIN {
 
 # Pithub::Gists->list
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -153,7 +153,7 @@ BEGIN {
 
 # Pithub::Gists->star
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -173,7 +173,7 @@ BEGIN {
 
 # Pithub::Gists->unstar
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -193,7 +193,7 @@ BEGIN {
 
 # Pithub::Gists->update
 {
-    my $obj = Pithub::Test->create('Pithub::Gists');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists');
 
     isa_ok $obj, 'Pithub::Gists';
 
@@ -224,22 +224,22 @@ BEGIN {
 
 # Pithub::Gists::Comments->create
 {
-    my $obj = Pithub::Test->create('Pithub::Gists::Comments');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists::Comments');
 
     isa_ok $obj, 'Pithub::Gists::Comments';
 
     throws_ok { $obj->create } qr{Missing key in parameters: gist_id}, 'No parameters';
-    throws_ok { $obj->create( gist_id => 123 ) } qr{Missing key in parameters: data \(hashref\)}, 'No data parameter';
-    throws_ok { $obj->create( gist_id => 123, data => 5 ) } qr{Missing key in parameters: data \(hashref\)}, 'Wrong type';
-    throws_ok { $obj->create( gist_id => 123, data => { body => 'bar' } ); } qr{Access token required for: POST /gists/123/comments}, 'Token required';
+    throws_ok { $obj->create( gist_id => 'c0ff33' ) } qr{Missing key in parameters: data \(hashref\)}, 'No data parameter';
+    throws_ok { $obj->create( gist_id => 'c0ff33', data => 5 ) } qr{Missing key in parameters: data \(hashref\)}, 'Wrong type';
+    throws_ok { $obj->create( gist_id => 'c0ff33', data => { body => 'bar' } ); } qr{Access token required for: POST /gists/c0ff33/comments}, 'Token required';
 
     ok $obj->token(123), 'Token set';
 
     {
         my $json = JSON->new;
-        my $result = $obj->create( gist_id => 123, data => { body => 'some comment' } );
+        my $result = $obj->create( gist_id => 'c0ff33', data => { body => 'some comment' } );
         is $result->request->method, 'POST', 'HTTP method';
-        is $result->request->uri->path, '/gists/123/comments', 'HTTP path';
+        is $result->request->uri->path, '/gists/c0ff33/comments', 'HTTP path';
         my $http_request = $result->request;
         eq_or_diff $json->decode( $http_request->content ), { 'body' => 'some comment' }, 'HTTP body';
     }
@@ -247,19 +247,20 @@ BEGIN {
 
 # Pithub::Gists::Comments->delete
 {
-    my $obj = Pithub::Test->create('Pithub::Gists::Comments');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists::Comments');
 
     isa_ok $obj, 'Pithub::Gists::Comments';
 
-    throws_ok { $obj->delete } qr{Missing key in parameters: comment_id}, 'No parameters';
-    throws_ok { $obj->delete( comment_id => 123 ); } qr{Access token required for: DELETE /gists/comments/123}, 'Token required';
+    throws_ok { $obj->delete } qr{Missing key in parameters: gist_id}, 'No parameters';
+    throws_ok { $obj->delete( gist_id => 'c0ff33' ) } qr{Missing key in parameters: comment_id}, 'No parameters';
+    throws_ok { $obj->delete( gist_id => 'c0ff33', comment_id => 123 ); } qr{Access token required for: DELETE /gists/c0ff33/comments/123}, 'Token required';
 
     ok $obj->token(123), 'Token set';
 
     {
-        my $result = $obj->delete( comment_id => 123 );
+        my $result = $obj->delete( gist_id => 'c0ff33', comment_id => 123 );
         is $result->request->method, 'DELETE', 'HTTP method';
-        is $result->request->uri->path, '/gists/comments/123', 'HTTP path';
+        is $result->request->uri->path, '/gists/c0ff33/comments/123', 'HTTP path';
         my $http_request = $result->request;
         is $http_request->content, '', 'HTTP body';
     }
@@ -267,16 +268,17 @@ BEGIN {
 
 # Pithub::Gists::Comments->get
 {
-    my $obj = Pithub::Test->create('Pithub::Gists::Comments');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists::Comments');
 
     isa_ok $obj, 'Pithub::Gists::Comments';
 
-    throws_ok { $obj->get } qr{Missing key in parameters: comment_id}, 'No parameters';
+    throws_ok { $obj->get } qr{Missing key in parameters: gist_id}, 'No parameters';
+    throws_ok { $obj->get( gist_id => 'c0ff33' ) } qr{Missing key in parameters: comment_id}, 'No parameters';
 
     {
-        my $result = $obj->get( comment_id => 123 );
+        my $result = $obj->get( gist_id => 'c0ff33', comment_id => 123 );
         is $result->request->method, 'GET', 'HTTP method';
-        is $result->request->uri->path, '/gists/comments/123', 'HTTP path';
+        is $result->request->uri->path, '/gists/c0ff33/comments/123', 'HTTP path';
         my $http_request = $result->request;
         is $http_request->content, '', 'HTTP body';
     }
@@ -284,7 +286,7 @@ BEGIN {
 
 # Pithub::Gists::Comments->list
 {
-    my $obj = Pithub::Test->create('Pithub::Gists::Comments');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists::Comments');
 
     isa_ok $obj, 'Pithub::Gists::Comments';
 
@@ -301,22 +303,23 @@ BEGIN {
 
 # Pithub::Gists::Comments->update
 {
-    my $obj = Pithub::Test->create('Pithub::Gists::Comments');
+    my $obj = Pithub::Test::Factory->create('Pithub::Gists::Comments');
 
     isa_ok $obj, 'Pithub::Gists::Comments';
 
-    throws_ok { $obj->update } qr{Missing key in parameters: comment_id}, 'No parameters';
-    throws_ok { $obj->update( comment_id => 123 ) } qr{Missing key in parameters: data \(hashref\)}, 'No data parameter';
-    throws_ok { $obj->update( comment_id => 123, data => 5 ) } qr{Missing key in parameters: data \(hashref\)}, 'Wrong type';
-    throws_ok { $obj->update( comment_id => 123, data => { body => 'bar' } ); } qr{Access token required for: PATCH /gists/comments/123}, 'Token required';
+    throws_ok { $obj->update } qr{Missing key in parameters: gist_id}, 'No parameters';
+    throws_ok { $obj->update( gist_id => 'c0ff33' ) } qr{Missing key in parameters: comment_id}, 'No parameters';
+    throws_ok { $obj->update( gist_id => 'c0ff33', comment_id => 123 ) } qr{Missing key in parameters: data \(hashref\)}, 'No data parameter';
+    throws_ok { $obj->update( gist_id => 'c0ff33', comment_id => 123, data => 5 ) } qr{Missing key in parameters: data \(hashref\)}, 'Wrong type';
+    throws_ok { $obj->update( gist_id => 'c0ff33', comment_id => 123, data => { body => 'bar' } ); } qr{Access token required for: PATCH /gists/c0ff33/comments/123}, 'Token required';
 
     ok $obj->token(123), 'Token set';
 
     {
         my $json = JSON->new;
-        my $result = $obj->update( comment_id => 123, data => { body => 'some comment' } );
+        my $result = $obj->update( gist_id => 'c0ff33', comment_id => 123, data => { body => 'some comment' } );
         is $result->request->method, 'PATCH', 'HTTP method';
-        is $result->request->uri->path, '/gists/comments/123', 'HTTP path';
+        is $result->request->uri->path, '/gists/c0ff33/comments/123', 'HTTP path';
         my $http_request = $result->request;
         eq_or_diff $json->decode( $http_request->content ), { 'body' => 'some comment' }, 'HTTP body';
     }
@@ -1,8 +1,8 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Pithub::Test;
-use Test::Most;
 
 BEGIN {
     use_ok('Pithub::GitData::Blobs');
@@ -15,7 +15,7 @@ BEGIN {
 # Pithub::GitData::Blobs->create
 {
     my $json = JSON->new;
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Blobs', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Blobs', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Blobs';
 
@@ -41,7 +41,7 @@ BEGIN {
 
 # Pithub::GitData::Blobs->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Blobs', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Blobs', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Blobs';
 
@@ -58,7 +58,7 @@ BEGIN {
 
 # Pithub::GitData::Commits->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Commits';
 
@@ -80,7 +80,7 @@ BEGIN {
 
 # Pithub::GitData::Commits->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Commits';
 
@@ -97,7 +97,7 @@ BEGIN {
 
 # Pithub::GitData::References->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::References';
 
@@ -114,7 +114,7 @@ BEGIN {
 
 # Pithub::GitData::References->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::References';
 
@@ -136,7 +136,7 @@ BEGIN {
 
 # Pithub::GitData::References->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::References';
 
@@ -159,7 +159,7 @@ BEGIN {
 
 # Pithub::GitData::References->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::References', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::References';
 
@@ -182,7 +182,7 @@ BEGIN {
 
 # Pithub::GitData::Tags->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Tags', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Tags', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Tags';
 
@@ -199,7 +199,7 @@ BEGIN {
 
 # Pithub::GitData::Tags->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Tags', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Tags', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Tags';
 
@@ -229,7 +229,7 @@ BEGIN {
 
 # Pithub::GitData::Trees->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Trees', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Trees', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Trees';
 
@@ -246,8 +246,7 @@ BEGIN {
     {
         my $result = $obj->get( sha => 456, recursive => 1 );
         is $result->request->method, 'GET', 'HTTP method';
-        is $result->request->uri->path, '/repos/foo/bar/git/trees/456', 'HTTP path';
-        is $result->request->uri->query, 'recursive=1', 'HTTP GET parameters';
+        uri_is $result->request->uri, 'https://api.github.com/repos/foo/bar/git/trees/456?recursive=1&per_page=100';
         my $http_request = $result->request;
         is $http_request->content, '', 'HTTP body';
     }
@@ -255,7 +254,7 @@ BEGIN {
 
 # Pithub::GitData::Trees->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::GitData::Trees', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::GitData::Trees', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::GitData::Trees';
 
@@ -1,7 +1,7 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
-use Pithub::Test;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -15,7 +15,7 @@ BEGIN {
 
 # Pithub::Issues->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues';
 
@@ -53,7 +53,7 @@ BEGIN {
 
 # Pithub::Issues->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues';
 
@@ -71,7 +71,7 @@ BEGIN {
 # Pithub::Issues->list
 {
     {
-        my $obj = Pithub::Test->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
+        my $obj = Pithub::Test::Factory->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
         isa_ok $obj, 'Pithub::Issues';
         my $result = $obj->list;
         is $result->request->method, 'GET', 'HTTP method';
@@ -82,7 +82,7 @@ BEGIN {
     }
 
     {
-        my $obj = Pithub::Test->create('Pithub::Issues');
+        my $obj = Pithub::Test::Factory->create('Pithub::Issues');
         isa_ok $obj, 'Pithub::Issues';
         throws_ok { $obj->list; } qr{Access token required for: GET /issues}, 'Token required';
         ok $obj->token(123), 'Token set';
@@ -96,7 +96,7 @@ BEGIN {
 
 # Pithub::Issues->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues';
 
@@ -138,7 +138,7 @@ BEGIN {
 
 # Pithub::Issues::Assignees->check
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Assignees', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Assignees', user => 'foo', repo => 'bar' );
 
     throws_ok { $obj->check } qr{Missing key in parameters: assignee}, 'No parameters';
 
@@ -155,7 +155,7 @@ BEGIN {
 
 # Pithub::Issues::Assignees->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Assignees', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Assignees', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Assignees';
 
@@ -170,7 +170,7 @@ BEGIN {
 
 # Pithub::Issues::Comments->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Comments';
 
@@ -197,7 +197,7 @@ BEGIN {
 
 # Pithub::Issues::Comments->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Comments';
 
@@ -217,7 +217,7 @@ BEGIN {
 
 # Pithub::Issues::Comments->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Comments';
 
@@ -234,7 +234,7 @@ BEGIN {
 
 # Pithub::Issues::Comments->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Comments';
 
@@ -251,7 +251,7 @@ BEGIN {
 
 # Pithub::Issues::Comments->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Comments';
 
@@ -277,7 +277,7 @@ BEGIN {
 
 # Pithub::Issues::Events->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Events', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Events', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Events';
 
@@ -294,7 +294,7 @@ BEGIN {
 
 # Pithub::Issues::Events->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Events', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Events', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Events';
 
@@ -317,7 +317,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->add
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -345,7 +345,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -372,7 +372,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -392,7 +392,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -409,7 +409,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -440,7 +440,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->remove
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -470,7 +470,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->replace
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -498,7 +498,7 @@ BEGIN {
 
 # Pithub::Issues::Labels->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Labels', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Labels';
 
@@ -526,7 +526,7 @@ BEGIN {
 
 # Pithub::Issues::Milestones->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Milestones';
 
@@ -556,7 +556,7 @@ BEGIN {
 
 # Pithub::Issues::Milestones->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Milestones';
 
@@ -576,7 +576,7 @@ BEGIN {
 
 # Pithub::Issues::Milestones->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Milestones';
 
@@ -593,7 +593,7 @@ BEGIN {
 
 # Pithub::Issues::Milestones->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Milestones';
 
@@ -608,7 +608,7 @@ BEGIN {
 
 # Pithub::Issues::Milestones->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Issues::Milestones', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Issues::Milestones';
 
@@ -0,0 +1,22 @@
+package    # hide from PAUSE
+  Pithub::Test::Factory;
+
+use strict;
+use warnings;
+use Pithub::Test::UA;
+
+sub create {
+    my ( $self, $class, %args ) = @_;
+    return $class->new( ua => Pithub::Test::UA->new, %args );
+}
+
+sub test_account {
+    return {
+        org      => 'buhtip-org',
+        org_repo => 'buhtip-org-repo',
+        repo     => 'buhtip-repo',
+        user     => 'buhtip',
+    };
+}
+
+1;
@@ -2,25 +2,28 @@ package    # hide from PAUSE
   Pithub::Test::UA;
 
 use Moo;
-use File::Basename qw(dirname);
-use File::Slurp qw(read_file);
+use Path::Tiny;
 use HTTP::Response;
 use Test::More;
 
+my @responses;
+
+sub add_response {
+    my ( $self, $path ) = @_;
+    my $full_path = sprintf '%s/http_response/api.github.com/%s', path(__FILE__)->dirname, $path;
+    my $response_string = path($full_path)->slurp;
+    my $response = HTTP::Response->parse($response_string);
+    push @responses, $response;
+}
+
 sub request {
     my ( $self, $request ) = @_;
-    my $path = sprintf '%s/http_response/%s/%s.%s', dirname(__FILE__), $request->uri->host, $request->uri->path, $request->method;
-    my %query_form = $request->uri->query_form;
-    foreach my $k ( sort keys %query_form ) {
-        $path .= sprintf '.%s-%s', $k, $query_form{$k};
-    }
-    my $response = HTTP::Response->new;
-    if ( -f $path ) {
-        my $res = read_file($path);
-        $response = HTTP::Response->parse($res);
+    my $result = HTTP::Response->new;
+    if ( my $response = shift(@responses) ) {
+        $result = $response;
     }
-    $response->request($request);
-    return $response;
+    $result->request($request);
+    return $result;
 }
 
 1;
@@ -1,22 +1,56 @@
-package    # hide from PAUSE
-  Pithub::Test;
+package Pithub::Test;
 
-use strict;
-use warnings;
-use Pithub::Test::UA;
+use Import::Into;
+use Test::Most;
 
-sub create {
-    my ( $self, $class, %args ) = @_;
-    return $class->new( ua => Pithub::Test::UA->new, %args );
+BEGIN {
+    require Exporter;
+    our @ISA    = qw(Exporter);
+    our @EXPORT = qw(uri_is);
 }
 
-sub test_account {
-    return {
-        org      => 'buhtip-org',
-        org_repo => 'buhtip-org-repo',
-        repo     => 'buhtip-repo',
-        user     => 'buhtip',
-    };
+sub import {
+    my $class  = shift;
+    my $caller = caller;
+
+    Test::Most->import::into($caller);
+
+    $class->export_to_level(1, @_);
+}
+
+sub uri_is {
+    my($have, $want, $name) = @_;
+
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+    $have = _make_uri($have);
+    $want = _make_uri($want);
+
+    for my $method (qw(scheme authority path fragment)) {
+        my $have_val = $have->$method;
+        my $want_val = $want->$method;
+
+        next if !defined $have_val && !defined $want_val;
+        if( (defined $have_val xor defined $want_val) ||
+            ($have_val ne $want_val)
+        ) {
+            return is( $have, $want, $name ) || diag "$method does not match";
+        }
+    }
+
+    my %have_queries = $have->query_form;
+    my %want_queries = $want->query_form;
+    return eq_or_diff( \%have_queries, \%want_queries, $name ) ||
+             diag "$have ne $want, queries do not match";
+}
+
+sub _make_uri {
+    my $uri = shift;
+
+    return $uri if ref $uri && $uri->isa("URI");
+
+    require URI;
+    return URI->new($uri);
 }
 
 1;
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -17,9 +17,41 @@ SKIP: {
         path   => '/'
     );
 
-    is $result->code,        200,  'HTTP status is 200';
-    is $result->success,     1,    'Successful';
-    is $result->raw_content, '{"current_user_url":"https://api.github.com/user","authorizations_url":"https://api.github.com/authorizations","emails_url":"https://api.github.com/user/emails","emojis_url":"https://api.github.com/emojis","events_url":"https://api.github.com/events","feeds_url":"https://api.github.com/feeds","following_url":"https://api.github.com/user/following{/target}","gists_url":"https://api.github.com/gists{/gist_id}","hub_url":"https://api.github.com/hub","issue_search_url":"https://api.github.com/legacy/issues/search/{owner}/{repo}/{state}/{keyword}","issues_url":"https://api.github.com/issues","keys_url":"https://api.github.com/user/keys","notifications_url":"https://api.github.com/notifications","organization_repositories_url":"https://api.github.com/orgs/{org}/repos/{?type,page,per_page,sort}","organization_url":"https://api.github.com/orgs/{org}","public_gists_url":"https://api.github.com/gists/public","rate_limit_url":"https://api.github.com/rate_limit","repository_url":"https://api.github.com/repos/{owner}/{repo}","repository_search_url":"https://api.github.com/legacy/repos/search/{keyword}{?language,start_page}","current_user_repositories_url":"https://api.github.com/user/repos{?type,page,per_page,sort}","starred_url":"https://api.github.com/user/starred{/owner}{/repo}","starred_gists_url":"https://api.github.com/gists/starred","team_url":"https://api.github.com/teams","user_url":"https://api.github.com/users/{user}","user_organizations_url":"https://api.github.com/user/orgs","user_repositories_url":"https://api.github.com/users/{user}/repos{?type,page,per_page,sort}","user_search_url":"https://api.github.com/legacy/user/search/{keyword}"}', 'Empty response';
+    is $result->code,        200,               'HTTP status is 200';
+    is $result->success,     1,                 'Successful';
+    like $result->etag,      qr{^"[a-f0-9]+"$}, 'ETag';
+
+    cmp_deeply $result->content, subhashof({
+        "current_user_url" => "https://api.github.com/user",
+        "authorizations_url" => "https://api.github.com/authorizations",
+        "code_search_url" => "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
+        "emails_url" => "https://api.github.com/user/emails",
+        "emojis_url" => "https://api.github.com/emojis",
+        "events_url" => "https://api.github.com/events",
+        "feeds_url" => "https://api.github.com/feeds",
+        "following_url" => "https://api.github.com/user/following{/target}",
+        "gists_url" => "https://api.github.com/gists{/gist_id}",
+        "hub_url" => "https://api.github.com/hub",
+        "issue_search_url" => "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}",
+        "issues_url" => "https://api.github.com/issues",
+        "keys_url" => "https://api.github.com/user/keys",
+        "notifications_url" => "https://api.github.com/notifications",
+        "organization_repositories_url" => "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}",
+        "organization_url" => "https://api.github.com/orgs/{org}",
+        "public_gists_url" => "https://api.github.com/gists/public",
+        "rate_limit_url" => "https://api.github.com/rate_limit",
+        "repository_url" => "https://api.github.com/repos/{owner}/{repo}",
+        "repository_search_url" => "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
+        "current_user_repositories_url" => "https://api.github.com/user/repos{?type,page,per_page,sort}",
+        "starred_url" => "https://api.github.com/user/starred{/owner}{/repo}",
+        "starred_gists_url" => "https://api.github.com/gists/starred",
+        "team_url" => "https://api.github.com/teams",
+        "user_url" => "https://api.github.com/users/{user}",
+        "user_organizations_url" => "https://api.github.com/user/orgs",
+        "user_repositories_url" => "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}",
+        "user_search_url" => "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"
+    }),
+    'Empty response';
 }
 
 # These tests may break very easily because data on Github can and will change, of course.
@@ -0,0 +1,46 @@
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+use Pithub;
+use Scalar::Util qw(refaddr);
+use Test::Most;
+
+plan skip_all => 'Set PITHUB_TEST_LIVE to true to run these tests' unless $ENV{PITHUB_TEST_LIVE};
+
+subtest "cached result" => sub {
+    my $p = Pithub->new;
+    my $result1 = $p->request(
+        method  => 'GET',
+        path    => '/'
+    );
+
+    my $result2 = $p->request(
+        method  => 'GET',
+        path    => '/'
+    );
+
+    is $result1->etag, $result2->etag;
+    is refaddr $result1->response, refaddr $result2->response;
+};
+
+
+subtest "lru" => sub {
+    my $p = Pithub->new;
+
+    # Reduce the cache size to just two elements for easier testing
+    $p->set_shared_cache( Cache::LRU->new( size => 2 ) );
+
+    # Get two items to fill the cache
+    my $repo_pithub = $p->repos->get( user => 'plu', repo => 'Pithub' );
+    my $user_plu    = $p->users->get( user => 'plu' );
+
+    # Get a third to bump $repo_pithub out
+    my $branches = $p->repos->branches( user => 'plu', repo => 'Pithub', per_page => 1 );
+
+    # Get $repo_pithub again, it should not be cached.
+    my $repo_pithub2 = $p->repos->get( user => 'plu', repo => 'Pithub' );
+    note "ETags @{[$repo_pithub->etag]} - @{[$repo_pithub2->etag]}";
+    isnt refaddr $repo_pithub->response, refaddr $repo_pithub2->response;
+};
+
+
+done_testing;
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -70,10 +70,10 @@ SKIP: {
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
     my $p        = Pithub->new(
         user  => $user,
         repo  => $repo,
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -27,7 +27,7 @@ SKIP: {
         is $result->success, 1, 'Pithub::Gists->list successful';
         while ( my $row = $result->next ) {
             ok $row->{id}, "Pithub::Gists->list has id: $row->{id}";
-            like $row->{url}, qr{https://api.github.com/gists/\d+$}, "Pithub::Gists->list has url: $row->{url}";
+            like $row->{url}, qr{https://api.github.com/gists/[a-f\d]+$}, "Pithub::Gists->list has url: $row->{url}";
         }
     }
 
@@ -37,7 +37,7 @@ SKIP: {
         is $result->success, 1, 'Pithub::Gists::Comments->list successful';
         while ( my $row = $result->next ) {
             ok $row->{id}, "Pithub::Gists::Comments->list has id: $row->{id}";
-            like $row->{url}, qr{https://api.github.com/gists/\d+/comments/\d+$}, "Pithub::Gists::Comments->list has url: $row->{url}";
+            like $row->{url}, qr{https://api.github.com/gists/[a-f\d]+/comments/\d+$}, "Pithub::Gists::Comments->list has url: $row->{url}";
         }
     }
 }
@@ -47,10 +47,10 @@ SKIP: {
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
     my $p        = Pithub->new(
         user  => $user,
         repo  => $repo,
@@ -100,21 +100,21 @@ SKIP: {
         like $comment_id, qr{^\d+$}, 'Pithub::Gists::Comments->create returned a comment id';
 
         # Pithub::Gists::Comments->get
-        is $p->gists->comments->get( comment_id => $comment_id )->content->{body}, 'some gist comment', 'Pithub::Gists::Comments->get body';
+        is $p->gists->comments->get( gist_id => $gist_id, comment_id => $comment_id )->content->{body}, 'some gist comment', 'Pithub::Gists::Comments->get body';
 
         # Pithub::Gists::Comments->update
-        ok $p->gists->comments->update( comment_id => $comment_id, data => { body => 'some UPDATED gist comment' } )->success,
+        ok $p->gists->comments->update( gist_id => $gist_id, comment_id => $comment_id, data => { body => 'some UPDATED gist comment' } )->success,
           'Pithub::Gists::Comments->update successful';
 
         # Pithub::Gists::Comments->get
-        is $p->gists->comments->get( comment_id => $comment_id )->content->{body}, 'some UPDATED gist comment',
+        is $p->gists->comments->get( gist_id => $gist_id, comment_id => $comment_id )->content->{body}, 'some UPDATED gist comment',
           'Pithub::Gists::Comments->get body after update';
 
         # Pithub::Gists::Comments->delete
-        ok $p->gists->comments->delete( comment_id => $comment_id )->success, 'Pithub::Gists::Comments->delete successful';
+        ok $p->gists->comments->delete( gist_id => $gist_id, comment_id => $comment_id )->success, 'Pithub::Gists::Comments->delete successful';
 
         # Pithub::Gists::Comments->get
-        ok !$p->gists->comments->get( comment_id => $comment_id )->success, 'Pithub::Gists::Comments->get not successful after delete';
+        ok !$p->gists->comments->get( gist_id => $gist_id, comment_id => $comment_id )->success, 'Pithub::Gists::Comments->get not successful after delete';
 
         # Pithub::Gists->delete
         ok $p->gists->delete( gist_id => $gist_id )->success, 'Pithub::Gists->delete successful';
@@ -1,7 +1,8 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
+use JSON::MaybeXS;
 
 BEGIN {
     use_ok('Pithub');
@@ -49,10 +50,10 @@ c3QgcmVsZWFzZQo=
                 'name'  => 'Johannes Plunien'
             },
             'message' => "Add Changes file.",
-            'html_url' => 'https://github.com/plu/Pithub/commits/20f946f933a911253e480eb0e9feced1e36dbd45',
+            'html_url' => 'https://github.com/plu/Pithub/commit/20f946f933a911253e480eb0e9feced1e36dbd45',
             'parents' => [
                 {
-                    'html_url' => 'https://github.com/plu/Pithub/commits/9616d4f1515bf4de1a32f85a8fa1b1cc441da164',
+                    'html_url' => 'https://github.com/plu/Pithub/commit/9616d4f1515bf4de1a32f85a8fa1b1cc441da164',
                     'sha' => '9616d4f1515bf4de1a32f85a8fa1b1cc441da164',
                     'url' => 'https://api.github.com/repos/plu/Pithub/git/commits/9616d4f1515bf4de1a32f85a8fa1b1cc441da164'
                 }
@@ -145,7 +146,8 @@ c3QgcmVsZWFzZQo=
                     'url'  => 'https://api.github.com/repos/plu/Pithub/git/trees/7d2b61bafb9a703b393af386e4bcc350ad2c9aa9'
                 }
             ],
-            'url' => 'https://api.github.com/repos/plu/Pithub/git/trees/7331484696162bf7b5c97de488fd2c1289fd175c'
+            'url' => 'https://api.github.com/repos/plu/Pithub/git/trees/7331484696162bf7b5c97de488fd2c1289fd175c',
+            truncated => JSON->false,
           },
           'Pithub::GitData::Trees->get content';
 
@@ -187,6 +189,7 @@ c3QgcmVsZWFzZQo=
                     'url'  => 'https://api.github.com/repos/plu/Pithub/git/blobs/b493b43e8016b86550c065fcf83df537052ad371'
                 }
             ],
+            truncated => JSON->false,
             'url' => 'https://api.github.com/repos/plu/Pithub/git/trees/7331484696162bf7b5c97de488fd2c1289fd175c'
           },
           'Pithub::GitData::Trees->get content recursive';
@@ -198,10 +201,10 @@ c3QgcmVsZWFzZQo=
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
     my $p        = Pithub->new(
         user  => $user,
         repo  => $repo,
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -69,10 +69,10 @@ SKIP: {
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
     my $p        = Pithub->new(
         user  => $user,
         repo  => $repo,
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -49,10 +49,10 @@ SKIP: {
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
     my $p        = Pithub->new(
         user  => $user,
         repo  => $repo,
@@ -119,6 +119,10 @@ SKIP: {
             user => $user,
         )->count, 1, 'Pithub::Orgs::Members->list one member';
 
+        foreach my $team (@{ $p->orgs->teams->list( org => $org )->content }) {
+            $p->orgs->teams->delete( team_id => $team->{id} );
+        }
+
         # Pithub::Orgs::Teams->create
         my $team_id = $p->orgs->teams->create(
             org  => $org,
@@ -128,7 +132,7 @@ SKIP: {
 
         # Pithub::Orgs::Teams->list
         my @teams = splice @{ $p->orgs->teams->list( org => $org )->content }, 0, 2;
-        eq_or_diff [ map { $_->{name} } @teams ], [qw(Core Owners)], 'Pithub::Orgs::Teams->list after create';
+        eq_or_diff [ sort map { $_->{name} } @teams ], [sort qw(Core Owners)], 'Pithub::Orgs::Teams->list after create';
 
         # Pithub::Orgs::Teams->update
         ok $p->orgs->teams->update(
@@ -181,7 +185,8 @@ SKIP: {
         # Pithub::Orgs::Teams->add_repo
         ok $p->orgs->teams->add_repo(
             team_id => $team_id,
-            repo    => "${org}/${org_repo}",
+            org     => $org,
+            repo    => $org_repo,
         )->success, 'Pithub::Orgs::Teams->add_repo successful';
 
         # Pithub::Orgs::Teams->has_repo
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -12,10 +12,10 @@ BEGIN {
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
 
     # Attention! Here we use $org and $org_repo
     my $p = Pithub->new(
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -19,7 +19,8 @@ SKIP: {
         my $result = $p->repos->branches( user => 'plu', repo => 'Pithub' );
         is $result->success, 1, 'Pithub::Repos->branches successful';
         ok $result->count > 0, 'Pithub::Repos->branches has some rows';
-        is $result->content->[0]{name}, 'master', 'Pithub::Repos->branches: Attribute name'
+        ok $result->content->[0]{name};
+        like $result->content->[0]{commit}{sha}, qr{^[a-f0-9]+$};
     }
 
     # Pithub::Repos->contributors
@@ -37,6 +38,17 @@ SKIP: {
         is $result->content->{owner}{login}, 'plu', 'Pithub::Repos->get: Attribute owner.login';
     }
 
+    subtest "Pithub::Repos->branch" => sub {
+        my $result = $p->repos->branch(
+            user        => 'plu',
+            repo        => 'Pithub',
+            branch      => 'master'
+        );
+        ok $result->success;
+        is $result->content->{name}, 'master';
+        like $result->content->{commit}{sha}, qr{^[a-f0-9]+$};
+    };
+
     # Pithub::Repos->languages
     {
         my $result = $p->repos->languages( user => 'plu', repo => 'Pithub' );
@@ -143,10 +155,10 @@ SKIP: {
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
     my $p        = Pithub->new(
         user  => $user,
         repo  => $repo,
@@ -194,13 +206,11 @@ SKIP: {
     }
 
     {
-        require File::Basename;
-
         # Pithub::Repos::Downloads->create
         my $result = $p->repos->downloads->create(
             data => {
-                name         => File::Basename::basename(__FILE__),
-                size         => ( stat(__FILE__) )[7],
+                name         => path(__FILE__)->basename,
+                size         => -s __FILE__,
                 description  => 'This test (t/live.t)',
                 content_type => 'text/plain',
             },
@@ -242,15 +252,6 @@ SKIP: {
         # Pithub::Repos::Keys->list
         is $p->repos->keys->list->first->{title}, 'someone@somewhere', 'Pithub::Repos::Keys->list title attribute';
 
-        # Pithub::Repos::Keys->update
-        ok $p->repos->keys->update(
-            key_id => $key_id,
-            data   => { title => 'someone@somewhereelse' }
-        )->success, 'Pithub::Repos::Keys->update successful';
-
-        # Pithub::Repos::Keys->get
-        is $p->repos->keys->get( key_id => $key_id )->content->{title}, 'someone@somewhereelse', 'Pithub::Repos::Keys->get title attribute after update';
-
         # Pithub::Repos::Keys->delete
         ok $p->repos->keys->delete( key_id => $key_id )->success, 'Pithub::Repos::Keys->delete successful';
 
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/../lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -29,10 +29,10 @@ SKIP: {
 SKIP: {
     skip 'PITHUB_TEST_TOKEN required to run this test - DO NOT DO THIS UNLESS YOU KNOW WHAT YOU ARE DOING', 1 unless $ENV{PITHUB_TEST_TOKEN};
 
-    my $org      = Pithub::Test->test_account->{org};
-    my $org_repo = Pithub::Test->test_account->{org_repo};
-    my $repo     = Pithub::Test->test_account->{repo};
-    my $user     = Pithub::Test->test_account->{user};
+    my $org      = Pithub::Test::Factory->test_account->{org};
+    my $org_repo = Pithub::Test::Factory->test_account->{org_repo};
+    my $repo     = Pithub::Test::Factory->test_account->{repo};
+    my $user     = Pithub::Test::Factory->test_account->{user};
     my $p        = Pithub->new(
         user  => $user,
         repo  => $repo,
@@ -45,7 +45,7 @@ SKIP: {
         my $key_id = $p->users->keys->create(
             data => {
                 title => 'someone@somewhere',
-                key   => "ssh-rsa C0FF33$$",
+                key   => "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuK40Ng6C0NfMrrVuE+6mkUyj90JcvPdwrqFi/tv4g5Ncny5FCkEMATmYA0NtByAS+2p+jwClbVI9dav077+DxHJbwDwcecXXqjUA4gnZM+03kksPbTjfuYql9nC8PdhgZ3kiftop7AVZZnhSKF5stLwa0hkCZkXVeaajQzaG1pCnJJNOcnaRPcuEkTToTnkw8y3Q3fpuMmRjz3NCayh/gJgcj/EtrextqnNpDT4j4r3IeCGvCMEtmUvepKG6sTdnh1EDX5U163is9Qnwfdo3D7CVUh2rhJ8pM6RnAbqbzWqQ+gbhWoXQ7T1Qdq1GXKN7lMMbjz9M7cPK3Vs0p5yl1",
             }
         )->content->{id};
 
@@ -55,15 +55,6 @@ SKIP: {
         # Pithub::Users::Keys->list
         is $p->users->keys->list->first->{title}, 'someone@somewhere', 'Pithub::Users::Keys->list title attribute';
 
-        # Pithub::Users::Keys->update
-        ok $p->users->keys->update(
-            key_id => $key_id,
-            data   => { title => 'someone@somewhereelse' }
-        )->success, 'Pithub::Users::Keys->update successful';
-
-        # Pithub::Users::Keys->get
-        is $p->users->keys->get( key_id => $key_id )->content->{title}, 'someone@somewhereelse', 'Pithub::Users::Keys->get title attribute after update';
-
         # Pithub::Users::Keys->delete
         ok $p->users->keys->delete( key_id => $key_id )->success, 'Pithub::Users::Keys->delete successful';
 
@@ -77,7 +68,7 @@ SKIP: {
         ok $p->users->emails->add( data => ['johannes@plunien.name'] )->success, 'Pithub::Users::Emails->add successful';
 
         # Pithub::Users::Emails->list
-        is $p->users->emails->list->content->[-1], 'johannes@plunien.name', 'Pithub::Users::Emails->list recently added email address';
+        is $p->users->emails->list->content->[0]->{email}, 'johannes@plunien.name', 'Pithub::Users::Emails->list recently added email address';
 
         # Pithub::Users::Emails->delete
         ok $p->users->emails->delete( data => ['johannes@plunien.name'] )->success, 'Pithub::Users::Emails->delete successful';
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 # branches.t
@@ -107,7 +107,7 @@ my @tests = (
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->pull_requests->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->pull_requests->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/pulls',
     tests => \@tests,
@@ -116,7 +116,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::PullRequests', %$c_args )->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::PullRequests', %$c_args )->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/pulls',
     tests => \@tests,
@@ -125,7 +125,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->collaborators->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->collaborators->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/collaborators',
     tests => \@tests,
@@ -134,7 +134,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->collaborators->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->collaborators->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/collaborators',
     tests => \@tests,
@@ -143,7 +143,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos::Collaborators', %$c_args )->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos::Collaborators', %$c_args )->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/collaborators',
     tests => \@tests,
@@ -152,7 +152,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->commits->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->commits->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/commits',
     tests => \@tests,
@@ -161,7 +161,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->commits->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->commits->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/commits',
     tests => \@tests,
@@ -170,7 +170,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos::Commits', %$c_args )->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos::Commits', %$c_args )->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/commits',
     tests => \@tests,
@@ -179,7 +179,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->downloads->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->downloads->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/downloads',
     tests => \@tests,
@@ -188,7 +188,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->downloads->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->downloads->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/downloads',
     tests => \@tests,
@@ -197,7 +197,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos::Downloads', %$c_args )->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos::Downloads', %$c_args )->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/downloads',
     tests => \@tests,
@@ -206,7 +206,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->forks->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->forks->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/forks',
     tests => \@tests,
@@ -215,7 +215,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->forks->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->forks->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/forks',
     tests => \@tests,
@@ -224,7 +224,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos::Forks', %$c_args )->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos::Forks', %$c_args )->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/forks',
     tests => \@tests,
@@ -233,7 +233,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->keys->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->keys->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/keys',
     tests => \@tests,
@@ -242,7 +242,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->keys->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->keys->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/keys',
     tests => \@tests,
@@ -251,7 +251,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos::Keys', %$c_args )->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos::Keys', %$c_args )->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/keys',
     tests => \@tests,
@@ -260,7 +260,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->watching->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->watching->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/watchers',
     tests => \@tests,
@@ -269,7 +269,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->watching->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->watching->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/watchers',
     tests => \@tests,
@@ -278,7 +278,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos::Watching', %$c_args )->list(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos::Watching', %$c_args )->list(%$m_args);
     },
     path  => '/repos/plu/Pithub/watchers',
     tests => \@tests,
@@ -287,7 +287,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->branches(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->branches(%$m_args);
     },
     path  => '/repos/plu/Pithub/branches',
     tests => \@tests,
@@ -296,7 +296,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->branches(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->branches(%$m_args);
     },
     path  => '/repos/plu/Pithub/branches',
     tests => \@tests,
@@ -305,7 +305,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->contributors(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->contributors(%$m_args);
     },
     path  => '/repos/plu/Pithub/contributors',
     tests => \@tests,
@@ -314,7 +314,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->contributors(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->contributors(%$m_args);
     },
     path  => '/repos/plu/Pithub/contributors',
     tests => \@tests,
@@ -323,7 +323,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->languages(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->languages(%$m_args);
     },
     path  => '/repos/plu/Pithub/languages',
     tests => \@tests,
@@ -332,7 +332,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->languages(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->languages(%$m_args);
     },
     path  => '/repos/plu/Pithub/languages',
     tests => \@tests,
@@ -341,7 +341,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->tags(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->tags(%$m_args);
     },
     path  => '/repos/plu/Pithub/tags',
     tests => \@tests,
@@ -350,7 +350,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->tags(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->tags(%$m_args);
     },
     path  => '/repos/plu/Pithub/tags',
     tests => \@tests,
@@ -359,7 +359,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub', %$c_args )->repos->teams(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub', %$c_args )->repos->teams(%$m_args);
     },
     path  => '/repos/plu/Pithub/teams',
     tests => \@tests,
@@ -368,7 +368,7 @@ test(
 test(
     code => sub {
         my ( $c_args, $m_args ) = @_;
-        return Pithub::Test->create( 'Pithub::Repos', %$c_args )->teams(%$m_args);
+        return Pithub::Test::Factory->create( 'Pithub::Repos', %$c_args )->teams(%$m_args);
     },
     path  => '/repos/plu/Pithub/teams',
     tests => \@tests,
@@ -1,7 +1,7 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
-use Pithub::Test;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Test::Most;
 use MIME::Base64 qw();
 
@@ -13,7 +13,7 @@ BEGIN {
 
 # Pithub::Orgs->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Orgs', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Orgs', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Orgs';
 
@@ -30,7 +30,7 @@ BEGIN {
 
 # Pithub::Orgs->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Orgs', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Orgs', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Orgs';
 
@@ -77,7 +77,7 @@ BEGIN {
 
 # Pithub::Orgs->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Orgs', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Orgs', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Orgs';
 
@@ -119,7 +119,7 @@ BEGIN {
 
 # Pithub::Orgs::Members->conceal
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Members');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Members');
 
     isa_ok $obj, 'Pithub::Orgs::Members';
 
@@ -140,7 +140,7 @@ BEGIN {
 
 # Pithub::Orgs::Members->delete
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Members');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Members');
 
     isa_ok $obj, 'Pithub::Orgs::Members';
 
@@ -161,7 +161,7 @@ BEGIN {
 
 # Pithub::Orgs::Members->is_member
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Members');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Members');
 
     isa_ok $obj, 'Pithub::Orgs::Members';
 
@@ -182,7 +182,7 @@ BEGIN {
 
 # Pithub::Orgs::Members->is_public
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Members');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Members');
 
     isa_ok $obj, 'Pithub::Orgs::Members';
 
@@ -202,7 +202,7 @@ BEGIN {
 
 # Pithub::Orgs::Members->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Orgs::Members', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Orgs::Members', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Orgs::Members';
 
@@ -219,7 +219,7 @@ BEGIN {
 
 # Pithub::Orgs::Members->list_public
 {
-    my $obj = Pithub::Test->create( 'Pithub::Orgs::Members', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Orgs::Members', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Orgs::Members';
 
@@ -236,7 +236,7 @@ BEGIN {
 
 # Pithub::Orgs::Members->publicize
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Members');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Members');
 
     isa_ok $obj, 'Pithub::Orgs::Members';
 
@@ -257,7 +257,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->add_member
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -278,7 +278,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->add_repo
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -300,7 +300,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->create
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -330,7 +330,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->delete
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -350,7 +350,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->get
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -370,7 +370,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->has_repo
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -391,7 +391,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->is_member
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -412,7 +412,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->list
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -432,7 +432,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->list_members
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -452,7 +452,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->list_repos
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -472,7 +472,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->remove_member
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -493,7 +493,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->remove_repo
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -514,7 +514,7 @@ BEGIN {
 
 # Pithub::Orgs::Teams->update
 {
-    my $obj = Pithub::Test->create('Pithub::Orgs::Teams');
+    my $obj = Pithub::Test::Factory->create('Pithub::Orgs::Teams');
 
     isa_ok $obj, 'Pithub::Orgs::Teams';
 
@@ -1,7 +1,7 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
-use Pithub::Test;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -11,7 +11,7 @@ BEGIN {
 
 # Pithub::PullRequests->commits
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
 
     throws_ok { $obj->commits } qr{Missing key in parameters: pull_request_id}, 'No parameters';
 
@@ -28,7 +28,7 @@ BEGIN {
 
 # Pithub::PullRequests->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests';
 
@@ -57,7 +57,7 @@ BEGIN {
 
 # Pithub::PullRequests->files
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
 
     throws_ok { $obj->files } qr{Missing key in parameters: pull_request_id}, 'No parameters';
 
@@ -74,7 +74,7 @@ BEGIN {
 
 # Pithub::PullRequests->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
 
     throws_ok { $obj->get } qr{Missing key in parameters: pull_request_id}, 'No parameters';
 
@@ -91,7 +91,7 @@ BEGIN {
 
 # Pithub::PullRequests->is_merged
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
 
     throws_ok { $obj->is_merged } qr{Missing key in parameters: pull_request_id}, 'No parameters';
 
@@ -108,7 +108,7 @@ BEGIN {
 
 # Pithub::PullRequests->merge
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests';
 
@@ -128,7 +128,7 @@ BEGIN {
 
 # Pithub::PullRequests->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests';
 
@@ -159,7 +159,7 @@ BEGIN {
 
 # Pithub::PullRequests::Comments->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests::Comments';
 
@@ -185,7 +185,7 @@ BEGIN {
 
 # Pithub::PullRequests::Comments->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests::Comments';
 
@@ -205,7 +205,7 @@ BEGIN {
 
 # Pithub::PullRequests::Comments->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests::Comments';
 
@@ -222,7 +222,7 @@ BEGIN {
 
 # Pithub::PullRequests::Comments->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests::Comments';
 
@@ -239,7 +239,7 @@ BEGIN {
 
 # Pithub::PullRequests::Comments->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::PullRequests::Comments', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::PullRequests::Comments';
 
@@ -1,8 +1,8 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Pithub::Test;
-use Test::Most;
 
 BEGIN {
     use_ok('Pithub::Repos');
@@ -22,7 +22,7 @@ BEGIN {
 
 # Pithub::Repos->create
 {
-    my $obj = Pithub::Test->create('Pithub::Repos');
+    my $obj = Pithub::Test::Factory->create('Pithub::Repos');
 
     isa_ok $obj, 'Pithub::Repos';
 
@@ -51,9 +51,25 @@ BEGIN {
     }
 }
 
+
+subtest "Pithub::Repos->delete" => sub {
+    my $obj = Pithub::Test::Factory->create('Pithub::Repos');
+    throws_ok { $obj->delete }
+      qr{^Missing key in parameters: user};
+    throws_ok { $obj->delete( user => "foobarorg" ); }
+      qr{^Missing key in parameters: repo};
+    throws_ok { $obj->delete( user => "foobarorg", repo => "blahblah" ); }
+      qr{^Access token required for: DELETE /repos/foobarorg/blahblah};
+
+    $obj->token(123);
+    my $result = $obj->delete( user => "foobarorg", repo => "blahblah" );
+    is $result->request->method, "DELETE";
+    uri_is $result->request->uri, "https://api.github.com/repos/foobarorg/blahblah?per_page=100";
+};
+
 # Pithub::Repos->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos';
 
@@ -66,9 +82,34 @@ BEGIN {
     }
 }
 
+
+subtest "Pithub::Repos->branch" => sub {
+    my $obj = Pithub::Test::Factory->create(
+        'Pithub::Repos',
+        user => 'foo',
+        repo => 'bar'
+    );
+
+    isa_ok $obj, 'Pithub::Repos';
+
+    subtest "too few arguments" => sub {
+        throws_ok { $obj->branch } qr/^Missing key in parameters: branch/;
+    };
+
+    subtest "basic get branch" => sub {
+        my $result = $obj->branch( branch => "master" );
+        is $result->request->method, 'GET', 'HTTP method';
+        is $result->request->uri->path, '/repos/foo/bar/branches/master', 'HTTP path';
+        my $http_request = $result->request;
+        is $http_request->content, '', 'HTTP body';
+    };
+};
+
 # Pithub::Repos->list
 {
-    my $obj = Pithub::Test->create('Pithub::Repos');
+    my $obj = Pithub::Test::Factory->create('Pithub::Repos');
+    $obj->ua->add_response('users/plu/repos.GET');
+    $obj->ua->add_response('orgs/CPAN-API/repos.GET');
 
     isa_ok $obj, 'Pithub::Repos';
 
@@ -112,7 +153,7 @@ BEGIN {
 
 # Pithub::Repos->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos';
 
@@ -133,7 +174,7 @@ BEGIN {
 
 # Pithub::Repos::Collaborators->add
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Collaborators', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Collaborators', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Collaborators';
 
@@ -149,7 +190,7 @@ BEGIN {
 
 # Pithub::Repos::Collaborators->is_collaborator
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Collaborators', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Collaborators', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Collaborators';
 
@@ -166,7 +207,7 @@ BEGIN {
 
 # Pithub::Repos::Collaborators->remove
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Collaborators', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Collaborators', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Collaborators';
 
@@ -182,7 +223,7 @@ BEGIN {
 
 # Pithub::Repos::Commits->compare
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Commits';
 
@@ -198,7 +239,7 @@ BEGIN {
 
 # Pithub::Repos::Commits->create_comment
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Commits';
 
@@ -224,7 +265,7 @@ BEGIN {
 
 # Pithub::Repos::Commits->delete_comment
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Commits';
 
@@ -242,7 +283,7 @@ BEGIN {
 
 # Pithub::Repos::Commits->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Commits';
 
@@ -257,7 +298,7 @@ BEGIN {
 
 # Pithub::Repos::Commits->get_comment
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Commits';
 
@@ -272,7 +313,7 @@ BEGIN {
 
 # Pithub::Repos::Commits->list_comments
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Commits';
 
@@ -291,7 +332,7 @@ BEGIN {
 
 # Pithub::Repos::Commits->update_comment
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Commits', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Commits';
 
@@ -315,7 +356,7 @@ BEGIN {
 
 # Pithub::Repos::Contents->archive
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Contents', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Contents', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Contents';
 
@@ -331,42 +372,39 @@ BEGIN {
 
 # Pithub::Repos::Contents->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Contents', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Contents', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Contents';
 
     {
         my $result = $obj->get( params => { ref => 'bla' } );
         is $result->request->method, 'GET', 'HTTP method';
-        is $result->request->uri->path, '/repos/foo/bar/contents', 'HTTP path';
-        is $result->request->uri->query, 'ref=bla', 'HTTP query params';
+        uri_is $result->request->uri, 'https://api.github.com/repos/foo/bar/contents?ref=bla&per_page=100';
     }
 
     {
         my $result = $obj->get( path => 'bla/fasel/file.pm', params => { ref => 'bla' } );
         is $result->request->method, 'GET', 'HTTP method';
-        is $result->request->uri->path, '/repos/foo/bar/contents/bla/fasel/file.pm', 'HTTP path';
-        is $result->request->uri->query, 'ref=bla', 'HTTP query params';
+        uri_is $result->request->uri, 'https://api.github.com/repos/foo/bar/contents/bla/fasel/file.pm?ref=bla&per_page=100';
     }
 }
 
 # Pithub::Repos::Contents->readme
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Contents', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Contents', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Contents';
 
     {
         my $result = $obj->readme( params => { ref => 'bla' } );
         is $result->request->method, 'GET', 'HTTP method';
-        is $result->request->uri->path, '/repos/foo/bar/readme', 'HTTP path';
-        is $result->request->uri->query, 'ref=bla', 'HTTP query params';
+        uri_is $result->request->uri, 'https://api.github.com/repos/foo/bar/readme?ref=bla&per_page=100';
     }
 }
 
 # Pithub::Repos::Downloads->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Downloads';
 
@@ -393,7 +431,7 @@ BEGIN {
 
 # Pithub::Repos::Downloads->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Downloads';
 
@@ -411,7 +449,7 @@ BEGIN {
 
 # Pithub::Repos::Downloads->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Downloads';
 
@@ -426,7 +464,8 @@ BEGIN {
 
 # Pithub::Repos::Downloads->upload
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Downloads', user => 'foo', repo => 'bar' );
+    $obj->ua->add_response('repos/foo/bar/downloads.POST');
 
     isa_ok $obj, 'Pithub::Repos::Downloads';
 
@@ -461,7 +500,7 @@ BEGIN {
 
 # Pithub::Repos::Forks->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Forks', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Forks', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Forks';
 
@@ -489,7 +528,7 @@ BEGIN {
 
 # Pithub::Repos::Keys->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Keys', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Keys', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Keys';
 
@@ -513,7 +552,7 @@ BEGIN {
 
 # Pithub::Repos::Keys->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Keys', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Keys', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Keys';
 
@@ -533,7 +572,7 @@ BEGIN {
 
 # Pithub::Repos::Keys->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Keys', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Keys', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Keys';
 
@@ -551,34 +590,9 @@ BEGIN {
     }
 }
 
-# Pithub::Repos::Keys->update
-{
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Keys', user => 'foo', repo => 'bar' );
-
-    isa_ok $obj, 'Pithub::Repos::Keys';
-
-    throws_ok { $obj->update } qr{Missing key in parameters: key_id}, 'No parameters';
-    throws_ok { $obj->update( key_id => 123 ) } qr{Missing key in parameters: data \(hashref\)}, 'No data parameter';
-    throws_ok {
-        $obj->update( key_id => 123, data => { title => 'some key' } );
-    }
-    qr{Access token required for: PATCH /repos/foo/bar/keys/123}, 'Token required';
-
-    ok $obj->token(123), 'Token set';
-
-    {
-        my $json = JSON->new;
-        my $result = $obj->update( key_id => 123, data => { title => 'some key' } );
-        is $result->request->method, 'PATCH', 'HTTP method';
-        is $result->request->uri->path, '/repos/foo/bar/keys/123', 'HTTP path';
-        my $http_request = $result->request;
-        eq_or_diff $json->decode( $http_request->content ), { 'title' => 'some key' }, 'HTTP body';
-    }
-}
-
 # Pithub::Repos::Releases->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases';
 
@@ -593,7 +607,7 @@ BEGIN {
 
 # Pithub::Repos::Releases->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases';
 
@@ -610,7 +624,7 @@ BEGIN {
 
 # Pithub::Repos::Releases->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases';
 
@@ -631,7 +645,7 @@ BEGIN {
 
 # Pithub::Repos::Releases->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases';
 
@@ -653,7 +667,7 @@ BEGIN {
 
 # Pithub::Repos::Releases->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases';
 
@@ -673,7 +687,7 @@ BEGIN {
 
 # Pithub::Repos::Releases::Assets->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases::Assets';
     throws_ok { $obj->create } qr{Missing key in parameters: name}, 'No parameters';
@@ -697,7 +711,7 @@ BEGIN {
 
 # Pithub::Repos::Releases::Assets->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases::Assets';
     throws_ok { $obj->delete } qr{Missing key in parameters: asset_id}, 'No parameters';
@@ -716,7 +730,7 @@ BEGIN {
 
 # Pithub::Repos::Releases::Assets->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases::Assets';
     throws_ok { $obj->get } qr{Missing key in parameters: asset_id}, 'No parameters';
@@ -734,7 +748,7 @@ BEGIN {
 
 # Pithub::Repos::Releases::Assets->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
 
     throws_ok { $obj->list } qr{Missing key in parameters: release_id}, 'No parameters';
 
@@ -752,7 +766,7 @@ BEGIN {
 # Pithub::Repos::Releases::Assets->update
 {
     my $json = JSON->new;
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Releases::Assets', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Releases::Assets';
     throws_ok { $obj->update } qr{Missing key in parameters: asset_id}, 'No parameters';
@@ -773,7 +787,7 @@ BEGIN {
 
 # Pithub::Repos::Starring->has_watching
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Starring';
 
@@ -792,7 +806,7 @@ BEGIN {
 
 # Pithub::Repos::Starring->list_repos
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Starring';
 
@@ -816,7 +830,7 @@ BEGIN {
 
 # Pithub::Repos::Starring->star
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Starring';
 
@@ -835,7 +849,7 @@ BEGIN {
 
 # Pithub::Repos::Starring->unstar
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Starring', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Starring';
 
@@ -854,7 +868,7 @@ BEGIN {
 
 # Pithub::Repos::Watching->is_watching
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Watching';
 
@@ -873,7 +887,7 @@ BEGIN {
 
 # Pithub::Repos::Watching->list_repos
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Watching';
 
@@ -899,7 +913,7 @@ BEGIN {
 
 # Pithub::Repos::Watching->start_watching
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Watching';
 
@@ -918,7 +932,7 @@ BEGIN {
 
 # Pithub::Repos::Watching->stop_watching
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Watching', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Watching';
 
@@ -937,7 +951,7 @@ BEGIN {
 
 # Pithub::Repos::Hooks->list
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Hooks';
 
@@ -954,7 +968,7 @@ BEGIN {
 
 # Pithub::Repos::Hooks->get
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Hooks';
 
@@ -972,7 +986,7 @@ BEGIN {
 
 # Pithub::Repos::Hooks->delete
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Hooks';
 
@@ -990,7 +1004,7 @@ BEGIN {
 
 # Pithub::Repos::Hooks->test
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Hooks';
 
@@ -1008,7 +1022,7 @@ BEGIN {
 
 # Pithub::Repos::Hooks->create
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Hooks';
 
@@ -1033,7 +1047,7 @@ BEGIN {
 
 # Pithub::Repos::Hooks->update
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Hooks', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Repos::Hooks';
 
@@ -1059,7 +1073,7 @@ BEGIN {
 
 # Pithub::Repos::Stats->contributors
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Stats', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Stats', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, "Pithub::Repos::Stats";
 
@@ -1077,7 +1091,7 @@ BEGIN {
 # Pithub::Repos::Statuses->create
 #
 {
-    my $obj = Pithub::Test->create( 'Pithub::Repos::Statuses', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Repos::Statuses', user => 'foo', repo => 'bar' );
     isa_ok $obj, "Pithub::Repos::Statuses";
 
     {
@@ -1,6 +1,6 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use Pithub::Test;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -9,7 +9,7 @@ BEGIN {
 
 # Pithub::Search->email
 {
-    my $obj = Pithub::Test->create('Pithub::Search');
+    my $obj = Pithub::Test::Factory->create('Pithub::Search');
 
     isa_ok $obj, 'Pithub::Search';
 
@@ -24,7 +24,7 @@ BEGIN {
 
 # Pithub::Search->issues
 {
-    my $obj = Pithub::Test->create( 'Pithub::Search', user => 'foo', repo => 'bar' );
+    my $obj = Pithub::Test::Factory->create( 'Pithub::Search', user => 'foo', repo => 'bar' );
 
     isa_ok $obj, 'Pithub::Search';
 
@@ -43,7 +43,7 @@ BEGIN {
 
 # Pithub::Search->repos
 {
-    my $obj = Pithub::Test->create('Pithub::Search');
+    my $obj = Pithub::Test::Factory->create('Pithub::Search');
 
     isa_ok $obj, 'Pithub::Search';
 
@@ -53,13 +53,13 @@ BEGIN {
         my $result = $obj->repos( keyword => 'bla', params => { language => 'Perl', start_page => '100' } );
         is $result->request->method, 'GET', 'HTTP method';
         is $result->request->uri->path, '/legacy/repos/search/bla', 'HTTP path';
-        eq_or_diff { $result->request->uri->query_form }, { language => 'Perl', start_page => '100' }, 'Query params';
+        eq_or_diff { $result->request->uri->query_form }, { language => 'Perl', start_page => '100', per_page => 100 }, 'Query params';
     }
 }
 
 # Pithub::Search->users
 {
-    my $obj = Pithub::Test->create('Pithub::Search');
+    my $obj = Pithub::Test::Factory->create('Pithub::Search');
 
     isa_ok $obj, 'Pithub::Search';
 
@@ -0,0 +1,16 @@
+use FindBin;
+use lib "$FindBin::Bin/lib";
+use Pithub::Test;
+
+subtest "Test::Most imported" => sub {
+    pass("Loaded test functions");
+    cmp_deeply {}, {}, "Test::Deep imported";
+};
+
+subtest "uri_is" => sub {
+    uri_is "http://example.com", "http://example.com", "same URI";
+    uri_is "http://example.com?foo=bar&up=down",
+           "http://example.com?up=down&foo=bar", "same query, different order";
+};
+
+done_testing;
@@ -1,7 +1,7 @@
 use FindBin;
 use lib "$FindBin::Bin/lib";
-use JSON;
-use Pithub::Test;
+use JSON::MaybeXS;
+use Pithub::Test::Factory;
 use Test::Most;
 
 BEGIN {
@@ -13,7 +13,8 @@ BEGIN {
 
 # Pithub::Users->get
 {
-    my $obj = Pithub::Test->create('Pithub::Users');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users');
+    $obj->ua->add_response('users/plu.GET');
 
     isa_ok $obj, 'Pithub::Users';
 
@@ -55,7 +56,7 @@ BEGIN {
 
 # Pithub::Users->update
 {
-    my $obj = Pithub::Test->create('Pithub::Users');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users');
 
     isa_ok $obj, 'Pithub::Users';
 
@@ -71,7 +72,7 @@ BEGIN {
 
 # Pithub::Users::Emails->add
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Emails');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Emails');
 
     isa_ok $obj, 'Pithub::Users::Emails';
 
@@ -101,7 +102,7 @@ BEGIN {
 
 # Pithub::Users::Emails->delete
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Emails');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Emails');
 
     isa_ok $obj, 'Pithub::Users::Emails';
 
@@ -131,7 +132,7 @@ BEGIN {
 
 # Pithub::Users::Emails->list
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Emails');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Emails');
 
     isa_ok $obj, 'Pithub::Users::Emails';
 
@@ -148,7 +149,7 @@ BEGIN {
 
 # Pithub::Users::Followers->follow
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Followers');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Followers');
 
     isa_ok $obj, 'Pithub::Users::Followers';
 
@@ -166,7 +167,8 @@ BEGIN {
 
 # Pithub::Users::Followers->is_following
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Followers');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Followers');
+    $obj->ua->add_response('user/following/rafl.GET');
 
     isa_ok $obj, 'Pithub::Users::Followers';
 
@@ -190,7 +192,7 @@ BEGIN {
 
 # Pithub::Users::Followers->list
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Followers');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Followers');
 
     isa_ok $obj, 'Pithub::Users::Followers';
 
@@ -212,7 +214,7 @@ BEGIN {
 
 # Pithub::Users::Followers->list_following
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Followers');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Followers');
 
     isa_ok $obj, 'Pithub::Users::Followers';
 
@@ -234,7 +236,7 @@ BEGIN {
 
 # Pithub::Users::Followers->unfollow
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Followers');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Followers');
 
     isa_ok $obj, 'Pithub::Users::Followers';
 
@@ -251,7 +253,7 @@ BEGIN {
 
 # Pithub::Users::Keys->create
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Keys');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Keys');
 
     isa_ok $obj, 'Pithub::Users::Keys';
 
@@ -267,7 +269,7 @@ BEGIN {
 
 # Pithub::Users::Keys->delete
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Keys');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Keys');
 
     isa_ok $obj, 'Pithub::Users::Keys';
 
@@ -284,7 +286,7 @@ BEGIN {
 
 # Pithub::Users::Keys->get
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Keys');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Keys');
 
     isa_ok $obj, 'Pithub::Users::Keys';
 
@@ -301,7 +303,7 @@ BEGIN {
 
 # Pithub::Users::Keys->list
 {
-    my $obj = Pithub::Test->create('Pithub::Users::Keys');
+    my $obj = Pithub::Test::Factory->create('Pithub::Users::Keys');
 
     isa_ok $obj, 'Pithub::Users::Keys';
 
@@ -315,21 +317,4 @@ BEGIN {
     }
 }
 
-# Pithub::Users::Keys->update
-{
-    my $obj = Pithub::Test->create('Pithub::Users::Keys');
-
-    isa_ok $obj, 'Pithub::Users::Keys';
-
-    throws_ok { $obj->update } qr{Missing key in parameters: key_id}, 'No parameters';
-    throws_ok { $obj->update( key_id => 123 ) } qr{Missing key in parameters: data \(hashref\)}, 'No parameters';
-    throws_ok { $obj->update( key_id => 123 => data => { title => 1, key => 1 } ) } qr{Access token required for: PATCH /user/keys/123}, 'Token required';
-
-    ok $obj->token(123), 'Token set';
-
-    my $result = $obj->update( key_id => 123 => data => { title => 'plu@localhost', key => 'ssh-rsa AAA...' } );
-    is $result->request->method, 'PATCH', 'HTTP method';
-    is $result->request->uri->path, '/user/keys/123', 'HTTP path';
-}
-
 done_testing;