diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..707a20898
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.java text eol=lf
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 000000000..6926cdcff
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "java.configuration.updateBuildConfiguration": "automatic",
+ "liveServer.settings.port": 5501
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index b90ef2e5f..0cc02108f 100644
--- a/README.md
+++ b/README.md
@@ -1,180 +1,62 @@
-# Welcome to the home of ScribeJava, the simple OAuth client Java lib!
-
-[](https://github.com/scribejava/scribejava/blob/master/donate.md) [](https://maven-badges.herokuapp.com/maven-central/com.github.scribejava/scribejava)
-
-
-# Why use ScribeJava?
-
-### Dead Simple
-
-Who said OAuth/OAuth2 was difficult? Configuring ScribeJava is __so easy your grandma can do it__! check it out:
-
-```java
-OAuthService service = new ServiceBuilder(YOUR_CLIENT_ID)
- .apiSecret(YOUR_CLIENT_SECRET)
- .build(LinkedInApi20.instance());
-```
-
-That **single line** (added newlines for readability) is the only thing you need to configure ScribeJava with LinkedIn's OAuth API for example.
-
-Working executable examples are [here](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples)
-Common usage: [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java)
-
-### Threadsafe
-
-Hit ScribeJava as hard and with many threads as you like.
-
-### Java 7 compatible
-
-That's it. You can use it in old environments and in android apps.
-note: To compile from sources you will need Java 9 or newer
-
-### Async and other HTTP clients
-
-ScribeJava support out-of-box several HTTP clients:
- * ning async http client 1.9.x (maven module scribejava-httpclient-ning) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncNingExample.java)
- * Async Http Client asynchttpclient 2.x (maven module scribejava-httpclient-ahc) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20AsyncAHCExample.java)
- * OkHttp (maven module scribejava-httpclient-okhttp) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubAsyncOkHttpExample.java)
- * Apache HttpComponents HttpClient (maven module scribejava-httpclient-apache) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncApacheExample.java)
- * Armeria HTTP client (required >= java 8) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20ArmeriaExample.java)
- * any externally created HTTP client [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExternalHttpExample.java)
-
- just add corresponding maven modules to your pom
-
-### Supports many flows and additional features
-
- * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Authorization Code Authorization Grant](https://tools.ietf.org/html/rfc6749#section-4.1), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java)
- * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Resource Owner Password Credentials Authorization Grant](https://tools.ietf.org/html/rfc6749#section-4.3)
- * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Client Credentials Authorization Grant](https://tools.ietf.org/html/rfc6749#section-4.4), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteClientCredentialsGrantExample.java)
- * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Refreshing an Access Token](https://tools.ietf.org/html/rfc6749#section-6), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java#L77)
- * [RFC 6750](https://tools.ietf.org/html/rfc6750) The OAuth 2.0 Authorization Framework: Bearer Token Usage
- * [RFC 7636](https://tools.ietf.org/html/rfc7636) Proof Key for Code Exchange by OAuth Public Clients (PKCE), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20WithPKCEExample.java)
- * [RFC 7009](https://tools.ietf.org/html/rfc7009) OAuth 2.0 Token Revocation, [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20RevokeExample.java)
- * [RFC 8628](https://tools.ietf.org/html/rfc8628) OAuth 2.0 Device Authorization Grant [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20DeviceAuthorizationGrantExample.java)
- * [RFC 5849](https://tools.ietf.org/html/rfc5849) The OAuth 1.0 Protocol, [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java)
-
-### Supports all (50+) major 1.0a and 2.0 OAuth APIs out-of-the-box
-
-* Asana (https://asana.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AsanaExample.java)
-* Automatic (https://www.automatic.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AutomaticExample.java)
-* AWeber (http://www.aweber.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AWeberExample.java)
-* Box (https://www.box.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Box20Example.java)
-* Dataporten (https://docs.dataporten.no/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DataportenExample.java)
-* Digg (http://digg.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiggExample.java)
-* Discord (https://discordapp.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiscordExample.java)
-* Доктор на работе (https://www.doktornarabote.ru/)
-* Dropbox (https://www.dropbox.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DropboxExample.java)
-* Etsy (https://www.etsy.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/EtsyExample.java)
-* Facebook (https://www.facebook.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookExample.java), [example with Async Apache HTTP client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncApacheExample.java), [example with Async Ning HTTP client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncNingExample.java)
-* Fitbit (https://www.fitbit.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FitbitApi20Example.java)
-* Flickr (https://www.flickr.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FlickrExample.java)
-* Foursquare (https://foursquare.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Foursquare2Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FoursquareExample.java)
-* Frappe (https://github.com/frappe/frappe) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FrappeExample.java)
-* Freelancer (https://www.freelancer.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FreelancerExample.java)
-* Genius (http://genius.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GeniusExample.java)
-* GitHub (https://github.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubExample.java), [example with OkHttp HTTP client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubAsyncOkHttpExample.java)
-* Google (https://www.google.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java), [example with Async Http Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20AsyncAHCExample.java), [example Revoke](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20RevokeExample.java), [example with PKCEE](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20WithPKCEExample.java)
-* HeadHunter ХэдХантер (https://hh.ru/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HHExample.java)
-* HiOrg-Server (https://www.hiorg-server.de/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HiOrgServerExample.java)
-* Imgur (http://imgur.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ImgurExample.java)
-* Instagram (https://www.instagram.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/InstagramExample.java)
-* Kaixin 开心网 (http://www.kaixin001.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Kaixin20Example.java)
-* Kakao (https://kakao.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/KakaoExample.java)
-* Keycloak (https://www.keycloak.org/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/KeycloakExample.java)
-* LinkedIn (https://www.linkedin.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedIn20Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExample.java), [example with custom scopes](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExampleWithScopes.java)
-* Mail.Ru (https://mail.ru/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruExample.java), [example with Async Ning HTTP Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruAsyncExample.java)
-* MediaWiki (https://www.mediawiki.org/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MediaWikiExample.java)
-* Meetup (https://www.meetup.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Meetup20Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MeetupExample.java)
-* Microsoft Azure Active Directory (Azure AD) (http://azure.microsoft.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MicrosoftAzureActiveDirectoryExample.java)
-* Microsoft Azure Active Directory (Azure AD) 2.0 (http://azure.microsoft.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MicrosoftAzureActiveDirectory20Example.java)
-* Microsoft Live (https://login.live.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LiveExample.java)
-* Misfit (http://misfit.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MisfitExample.java)
-* NAVER (http://www.naver.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NaverExample.java)
-* Odnoklassniki Одноклассники (http://ok.ru/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OdnoklassnikiExample.java)
-* Polar (https://www.polar.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PolarAPIExample.java)
-* Pinterest (https://www.pinterest.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PinterestExample.java)
-* 500px (https://500px.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Px500Example.java)
-* Renren (http://renren.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/RenrenExample.java)
-* Salesforce (https://www.salesforce.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceExample.java), [example with Async Ning HTTP Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceNingAsyncExample.java)
-* Sina (http://www.sina.com.cn/ http://weibo.com/login.php) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeibo2Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeiboExample.java)
-* Skyrock (http://skyrock.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SkyrockExample.java)
-* Slack (https://slack.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SlackExample.java)
-* StackExchange (http://stackexchange.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/StackExchangeExample.java)
-* The Things Network (v1-staging and v2-preview) (https://www.thethingsnetwork.org/) [example v1](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV1StagingExample.java), [example v2 preview](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV2PreviewExample.java)
-* Trello (https://trello.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TrelloExample.java)
-* Tumblr (https://www.tumblr.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TumblrExample.java)
-* TUT.BY (http://www.tut.by/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TutByExample.java)
-* Twitter (https://twitter.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java)
-* uCoz (https://www.ucoz.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/UcozExample.java)
-* Viadeo (http://viadeo.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ViadeoExample.java)
-* VK ВКонтакте (http://vk.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExample.java), [example Client Credentials Grant](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteClientCredentialsGrantExample.java), [example with External HTTP Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExternalHttpExample.java)
-* Wunderlist (https://www.wunderlist.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/WunderlistExample.java)
-* Xero (https://www.xero.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XeroExample.java)
-* XING (https://www.xing.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XingExample.java)
-* Yahoo (https://www.yahoo.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Yahoo20Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/YahooExample.java)
-* check the [examples folder](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples)
-
-### Small and modular
-
-ScribeJava's code is small (about 1k LOC) and simple to understand. No smart-ass or "clever" hacks here.
-You can use only 'core' or 'with apis' maven modules
-
-### Android-Ready
-
-Works out of the box with android(TM) applications.
-
-### Stable & bulletproof
-
-Good test coverage to keep you safe from harm.
-
-When something bad actually happens, ScribeJava's meaningful error messages will tell you exactly what went wrong, when and where.
-
-### Pull it from Maven Central!
-
-You can pull ScribeJava from the central maven repository, just add these to your __pom.xml__ file:
-
-```xml
-
- com.github.scribejava
- scribejava-apis
- 8.3.3
-
-```
-
-And in case you need just core classes (that's it, without any external API (FB, VK, GitHub, Google etc) specific code), you could pull just 'core' artifact.
-```xml
-
- com.github.scribejava
- scribejava-core
- 8.3.3
-
-```
-
-## How can I help ScribeJava
-
-First of all, Pull Requests are welcome, the second option is [donations](https://github.com/scribejava/scribejava/blob/master/donate.md).
-
-## When will ScribeJava support XXX (new RFC, custom functionality, new API etc.)
-
-When you will send the pull request. That's the way for a majority of changes here.
-Or you can ask someone to make the paid job for you.
-In some cases, when I'm interested in changes (technically or financially), I can implement the request myself.
-
-## Paid consulting
-If you or your business depends on the Scribejava and you need any specific improvement or new feature not currently implemented in the Scribejava, consider contacting me about a paid job.
-
-## Getting started in less than 2 minutes
-
-Check the [Getting Started](https://github.com/scribejava/scribejava/wiki/getting-started) page and start rocking! Please Read the [FAQ](https://github.com/scribejava/scribejava/wiki/faq) before creating an issue :)
-
-Some useful info and answers you can find on the [wiki](https://github.com/scribejava/scribejava/wiki)
-
-Also, remember to read the [fantastic tutorial](http://akoskm.github.io/2015/07/31/twitter-sign-in-for-web-apps.html) that [@akoskm](https://twitter.com/akoskm) wrote to easily integrate a server side app with an API (twitter in this case).
-
-## Questions?
-
-Feel free to drop us an email or create issue right here on github.com
-
-## Forks
-
-If you have a useful fork that should be listed there please contact us
+# Report for Assignment 1
+
+## Project chosen
+Name: cribeJava
+URL: https://github.com/scribejava/scribejava
+Number of lines of code and tool used to count it: 17332, lizard
+Programming language: Java
+
+## Coverage measurement
+### Existing tool
+Name of the existing tool used was Jacoco. It was executed by adding a Jacoco plugin into the pom.xml file and then executing maven. (Add some details)
+(Provide screenshot, there is a problem that it only creates reports for specific parts such as scribejava-core, figure out a way to put it all in one report)
+
+
+### Our own coverage tool
+Tomas Busa
+Function 1: com.github.scribejava.httpclient.apache.ApacheHttpClient.getRequestBuilder
+
+
+
+
+
+Function 2: com.github.scribejava.httpclient.apache.OAuthAsyncCompletionHandler.completed
+
+
+
+
+
+
+
+Jayran Duggins
+Function 1: scribejava-httpclient-armeria/src/main/java/com/github/scribejava/httpclient/armeria/ArmeriaHttpClient.java (getHttpMethod)
+
+Function 2: scribejava-httpclient-armeria/src/main/java/com/github/scribejava/httpclient/armeria/ArmeriaWebClientBuilder.java (newWebClient)
+
+
+
+Nikola Bakalinov
+Function 1: scribejava/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning
+/NingHttpClient.java (doExecuteAsync)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README_original.md b/README_original.md
new file mode 100644
index 000000000..b90ef2e5f
--- /dev/null
+++ b/README_original.md
@@ -0,0 +1,180 @@
+# Welcome to the home of ScribeJava, the simple OAuth client Java lib!
+
+[](https://github.com/scribejava/scribejava/blob/master/donate.md) [](https://maven-badges.herokuapp.com/maven-central/com.github.scribejava/scribejava)
+
+
+# Why use ScribeJava?
+
+### Dead Simple
+
+Who said OAuth/OAuth2 was difficult? Configuring ScribeJava is __so easy your grandma can do it__! check it out:
+
+```java
+OAuthService service = new ServiceBuilder(YOUR_CLIENT_ID)
+ .apiSecret(YOUR_CLIENT_SECRET)
+ .build(LinkedInApi20.instance());
+```
+
+That **single line** (added newlines for readability) is the only thing you need to configure ScribeJava with LinkedIn's OAuth API for example.
+
+Working executable examples are [here](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples)
+Common usage: [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java)
+
+### Threadsafe
+
+Hit ScribeJava as hard and with many threads as you like.
+
+### Java 7 compatible
+
+That's it. You can use it in old environments and in android apps.
+note: To compile from sources you will need Java 9 or newer
+
+### Async and other HTTP clients
+
+ScribeJava support out-of-box several HTTP clients:
+ * ning async http client 1.9.x (maven module scribejava-httpclient-ning) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncNingExample.java)
+ * Async Http Client asynchttpclient 2.x (maven module scribejava-httpclient-ahc) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20AsyncAHCExample.java)
+ * OkHttp (maven module scribejava-httpclient-okhttp) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubAsyncOkHttpExample.java)
+ * Apache HttpComponents HttpClient (maven module scribejava-httpclient-apache) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncApacheExample.java)
+ * Armeria HTTP client (required >= java 8) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20ArmeriaExample.java)
+ * any externally created HTTP client [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExternalHttpExample.java)
+
+ just add corresponding maven modules to your pom
+
+### Supports many flows and additional features
+
+ * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Authorization Code Authorization Grant](https://tools.ietf.org/html/rfc6749#section-4.1), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java)
+ * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Resource Owner Password Credentials Authorization Grant](https://tools.ietf.org/html/rfc6749#section-4.3)
+ * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Client Credentials Authorization Grant](https://tools.ietf.org/html/rfc6749#section-4.4), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteClientCredentialsGrantExample.java)
+ * [RFC 6749](https://tools.ietf.org/html/rfc6749) The OAuth 2.0 Authorization Framework, [Refreshing an Access Token](https://tools.ietf.org/html/rfc6749#section-6), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java#L77)
+ * [RFC 6750](https://tools.ietf.org/html/rfc6750) The OAuth 2.0 Authorization Framework: Bearer Token Usage
+ * [RFC 7636](https://tools.ietf.org/html/rfc7636) Proof Key for Code Exchange by OAuth Public Clients (PKCE), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20WithPKCEExample.java)
+ * [RFC 7009](https://tools.ietf.org/html/rfc7009) OAuth 2.0 Token Revocation, [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20RevokeExample.java)
+ * [RFC 8628](https://tools.ietf.org/html/rfc8628) OAuth 2.0 Device Authorization Grant [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20DeviceAuthorizationGrantExample.java)
+ * [RFC 5849](https://tools.ietf.org/html/rfc5849) The OAuth 1.0 Protocol, [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java)
+
+### Supports all (50+) major 1.0a and 2.0 OAuth APIs out-of-the-box
+
+* Asana (https://asana.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AsanaExample.java)
+* Automatic (https://www.automatic.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AutomaticExample.java)
+* AWeber (http://www.aweber.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/AWeberExample.java)
+* Box (https://www.box.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Box20Example.java)
+* Dataporten (https://docs.dataporten.no/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DataportenExample.java)
+* Digg (http://digg.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiggExample.java)
+* Discord (https://discordapp.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DiscordExample.java)
+* Доктор на работе (https://www.doktornarabote.ru/)
+* Dropbox (https://www.dropbox.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/DropboxExample.java)
+* Etsy (https://www.etsy.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/EtsyExample.java)
+* Facebook (https://www.facebook.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookExample.java), [example with Async Apache HTTP client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncApacheExample.java), [example with Async Ning HTTP client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FacebookAsyncNingExample.java)
+* Fitbit (https://www.fitbit.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FitbitApi20Example.java)
+* Flickr (https://www.flickr.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FlickrExample.java)
+* Foursquare (https://foursquare.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Foursquare2Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FoursquareExample.java)
+* Frappe (https://github.com/frappe/frappe) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FrappeExample.java)
+* Freelancer (https://www.freelancer.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/FreelancerExample.java)
+* Genius (http://genius.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GeniusExample.java)
+* GitHub (https://github.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubExample.java), [example with OkHttp HTTP client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/GitHubAsyncOkHttpExample.java)
+* Google (https://www.google.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20Example.java), [example with Async Http Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20AsyncAHCExample.java), [example Revoke](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20RevokeExample.java), [example with PKCEE](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Google20WithPKCEExample.java)
+* HeadHunter ХэдХантер (https://hh.ru/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HHExample.java)
+* HiOrg-Server (https://www.hiorg-server.de/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/HiOrgServerExample.java)
+* Imgur (http://imgur.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ImgurExample.java)
+* Instagram (https://www.instagram.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/InstagramExample.java)
+* Kaixin 开心网 (http://www.kaixin001.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Kaixin20Example.java)
+* Kakao (https://kakao.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/KakaoExample.java)
+* Keycloak (https://www.keycloak.org/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/KeycloakExample.java)
+* LinkedIn (https://www.linkedin.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedIn20Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExample.java), [example with custom scopes](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LinkedInExampleWithScopes.java)
+* Mail.Ru (https://mail.ru/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruExample.java), [example with Async Ning HTTP Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MailruAsyncExample.java)
+* MediaWiki (https://www.mediawiki.org/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MediaWikiExample.java)
+* Meetup (https://www.meetup.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Meetup20Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MeetupExample.java)
+* Microsoft Azure Active Directory (Azure AD) (http://azure.microsoft.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MicrosoftAzureActiveDirectoryExample.java)
+* Microsoft Azure Active Directory (Azure AD) 2.0 (http://azure.microsoft.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MicrosoftAzureActiveDirectory20Example.java)
+* Microsoft Live (https://login.live.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/LiveExample.java)
+* Misfit (http://misfit.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/MisfitExample.java)
+* NAVER (http://www.naver.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/NaverExample.java)
+* Odnoklassniki Одноклассники (http://ok.ru/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/OdnoklassnikiExample.java)
+* Polar (https://www.polar.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PolarAPIExample.java)
+* Pinterest (https://www.pinterest.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/PinterestExample.java)
+* 500px (https://500px.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Px500Example.java)
+* Renren (http://renren.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/RenrenExample.java)
+* Salesforce (https://www.salesforce.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceExample.java), [example with Async Ning HTTP Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SalesforceNingAsyncExample.java)
+* Sina (http://www.sina.com.cn/ http://weibo.com/login.php) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeibo2Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SinaWeiboExample.java)
+* Skyrock (http://skyrock.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SkyrockExample.java)
+* Slack (https://slack.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/SlackExample.java)
+* StackExchange (http://stackexchange.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/StackExchangeExample.java)
+* The Things Network (v1-staging and v2-preview) (https://www.thethingsnetwork.org/) [example v1](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV1StagingExample.java), [example v2 preview](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TheThingsNetworkV2PreviewExample.java)
+* Trello (https://trello.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TrelloExample.java)
+* Tumblr (https://www.tumblr.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TumblrExample.java)
+* TUT.BY (http://www.tut.by/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TutByExample.java)
+* Twitter (https://twitter.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/TwitterExample.java)
+* uCoz (https://www.ucoz.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/UcozExample.java)
+* Viadeo (http://viadeo.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/ViadeoExample.java)
+* VK ВКонтакте (http://vk.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExample.java), [example Client Credentials Grant](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteClientCredentialsGrantExample.java), [example with External HTTP Client](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/VkontakteExternalHttpExample.java)
+* Wunderlist (https://www.wunderlist.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/WunderlistExample.java)
+* Xero (https://www.xero.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XeroExample.java)
+* XING (https://www.xing.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/XingExample.java)
+* Yahoo (https://www.yahoo.com/) [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/Yahoo20Example.java), [example](https://github.com/scribejava/scribejava/blob/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples/YahooExample.java)
+* check the [examples folder](https://github.com/scribejava/scribejava/tree/master/scribejava-apis/src/test/java/com/github/scribejava/apis/examples)
+
+### Small and modular
+
+ScribeJava's code is small (about 1k LOC) and simple to understand. No smart-ass or "clever" hacks here.
+You can use only 'core' or 'with apis' maven modules
+
+### Android-Ready
+
+Works out of the box with android(TM) applications.
+
+### Stable & bulletproof
+
+Good test coverage to keep you safe from harm.
+
+When something bad actually happens, ScribeJava's meaningful error messages will tell you exactly what went wrong, when and where.
+
+### Pull it from Maven Central!
+
+You can pull ScribeJava from the central maven repository, just add these to your __pom.xml__ file:
+
+```xml
+
+ com.github.scribejava
+ scribejava-apis
+ 8.3.3
+
+```
+
+And in case you need just core classes (that's it, without any external API (FB, VK, GitHub, Google etc) specific code), you could pull just 'core' artifact.
+```xml
+
+ com.github.scribejava
+ scribejava-core
+ 8.3.3
+
+```
+
+## How can I help ScribeJava
+
+First of all, Pull Requests are welcome, the second option is [donations](https://github.com/scribejava/scribejava/blob/master/donate.md).
+
+## When will ScribeJava support XXX (new RFC, custom functionality, new API etc.)
+
+When you will send the pull request. That's the way for a majority of changes here.
+Or you can ask someone to make the paid job for you.
+In some cases, when I'm interested in changes (technically or financially), I can implement the request myself.
+
+## Paid consulting
+If you or your business depends on the Scribejava and you need any specific improvement or new feature not currently implemented in the Scribejava, consider contacting me about a paid job.
+
+## Getting started in less than 2 minutes
+
+Check the [Getting Started](https://github.com/scribejava/scribejava/wiki/getting-started) page and start rocking! Please Read the [FAQ](https://github.com/scribejava/scribejava/wiki/faq) before creating an issue :)
+
+Some useful info and answers you can find on the [wiki](https://github.com/scribejava/scribejava/wiki)
+
+Also, remember to read the [fantastic tutorial](http://akoskm.github.io/2015/07/31/twitter-sign-in-for-web-apps.html) that [@akoskm](https://twitter.com/akoskm) wrote to easily integrate a server side app with an API (twitter in this case).
+
+## Questions?
+
+Feel free to drop us an email or create issue right here on github.com
+
+## Forks
+
+If you have a useful fork that should be listed there please contact us
diff --git a/image-1.png b/image-1.png
new file mode 100644
index 000000000..330cfee64
Binary files /dev/null and b/image-1.png differ
diff --git a/image.png b/image.png
new file mode 100644
index 000000000..30df2f243
Binary files /dev/null and b/image.png differ
diff --git a/pom.xml b/pom.xml
index b484b6a71..10bf82abd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,11 @@
4.13.2
test
+
+ com.github.scribejava
+ scribejava-apis
+ 8.3.3
+
com.squareup.okhttp3
mockwebserver
@@ -87,6 +92,64 @@
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.12
+
+
+ default-prepare-agent
+
+ prepare-agent
+
+
+
+ default-report
+
+ report
+
+
+
+ default-check
+
+ check
+
+
+
+
+ BUNDLE
+
+
+ COMPLEXITY
+ COVEREDRATIO
+ 0.60
+
+
+
+
+
+
+
+
org.apache.maven.plugins
maven-jar-plugin
@@ -97,7 +160,7 @@
-
+
org.apache.maven.plugins
maven-release-plugin
@@ -200,7 +263,7 @@
-
+
+
diff --git a/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponse.java b/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponse.java
index ea5053931..1719c4ee2 100644
--- a/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponse.java
+++ b/scribejava-apis/src/main/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponse.java
@@ -4,7 +4,9 @@
import com.github.scribejava.core.model.Response;
import java.io.IOException;
import java.util.Objects;
-
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* non standard Facebook replace for {@link com.github.scribejava.core.model.OAuth2AccessTokenErrorResponse}
*
@@ -25,6 +27,32 @@ public class FacebookAccessTokenErrorResponse extends OAuthResponseException {
private final int codeInt;
private final String fbtraceId;
+ // Branch coverage data structure Nikola
+ private static final ConcurrentHashMap branchCoverage = new ConcurrentHashMap<>();
+
+ static {
+ branchCoverage.put("FacebookAccessTokenErrorResponse.equals.branch_1", new AtomicBoolean(false));
+ branchCoverage.put("FacebookAccessTokenErrorResponse.equals.branch_2", new AtomicBoolean(false));
+ branchCoverage.put("FacebookAccessTokenErrorResponse.equals.branch_3", new AtomicBoolean(false));
+ branchCoverage.put("FacebookAccessTokenErrorResponse.equals.branch_4", new AtomicBoolean(false));
+ branchCoverage.put("FacebookAccessTokenErrorResponse.equals.branch_5", new AtomicBoolean(false));
+ branchCoverage.put("FacebookAccessTokenErrorResponse.equals.branch_6", new AtomicBoolean(false));
+ branchCoverage.put("FacebookAccessTokenErrorResponse.equals.branch_7", new AtomicBoolean(false));
+
+
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (System.out) {
+ System.out.println("FacebookAccessTokenErrorResponse equals method coverage:");
+ for (Map.Entry entry : branchCoverage.entrySet()) {
+ System.out.println(entry.getKey() + ": " + (entry.getValue().get() ? "Taken" : "Not taken"));
+ }
+ }
+ }
+ }));
+ }
+
public FacebookAccessTokenErrorResponse(String errorMessage, String type, int code, String fbtraceId,
Response response)
throws IOException {
@@ -61,33 +89,39 @@ public int hashCode() {
return hash;
}
+ // branch coverage Nikola
@Override
public boolean equals(Object obj) {
if (this == obj) {
+ branchCoverage.get("FacebookAccessTokenErrorResponse.equals.branch_1").set(true);
return true;
}
if (obj == null) {
+ branchCoverage.get("FacebookAccessTokenErrorResponse.equals.branch_2").set(true);
return false;
}
if (getClass() != obj.getClass()) {
+ branchCoverage.get("FacebookAccessTokenErrorResponse.equals.branch_3").set(true);
return false;
}
- if (!super.equals(obj)) {
+ FacebookAccessTokenErrorResponse other = (FacebookAccessTokenErrorResponse) obj;
+ if (!Objects.equals(errorMessage, other.errorMessage)) {
+ branchCoverage.get("FacebookAccessTokenErrorResponse.equals.branch_4").set(true);
return false;
}
-
- final FacebookAccessTokenErrorResponse other = (FacebookAccessTokenErrorResponse) obj;
-
- if (!Objects.equals(errorMessage, other.getErrorMessage())) {
+ if (!Objects.equals(type, other.type)) {
+ branchCoverage.get("FacebookAccessTokenErrorResponse.equals.branch_5").set(true);
return false;
}
- if (!Objects.equals(type, other.getType())) {
+ if (codeInt != other.codeInt) {
+ branchCoverage.get("FacebookAccessTokenErrorResponse.equals.branch_6").set(true);
return false;
}
- if (codeInt != other.getCodeInt()) {
+ if (!Objects.equals(fbtraceId, other.fbtraceId)) {
+ branchCoverage.get("FacebookAccessTokenErrorResponse.equals.branch_7").set(true);
return false;
}
- return Objects.equals(fbtraceId, other.getFbtraceId());
+ return true;
}
@Override
diff --git a/scribejava-apis/src/test/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponseTest.java b/scribejava-apis/src/test/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponseTest.java
new file mode 100644
index 000000000..3d6476bbd
--- /dev/null
+++ b/scribejava-apis/src/test/java/com/github/scribejava/apis/facebook/FacebookAccessTokenErrorResponseTest.java
@@ -0,0 +1,89 @@
+package com.github.scribejava.apis.facebook;
+
+import com.github.scribejava.core.model.Response;
+import java.io.IOException;
+import java.util.Collections;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+public class FacebookAccessTokenErrorResponseTest {
+
+ @Test
+ public void testEquals_Self() throws IOException {
+ Response response = new Response(200, "OK", Collections.emptyMap(), "Body content here");
+ FacebookAccessTokenErrorResponse errorResponse = new FacebookAccessTokenErrorResponse(
+ "Message", "Type", 100, "TraceID", response);
+
+ assertTrue("Should return true when comparing to itself.",
+ errorResponse.equals(errorResponse));
+ }
+
+ @Test
+ public void testEquals_NullObject() throws IOException {
+ Response response = new Response(200, "OK", Collections.emptyMap(), "Body content here");
+ FacebookAccessTokenErrorResponse errorResponse = new FacebookAccessTokenErrorResponse(
+ "Message", "Type", 100, "TraceID", response);
+
+ assertFalse("Should return false when comparing to null.",
+ errorResponse.equals(null));
+ }
+
+ @Test
+ public void testEquals_DifferentClass() throws IOException {
+ Response response = new Response(200, "OK", Collections.emptyMap(), "Body content here");
+ FacebookAccessTokenErrorResponse errorResponse = new FacebookAccessTokenErrorResponse(
+ "Message", "Type", 100, "TraceID", response);
+ Object otherObject = new Object();
+
+ assertFalse("Should return false when comparing different classes.",
+ errorResponse.equals(otherObject));
+ }
+
+ @Test
+ public void testEquals_DifferentErrorMessage() throws IOException {
+ Response response = new Response(200, "OK", Collections.emptyMap(), "Body content here");
+ FacebookAccessTokenErrorResponse errorResponse1 = new FacebookAccessTokenErrorResponse(
+ "Message1", "Type", 100, "TraceID", response);
+ FacebookAccessTokenErrorResponse errorResponse2 = new FacebookAccessTokenErrorResponse(
+ "Message2", "Type", 100, "TraceID", response);
+
+ assertFalse("Should return false when errorMessages are different.",
+ errorResponse1.equals(errorResponse2));
+ }
+
+ @Test
+ public void testEquals_DifferentType() throws IOException {
+ Response response = new Response(200, "OK", Collections.emptyMap(), "Body content here");
+ FacebookAccessTokenErrorResponse errorResponse1 = new FacebookAccessTokenErrorResponse(
+ "Message", "Type1", 100, "TraceID", response);
+ FacebookAccessTokenErrorResponse errorResponse2 = new FacebookAccessTokenErrorResponse(
+ "Message", "Type2", 100, "TraceID", response);
+
+ assertFalse("Should return false when types are different.",
+ errorResponse1.equals(errorResponse2));
+ }
+
+ @Test
+ public void testEquals_DifferentCode() throws IOException {
+ Response response = new Response(200, "OK", Collections.emptyMap(), "Body content here");
+ FacebookAccessTokenErrorResponse errorResponse1 = new FacebookAccessTokenErrorResponse(
+ "Message", "Type", 100, "TraceID", response);
+ FacebookAccessTokenErrorResponse errorResponse2 = new FacebookAccessTokenErrorResponse(
+ "Message", "Type", 101, "TraceID", response);
+
+ assertFalse("Should return false when codes are different.",
+ errorResponse1.equals(errorResponse2));
+ }
+
+ @Test
+ public void testEquals_DifferentFbtraceId() throws IOException {
+ Response response = new Response(200, "OK", Collections.emptyMap(), "Body content here");
+ FacebookAccessTokenErrorResponse errorResponse1 = new FacebookAccessTokenErrorResponse(
+ "Message", "Type", 100, "TraceID1", response);
+ FacebookAccessTokenErrorResponse errorResponse2 = new FacebookAccessTokenErrorResponse(
+ "Message", "Type", 100, "TraceID2", response);
+
+ assertFalse("Should return false when fbtraceIds are different.",
+ errorResponse1.equals(errorResponse2));
+ }
+}
diff --git a/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/ApacheHttpClient.java b/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/ApacheHttpClient.java
index 8c204e67b..0ad637914 100644
--- a/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/ApacheHttpClient.java
+++ b/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/ApacheHttpClient.java
@@ -100,7 +100,8 @@ private Future doExecuteAsync(String userAgent, Map heade
final Future future = client.execute(builder.build(), handler);
return new ApacheHttpFuture<>(future, handler);
}
-
+
+ //branch coverage: Tomas
private static RequestBuilder getRequestBuilder(Verb httpVerb) {
switch (httpVerb) {
case GET:
diff --git a/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/OAuthAsyncCompletionHandler.java b/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/OAuthAsyncCompletionHandler.java
index 7779b83e7..d2f90ac09 100644
--- a/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/OAuthAsyncCompletionHandler.java
+++ b/scribejava-httpclient-apache/src/main/java/com/github/scribejava/httpclient/apache/OAuthAsyncCompletionHandler.java
@@ -34,6 +34,7 @@ public OAuthAsyncCompletionHandler(OAuthAsyncRequestCallback callback, Respon
this.latch = new CountDownLatch(1);
}
+ //branch coverage Tomas
@Override
public void completed(HttpResponse httpResponse) {
try {
diff --git a/scribejava-httpclient-armeria/src/main/java/com/github/scribejava/httpclient/armeria/ArmeriaHttpClient.java b/scribejava-httpclient-armeria/src/main/java/com/github/scribejava/httpclient/armeria/ArmeriaHttpClient.java
index 982ddc63a..211f1e334 100644
--- a/scribejava-httpclient-armeria/src/main/java/com/github/scribejava/httpclient/armeria/ArmeriaHttpClient.java
+++ b/scribejava-httpclient-armeria/src/main/java/com/github/scribejava/httpclient/armeria/ArmeriaHttpClient.java
@@ -44,7 +44,8 @@ public class ArmeriaHttpClient extends AbstractAsyncOnlyHttpClient {
*/
private final ArmeriaWebClientBuilder clientBuilder;
/**
- * A list of cached Endpoints. It helps avoiding building a new Endpoint per each request.
+ * A list of cached Endpoints. It helps avoiding building a new Endpoint per
+ * each request.
*/
private final Map httpClients = new HashMap<>();
/**
@@ -149,7 +150,8 @@ private CompletableFuture doExecuteAsync(String userAgent, Map converter {@link OAuthRequest.ResponseConverter} specific type or {@link Response}
- * @return either instance of {@link Response} or converted result based on {@link OAuthRequest.ResponseConverter}
+ * @param converter {@link OAuthRequest.ResponseConverter}
+ * specific type or {@link Response}
+ * @return either instance of {@link Response} or converted result based on
+ * {@link OAuthRequest.ResponseConverter}
*/
private T whenResponseComplete(OAuthAsyncRequestCallback callback,
OAuthRequest.ResponseConverter converter, AggregatedHttpResponse aggregatedResponse) {
@@ -292,9 +346,11 @@ private T whenResponseComplete(OAuthAsyncRequestCallback callback,
/**
* Invokes {@link OAuthAsyncRequestCallback} upon {@link Throwable} error result
*
- * @param callback a {@link OAuthAsyncRequestCallback} callback to invoke upon response completion
+ * @param callback a {@link OAuthAsyncRequestCallback} callback to invoke upon
+ * response completion
* @param throwable a {@link Throwable} error result
- * @param converter {@link OAuthRequest.ResponseConverter} specific type or {@link Response}
+ * @param converter {@link OAuthRequest.ResponseConverter} specific
+ * type or {@link Response}
* @return null
*/
private T completeExceptionally(OAuthAsyncRequestCallback callback, Throwable throwable) {
@@ -372,4 +428,4 @@ public HttpData get() {
}
}
}
-}
+}
\ No newline at end of file
diff --git a/scribejava-httpclient-ning/pom.xml b/scribejava-httpclient-ning/pom.xml
index 39696d698..dcf82d83e 100644
--- a/scribejava-httpclient-ning/pom.xml
+++ b/scribejava-httpclient-ning/pom.xml
@@ -1,12 +1,14 @@
-
+
4.0.0
com.github.scribejava
scribejava
8.3.4-SNAPSHOT
- ../pom.xml
+ ../pom.xml
com.github.scribejava
@@ -50,6 +52,24 @@
org.apache.maven.plugins
maven-jar-plugin
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.10.1
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.19.0
+
+ true
+
+
diff --git a/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClient.java b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClient.java
index 52250f698..cb55df05c 100644
--- a/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClient.java
+++ b/scribejava-httpclient-ning/src/main/java/com/github/scribejava/httpclient/ning/NingHttpClient.java
@@ -8,15 +8,41 @@
import com.github.scribejava.core.model.Verb;
import com.ning.http.client.AsyncHttpClient;
+
import java.util.Map;
import java.util.concurrent.Future;
import com.ning.http.client.AsyncHttpClientConfig;
import java.io.File;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
public class NingHttpClient extends AbstractAsyncOnlyHttpClient {
private final AsyncHttpClient client;
+ public static final ConcurrentHashMap branchCoverage = new ConcurrentHashMap<>();
+ // Branch coverage data structure Nikola
+ static {
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_1", new AtomicBoolean(false));
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_2", new AtomicBoolean(false));
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_3", new AtomicBoolean(false));
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_4", new AtomicBoolean(false));
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_5", new AtomicBoolean(false));
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_6", new AtomicBoolean(false));
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_7", new AtomicBoolean(false));
+ branchCoverage.put("NingHttpClientdoExecuteAsync.branch_8", new AtomicBoolean(false));
+
+
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("Branch coverage results:");
+ for (Map.Entry entry : branchCoverage.entrySet()) {
+ System.out.println(entry.getKey() + ": " + (entry.getValue().get() ? "Taken" : "Not taken"));
+ }
+ }
+ }));
+ }
public NingHttpClient() {
this(NingHttpClientConfig.defaultConfig());
@@ -79,46 +105,64 @@ public Future executeAsync(String userAgent, Map headers,
converter);
}
- private Future doExecuteAsync(String userAgent, Map headers, Verb httpVerb,
- String completeUrl, BodySetter bodySetter, Object bodyContents, OAuthAsyncRequestCallback callback,
- OAuthRequest.ResponseConverter converter) {
- final AsyncHttpClient.BoundRequestBuilder boundRequestBuilder;
- switch (httpVerb) {
- case GET:
- boundRequestBuilder = client.prepareGet(completeUrl);
- break;
- case POST:
- boundRequestBuilder = client.preparePost(completeUrl);
- break;
- case PUT:
- boundRequestBuilder = client.preparePut(completeUrl);
- break;
- case DELETE:
- boundRequestBuilder = client.prepareDelete(completeUrl);
- break;
- default:
- throw new IllegalArgumentException("message build error: unknown verb type");
- }
-
- if (httpVerb.isPermitBody()) {
- if (!headers.containsKey(CONTENT_TYPE)) {
- boundRequestBuilder.addHeader(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
- }
- bodySetter.setBody(boundRequestBuilder, bodyContents);
- }
+ // branch coverage: Nikola
+ public Future doExecuteAsync(String userAgent, Map headers, Verb httpVerb,
+ String completeUrl, BodySetter bodySetter, Object bodyContents, OAuthAsyncRequestCallback callback,
+ OAuthRequest.ResponseConverter converter) {
+ final AsyncHttpClient.BoundRequestBuilder boundRequestBuilder;
+ switch (httpVerb) {
+ // ID: branch_1
+ case GET:
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_1").set(true);
+ boundRequestBuilder = client.prepareGet(completeUrl);
+ break;
+ // ID: branch_2
+ case POST:
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_2").set(true);
+ boundRequestBuilder = client.preparePost(completeUrl);
+ break;
+ // ID: branch_3
+ case PUT:
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_3").set(true);
+ boundRequestBuilder = client.preparePut(completeUrl);
+ break;
+ // ID: branch_4
+ case DELETE:
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_4").set(true);
+ boundRequestBuilder = client.prepareDelete(completeUrl);
+ break;
+ // ID: branch_5
+ default:
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_5").set(true);
+ throw new IllegalArgumentException("message build error: unknown verb type");
+ }
- for (Map.Entry header : headers.entrySet()) {
- boundRequestBuilder.addHeader(header.getKey(), header.getValue());
+ // ID: branch_6
+ if (httpVerb.isPermitBody()) {
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_6").set(true);
+ // ID: branch_7
+ if (!headers.containsKey("Content-Type")) {
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_7").set(true);
+ boundRequestBuilder.addHeader("Content-Type", "application/x-www-form-urlencoded");
}
+ bodySetter.setBody(boundRequestBuilder, bodyContents);
+ }
- if (userAgent != null) {
- boundRequestBuilder.setHeader(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent);
- }
+ for (Map.Entry header : headers.entrySet()) {
+ boundRequestBuilder.addHeader(header.getKey(), header.getValue());
+ }
- return boundRequestBuilder.execute(new OAuthAsyncCompletionHandler<>(callback, converter));
+ // ID: branch_8
+ if (userAgent != null) {
+ branchCoverage.get("NingHttpClientdoExecuteAsync.branch_8").set(true);
+ boundRequestBuilder.setHeader(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent);
}
- private enum BodySetter {
+ return boundRequestBuilder.execute(new OAuthAsyncCompletionHandler<>(callback, converter));
+}
+
+
+ public enum BodySetter {
BYTE_ARRAY {
@Override
AsyncHttpClient.BoundRequestBuilder setBody(AsyncHttpClient.BoundRequestBuilder requestBuilder,
diff --git a/scribejava-httpclient-ning/src/test/java/com/github/scribejava/httpclient/ning/NingHttpClientTest.java b/scribejava-httpclient-ning/src/test/java/com/github/scribejava/httpclient/ning/NingHttpClientTest.java
index 6ebf6456f..5a389a5f1 100644
--- a/scribejava-httpclient-ning/src/test/java/com/github/scribejava/httpclient/ning/NingHttpClientTest.java
+++ b/scribejava-httpclient-ning/src/test/java/com/github/scribejava/httpclient/ning/NingHttpClientTest.java
@@ -2,6 +2,24 @@
import com.github.scribejava.core.AbstractClientTest;
import com.github.scribejava.core.httpclient.HttpClient;
+import com.github.scribejava.core.model.Verb;
+import org.junit.Test;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.concurrent.Future;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import java.util.concurrent.Future;
+
+import static org.junit.Assert.fail;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+
+
+
public class NingHttpClientTest extends AbstractClientTest {
@@ -9,4 +27,52 @@ public class NingHttpClientTest extends AbstractClientTest {
protected HttpClient createNewClient() {
return new NingHttpClient();
}
+
+
+//new tests
+
+
+@Test
+public void testDoExecuteAsyncPut() {
+ NingHttpClient client = (NingHttpClient) createNewClient();
+ String completeUrl = "http://example.com/put";
+ Map headers = new HashMap<>();
+
+ Future> future = client.doExecuteAsync("TestAgent", headers, Verb.PUT, completeUrl, NingHttpClient.BodySetter.STRING, "", null, null);
+
+ assertTrue(NingHttpClient.branchCoverage.get("NingHttpClientdoExecuteAsync.branch_3").get());
+ assertNotNull(future);
+}
+
+
+
+@Test
+public void testDoExecuteAsyncDelete() {
+ NingHttpClient client = (NingHttpClient) createNewClient();
+ String completeUrl = "http://example.com/delete";
+ Map headers = new HashMap<>();
+ Future> future = client.doExecuteAsync("TestAgent", headers, Verb.DELETE, completeUrl, NingHttpClient.BodySetter.STRING, "", null, null);
+
+ assertTrue(NingHttpClient.branchCoverage.get("NingHttpClientdoExecuteAsync.branch_4").get());
+ assertNotNull(future);
+}
+
+
+@Test(expected = IllegalArgumentException.class)
+public void testDoExecuteAsyncDefault() {
+ NingHttpClient client = (NingHttpClient) createNewClient();
+ String completeUrl = "http://example.com/default";
+ Map headers = new HashMap<>();
+
+ // Attempt to use the UNSUPPORTED verb, expecting an IllegalArgumentException
+ client.doExecuteAsync("TestAgent", headers, Verb.TRACE, completeUrl, NingHttpClient.BodySetter.STRING, "", null, null);
+
+ fail("Expected an IllegalArgumentException to be thrown for UNSUPPORTED verb.");
+}
+
+
+
+
+
+
}