diff --git a/README.md b/README.md index ebcf5523..78bfa558 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ grab **FastHub** from [Here](https://github.com/thermatk/FastHub-Libre) maintain - Notifications overview and "Mark all as read" - Search users/orgs, repos, issues/prs & code. - Pinned Repos + - Trending - **Repositories** - Search Repos - Browse and search Repos @@ -81,6 +82,7 @@ Ads are no longer available until further notice # Specs / Open-source libraries: - Minimum **SDK 21**, _but AppCompat is used all the way ;-)_ +- **Kotlin** all new modules starting from 2.5.3 will be written in **#Kotlin**. - **MVP**-architecture: [**ThirtyInch**](https://github.com/grandcentrix/ThirtyInch) because its ThirtyInch. - [**RxJava2**](https://github.com/ReactiveX/RxJava) & [**RxAndroid**](https://github.com/ReactiveX/RxAndroid) for Retrofit & background threads - [**Retrofit**](https://github.com/square/retrofit) for constructing the REST API @@ -95,7 +97,7 @@ Ads are no longer available until further notice - [**Toasty**](https://github.com/GrenderG/Toasty) for displaying error/success messages - [**ShapedImageView**](https://github.com/gavinliu/ShapedImageView) for round avatars - [**MaterialTapTargetPrompt**](https://github.com/sjwall/MaterialTapTargetPrompt) for displaying tips throughout the app -- **Firebase** crash reporting +- **Fabric** analytics & crash reporting. - **Android Support Libraries**, the almighty ;-) # Contribution diff --git a/app/build.gradle b/app/build.gradle index bbc68083..d6283337 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,8 +28,8 @@ android { applicationId "com.fastaccess.github" minSdkVersion 21 targetSdkVersion 26 - versionCode 253 - versionName "2.5.3" + versionCode 301 + versionName "3.0.1" signingConfig signingConfigs.signing buildConfigString "GITHUB_CLIENT_ID", (buildProperties.secrets['github_client_id'] | buildProperties.notThere['github_client_id']).string buildConfigString "GITHUB_SECRET", (buildProperties.secrets['github_secret'] | buildProperties.notThere['github_secret']).string @@ -49,7 +49,7 @@ android { buildTypes { release { minifyEnabled true - shrinkResources true + shrinkResources false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } @@ -92,6 +92,10 @@ android { compileOptions.incremental = false } +kapt { + generateStubs = true +} + repositories { maven { url "https://clojars.org/repo/" } maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } @@ -101,8 +105,6 @@ repositories { mavenCentral() } - - dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile "com.android.support:appcompat-v7:${supportVersion}" @@ -145,8 +147,6 @@ dependencies { } compile "com.github.miguelbcr:RxBillingService:0.0.3" compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" - compile "com.github.florent37:retrojsoup:${retrojsoupVersion}" - compile "com.github.florent37:rxjsoup:${retrojsoupVersion}" compile 'org.jsoup:jsoup:1.10.2' compile "com.evernote:android-state:${state_version}" provided "org.projectlombok:lombok:${lombokVersion}" @@ -156,7 +156,6 @@ dependencies { kapt "com.jakewharton:butterknife-compiler:${butterKnifeVersion}" kapt 'com.github.matthiasrobbers:shortbread-compiler:1.0.1' kapt "org.projectlombok:lombok:${lombokVersion}" - kapt "com.github.florent37:retrojsoup-compiler:${retrojsoupVersion}" // testCompile "net.grandcentrix.thirtyinch:thirtyinch-test:$thirtyinchVersion" testCompile "junit:junit:${junitVersion}" testCompile "org.mockito:mockito-core:${mockitoVersion}" diff --git a/app/fastacecss-public b/app/fastaccess-public similarity index 100% rename from app/fastacecss-public rename to app/fastaccess-public diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index eda99f73..943bb4f1 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -32,8 +32,7 @@ } -keep class com.google.gson.** { *; } -keep class com.google.inject.** { *; } --keep class org.apache.http.** { *; } --keep class org.apache.james.mime4j.** { *; } +-keep class org.apache.** { *; } -keep class javax.inject.** { *; } -keep class retrofit.** { *; } -keep class com.squareup.okhttp.** { *; } @@ -45,7 +44,7 @@ -dontwarn rx.** -dontwarn com.squareup.okhttp.** -dontwarn okio.** --dontwarn org.apache.http.** +-dontwarn org.apache.** -dontwarn android.net.http.AndroidHttpClient -dontwarn retrofit.** -dontwarn retrofit2.adapter.rxjava.CompletableHelper$** @@ -72,7 +71,8 @@ -keepclasseswithmembernames class * { @icepick.* ; } --keep class com.fastaccess.data.dao.** { *; } +-keep class com.fastaccess.data.** { *; } +-keep class com.fastaccess.provider.rest.** { *; } -keepclassmembers class com.prettifier.pretty.callback.MarkDownInterceptorInterface { public *; } @@ -80,6 +80,7 @@ -dontwarn java.util.** -dontwarn java.time.** -dontwarn javax.annotation.** +-dontwarn org.jetbrains.annotations.** -dontwarn javax.cache.** -dontwarn javax.naming.** -dontwarn javax.transaction.** @@ -101,11 +102,23 @@ ; } --keep class net.nightwhistler.** {*;} --keep class org.htmlcleaner.** {*;} +-keep class net.nightwhistler.** { *; } +-keep class org.htmlcleaner.** { *; } -dontwarn org.jaxen.** -dontwarn org.jdom.** -dontwarn com.google.android.gms.** -dontwarn android.animation.** -dontwarn java.io.** --dontwarn android.content.** +-dontwarn android.content.** +-dontwarn org.jdom.** +-dontwarn kotlin.reflect.jvm.internal.impl.descriptors.CallableDescriptor +-dontwarn kotlin.reflect.jvm.internal.impl.descriptors.ClassDescriptor +-dontwarn kotlin.reflect.jvm.internal.impl.descriptors.ClassifierDescriptorWithTypeParameters +-dontwarn kotlin.reflect.jvm.internal.impl.descriptors.annotations.AnnotationDescriptor +-dontwarn kotlin.reflect.jvm.internal.impl.descriptors.impl.PropertyDescriptorImpl +-dontwarn kotlin.reflect.jvm.internal.impl.load.java.JavaClassFinder +-dontwarn kotlin.reflect.jvm.internal.impl.resolve.OverridingUtil +-dontwarn kotlin.reflect.jvm.internal.impl.types.DescriptorSubstitutor +-dontwarn kotlin.reflect.jvm.internal.impl.types.DescriptorSubstitutor +-dontwarn kotlin.reflect.jvm.internal.impl.types.TypeConstructor +-keeppackagenames org.jsoup.nodes \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a5807739..64f0ef8d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -220,7 +220,7 @@ + android:exported="true"> diff --git a/app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl b/app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl deleted file mode 100755 index 2a492f78..00000000 --- a/app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.vending.billing; - -import android.os.Bundle; - -/** - * InAppBillingService is the service that provides in-app billing version 3 and beyond. - * This service provides the following features: - * 1. Provides a new API to get details of in-app items published for the app including - * price, type, title and description. - * 2. The purchase flow is synchronous and purchase information is available immediately - * after it completes. - * 3. Purchase information of in-app purchases is maintained within the Google Play system - * till the purchase is consumed. - * 4. An API to consume a purchase of an inapp item. All purchases of one-time - * in-app items are consumable and thereafter can be purchased again. - * 5. An API to get current purchases of the user immediately. This will not contain any - * consumed purchases. - * - * All calls will give a response code with the following possible values - * RESULT_OK = 0 - success - * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog - * RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested - * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase - * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API - * RESULT_ERROR = 6 - Fatal error during the API action - * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned - * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned - */ -interface IInAppBillingService { - /** - * Checks support for the requested billing API version, package and in-app type. - * Minimum API version supported by this interface is 3. - * @param apiVersion the billing version which the app is using - * @param packageName the package name of the calling app - * @param type type of the in-app item being purchased "inapp" for one-time purchases - * and "subs" for subscription. - * @return RESULT_OK(0) on success, corresponding result code on failures - */ - int isBillingSupported(int apiVersion, String packageName, String type); - - /** - * Provides details of a list of SKUs - * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle - * with a list JSON strings containing the productId, price, title and description. - * This API can be called with a maximum of 20 SKUs. - * @param apiVersion billing API version that the Third-party is using - * @param packageName the package name of the calling app - * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on - * failure as listed above. - * "DETAILS_LIST" with a StringArrayList containing purchase information - * in JSON format similar to: - * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00", - * "title : "Example Title", "description" : "This is an example description" }' - */ - Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle); - - /** - * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, - * the type, a unique purchase token and an optional developer payload. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param sku the SKU of the in-app item as published in the developer console - * @param type the type of the in-app item ("inapp" for one-time purchases - * and "subs" for subscription). - * @param developerPayload optional argument to be sent back with the purchase information - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on - * failure as listed above. - * "BUY_INTENT" - PendingIntent to start the purchase flow - * - * The Pending intent should be launched with startIntentSenderForResult. When purchase flow - * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. - * If the purchase is successful, the result data will contain the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on - * failure as listed above. - * "INAPP_PURCHASE_DATA" - String in JSON format similar to - * '{"orderId":"12999763169054705758.1371079406387615", - * "packageName":"com.example.app", - * "productId":"exampleSku", - * "purchaseTime":1345678900000, - * "purchaseToken" : "122333444455555", - * "developerPayload":"example developer payload" }' - * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that - * was signed with the private key of the developer - * TODO: change this to app-specific keys. - */ - Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type, - String developerPayload); - - /** - * Returns the current SKUs owned by the user of the type and package name specified along with - * purchase information and a signature of the data to be validated. - * This will return all SKUs that have been purchased in V3 and managed items purchased using - * V1 and V2 that have not been consumed. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param type the type of the in-app items being requested - * ("inapp" for one-time purchases and "subs" for subscription). - * @param continuationToken to be set as null for the first call, if the number of owned - * skus are too many, a continuationToken is returned in the response bundle. - * This method can be called again with the continuation token to get the next set of - * owned skus. - * @return Bundle containing the following key-value pairs - * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on - * failure as listed above. - * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs - * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information - * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures - * of the purchase information - * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the - * next set of in-app purchases. Only set if the - * user has more owned skus than the current list. - */ - Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken); - - /** - * Consume the last purchase of the given SKU. This will result in this item being removed - * from all subsequent responses to getPurchases() and allow re-purchase of this item. - * @param apiVersion billing API version that the app is using - * @param packageName package name of the calling app - * @param purchaseToken token in the purchase information JSON that identifies the purchase - * to be consumed - * @return 0 if consumption succeeded. Appropriate error values for failures. - */ - int consumePurchase(int apiVersion, String packageName, String purchaseToken); -} diff --git a/app/src/main/assets/highlight/js/lang-Splus.js b/app/src/main/assets/highlight/js/lang-Splus.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-aea.js b/app/src/main/assets/highlight/js/lang-aea.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-agc.js b/app/src/main/assets/highlight/js/lang-agc.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-apollo.js b/app/src/main/assets/highlight/js/lang-apollo.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-basic.js b/app/src/main/assets/highlight/js/lang-basic.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-cbm.js b/app/src/main/assets/highlight/js/lang-cbm.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-cl.js b/app/src/main/assets/highlight/js/lang-cl.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-clj.js b/app/src/main/assets/highlight/js/lang-clj.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-css.js b/app/src/main/assets/highlight/js/lang-css.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-dart.js b/app/src/main/assets/highlight/js/lang-dart.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-el.js b/app/src/main/assets/highlight/js/lang-el.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-erl.js b/app/src/main/assets/highlight/js/lang-erl.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-erlang.js b/app/src/main/assets/highlight/js/lang-erlang.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-fs.js b/app/src/main/assets/highlight/js/lang-fs.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-go.js b/app/src/main/assets/highlight/js/lang-go.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-hs.js b/app/src/main/assets/highlight/js/lang-hs.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-lasso.js b/app/src/main/assets/highlight/js/lang-lasso.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-lassoscript.js b/app/src/main/assets/highlight/js/lang-lassoscript.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-latex.js b/app/src/main/assets/highlight/js/lang-latex.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-lgt.js b/app/src/main/assets/highlight/js/lang-lgt.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-lisp.js b/app/src/main/assets/highlight/js/lang-lisp.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-ll.js b/app/src/main/assets/highlight/js/lang-ll.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-llvm.js b/app/src/main/assets/highlight/js/lang-llvm.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-logtalk.js b/app/src/main/assets/highlight/js/lang-logtalk.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-ls.js b/app/src/main/assets/highlight/js/lang-ls.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-lsp.js b/app/src/main/assets/highlight/js/lang-lsp.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-lua.js b/app/src/main/assets/highlight/js/lang-lua.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-matlab.js b/app/src/main/assets/highlight/js/lang-matlab.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-ml.js b/app/src/main/assets/highlight/js/lang-ml.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-mumps.js b/app/src/main/assets/highlight/js/lang-mumps.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-n.js b/app/src/main/assets/highlight/js/lang-n.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-nemerle.js b/app/src/main/assets/highlight/js/lang-nemerle.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-pascal.js b/app/src/main/assets/highlight/js/lang-pascal.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-proto.js b/app/src/main/assets/highlight/js/lang-proto.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-r.js b/app/src/main/assets/highlight/js/lang-r.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-rd.js b/app/src/main/assets/highlight/js/lang-rd.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-rkt.js b/app/src/main/assets/highlight/js/lang-rkt.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-rust.js b/app/src/main/assets/highlight/js/lang-rust.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-s.js b/app/src/main/assets/highlight/js/lang-s.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-scala.js b/app/src/main/assets/highlight/js/lang-scala.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-scm.js b/app/src/main/assets/highlight/js/lang-scm.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-sql.js b/app/src/main/assets/highlight/js/lang-sql.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-ss.js b/app/src/main/assets/highlight/js/lang-ss.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-swift.js b/app/src/main/assets/highlight/js/lang-swift.js old mode 100644 new mode 100755 index 5442fa77..eb5c3143 --- a/app/src/main/assets/highlight/js/lang-swift.js +++ b/app/src/main/assets/highlight/js/lang-swift.js @@ -1,16 +1,18 @@ /* Copyright (C) 2015 Google Inc. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[ \n\r\t\v\f\0]+/,null," \n\r\t\v\f\x00"],["str",/^"(?:[^"\\]|(?:\\.)|(?:\\\((?:[^"\\)]|\\.)*\)))*"/,null,'"']],[["lit",/^(?:(?:0x[\da-fA-F][\da-fA-F_]*\.[\da-fA-F][\da-fA-F_]*[pP]?)|(?:\d[\d_]*\.\d[\d_]*[eE]?))[+-]?\d[\d_]*/,null],["lit",/^-?(?:(?:0(?:(?:b[01][01_]*)|(?:o[0-7][0-7_]*)|(?:x[\da-fA-F][\da-fA-F_]*)))|(?:\d[\d_]*))/,null],["lit",/^(?:true|false|nil)\b/,null],["kwd",/^\b(?:__COLUMN__|__FILE__|__FUNCTION__|__LINE__|#available|#else|#elseif|#endif|#if|#line|arch|arm|arm64|associativity|as|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|dynamicType|else|enum|fallthrough|final|for|func|get|import|indirect|infix|init|inout|internal|i386|if|in|iOS|iOSApplicationExtension|is|lazy|left|let|mutating|none|nonmutating|operator|optional|OSX|OSXApplicationExtension|override|postfix|precedence|prefix|private|protocol|Protocol|public|required|rethrows|return|right|safe|self|set|static|struct|subscript|super|switch|throw|try|Type|typealias|unowned|unsafe|var|weak|watchOS|while|willSet|x86_64)\b/, +PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[ \n\r\t\v\f\0]+/,null," \n\r\t\v\f\x00"],["str",/^"(?:[^"\\]|(?:\\.)|(?:\\\((?:[^"\\)]|\\.)*\)))*"/,null,'"']],[["lit",/^(?:(?:0x[\da-fA-F][\da-fA-F_]*\.[\da-fA-F][\da-fA-F_]*[pP]?)|(?:\d[\d_]*\.\d[\d_]*[eE]?))[+-]?\d[\d_]*/,null],["lit",/^-?(?:(?:0(?:(?:b[01][01_]*)|(?:o[0-7][0-7_]*)|(?:x[\da-fA-F][\da-fA-F_]*)))|(?:\d[\d_]*))/,null],["lit",/^(?:true|false|nil)\b/,null],["kwd",/^\b(?:__COLUMN__|__FILE__|__FUNCTION__|__LINE__|#available|#else|#elseif|#endif|#if|#line|arch|arm|arm64|associativity|as|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|dynamicType|else|enum|extension|fallthrough|final|for|func|get|guard|import|indirect|infix|init|inout|internal|i386|if|in|iOS|iOSApplicationExtension|is|lazy|left|let|mutating|none|nonmutating|operator|optional|OSX|OSXApplicationExtension|override|postfix|precedence|prefix|private|protocol|Protocol|public|required|rethrows|return|right|safe|self|set|static|struct|subscript|super|switch|throw|try|Type|typealias|unowned|unsafe|var|weak|watchOS|while|willSet|x86_64)\b/, null],["com",/^\/\/.*?[\n\r]/,null],["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null],["pun",/^<<=|<=|<<|>>=|>=|>>|===|==|\.\.\.|&&=|\.\.<|!==|!=|&=|~=|~|\(|\)|\[|\]|{|}|@|#|;|\.|,|:|\|\|=|\?\?|\|\||&&|&\*|&\+|&-|&=|\+=|-=|\/=|\*=|\^=|%=|\|=|->|`|==|\+\+|--|\/|\+|!|\*|%|<|>|&|\||\^|\?|=|-|_/,null],["typ",/^\b(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null]]),["swift"]); diff --git a/app/src/main/assets/highlight/js/lang-tcl.js b/app/src/main/assets/highlight/js/lang-tcl.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-tex.js b/app/src/main/assets/highlight/js/lang-tex.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-vb.js b/app/src/main/assets/highlight/js/lang-vb.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-vbs.js b/app/src/main/assets/highlight/js/lang-vbs.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-vhd.js b/app/src/main/assets/highlight/js/lang-vhd.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-vhdl.js b/app/src/main/assets/highlight/js/lang-vhdl.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-wiki.js b/app/src/main/assets/highlight/js/lang-wiki.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-xq.js b/app/src/main/assets/highlight/js/lang-xq.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-xquery.js b/app/src/main/assets/highlight/js/lang-xquery.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-yaml.js b/app/src/main/assets/highlight/js/lang-yaml.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/lang-yml.js b/app/src/main/assets/highlight/js/lang-yml.js old mode 100644 new mode 100755 diff --git a/app/src/main/assets/highlight/js/prettify.js b/app/src/main/assets/highlight/js/prettify.js index abf46393..7809a8f0 100644 --- a/app/src/main/assets/highlight/js/prettify.js +++ b/app/src/main/assets/highlight/js/prettify.js @@ -1,6 +1,6 @@ /** * @license - * Copyright (C) 2006 Google Inc. + * Copyright (C) 2013 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,47 +17,50 @@ /** * @fileoverview - * some functions for browser-side pretty printing of code contained in html. + *
+ * Looks at query parameters to decide which language handlers and style-sheets + * to load. * - *

- * For a fairly comprehensive set of languages see the - * README - * file that came with this source. At a minimum, the lexer should work on a - * number of languages including C and friends, Java, Python, Bash, SQL, HTML, - * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk - * and a subset of Perl, but, because of commenting conventions, doesn't work on - * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. - *

- * Usage:

    - *
  1. include this source file in an html page via - * {@code } - *
  2. define style rules. See the example page for examples. - *
  3. mark the {@code
    } and {@code } tags in your source with
    - *    {@code class=prettyprint.}
    - *    You can also use the (html deprecated) {@code } tag, but the pretty
    - *    printer needs to do more substantial DOM manipulations to support that, so
    - *    some css styles may not be preserved.
    - * </ol>
    - * That's it.  I wanted to keep the API as simple as possible, so there's no
    - * need to specify which language the code is in, but if you wish, you can add
    - * another class to the {@code <pre>} or {@code <code>} element to specify the
    - * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    - * starts with "lang-" followed by a file extension, specifies the file type.
    - * See the "lang-*.js" files in this directory for code that implements
    - * per-language file handlers.
    - * <p>
    - * Change log:<br>
    - * cbeust, 2006/08/22
    - * <blockquote>
    - *   Java annotations (start with "@") are now captured as literals ("lit")
    - * </blockquote>
    - * @requires console
    + * Query Parameter     Format           Effect                        Default
    + * +------------------+---------------+------------------------------+--------+
    + * | autorun=         | true | false  | If true then prettyPrint()   | "true" |
    + * |                  |               | is called on page load.      |        |
    + * +------------------+---------------+------------------------------+--------+
    + * | lang=            | language name | Loads the language handler   | Can    |
    + * |                  |               | named "lang-<NAME>.js".      | appear |
    + * |                  |               | See available handlers at    | many   |
    + * |                  |               | https://github.com/google/   | times. |
    + * |                  |               | code-prettify/tree/master/   |        |
    + * |                  |               | src                          |        |
    + * +------------------+---------------+------------------------------+--------+
    + * | skin=            | skin name     | Loads the skin stylesheet    | none.  |
    + * |                  |               | named "<NAME>.css".          |        |
    + * |                  |               | https://cdn.rawgit.com/      |        |
    + * |                  |               | google/code-prettify/master/ |        |
    + * |                  |               | styles/index.html            |        |
    + * +------------------+---------------+------------------------------+--------+
    + * | callback=        | JS identifier | When "prettyPrint" finishes  | none   |
    + * |                  |               | window.exports[js_ident] is  |        |
    + * |                  |               | called.                      |        |
    + * |                  |               | The callback must be under   |        |
    + * |                  |               | exports to reduce the risk   |        |
    + * |                  |               | of XSS via query parameter   |        |
    + * |                  |               | injection.                   |        |
    + * +------------------+---------------+------------------------------+--------+
    + *
    + * Exmaples
    + * .../run_prettify.js?lang=css&skin=sunburst
    + *   1. Loads the CSS language handler which can be used to prettify CSS
    + *      stylesheets, HTML <style> element bodies and style="..." attributes
    + *      values.
    + *   2. Loads the sunburst.css stylesheet instead of the default prettify.css
    + *      stylesheet.
    + *      A gallery of stylesheets is available at
    + *      https://cdn.rawgit.com/google/code-prettify/master/styles/index.html
    + *   3. Since autorun=false is not specified, calls prettyPrint() on page load.
    + * </div>
      */
     
    -// JSLint declarations
    -/*global console, document, navigator, setTimeout, window, define */
    -
    -
     /**
     * @typedef {!Array.<number|string>}
     * Alternating indices and the decorations that should be inserted there.
    @@ -109,1634 +112,1887 @@ var SourceSpansT;
     /** @define {boolean} */
     var IN_GLOBAL_SCOPE = false;
     
    -var HACK_TO_FIX_JS_INCLUDE_PL;
    -
    -/**
    - * {@type !{
    - *   'createSimpleLexer': function (Array, Array): (function (JobT)),
    - *   'registerLangHandler': function (function (JobT), Array.<string>),
    - *   'PR_ATTRIB_NAME': string,
    - *   'PR_ATTRIB_NAME': string,
    - *   'PR_ATTRIB_VALUE': string,
    - *   'PR_COMMENT': string,
    - *   'PR_DECLARATION': string,
    - *   'PR_KEYWORD': string,
    - *   'PR_LITERAL': string,
    - *   'PR_NOCODE': string,
    - *   'PR_PLAIN': string,
    - *   'PR_PUNCTUATION': string,
    - *   'PR_SOURCE': string,
    - *   'PR_STRING': string,
    - *   'PR_TAG': string,
    - *   'PR_TYPE': string,
    - *   'prettyPrintOne': function (string, string, number|boolean),
    - *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
    - * }}
    - * @const
    - */
    -var PR;
    -
    -/**
    - * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    - * UI events.
    - * If set to {@code false}, {@code prettyPrint()} is synchronous.
    - */
    -window['PR_SHOULD_USE_CONTINUATION'] = true;
    -
    -/**
    - * Pretty print a chunk of code.
    - * @param {string} sourceCodeHtml The HTML to pretty print.
    - * @param {string} opt_langExtension The language name to use.
    - *     Typically, a filename extension like 'cpp' or 'java'.
    - * @param {number|boolean} opt_numberLines True to number lines,
    - *     or the 1-indexed number of the first line in sourceCodeHtml.
    - * @return {string} code as html, but prettier
    - */
    -var prettyPrintOne;
    -/**
    - * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    - * {@code class=prettyprint} and prettify them.
    - *
    - * @param {Function} opt_whenDone called when prettifying is done.
    - * @param {HTMLElement|HTMLDocument} opt_root an element or document
    - *   containing all the elements to pretty print.
    - *   Defaults to {@code document.body}.
    - */
    -var prettyPrint;
    -
    -
     (function () {
    +  "use strict";
    +
       var win = window;
    -  // Keyword lists for various languages.
    -  // We use things that coerce to strings to make them compact when minified
    -  // and to defeat aggressive optimizers that fold large string constants.
    -  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
    -  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
    -      "double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed," +
    -      "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
    -  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
    -      "new,operator,private,protected,public,this,throw,true,try,typeof"];
    -  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignas,alignof,align_union,asm,axiom,bool," +
    -      "concept,concept_map,const_cast,constexpr,decltype,delegate," +
    -      "dynamic_cast,explicit,export,friend,generic,late_check," +
    -      "mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert," +
    -      "static_cast,template,typeid,typename,using,virtual,where"];
    -  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
    -      "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
    -      "instanceof,interface,null,native,package,strictfp,super,synchronized," +
    -      "throws,transient"];
    -  var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
    -      "abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending," +
    -      "dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface," +
    -      "internal,into,is,join,let,lock,null,object,out,override,orderby,params," +
    -      "partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong," +
    -      "unchecked,unsafe,ushort,value,var,virtual,where,yield"];
    -  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
    -      "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
    -      "throw,true,try,unless,until,when,while,yes";
    -  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
    -      "abstract,async,await,constructor,debugger,enum,eval,export,function," +
    -      "get,implements,instanceof,interface,let,null,set,undefined,var,with," +
    -      "yield,Infinity,NaN"];
    -  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
    -      "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
    -      "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
    -  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
    -      "elif,except,exec,finally,from,global,import,in,is,lambda," +
    -      "nonlocal,not,or,pass,print,raise,try,with,yield," +
    -      "False,True,None"];
    -  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
    -      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
    -      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
    -      "BEGIN,END"];
    -  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
    -      "function,in,local,set,then,until"];
    -  var ALL_KEYWORDS = [
    -      CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
    -      PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
    -  var C_TYPES = /^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
    +  var doc = document;
    +  var root = doc.documentElement;
    +  var head = doc['head'] || doc.getElementsByTagName("head")[0] || root;
     
    -  // token style names.  correspond to css classes
    -  /**
    -   * token style for a string literal
    -   * @const
    -   */
    -  var PR_STRING = 'str';
    -  /**
    -   * token style for a keyword
    -   * @const
    -   */
    -  var PR_KEYWORD = 'kwd';
    -  /**
    -   * token style for a comment
    -   * @const
    -   */
    -  var PR_COMMENT = 'com';
    -  /**
    -   * token style for a type
    -   * @const
    -   */
    -  var PR_TYPE = 'typ';
    -  /**
    -   * token style for a literal value.  e.g. 1, null, true.
    -   * @const
    -   */
    -  var PR_LITERAL = 'lit';
    -  /**
    -   * token style for a punctuation string.
    -   * @const
    -   */
    -  var PR_PUNCTUATION = 'pun';
    -  /**
    -   * token style for plain text.
    -   * @const
    -   */
    -  var PR_PLAIN = 'pln';
    +  // From http://javascript.nwbox.com/ContentLoaded/contentloaded.js
    +  // Author: Diego Perini (diego.perini at gmail.com)
    +  // Summary: cross-browser wrapper for DOMContentLoaded
    +  // Updated: 20101020
    +  // License: MIT
    +  // Version: 1.2
    +  function contentLoaded(callback) {
    +    var addEventListener = doc['addEventListener'];
    +    var done = false, top = true,
    +        add = addEventListener ? 'addEventListener' : 'attachEvent',
    +        rem = addEventListener ? 'removeEventListener' : 'detachEvent',
    +        pre = addEventListener ? '' : 'on',
     
    -  /**
    -   * token style for an sgml tag.
    -   * @const
    -   */
    -  var PR_TAG = 'tag';
    -  /**
    -   * token style for a markup declaration such as a DOCTYPE.
    -   * @const
    -   */
    -  var PR_DECLARATION = 'dec';
    -  /**
    -   * token style for embedded source.
    -   * @const
    -   */
    -  var PR_SOURCE = 'src';
    -  /**
    -   * token style for an sgml attribute name.
    -   * @const
    -   */
    -  var PR_ATTRIB_NAME = 'atn';
    -  /**
    -   * token style for an sgml attribute value.
    -   * @const
    -   */
    -  var PR_ATTRIB_VALUE = 'atv';
    -
    -  /**
    -   * A class that indicates a section of markup that is not code, e.g. to allow
    -   * embedding of line numbers within code listings.
    -   * @const
    -   */
    -  var PR_NOCODE = 'nocode';
    -
    -  
    -  
    -  /**
    -   * A set of tokens that can precede a regular expression literal in
    -   * javascript
    -   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
    -   * has the full list, but I've removed ones that might be problematic when
    -   * seen in languages that don't support regular expression literals.
    -   *
    -   * <p>Specifically, I've removed any keywords that can't precede a regexp
    -   * literal in a syntactically legal javascript program, and I've removed the
    -   * "in" keyword since it's not a keyword in many languages, and might be used
    -   * as a count of inches.
    -   *
    -   * <p>The link above does not accurately describe EcmaScript rules since
    -   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    -   * very well in practice.
    -   *
    -   * @private
    -   * @const
    -   */
    -  var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    -  
    -  // CAVEAT: this does not properly handle the case where a regular
    -  // expression immediately follows another since a regular expression may
    -  // have flags for case-sensitivity and the like.  Having regexp tokens
    -  // adjacent is not valid in any language I'm aware of, so I'm punting.
    -  // TODO: maybe style special characters inside a regexp as punctuation.
    -
    -  /**
    -   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    -   * matches the union of the sets of strings matched by the input RegExp.
    -   * Since it matches globally, if the input strings have a start-of-input
    -   * anchor (/^.../), it is ignored for the purposes of unioning.
    -   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    -   * @return {RegExp} a global regex.
    -   */
    -  function combinePrefixPatterns(regexs) {
    -    var capturedGroupIndex = 0;
    -  
    -    var needToFoldCase = false;
    -    var ignoreCase = false;
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.ignoreCase) {
    -        ignoreCase = true;
    -      } else if (/[a-z]/i.test(regex.source.replace(
    -                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    -        needToFoldCase = true;
    -        ignoreCase = false;
    -        break;
    -      }
    -    }
    -  
    -    var escapeCharToCodeUnit = {
    -      'b': 8,
    -      't': 9,
    -      'n': 0xa,
    -      'v': 0xb,
    -      'f': 0xc,
    -      'r': 0xd
    -    };
    -  
    -    function decodeEscape(charsetPart) {
    -      var cc0 = charsetPart.charCodeAt(0);
    -      if (cc0 !== 92 /* \\ */) {
    -        return cc0;
    -      }
    -      var c1 = charsetPart.charAt(1);
    -      cc0 = escapeCharToCodeUnit[c1];
    -      if (cc0) {
    -        return cc0;
    -      } else if ('0' <= c1 && c1 <= '7') {
    -        return parseInt(charsetPart.substring(1), 8);
    -      } else if (c1 === 'u' || c1 === 'x') {
    -        return parseInt(charsetPart.substring(2), 16);
    -      } else {
    -        return charsetPart.charCodeAt(1);
    -      }
    -    }
    -  
    -    function encodeEscape(charCode) {
    -      if (charCode < 0x20) {
    -        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    -      }
    -      var ch = String.fromCharCode(charCode);
    -      return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
    -          ? "\\" + ch : ch;
    -    }
    -  
    -    function caseFoldCharset(charSet) {
    -      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    -          new RegExp(
    -              '\\\\u[0-9A-Fa-f]{4}'
    -              + '|\\\\x[0-9A-Fa-f]{2}'
    -              + '|\\\\[0-3][0-7]{0,2}'
    -              + '|\\\\[0-7]{1,2}'
    -              + '|\\\\[\\s\\S]'
    -              + '|-'
    -              + '|[^-\\\\]',
    -              'g'));
    -      var ranges = [];
    -      var inverse = charsetParts[0] === '^';
    -  
    -      var out = ['['];
    -      if (inverse) { out.push('^'); }
    -  
    -      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    -        var p = charsetParts[i];
    -        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
    -          out.push(p);
    -        } else {
    -          var start = decodeEscape(p);
    -          var end;
    -          if (i + 2 < n && '-' === charsetParts[i + 1]) {
    -            end = decodeEscape(charsetParts[i + 2]);
    -            i += 2;
    -          } else {
    -            end = start;
    +        init = function(e) {
    +          if (e.type == 'readystatechange' && doc.readyState != 'complete') {
    +            return;
               }
    -          ranges.push([start, end]);
    -          // If the range might intersect letters, then expand it.
    -          // This case handling is too simplistic.
    -          // It does not deal with non-latin case folding.
    -          // It works for latin source code identifiers though.
    -          if (!(end < 65 || start > 122)) {
    -            if (!(end < 65 || start > 90)) {
    -              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    -            }
    -            if (!(end < 97 || start > 122)) {
    -              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    -            }
    +          (e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
    +          if (!done && (done = true)) { callback.call(win, e.type || e); }
    +        },
    +
    +        poll = function() {
    +          try {
    +            root.doScroll('left');
    +          } catch(e) {
    +            win.setTimeout(poll, 50);
    +            return;
               }
    -        }
    -      }
    -  
    -      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    -      // -> [[1, 12], [14, 14], [16, 17]]
    -      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    -      var consolidatedRanges = [];
    -      var lastRange = [];
    -      for (var i = 0; i < ranges.length; ++i) {
    -        var range = ranges[i];
    -        if (range[0] <= lastRange[1] + 1) {
    -          lastRange[1] = Math.max(lastRange[1], range[1]);
    -        } else {
    -          consolidatedRanges.push(lastRange = range);
    -        }
    -      }
    -  
    -      for (var i = 0; i < consolidatedRanges.length; ++i) {
    -        var range = consolidatedRanges[i];
    -        out.push(encodeEscape(range[0]));
    -        if (range[1] > range[0]) {
    -          if (range[1] + 1 > range[0]) { out.push('-'); }
    -          out.push(encodeEscape(range[1]));
    -        }
    -      }
    -      out.push(']');
    -      return out.join('');
    -    }
    -  
    -    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    -      // Split into character sets, escape sequences, punctuation strings
    -      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    -      // include any of the above.
    -      var parts = regex.source.match(
    -          new RegExp(
    -              '(?:'
    -              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    -              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    -              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    -              + '|\\\\[0-9]+'  // a back-reference or octal escape
    -              + '|\\\\[^ux0-9]'  // other escape sequence
    -              + '|\\(\\?[:!=]'  // start of a non-capturing group
    -              + '|[\\(\\)\\^]'  // start/end of a group, or line start
    -              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    -              + ')',
    -              'g'));
    -      var n = parts.length;
    -  
    -      // Maps captured group numbers to the number they will occupy in
    -      // the output or to -1 if that has not been determined, or to
    -      // undefined if they need not be capturing in the output.
    -      var capturedGroups = [];
    -  
    -      // Walk over and identify back references to build the capturedGroups
    -      // mapping.
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          // groups are 1-indexed, so max group index is count of '('
    -          ++groupIndex;
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue) {
    -            if (decimalValue <= groupIndex) {
    -              capturedGroups[decimalValue] = -1;
    -            } else {
    -              // Replace with an unambiguous escape sequence so that
    -              // an octal escape sequence does not turn into a backreference
    -              // to a capturing group from an earlier regex.
    -              parts[i] = encodeEscape(decimalValue);
    -            }
    -          }
    -        }
    -      }
    -  
    -      // Renumber groups and reduce capturing groups to non-capturing groups
    -      // where possible.
    -      for (var i = 1; i < capturedGroups.length; ++i) {
    -        if (-1 === capturedGroups[i]) {
    -          capturedGroups[i] = ++capturedGroupIndex;
    -        }
    -      }
    -      for (var i = 0, groupIndex = 0; i < n; ++i) {
    -        var p = parts[i];
    -        if (p === '(') {
    -          ++groupIndex;
    -          if (!capturedGroups[groupIndex]) {
    -            parts[i] = '(?:';
    -          }
    -        } else if ('\\' === p.charAt(0)) {
    -          var decimalValue = +p.substring(1);
    -          if (decimalValue && decimalValue <= groupIndex) {
    -            parts[i] = '\\' + capturedGroups[decimalValue];
    -          }
    -        }
    -      }
    -  
    -      // Remove any prefix anchors so that the output will match anywhere.
    -      // ^^ really does mean an anchored match though.
    -      for (var i = 0; i < n; ++i) {
    -        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    -      }
    -  
    -      // Expand letters to groups to handle mixing of case-sensitive and
    -      // case-insensitive patterns if necessary.
    -      if (regex.ignoreCase && needToFoldCase) {
    -        for (var i = 0; i < n; ++i) {
    -          var p = parts[i];
    -          var ch0 = p.charAt(0);
    -          if (p.length >= 2 && ch0 === '[') {
    -            parts[i] = caseFoldCharset(p);
    -          } else if (ch0 !== '\\') {
    -            // TODO: handle letters in numeric escapes.
    -            parts[i] = p.replace(
    -                /[a-zA-Z]/g,
    -                function (ch) {
    -                  var cc = ch.charCodeAt(0);
    -                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    -                });
    -          }
    -        }
    -      }
    -  
    -      return parts.join('');
    -    }
    -  
    -    var rewritten = [];
    -    for (var i = 0, n = regexs.length; i < n; ++i) {
    -      var regex = regexs[i];
    -      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    -      rewritten.push(
    -          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    -    }
    -  
    -    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    -  }
    +          init('poll');
    +        };
     
    -  /**
    -   * Split markup into a string of source code and an array mapping ranges in
    -   * that string to the text nodes in which they appear.
    -   *
    -   * <p>
    -   * The HTML DOM structure:</p>
    -   * <pre>
    -   * (Element   "p"
    -   *   (Element "b"
    -   *     (Text  "print "))       ; #1
    -   *   (Text    "'Hello '")      ; #2
    -   *   (Element "br")            ; #3
    -   *   (Text    "  + 'World';")) ; #4
    -   * </pre>
    -   * <p>
    -   * corresponds to the HTML
    -   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
    -   *
    -   * <p>
    -   * It will produce the output:</p>
    -   * <pre>
    -   * {
    -   *   sourceCode: "print 'Hello '\n  + 'World';",
    -   *   //                     1          2
    -   *   //           012345678901234 5678901234567
    -   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
    -   * }
    -   * </pre>
    -   * <p>
    -   * where #1 is a reference to the {@code "print "} text node above, and so
    -   * on for the other text nodes.
    -   * </p>
    -   *
    -   * <p>
    -   * The {@code} spans array is an array of pairs.  Even elements are the start
    -   * indices of substrings, and odd elements are the text nodes (or BR elements)
    -   * that contain the text for those substrings.
    -   * Substrings continue until the next index or the end of the source.
    -   * </p>
    -   *
    -   * @param {Node} node an HTML DOM subtree containing source-code.
    -   * @param {boolean|number} isPreformatted truthy if white-space in
    -   *    text nodes should be considered significant.
    -   * @return {SourceSpansT} source code and the nodes in which they occur.
    -   */
    -  function extractSourceSpans(node, isPreformatted) {
    -    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    -  
    -    var chunks = [];
    -    var length = 0;
    -    var spans = [];
    -    var k = 0;
    -  
    -    function walk(node) {
    -      var type = node.nodeType;
    -      if (type == 1) {  // Element
    -        if (nocode.test(node.className)) { return; }
    -        for (var child = node.firstChild; child; child = child.nextSibling) {
    -          walk(child);
    -        }
    -        var nodeName = node.nodeName.toLowerCase();
    -        if ('br' === nodeName || 'li' === nodeName) {
    -          chunks[k] = '\n';
    -          spans[k << 1] = length++;
    -          spans[(k++ << 1) | 1] = node;
    -        }
    -      } else if (type == 3 || type == 4) {  // Text
    -        var text = node.nodeValue;
    -        if (text.length) {
    -          if (!isPreformatted) {
    -            text = text.replace(/[ \t\r\n]+/g, ' ');
    -          } else {
    -            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
    -          }
    -          // TODO: handle tabs here?
    -          chunks[k] = text;
    -          spans[k << 1] = length;
    -          length += text.length;
    -          spans[(k++ << 1) | 1] = node;
    -        }
    -      }
    -    }
    -  
    -    walk(node);
    -  
    -    return {
    -      sourceCode: chunks.join('').replace(/\n$/, ''),
    -      spans: spans
    -    };
    -  }
    -
    -  /**
    -   * Apply the given language handler to sourceCode and add the resulting
    -   * decorations to out.
    -   * @param {!Element} sourceNode
    -   * @param {number} basePos the index of sourceCode within the chunk of source
    -   *    whose decorations are already present on out.
    -   * @param {string} sourceCode
    -   * @param {function(JobT)} langHandler
    -   * @param {DecorationsT} out
    -   */
    -  function appendDecorations(
    -      sourceNode, basePos, sourceCode, langHandler, out) {
    -    if (!sourceCode) { return; }
    -    /** @type {JobT} */
    -    var job = {
    -      sourceNode: sourceNode,
    -      pre: 1,
    -      langExtension: null,
    -      numberLines: null,
    -      sourceCode: sourceCode,
    -      spans: null,
    -      basePos: basePos,
    -      decorations: null
    -    };
    -    langHandler(job);
    -    out.push.apply(out, job.decorations);
    -  }
    -
    -  var notWs = /\S/;
    -
    -  /**
    -   * Given an element, if it contains only one child element and any text nodes
    -   * it contains contain only space characters, return the sole child element.
    -   * Otherwise returns undefined.
    -   * <p>
    -   * This is meant to return the CODE element in {@code <pre><code ...>} when
    -   * there is a single child element that contains all the non-space textual
    -   * content, but not to return anything where there are multiple child elements
    -   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
    -   * is textual content.
    -   */
    -  function childContentWrapper(element) {
    -    var wrapper = undefined;
    -    for (var c = element.firstChild; c; c = c.nextSibling) {
    -      var type = c.nodeType;
    -      wrapper = (type === 1)  // Element Node
    -          ? (wrapper ? element : c)
    -          : (type === 3)  // Text Node
    -          ? (notWs.test(c.nodeValue) ? element : wrapper)
    -          : wrapper;
    -    }
    -    return wrapper === element ? undefined : wrapper;
    -  }
    -
    -  /** Given triples of [style, pattern, context] returns a lexing function,
    -    * The lexing function interprets the patterns to find token boundaries and
    -    * returns a decoration list of the form
    -    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    -    * where index_n is an index into the sourceCode, and style_n is a style
    -    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    -    * all characters in sourceCode[index_n-1:index_n].
    -    *
    -    * The stylePatterns is a list whose elements have the form
    -    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    -    *
    -    * Style is a style constant like PR_PLAIN, or can be a string of the
    -    * form 'lang-FOO', where FOO is a language extension describing the
    -    * language of the portion of the token in $1 after pattern executes.
    -    * E.g., if style is 'lang-lisp', and group 1 contains the text
    -    * '(hello (world))', then that portion of the token will be passed to the
    -    * registered lisp handler for formatting.
    -    * The text before and after group 1 will be restyled using this decorator
    -    * so decorators should take care that this doesn't result in infinite
    -    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    -    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    -    * '<script>foo()<\/script>', which would cause the current decorator to
    -    * be called with '<script>' which would not match the same rule since
    -    * group 1 must not be empty, so it would be instead styled as PR_TAG by
    -    * the generic tag rule.  The handler registered for the 'js' extension would
    -    * then be called with 'foo()', and finally, the current decorator would
    -    * be called with '<\/script>' which would not match the original rule and
    -    * so the generic tag rule would identify it as a tag.
    -    *
    -    * Pattern must only match prefixes, and if it matches a prefix, then that
    -    * match is considered a token with the same style.
    -    *
    -    * Context is applied to the last non-whitespace, non-comment token
    -    * recognized.
    -    *
    -    * Shortcut is an optional string of characters, any of which, if the first
    -    * character, gurantee that this pattern and only this pattern matches.
    -    *
    -    * @param {Array} shortcutStylePatterns patterns that always start with
    -    *   a known character.  Must have a shortcut string.
    -    * @param {Array} fallthroughStylePatterns patterns that will be tried in
    -    *   order if the shortcut ones fail.  May have shortcuts.
    -    *
    -    * @return {function (JobT)} a function that takes an undecorated job and
    -    *   attaches a list of decorations.
    -    */
    -  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    -    var shortcuts = {};
    -    var tokenizer;
    -    (function () {
    -      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    -      var allRegexs = [];
    -      var regexKeys = {};
    -      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    -        var patternParts = allPatterns[i];
    -        var shortcutChars = patternParts[3];
    -        if (shortcutChars) {
    -          for (var c = shortcutChars.length; --c >= 0;) {
    -            shortcuts[shortcutChars.charAt(c)] = patternParts;
    -          }
    -        }
    -        var regex = patternParts[1];
    -        var k = '' + regex;
    -        if (!regexKeys.hasOwnProperty(k)) {
    -          allRegexs.push(regex);
    -          regexKeys[k] = null;
    -        }
    -      }
    -      allRegexs.push(/[\0-\uffff]/);
    -      tokenizer = combinePrefixPatterns(allRegexs);
    -    })();
    -
    -    var nPatterns = fallthroughStylePatterns.length;
    -
    -    /**
    -     * Lexes job.sourceCode and attaches an output array job.decorations of
    -     * style classes preceded by the position at which they start in
    -     * job.sourceCode in order.
    -     *
    -     * @type{function (JobT)}
    -     */
    -    var decorate = function (job) {
    -      var sourceCode = job.sourceCode, basePos = job.basePos;
    -      var sourceNode = job.sourceNode;
    -      /** Even entries are positions in source in ascending order.  Odd enties
    -        * are style markers (e.g., PR_COMMENT) that run from that position until
    -        * the end.
    -        * @type {DecorationsT}
    -        */
    -      var decorations = [basePos, PR_PLAIN];
    -      var pos = 0;  // index into sourceCode
    -      var tokens = sourceCode.match(tokenizer) || [];
    -      var styleCache = {};
    -
    -      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    -        var token = tokens[ti];
    -        var style = styleCache[token];
    -        var match = void 0;
    -
    -        var isEmbedded;
    -        if (typeof style === 'string') {
    -          isEmbedded = false;
    -        } else {
    -          var patternParts = shortcuts[token.charAt(0)];
    -          if (patternParts) {
    -            match = token.match(patternParts[1]);
    -            style = patternParts[0];
    -          } else {
    -            for (var i = 0; i < nPatterns; ++i) {
    -              patternParts = fallthroughStylePatterns[i];
    -              match = token.match(patternParts[1]);
    -              if (match) {
    -                style = patternParts[0];
    -                break;
    -              }
    -            }
    -
    -            if (!match) {  // make sure that we make progress
    -              style = PR_PLAIN;
    -            }
    -          }
    -
    -          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    -          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    -            isEmbedded = false;
    -            style = PR_SOURCE;
    -          }
    -
    -          if (!isEmbedded) { styleCache[token] = style; }
    -        }
    -
    -        var tokenStart = pos;
    -        pos += token.length;
    -
    -        if (!isEmbedded) {
    -          decorations.push(basePos + tokenStart, style);
    -        } else {  // Treat group 1 as an embedded block of source code.
    -          var embeddedSource = match[1];
    -          var embeddedSourceStart = token.indexOf(embeddedSource);
    -          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    -          if (match[2]) {
    -            // If embeddedSource can be blank, then it would match at the
    -            // beginning which would cause us to infinitely recurse on the
    -            // entire token, so we catch the right context in match[2].
    -            embeddedSourceEnd = token.length - match[2].length;
    -            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    -          }
    -          var lang = style.substring(5);
    -          // Decorate the left of the embedded source
    -          appendDecorations(
    -              sourceNode,
    -              basePos + tokenStart,
    -              token.substring(0, embeddedSourceStart),
    -              decorate, decorations);
    -          // Decorate the embedded source
    -          appendDecorations(
    -              sourceNode,
    -              basePos + tokenStart + embeddedSourceStart,
    -              embeddedSource,
    -              langHandlerForExtension(lang, embeddedSource),
    -              decorations);
    -          // Decorate the right of the embedded section
    -          appendDecorations(
    -              sourceNode,
    -              basePos + tokenStart + embeddedSourceEnd,
    -              token.substring(embeddedSourceEnd),
    -              decorate, decorations);
    -        }
    -      }
    -      job.decorations = decorations;
    -    };
    -    return decorate;
    -  }
    -
    -  /** returns a function that produces a list of decorations from source text.
    -    *
    -    * This code treats ", ', and ` as string delimiters, and \ as a string
    -    * escape.  It does not recognize perl's qq() style strings.
    -    * It has no special handling for double delimiter escapes as in basic, or
    -    * the tripled delimiters used in python, but should work on those regardless
    -    * although in those cases a single string literal may be broken up into
    -    * multiple adjacent string literals.
    -    *
    -    * It recognizes C, C++, and shell style comments.
    -    *
    -    * @param {Object} options a set of optional parameters.
    -    * @return {function (JobT)} a function that examines the source code
    -    *     in the input job and builds a decoration list which it attaches to
    -    *     the job.
    -    */
    -  function sourceDecorator(options) {
    -    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    -    if (options['tripleQuotedStrings']) {
    -      // '''multi-line-string''', 'single-line-string', and double-quoted
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    -           null, '\'"']);
    -    } else if (options['multiLineStrings']) {
    -      // 'multi-line-string', "multi-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    -           null, '\'"`']);
    +    if (doc.readyState == 'complete') {
    +      callback.call(win, 'lazy');
         } else {
    -      // 'single-line-string', "single-line-string"
    -      shortcutStylePatterns.push(
    -          [PR_STRING,
    -           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    -           null, '"\'']);
    -    }
    -    if (options['verbatimStrings']) {
    -      // verbatim-string-literal production from the C# grammar.  See issue 93.
    -      fallthroughStylePatterns.push(
    -          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    -    }
    -    var hc = options['hashComments'];
    -    if (hc) {
    -      if (options['cStyleComments']) {
    -        if (hc > 1) {  // multiline hash comments
    -          shortcutStylePatterns.push(
    -              [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
    -        } else {
    -          // Stop C preprocessor declarations at an unclosed open comment
    -          shortcutStylePatterns.push(
    -              [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
    -               null, '#']);
    -        }
    -        // #include <stdio.h>
    -        fallthroughStylePatterns.push(
    -            [PR_STRING,
    -             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
    -             null]);
    -      } else {
    -        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    +      if (doc.createEventObject && root.doScroll) {
    +        try { top = !win.frameElement; } catch(e) { }
    +        if (top) { poll(); }
           }
    +      doc[add](pre + 'DOMContentLoaded', init, false);
    +      doc[add](pre + 'readystatechange', init, false);
    +      win[add](pre + 'load', init, false);
         }
    -    if (options['cStyleComments']) {
    -      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    -      fallthroughStylePatterns.push(
    -          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    -    }
    -    var regexLiterals = options['regexLiterals'];
    -    if (regexLiterals) {
    -      /**
    -       * @const
    -       */
    -      var regexExcls = regexLiterals > 1
    -        ? ''  // Multiline regex literals
    -        : '\n\r';
    -      /**
    -       * @const
    -       */
    -      var regexAny = regexExcls ? '.' : '[\\S\\s]';
    -      /**
    -       * @const
    -       */
    -      var REGEX_LITERAL = (
    -          // A regular expression literal starts with a slash that is
    -          // not followed by * or / so that it is not confused with
    -          // comments.
    -          '/(?=[^/*' + regexExcls + '])'
    -          // and then contains any number of raw characters,
    -          + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
    -          // escape sequences (\x5C),
    -          +    '|\\x5C' + regexAny
    -          // or non-nesting character sets (\x5B\x5D);
    -          +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
    -          +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
    -          // finally closed by a /.
    -          + '/');
    -      fallthroughStylePatterns.push(
    -          ['lang-regex',
    -           RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    -           ]);
    -    }
    -
    -    var types = options['types'];
    -    if (types) {
    -      fallthroughStylePatterns.push([PR_TYPE, types]);
    -    }
    -
    -    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
    -    if (keywords.length) {
    -      fallthroughStylePatterns.push(
    -          [PR_KEYWORD,
    -           new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
    -           null]);
    -    }
    -
    -    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    -
    -    var punctuation =
    -      // The Bash man page says
    -
    -      // A word is a sequence of characters considered as a single
    -      // unit by GRUB. Words are separated by metacharacters,
    -      // which are the following plus space, tab, and newline: { }
    -      // | & $ ; < >
    -      // ...
    -
    -      // A word beginning with # causes that word and all remaining
    -      // characters on that line to be ignored.
    -
    -      // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
    -      // comment but empirically
    -      // $ echo {#}
    -      // {#}
    -      // $ echo \$#
    -      // $#
    -      // $ echo }#
    -      // }#
    -
    -      // so /(?:^|[|&;<>\s])/ is more appropriate.
    -
    -      // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
    -      // suggests that this definition is compatible with a
    -      // default mode that tries to use a single token definition
    -      // to recognize both bash/python style comments and C
    -      // preprocessor directives.
    -
    -      // This definition of punctuation does not include # in the list of
    -      // follow-on exclusions, so # will not be broken before if preceeded
    -      // by a punctuation character.  We could try to exclude # after
    -      // [|&;<>] but that doesn't seem to cause many major problems.
    -      // If that does turn out to be a problem, we should change the below
    -      // when hc is truthy to include # in the run of punctuation characters
    -      // only when not followint [|&;<>].
    -      '^.[^\\s\\w.$@\'"`/\\\\]*';
    -    if (options['regexLiterals']) {
    -      punctuation += '(?!\s*\/)';
    -    }
    -
    -    fallthroughStylePatterns.push(
    -        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    -        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
    -        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    -        [PR_LITERAL,
    -         new RegExp(
    -             '^(?:'
    -             // A hex number
    -             + '0x[a-f0-9]+'
    -             // or an octal or decimal number,
    -             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    -             // possibly in scientific notation
    -             + '(?:e[+\\-]?\\d+)?'
    -             + ')'
    -             // with an optional modifier like UL for unsigned long
    -             + '[a-z]*', 'i'),
    -         null, '0123456789'],
    -        // Don't treat escaped quotes in bash as starting strings.
    -        // See issue 144.
    -        [PR_PLAIN,       /^\\[\s\S]?/, null],
    -        [PR_PUNCTUATION, new RegExp(punctuation), null]);
    -
    -    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
       }
     
    -  var decorateSource = sourceDecorator({
    -        'keywords': ALL_KEYWORDS,
    -        'hashComments': true,
    -        'cStyleComments': true,
    -        'multiLineStrings': true,
    -        'regexLiterals': true
    +  // Given a list of URLs to stylesheets, loads the first that loads without
    +  // triggering an error event.
    +  function loadStylesheetsFallingBack(stylesheets) {
    +    var n = stylesheets.length;
    +    function load(i) {
    +      if (i === n) { return; }
    +      var link = doc.createElement('link');
    +      link.rel = 'stylesheet';
    +      link.type = 'text/css';
    +      if (i + 1 < n) {
    +        // http://pieisgood.org/test/script-link-events/ indicates that many
    +        // versions of IE do not support onerror on <link>s, though
    +        // http://msdn.microsoft.com/en-us/library/ie/ms535848(v=vs.85).aspx
    +        // indicates that recent IEs do support error.
    +        link.error = link.onerror = function () { load(i + 1); };
    +      }
    +      link.href = stylesheets[i];
    +      head.appendChild(link);
    +    }
    +    load(0);
    +  }
    +
    +  var scriptQuery = '';
    +  // Look for the <script> node that loads this script to get its parameters.
    +  // This starts looking at the end instead of just considering the last
    +  // because deferred and async scripts run out of order.
    +  // If the script is loaded twice, then this will run in reverse order.
    +  var scripts = doc.getElementsByTagName('script');
    +  for (var i = scripts.length; --i >= 0;) {
    +    var script = scripts[i];
    +    var match = script.src.match(
    +        /^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);
    +    if (match) {
    +      scriptQuery = match[1] || '';
    +      // Remove the script from the DOM so that multiple runs at least run
    +      // multiple times even if parameter sets are interpreted in reverse
    +      // order.
    +      script.parentNode.removeChild(script);
    +      break;
    +    }
    +  }
    +
    +  // Pull parameters into local variables.
    +  var autorun = true;
    +  var langs = [];
    +  var skins = [];
    +  var callbacks = [];
    +  scriptQuery.replace(
    +      /[?&]([^&=]+)=([^&]+)/g,
    +      function (_, name, value) {
    +        value = decodeURIComponent(value);
    +        name = decodeURIComponent(name);
    +        if (name == 'autorun')   { autorun = !/^[0fn]/i.test(value); } else
    +        if (name == 'lang')      { langs.push(value);                } else
    +        if (name == 'skin')      { skins.push(value);                } else
    +        if (name == 'callback')  { callbacks.push(value);            }
           });
     
    -  /**
    -   * Given a DOM subtree, wraps it in a list, and puts each line into its own
    -   * list item.
    -   *
    -   * @param {Node} node modified in place.  Its content is pulled into an
    -   *     HTMLOListElement, and each line is moved into a separate list item.
    -   *     This requires cloning elements, so the input might not have unique
    -   *     IDs after numbering.
    -   * @param {number|null|boolean} startLineNum
    -   *     If truthy, coerced to an integer which is the 1-indexed line number
    -   *     of the first line of code.  The number of the first line will be
    -   *     attached to the list.
    -   * @param {boolean} isPreformatted true iff white-space in text nodes should
    -   *     be treated as significant.
    -   */
    -  function numberLines(node, startLineNum, isPreformatted) {
    -    var nocode = /(?:^|\s)nocode(?:\s|$)/;
    -    var lineBreak = /\r\n?|\n/;
    -  
    -    var document = node.ownerDocument;
    -  
    -    var li = document.createElement('li');
    -    while (node.firstChild) {
    -      li.appendChild(node.firstChild);
    -    }
    -    // An array of lines.  We split below, so this is initialized to one
    -    // un-split line.
    -    var listItems = [li];
    -  
    -    function walk(node) {
    -      var type = node.nodeType;
    -      if (type == 1 && !nocode.test(node.className)) {  // Element
    -        if ('br' === node.nodeName) {
    -          breakAfter(node);
    -          // Discard the <BR> since it is now flush against a </LI>.
    -          if (node.parentNode) {
    -            node.parentNode.removeChild(node);
    -          }
    -        } else {
    -          for (var child = node.firstChild; child; child = child.nextSibling) {
    -            walk(child);
    -          }
    +  // Use https to avoid mixed content warnings in client pages and to
    +  // prevent a MITM from rewrite prettify mid-flight.
    +  // This only works if this script is loaded via https : something
    +  // over which we exercise no control.
    +  var LOADER_BASE_URL =
    +     'https://cdn.rawgit.com/google/code-prettify/master/loader';
    +
    +  for (var i = 0, n = langs.length; i < n; ++i) (function (lang) {
    +    var script = doc.createElement("script");
    +
    +    // Excerpted from jQuery.ajaxTransport("script") to fire events when
    +    // a script is finished loading.
    +    // Attach handlers for each script
    +    script.onload = script.onerror = script.onreadystatechange = function () {
    +      if (script && (
    +            !script.readyState || /loaded|complete/.test(script.readyState))) {
    +        // Handle memory leak in IE
    +        script.onerror = script.onload = script.onreadystatechange = null;
    +
    +        --pendingLanguages;
    +        checkPendingLanguages();
    +
    +        // Remove the script
    +        if (script.parentNode) {
    +          script.parentNode.removeChild(script);
             }
    -      } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
    -        var text = node.nodeValue;
    -        var match = text.match(lineBreak);
    -        if (match) {
    -          var firstLine = text.substring(0, match.index);
    -          node.nodeValue = firstLine;
    -          var tail = text.substring(match.index + match[0].length);
    -          if (tail) {
    -            var parent = node.parentNode;
    -            parent.insertBefore(
    -              document.createTextNode(tail), node.nextSibling);
    -          }
    -          breakAfter(node);
    -          if (!firstLine) {
    -            // Don't leave blank text nodes in the DOM.
    -            node.parentNode.removeChild(node);
    -          }
    -        }
    -      }
    -    }
    -  
    -    // Split a line after the given node.
    -    function breakAfter(lineEndNode) {
    -      // If there's nothing to the right, then we can skip ending the line
    -      // here, and move root-wards since splitting just before an end-tag
    -      // would require us to create a bunch of empty copies.
    -      while (!lineEndNode.nextSibling) {
    -        lineEndNode = lineEndNode.parentNode;
    -        if (!lineEndNode) { return; }
    -      }
    -  
    -      function breakLeftOf(limit, copy) {
    -        // Clone shallowly if this node needs to be on both sides of the break.
    -        var rightSide = copy ? limit.cloneNode(false) : limit;
    -        var parent = limit.parentNode;
    -        if (parent) {
    -          // We clone the parent chain.
    -          // This helps us resurrect important styling elements that cross lines.
    -          // E.g. in <i>Foo<br>Bar</i>
    -          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
    -          var parentClone = breakLeftOf(parent, 1);
    -          // Move the clone and everything to the right of the original
    -          // onto the cloned parent.
    -          var next = limit.nextSibling;
    -          parentClone.appendChild(rightSide);
    -          for (var sibling = next; sibling; sibling = next) {
    -            next = sibling.nextSibling;
    -            parentClone.appendChild(sibling);
    -          }
    -        }
    -        return rightSide;
    -      }
    -  
    -      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
    -  
    -      // Walk the parent chain until we reach an unattached LI.
    -      for (var parent;
    -           // Check nodeType since IE invents document fragments.
    -           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
    -        copiedListItem = parent;
    -      }
    -      // Put it on the list of lines for later processing.
    -      listItems.push(copiedListItem);
    -    }
    -  
    -    // Split lines while there are lines left to split.
    -    for (var i = 0;  // Number of lines that have been split so far.
    -         i < listItems.length;  // length updated by breakAfter calls.
    -         ++i) {
    -      walk(listItems[i]);
    -    }
    -  
    -    // Make sure numeric indices show correctly.
    -    if (startLineNum === (startLineNum|0)) {
    -      listItems[0].setAttribute('value', startLineNum);
    -    }
    -  
    -    var ol = document.createElement('ol');
    -    ol.className = 'linenums';
    -    var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
    -    for (var i = 0, n = listItems.length; i < n; ++i) {
    -      li = listItems[i];
    -      // Stick a class on the LIs so that stylesheets can
    -      // color odd/even rows, or any other row pattern that
    -      // is co-prime with 10.
    -      li.className = 'L' + ((i + offset) % 10);
    -      if (!li.firstChild) {
    -        li.appendChild(document.createTextNode('\xA0'));
    -      }
    -      ol.appendChild(li);
    -    }
    -  
    -    node.appendChild(ol);
    -  }
     
    -  /**
    -   * Breaks {@code job.sourceCode} around style boundaries in
    -   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
    -   * @param {JobT} job
    -   * @private
    -   */
    -  function recombineTagsAndDecorations(job) {
    -    var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
    -    isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
    -    var newlineRe = /\n/g;
    -  
    -    var source = job.sourceCode;
    -    var sourceLength = source.length;
    -    // Index into source after the last code-unit recombined.
    -    var sourceIndex = 0;
    -  
    -    var spans = job.spans;
    -    var nSpans = spans.length;
    -    // Index into spans after the last span which ends at or before sourceIndex.
    -    var spanIndex = 0;
    -  
    -    var decorations = job.decorations;
    -    var nDecorations = decorations.length;
    -    // Index into decorations after the last decoration which ends at or before
    -    // sourceIndex.
    -    var decorationIndex = 0;
    -  
    -    // Remove all zero-length decorations.
    -    decorations[nDecorations] = sourceLength;
    -    var decPos, i;
    -    for (i = decPos = 0; i < nDecorations;) {
    -      if (decorations[i] !== decorations[i + 2]) {
    -        decorations[decPos++] = decorations[i++];
    -        decorations[decPos++] = decorations[i++];
    -      } else {
    -        i += 2;
    +        script = null;
           }
    -    }
    -    nDecorations = decPos;
    -  
    -    // Simplify decorations.
    -    for (i = decPos = 0; i < nDecorations;) {
    -      var startPos = decorations[i];
    -      // Conflate all adjacent decorations that use the same style.
    -      var startDec = decorations[i + 1];
    -      var end = i + 2;
    -      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
    -        end += 2;
    -      }
    -      decorations[decPos++] = startPos;
    -      decorations[decPos++] = startDec;
    -      i = end;
    -    }
    -  
    -    nDecorations = decorations.length = decPos;
    -  
    -    var sourceNode = job.sourceNode;
    -    var oldDisplay = "";
    -    if (sourceNode) {
    -      oldDisplay = sourceNode.style.display;
    -      sourceNode.style.display = 'none';
    -    }
    -    try {
    -      var decoration = null;
    -      while (spanIndex < nSpans) {
    -        var spanStart = spans[spanIndex];
    -        var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
    -            || sourceLength;
    -  
    -        var decEnd = decorations[decorationIndex + 2] || sourceLength;
    -  
    -        var end = Math.min(spanEnd, decEnd);
    -  
    -        var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
    -        var styledText;
    -        if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
    -            // Don't introduce spans around empty text nodes.
    -            && (styledText = source.substring(sourceIndex, end))) {
    -          // This may seem bizarre, and it is.  Emitting LF on IE causes the
    -          // code to display with spaces instead of line breaks.
    -          // Emitting Windows standard issue linebreaks (CRLF) causes a blank
    -          // space to appear at the beginning of every line but the first.
    -          // Emitting an old Mac OS 9 line separator makes everything spiffy.
    -          if (isIE8OrEarlier) {
    -            styledText = styledText.replace(newlineRe, '\r');
    -          }
    -          textNode.nodeValue = styledText;
    -          var document = textNode.ownerDocument;
    -          var span = document.createElement('span');
    -          span.className = decorations[decorationIndex + 1];
    -          var parentNode = textNode.parentNode;
    -          parentNode.replaceChild(span, textNode);
    -          span.appendChild(textNode);
    -          if (sourceIndex < spanEnd) {  // Split off a text node.
    -            spans[spanIndex + 1] = textNode
    -                // TODO: Possibly optimize by using '' if there's no flicker.
    -                = document.createTextNode(source.substring(end, spanEnd));
    -            parentNode.insertBefore(textNode, span.nextSibling);
    -          }
    -        }
    -  
    -        sourceIndex = end;
    -  
    -        if (sourceIndex >= spanEnd) {
    -          spanIndex += 2;
    -        }
    -        if (sourceIndex >= decEnd) {
    -          decorationIndex += 2;
    -        }
    -      }
    -    } finally {
    -      if (sourceNode) {
    -        sourceNode.style.display = oldDisplay;
    -      }
    -    }
    -  }
    -
    -  /** Maps language-specific file extensions to handlers. */
    -  var langHandlerRegistry = {};
    -  /** Register a language handler for the given file extensions.
    -    * @param {function (JobT)} handler a function from source code to a list
    -    *      of decorations.  Takes a single argument job which describes the
    -    *      state of the computation and attaches the decorations to it.
    -    * @param {Array.<string>} fileExtensions
    -    */
    -  function registerLangHandler(handler, fileExtensions) {
    -    for (var i = fileExtensions.length; --i >= 0;) {
    -      var ext = fileExtensions[i];
    -      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    -        langHandlerRegistry[ext] = handler;
    -      } else if (win['console']) {
    -        console['warn']('cannot override language handler %s', ext);
    -      }
    -    }
    -  }
    -  function langHandlerForExtension(extension, source) {
    -    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    -      // Treat it as markup if the first non whitespace character is a < and
    -      // the last non-whitespace character is a >.
    -      extension = /^\s*</.test(source)
    -          ? 'default-markup'
    -          : 'default-code';
    -    }
    -    return langHandlerRegistry[extension];
    -  }
    -  registerLangHandler(decorateSource, ['default-code']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [],
    -          [
    -           [PR_PLAIN,       /^[^<?]+/],
    -           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    -           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    -           // Unescaped content in an unknown language
    -           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    -           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    -           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    -           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    -           // Unescaped content in javascript.  (Or possibly vbscript).
    -           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    -           // Contains unescaped stylesheet content
    -           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    -           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    -          ]),
    -      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    -  registerLangHandler(
    -      createSimpleLexer(
    -          [
    -           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    -           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    -           ],
    -          [
    -           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    -           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    -           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    -           [PR_PUNCTUATION,  /^[=<>\/]+/],
    -           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    -           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    -           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    -           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    -           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    -           ]),
    -      ['in.tag']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CPP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true,
    -          'types': C_TYPES
    -        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': 'null,true,false'
    -        }), ['json']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': CSHARP_KEYWORDS,
    -          'hashComments': true,
    -          'cStyleComments': true,
    -          'verbatimStrings': true,
    -          'types': C_TYPES
    -        }), ['cs']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JAVA_KEYWORDS,
    -          'cStyleComments': true
    -        }), ['java']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': SH_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true
    -        }), ['bash', 'bsh', 'csh', 'sh']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PYTHON_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'tripleQuotedStrings': true
    -        }), ['cv', 'py', 'python']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': PERL_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': 2  // multiline regex literals
    -        }), ['perl', 'pl', 'pm']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': RUBY_KEYWORDS,
    -          'hashComments': true,
    -          'multiLineStrings': true,
    -          'regexLiterals': true
    -        }), ['rb', 'ruby']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': JSCRIPT_KEYWORDS,
    -          'cStyleComments': true,
    -          'regexLiterals': true
    -        }), ['javascript', 'js', 'ts', 'typescript']);
    -  registerLangHandler(sourceDecorator({
    -          'keywords': COFFEE_KEYWORDS,
    -          'hashComments': 3,  // ### style block comments
    -          'cStyleComments': true,
    -          'multilineStrings': true,
    -          'tripleQuotedStrings': true,
    -          'regexLiterals': true
    -        }), ['coffee']);
    -  registerLangHandler(
    -      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    -
    -  /** @param {JobT} job */
    -  function applyDecorator(job) {
    -    var opt_langExtension = job.langExtension;
    -
    -    try {
    -      // Extract tags, and convert the source code to plain text.
    -      var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
    -      /** Plain text. @type {string} */
    -      var source = sourceAndSpans.sourceCode;
    -      job.sourceCode = source;
    -      job.spans = sourceAndSpans.spans;
    -      job.basePos = 0;
    -
    -      // Apply the appropriate language handler
    -      langHandlerForExtension(opt_langExtension, source)(job);
    -
    -      // Integrate the decorations and tags back into the source code,
    -      // modifying the sourceNode in place.
    -      recombineTagsAndDecorations(job);
    -    } catch (e) {
    -      if (win['console']) {
    -        console['log'](e && e['stack'] || e);
    -      }
    -    }
    -  }
    -
    -  /**
    -   * Pretty print a chunk of code.
    -   * @param sourceCodeHtml {string} The HTML to pretty print.
    -   * @param opt_langExtension {string} The language name to use.
    -   *     Typically, a filename extension like 'cpp' or 'java'.
    -   * @param opt_numberLines {number|boolean} True to number lines,
    -   *     or the 1-indexed number of the first line in sourceCodeHtml.
    -   */
    -  function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
    -    /** @type{number|boolean} */
    -    var nl = opt_numberLines || false;
    -    /** @type{string|null} */
    -    var langExtension = opt_langExtension || null;
    -    /** @type{!Element} */
    -    var container = document.createElement('div');
    -    // This could cause images to load and onload listeners to fire.
    -    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
    -    // We assume that the inner HTML is from a trusted source.
    -    // The pre-tag is required for IE8 which strips newlines from innerHTML
    -    // when it is injected into a <pre> tag.
    -    // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
    -    // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
    -    container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
    -    container = /** @type{!Element} */(container.firstChild);
    -    if (nl) {
    -      numberLines(container, nl, true);
    -    }
    -
    -    /** @type{JobT} */
    -    var job = {
    -      langExtension: langExtension,
    -      numberLines: nl,
    -      sourceNode: container,
    -      pre: 1,
    -      sourceCode: null,
    -      basePos: null,
    -      spans: null,
    -      decorations: null
         };
    -    applyDecorator(job);
    -    return container.innerHTML;
    +
    +    script.type = 'text/javascript';
    +    script.src = LOADER_BASE_URL
    +      + '/lang-' + encodeURIComponent(langs[i]) + '.js';
    +
    +    // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
    +    head.insertBefore(script, head.firstChild);
    +  })(langs[i]);
    +
    +  var pendingLanguages = langs.length;
    +  function checkPendingLanguages() {
    +    if (!pendingLanguages) {
    +      win.setTimeout(onLangsLoaded, 0);
    +    }
       }
     
    -   /**
    -    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    -    * {@code class=prettyprint} and prettify them.
    -    *
    -    * @param {Function} opt_whenDone called when prettifying is done.
    -    * @param {HTMLElement|HTMLDocument} opt_root an element or document
    -    *   containing all the elements to pretty print.
    -    *   Defaults to {@code document.body}.
    -    */
    -  function $prettyPrint(opt_whenDone, opt_root) {
    -    var root = opt_root || document.body;
    -    var doc = root.ownerDocument || document;
    -    function byTagName(tn) { return root.getElementsByTagName(tn); }
    -    // fetch a list of nodes to rewrite
    -    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    -    var elements = [];
    -    for (var i = 0; i < codeSegments.length; ++i) {
    -      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    -        elements.push(codeSegments[i][j]);
    -      }
    -    }
    -    codeSegments = null;
    +  var skinUrls = [];
    +  for (var i = 0, n = skins.length; i < n; ++i) {
    +    skinUrls.push(LOADER_BASE_URL
    +        + '/skins/' + encodeURIComponent(skins[i]) + '.css');
    +  }
    +  skinUrls.push(LOADER_BASE_URL + '/prettify.css');
    +  loadStylesheetsFallingBack(skinUrls);
     
    -    var clock = Date;
    -    if (!clock['now']) {
    -      clock = { 'now': function () { return +(new Date); } };
    -    }
    -
    -    // The loop is broken into a series of continuations to make sure that we
    -    // don't make the browser unresponsive when rewriting a large page.
    -    var k = 0;
    -
    -    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
    -    var prettyPrintRe = /\bprettyprint\b/;
    -    var prettyPrintedRe = /\bprettyprinted\b/;
    -    var preformattedTagNameRe = /pre|xmp/i;
    -    var codeRe = /^code$/i;
    -    var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
    -    var EMPTY = {};
    -
    -    function doWork() {
    -      var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
    -                     clock['now']() + 250 /* ms */ :
    -                     Infinity);
    -      for (; k < elements.length && clock['now']() < endTime; k++) {
    -        var cs = elements[k];
    -
    -        // Look for a preceding comment like
    -        // <?prettify lang="..." linenums="..."?>
    -        var attrs = EMPTY;
    -        {
    -          for (var preceder = cs; (preceder = preceder.previousSibling);) {
    -            var nt = preceder.nodeType;
    -            // <?foo?> is parsed by HTML 5 to a comment node (8)
    -            // like <!--?foo?-->, but in XML is a processing instruction
    -            var value = (nt === 7 || nt === 8) && preceder.nodeValue;
    -            if (value
    -                ? !/^\??prettify\b/.test(value)
    -                : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
    -              // Skip over white-space text nodes but not others.
    -              break;
    -            }
    -            if (value) {
    -              attrs = {};
    -              value.replace(
    -                  /\b(\w+)=([\w:.%+-]+)/g,
    -                function (_, name, value) { attrs[name] = value; });
    -              break;
    -            }
    +  var prettyPrint = (function () {
    +    /**
    +     * @license
    +     * Copyright (C) 2006 Google Inc.
    +     *
    +     * Licensed under the Apache License, Version 2.0 (the "License");
    +     * you may not use this file except in compliance with the License.
    +     * You may obtain a copy of the License at
    +     *
    +     *      http://www.apache.org/licenses/LICENSE-2.0
    +     *
    +     * Unless required by applicable law or agreed to in writing, software
    +     * distributed under the License is distributed on an "AS IS" BASIS,
    +     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +     * See the License for the specific language governing permissions and
    +     * limitations under the License.
    +     */
    +    
    +    /**
    +     * @fileoverview
    +     * some functions for browser-side pretty printing of code contained in html.
    +     *
    +     * <p>
    +     * For a fairly comprehensive set of languages see the
    +     * <a href="https://github.com/google/code-prettify#for-which-languages-does-it-work">README</a>
    +     * file that came with this source.  At a minimum, the lexer should work on a
    +     * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
    +     * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk
    +     * and a subset of Perl, but, because of commenting conventions, doesn't work on
    +     * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
    +     * <p>
    +     * Usage: <ol>
    +     * <li> include this source file in an html page via
    +     *   {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
    +     * <li> define style rules.  See the example page for examples.
    +     * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
    +     *    {@code class=prettyprint.}
    +     *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
    +     *    printer needs to do more substantial DOM manipulations to support that, so
    +     *    some css styles may not be preserved.
    +     * </ol>
    +     * That's it.  I wanted to keep the API as simple as possible, so there's no
    +     * need to specify which language the code is in, but if you wish, you can add
    +     * another class to the {@code <pre>} or {@code <code>} element to specify the
    +     * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    +     * starts with "lang-" followed by a file extension, specifies the file type.
    +     * See the "lang-*.js" files in this directory for code that implements
    +     * per-language file handlers.
    +     * <p>
    +     * Change log:<br>
    +     * cbeust, 2006/08/22
    +     * <blockquote>
    +     *   Java annotations (start with "@") are now captured as literals ("lit")
    +     * </blockquote>
    +     * @requires console
    +     */
    +    
    +    // JSLint declarations
    +    /*global console, document, navigator, setTimeout, window, define */
    +    
    +    
    +    var HACK_TO_FIX_JS_INCLUDE_PL;
    +    
    +    /**
    +     * {@type !{
    +     *   'createSimpleLexer': function (Array, Array): (function (JobT)),
    +     *   'registerLangHandler': function (function (JobT), Array.<string>),
    +     *   'PR_ATTRIB_NAME': string,
    +     *   'PR_ATTRIB_NAME': string,
    +     *   'PR_ATTRIB_VALUE': string,
    +     *   'PR_COMMENT': string,
    +     *   'PR_DECLARATION': string,
    +     *   'PR_KEYWORD': string,
    +     *   'PR_LITERAL': string,
    +     *   'PR_NOCODE': string,
    +     *   'PR_PLAIN': string,
    +     *   'PR_PUNCTUATION': string,
    +     *   'PR_SOURCE': string,
    +     *   'PR_STRING': string,
    +     *   'PR_TAG': string,
    +     *   'PR_TYPE': string,
    +     *   'prettyPrintOne': function (string, string, number|boolean),
    +     *   'prettyPrint': function (?function, ?(HTMLElement|HTMLDocument))
    +     * }}
    +     * @const
    +     */
    +    var PR;
    +    
    +    /**
    +     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    +     * UI events.
    +     * If set to {@code false}, {@code prettyPrint()} is synchronous.
    +     */
    +    window['PR_SHOULD_USE_CONTINUATION'] = true;
    +    
    +    /**
    +     * Pretty print a chunk of code.
    +     * @param {string} sourceCodeHtml The HTML to pretty print.
    +     * @param {string} opt_langExtension The language name to use.
    +     *     Typically, a filename extension like 'cpp' or 'java'.
    +     * @param {number|boolean} opt_numberLines True to number lines,
    +     *     or the 1-indexed number of the first line in sourceCodeHtml.
    +     * @return {string} code as html, but prettier
    +     */
    +    var prettyPrintOne;
    +    /**
    +     * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    +     * {@code class=prettyprint} and prettify them.
    +     *
    +     * @param {Function} opt_whenDone called when prettifying is done.
    +     * @param {HTMLElement|HTMLDocument} opt_root an element or document
    +     *   containing all the elements to pretty print.
    +     *   Defaults to {@code document.body}.
    +     */
    +    var prettyPrint;
    +    
    +    
    +    (function () {
    +      var win = window;
    +      // Keyword lists for various languages.
    +      // We use things that coerce to strings to make them compact when minified
    +      // and to defeat aggressive optimizers that fold large string constants.
    +      var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
    +      var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
    +          "double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed," +
    +          "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
    +      var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
    +          "new,operator,private,protected,public,this,throw,true,try,typeof"];
    +      var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignas,alignof,align_union,asm,axiom,bool," +
    +          "concept,concept_map,const_cast,constexpr,decltype,delegate," +
    +          "dynamic_cast,explicit,export,friend,generic,late_check," +
    +          "mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert," +
    +          "static_cast,template,typeid,typename,using,virtual,where"];
    +      var JAVA_KEYWORDS = [COMMON_KEYWORDS,
    +          "abstract,assert,boolean,byte,extends,finally,final,implements,import," +
    +          "instanceof,interface,null,native,package,strictfp,super,synchronized," +
    +          "throws,transient"];
    +      var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
    +          "abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending," +
    +          "dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface," +
    +          "internal,into,is,join,let,lock,null,object,out,override,orderby,params," +
    +          "partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong," +
    +          "unchecked,unsafe,ushort,value,var,virtual,where,yield"];
    +      var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
    +          "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
    +          "throw,true,try,unless,until,when,while,yes";
    +      var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
    +          "abstract,async,await,constructor,debugger,enum,eval,export,function," +
    +          "get,implements,instanceof,interface,let,null,set,undefined,var,with," +
    +          "yield,Infinity,NaN"];
    +      var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
    +          "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
    +          "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
    +      var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
    +          "elif,except,exec,finally,from,global,import,in,is,lambda," +
    +          "nonlocal,not,or,pass,print,raise,try,with,yield," +
    +          "False,True,None"];
    +      var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
    +          "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
    +          "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
    +          "BEGIN,END"];
    +      var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
    +          "function,in,local,set,then,until"];
    +      var ALL_KEYWORDS = [
    +          CPP_KEYWORDS, CSHARP_KEYWORDS, JAVA_KEYWORDS, JSCRIPT_KEYWORDS,
    +          PERL_KEYWORDS, PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
    +      var C_TYPES = /^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
    +    
    +      // token style names.  correspond to css classes
    +      /**
    +       * token style for a string literal
    +       * @const
    +       */
    +      var PR_STRING = 'str';
    +      /**
    +       * token style for a keyword
    +       * @const
    +       */
    +      var PR_KEYWORD = 'kwd';
    +      /**
    +       * token style for a comment
    +       * @const
    +       */
    +      var PR_COMMENT = 'com';
    +      /**
    +       * token style for a type
    +       * @const
    +       */
    +      var PR_TYPE = 'typ';
    +      /**
    +       * token style for a literal value.  e.g. 1, null, true.
    +       * @const
    +       */
    +      var PR_LITERAL = 'lit';
    +      /**
    +       * token style for a punctuation string.
    +       * @const
    +       */
    +      var PR_PUNCTUATION = 'pun';
    +      /**
    +       * token style for plain text.
    +       * @const
    +       */
    +      var PR_PLAIN = 'pln';
    +    
    +      /**
    +       * token style for an sgml tag.
    +       * @const
    +       */
    +      var PR_TAG = 'tag';
    +      /**
    +       * token style for a markup declaration such as a DOCTYPE.
    +       * @const
    +       */
    +      var PR_DECLARATION = 'dec';
    +      /**
    +       * token style for embedded source.
    +       * @const
    +       */
    +      var PR_SOURCE = 'src';
    +      /**
    +       * token style for an sgml attribute name.
    +       * @const
    +       */
    +      var PR_ATTRIB_NAME = 'atn';
    +      /**
    +       * token style for an sgml attribute value.
    +       * @const
    +       */
    +      var PR_ATTRIB_VALUE = 'atv';
    +    
    +      /**
    +       * A class that indicates a section of markup that is not code, e.g. to allow
    +       * embedding of line numbers within code listings.
    +       * @const
    +       */
    +      var PR_NOCODE = 'nocode';
    +    
    +      
    +      
    +      /**
    +       * A set of tokens that can precede a regular expression literal in
    +       * javascript
    +       * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
    +       * has the full list, but I've removed ones that might be problematic when
    +       * seen in languages that don't support regular expression literals.
    +       *
    +       * <p>Specifically, I've removed any keywords that can't precede a regexp
    +       * literal in a syntactically legal javascript program, and I've removed the
    +       * "in" keyword since it's not a keyword in many languages, and might be used
    +       * as a count of inches.
    +       *
    +       * <p>The link above does not accurately describe EcmaScript rules since
    +       * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    +       * very well in practice.
    +       *
    +       * @private
    +       * @const
    +       */
    +      var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    +      
    +      // CAVEAT: this does not properly handle the case where a regular
    +      // expression immediately follows another since a regular expression may
    +      // have flags for case-sensitivity and the like.  Having regexp tokens
    +      // adjacent is not valid in any language I'm aware of, so I'm punting.
    +      // TODO: maybe style special characters inside a regexp as punctuation.
    +    
    +      /**
    +       * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    +       * matches the union of the sets of strings matched by the input RegExp.
    +       * Since it matches globally, if the input strings have a start-of-input
    +       * anchor (/^.../), it is ignored for the purposes of unioning.
    +       * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    +       * @return {RegExp} a global regex.
    +       */
    +      function combinePrefixPatterns(regexs) {
    +        var capturedGroupIndex = 0;
    +      
    +        var needToFoldCase = false;
    +        var ignoreCase = false;
    +        for (var i = 0, n = regexs.length; i < n; ++i) {
    +          var regex = regexs[i];
    +          if (regex.ignoreCase) {
    +            ignoreCase = true;
    +          } else if (/[a-z]/i.test(regex.source.replace(
    +                         /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    +            needToFoldCase = true;
    +            ignoreCase = false;
    +            break;
               }
             }
    -
    -        var className = cs.className;
    -        if ((attrs !== EMPTY || prettyPrintRe.test(className))
    -            // Don't redo this if we've already done it.
    -            // This allows recalling pretty print to just prettyprint elements
    -            // that have been added to the page since last call.
    -            && !prettyPrintedRe.test(className)) {
    -
    -          // make sure this is not nested in an already prettified element
    -          var nested = false;
    -          for (var p = cs.parentNode; p; p = p.parentNode) {
    -            var tn = p.tagName;
    -            if (preCodeXmpRe.test(tn)
    -                && p.className && prettyPrintRe.test(p.className)) {
    -              nested = true;
    -              break;
    -            }
    +      
    +        var escapeCharToCodeUnit = {
    +          'b': 8,
    +          't': 9,
    +          'n': 0xa,
    +          'v': 0xb,
    +          'f': 0xc,
    +          'r': 0xd
    +        };
    +      
    +        function decodeEscape(charsetPart) {
    +          var cc0 = charsetPart.charCodeAt(0);
    +          if (cc0 !== 92 /* \\ */) {
    +            return cc0;
               }
    -          if (!nested) {
    -            // Mark done.  If we fail to prettyprint for whatever reason,
    -            // we shouldn't try again.
    -            cs.className += ' prettyprinted';
    -
    -            // If the classes includes a language extensions, use it.
    -            // Language extensions can be specified like
    -            //     <pre class="prettyprint lang-cpp">
    -            // the language extension "cpp" is used to find a language handler
    -            // as passed to PR.registerLangHandler.
    -            // HTML5 recommends that a language be specified using "language-"
    -            // as the prefix instead.  Google Code Prettify supports both.
    -            // http://dev.w3.org/html5/spec-author-view/the-code-element.html
    -            var langExtension = attrs['lang'];
    -            if (!langExtension) {
    -              langExtension = className.match(langExtensionRe);
    -              // Support <pre class="prettyprint"><code class="language-c">
    -              var wrapper;
    -              if (!langExtension && (wrapper = childContentWrapper(cs))
    -                  && codeRe.test(wrapper.tagName)) {
    -                langExtension = wrapper.className.match(langExtensionRe);
    -              }
    -
    -              if (langExtension) { langExtension = langExtension[1]; }
    -            }
    -
    -            var preformatted;
    -            if (preformattedTagNameRe.test(cs.tagName)) {
    -              preformatted = 1;
    +          var c1 = charsetPart.charAt(1);
    +          cc0 = escapeCharToCodeUnit[c1];
    +          if (cc0) {
    +            return cc0;
    +          } else if ('0' <= c1 && c1 <= '7') {
    +            return parseInt(charsetPart.substring(1), 8);
    +          } else if (c1 === 'u' || c1 === 'x') {
    +            return parseInt(charsetPart.substring(2), 16);
    +          } else {
    +            return charsetPart.charCodeAt(1);
    +          }
    +        }
    +      
    +        function encodeEscape(charCode) {
    +          if (charCode < 0x20) {
    +            return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    +          }
    +          var ch = String.fromCharCode(charCode);
    +          return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
    +              ? "\\" + ch : ch;
    +        }
    +      
    +        function caseFoldCharset(charSet) {
    +          var charsetParts = charSet.substring(1, charSet.length - 1).match(
    +              new RegExp(
    +                  '\\\\u[0-9A-Fa-f]{4}'
    +                  + '|\\\\x[0-9A-Fa-f]{2}'
    +                  + '|\\\\[0-3][0-7]{0,2}'
    +                  + '|\\\\[0-7]{1,2}'
    +                  + '|\\\\[\\s\\S]'
    +                  + '|-'
    +                  + '|[^-\\\\]',
    +                  'g'));
    +          var ranges = [];
    +          var inverse = charsetParts[0] === '^';
    +      
    +          var out = ['['];
    +          if (inverse) { out.push('^'); }
    +      
    +          for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    +            var p = charsetParts[i];
    +            if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
    +              out.push(p);
                 } else {
    -              var currentStyle = cs['currentStyle'];
    -              var defaultView = doc.defaultView;
    -              var whitespace = (
    -                  currentStyle
    -                  ? currentStyle['whiteSpace']
    -                  : (defaultView
    -                     && defaultView.getComputedStyle)
    -                  ? defaultView.getComputedStyle(cs, null)
    -                  .getPropertyValue('white-space')
    -                  : 0);
    -              preformatted = whitespace
    -                  && 'pre' === whitespace.substring(0, 3);
    +              var start = decodeEscape(p);
    +              var end;
    +              if (i + 2 < n && '-' === charsetParts[i + 1]) {
    +                end = decodeEscape(charsetParts[i + 2]);
    +                i += 2;
    +              } else {
    +                end = start;
    +              }
    +              ranges.push([start, end]);
    +              // If the range might intersect letters, then expand it.
    +              // This case handling is too simplistic.
    +              // It does not deal with non-latin case folding.
    +              // It works for latin source code identifiers though.
    +              if (!(end < 65 || start > 122)) {
    +                if (!(end < 65 || start > 90)) {
    +                  ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    +                }
    +                if (!(end < 97 || start > 122)) {
    +                  ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    +                }
    +              }
                 }
    -
    -            // Look for a class like linenums or linenums:<n> where <n> is the
    -            // 1-indexed number of the first line.
    -            var lineNums = attrs['linenums'];
    -            if (!(lineNums = lineNums === 'true' || +lineNums)) {
    -              lineNums = className.match(/\blinenums\b(?::(\d+))?/);
    -              lineNums =
    -                lineNums
    -                ? lineNums[1] && lineNums[1].length
    -                  ? +lineNums[1] : true
    -                : false;
    +          }
    +      
    +          // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    +          // -> [[1, 12], [14, 14], [16, 17]]
    +          ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    +          var consolidatedRanges = [];
    +          var lastRange = [];
    +          for (var i = 0; i < ranges.length; ++i) {
    +            var range = ranges[i];
    +            if (range[0] <= lastRange[1] + 1) {
    +              lastRange[1] = Math.max(lastRange[1], range[1]);
    +            } else {
    +              consolidatedRanges.push(lastRange = range);
                 }
    -            if (lineNums) { numberLines(cs, lineNums, preformatted); }
    -
    -            // do the pretty printing
    -            var prettyPrintingJob = {
    -              langExtension: langExtension,
    -              sourceNode: cs,
    -              numberLines: lineNums,
    -              pre: preformatted,
    -              sourceCode: null,
    -              basePos: null,
    -              spans: null,
    -              decorations: null
    -            };
    -            applyDecorator(prettyPrintingJob);
    +          }
    +      
    +          for (var i = 0; i < consolidatedRanges.length; ++i) {
    +            var range = consolidatedRanges[i];
    +            out.push(encodeEscape(range[0]));
    +            if (range[1] > range[0]) {
    +              if (range[1] + 1 > range[0]) { out.push('-'); }
    +              out.push(encodeEscape(range[1]));
    +            }
    +          }
    +          out.push(']');
    +          return out.join('');
    +        }
    +      
    +        function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    +          // Split into character sets, escape sequences, punctuation strings
    +          // like ('(', '(?:', ')', '^'), and runs of characters that do not
    +          // include any of the above.
    +          var parts = regex.source.match(
    +              new RegExp(
    +                  '(?:'
    +                  + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    +                  + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    +                  + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    +                  + '|\\\\[0-9]+'  // a back-reference or octal escape
    +                  + '|\\\\[^ux0-9]'  // other escape sequence
    +                  + '|\\(\\?[:!=]'  // start of a non-capturing group
    +                  + '|[\\(\\)\\^]'  // start/end of a group, or line start
    +                  + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    +                  + ')',
    +                  'g'));
    +          var n = parts.length;
    +      
    +          // Maps captured group numbers to the number they will occupy in
    +          // the output or to -1 if that has not been determined, or to
    +          // undefined if they need not be capturing in the output.
    +          var capturedGroups = [];
    +      
    +          // Walk over and identify back references to build the capturedGroups
    +          // mapping.
    +          for (var i = 0, groupIndex = 0; i < n; ++i) {
    +            var p = parts[i];
    +            if (p === '(') {
    +              // groups are 1-indexed, so max group index is count of '('
    +              ++groupIndex;
    +            } else if ('\\' === p.charAt(0)) {
    +              var decimalValue = +p.substring(1);
    +              if (decimalValue) {
    +                if (decimalValue <= groupIndex) {
    +                  capturedGroups[decimalValue] = -1;
    +                } else {
    +                  // Replace with an unambiguous escape sequence so that
    +                  // an octal escape sequence does not turn into a backreference
    +                  // to a capturing group from an earlier regex.
    +                  parts[i] = encodeEscape(decimalValue);
    +                }
    +              }
    +            }
    +          }
    +      
    +          // Renumber groups and reduce capturing groups to non-capturing groups
    +          // where possible.
    +          for (var i = 1; i < capturedGroups.length; ++i) {
    +            if (-1 === capturedGroups[i]) {
    +              capturedGroups[i] = ++capturedGroupIndex;
    +            }
    +          }
    +          for (var i = 0, groupIndex = 0; i < n; ++i) {
    +            var p = parts[i];
    +            if (p === '(') {
    +              ++groupIndex;
    +              if (!capturedGroups[groupIndex]) {
    +                parts[i] = '(?:';
    +              }
    +            } else if ('\\' === p.charAt(0)) {
    +              var decimalValue = +p.substring(1);
    +              if (decimalValue && decimalValue <= groupIndex) {
    +                parts[i] = '\\' + capturedGroups[decimalValue];
    +              }
    +            }
    +          }
    +      
    +          // Remove any prefix anchors so that the output will match anywhere.
    +          // ^^ really does mean an anchored match though.
    +          for (var i = 0; i < n; ++i) {
    +            if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    +          }
    +      
    +          // Expand letters to groups to handle mixing of case-sensitive and
    +          // case-insensitive patterns if necessary.
    +          if (regex.ignoreCase && needToFoldCase) {
    +            for (var i = 0; i < n; ++i) {
    +              var p = parts[i];
    +              var ch0 = p.charAt(0);
    +              if (p.length >= 2 && ch0 === '[') {
    +                parts[i] = caseFoldCharset(p);
    +              } else if (ch0 !== '\\') {
    +                // TODO: handle letters in numeric escapes.
    +                parts[i] = p.replace(
    +                    /[a-zA-Z]/g,
    +                    function (ch) {
    +                      var cc = ch.charCodeAt(0);
    +                      return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    +                    });
    +              }
    +            }
    +          }
    +      
    +          return parts.join('');
    +        }
    +      
    +        var rewritten = [];
    +        for (var i = 0, n = regexs.length; i < n; ++i) {
    +          var regex = regexs[i];
    +          if (regex.global || regex.multiline) { throw new Error('' + regex); }
    +          rewritten.push(
    +              '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    +        }
    +      
    +        return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    +      }
    +    
    +      /**
    +       * Split markup into a string of source code and an array mapping ranges in
    +       * that string to the text nodes in which they appear.
    +       *
    +       * <p>
    +       * The HTML DOM structure:</p>
    +       * <pre>
    +       * (Element   "p"
    +       *   (Element "b"
    +       *     (Text  "print "))       ; #1
    +       *   (Text    "'Hello '")      ; #2
    +       *   (Element "br")            ; #3
    +       *   (Text    "  + 'World';")) ; #4
    +       * </pre>
    +       * <p>
    +       * corresponds to the HTML
    +       * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
    +       *
    +       * <p>
    +       * It will produce the output:</p>
    +       * <pre>
    +       * {
    +       *   sourceCode: "print 'Hello '\n  + 'World';",
    +       *   //                     1          2
    +       *   //           012345678901234 5678901234567
    +       *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
    +       * }
    +       * </pre>
    +       * <p>
    +       * where #1 is a reference to the {@code "print "} text node above, and so
    +       * on for the other text nodes.
    +       * </p>
    +       *
    +       * <p>
    +       * The {@code} spans array is an array of pairs.  Even elements are the start
    +       * indices of substrings, and odd elements are the text nodes (or BR elements)
    +       * that contain the text for those substrings.
    +       * Substrings continue until the next index or the end of the source.
    +       * </p>
    +       *
    +       * @param {Node} node an HTML DOM subtree containing source-code.
    +       * @param {boolean|number} isPreformatted truthy if white-space in
    +       *    text nodes should be considered significant.
    +       * @return {SourceSpansT} source code and the nodes in which they occur.
    +       */
    +      function extractSourceSpans(node, isPreformatted) {
    +        var nocode = /(?:^|\s)nocode(?:\s|$)/;
    +      
    +        var chunks = [];
    +        var length = 0;
    +        var spans = [];
    +        var k = 0;
    +      
    +        function walk(node) {
    +          var type = node.nodeType;
    +          if (type == 1) {  // Element
    +            if (nocode.test(node.className)) { return; }
    +            for (var child = node.firstChild; child; child = child.nextSibling) {
    +              walk(child);
    +            }
    +            var nodeName = node.nodeName.toLowerCase();
    +            if ('br' === nodeName || 'li' === nodeName) {
    +              chunks[k] = '\n';
    +              spans[k << 1] = length++;
    +              spans[(k++ << 1) | 1] = node;
    +            }
    +          } else if (type == 3 || type == 4) {  // Text
    +            var text = node.nodeValue;
    +            if (text.length) {
    +              if (!isPreformatted) {
    +                text = text.replace(/[ \t\r\n]+/g, ' ');
    +              } else {
    +                text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
    +              }
    +              // TODO: handle tabs here?
    +              chunks[k] = text;
    +              spans[k << 1] = length;
    +              length += text.length;
    +              spans[(k++ << 1) | 1] = node;
    +            }
    +          }
    +        }
    +      
    +        walk(node);
    +      
    +        return {
    +          sourceCode: chunks.join('').replace(/\n$/, ''),
    +          spans: spans
    +        };
    +      }
    +    
    +      /**
    +       * Apply the given language handler to sourceCode and add the resulting
    +       * decorations to out.
    +       * @param {!Element} sourceNode
    +       * @param {number} basePos the index of sourceCode within the chunk of source
    +       *    whose decorations are already present on out.
    +       * @param {string} sourceCode
    +       * @param {function(JobT)} langHandler
    +       * @param {DecorationsT} out
    +       */
    +      function appendDecorations(
    +          sourceNode, basePos, sourceCode, langHandler, out) {
    +        if (!sourceCode) { return; }
    +        /** @type {JobT} */
    +        var job = {
    +          sourceNode: sourceNode,
    +          pre: 1,
    +          langExtension: null,
    +          numberLines: null,
    +          sourceCode: sourceCode,
    +          spans: null,
    +          basePos: basePos,
    +          decorations: null
    +        };
    +        langHandler(job);
    +        out.push.apply(out, job.decorations);
    +      }
    +    
    +      var notWs = /\S/;
    +    
    +      /**
    +       * Given an element, if it contains only one child element and any text nodes
    +       * it contains contain only space characters, return the sole child element.
    +       * Otherwise returns undefined.
    +       * <p>
    +       * This is meant to return the CODE element in {@code <pre><code ...>} when
    +       * there is a single child element that contains all the non-space textual
    +       * content, but not to return anything where there are multiple child elements
    +       * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
    +       * is textual content.
    +       */
    +      function childContentWrapper(element) {
    +        var wrapper = undefined;
    +        for (var c = element.firstChild; c; c = c.nextSibling) {
    +          var type = c.nodeType;
    +          wrapper = (type === 1)  // Element Node
    +              ? (wrapper ? element : c)
    +              : (type === 3)  // Text Node
    +              ? (notWs.test(c.nodeValue) ? element : wrapper)
    +              : wrapper;
    +        }
    +        return wrapper === element ? undefined : wrapper;
    +      }
    +    
    +      /** Given triples of [style, pattern, context] returns a lexing function,
    +        * The lexing function interprets the patterns to find token boundaries and
    +        * returns a decoration list of the form
    +        * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    +        * where index_n is an index into the sourceCode, and style_n is a style
    +        * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    +        * all characters in sourceCode[index_n-1:index_n].
    +        *
    +        * The stylePatterns is a list whose elements have the form
    +        * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    +        *
    +        * Style is a style constant like PR_PLAIN, or can be a string of the
    +        * form 'lang-FOO', where FOO is a language extension describing the
    +        * language of the portion of the token in $1 after pattern executes.
    +        * E.g., if style is 'lang-lisp', and group 1 contains the text
    +        * '(hello (world))', then that portion of the token will be passed to the
    +        * registered lisp handler for formatting.
    +        * The text before and after group 1 will be restyled using this decorator
    +        * so decorators should take care that this doesn't result in infinite
    +        * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    +        * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    +        * '<script>foo()<\/script>', which would cause the current decorator to
    +        * be called with '<script>' which would not match the same rule since
    +        * group 1 must not be empty, so it would be instead styled as PR_TAG by
    +        * the generic tag rule.  The handler registered for the 'js' extension would
    +        * then be called with 'foo()', and finally, the current decorator would
    +        * be called with '<\/script>' which would not match the original rule and
    +        * so the generic tag rule would identify it as a tag.
    +        *
    +        * Pattern must only match prefixes, and if it matches a prefix, then that
    +        * match is considered a token with the same style.
    +        *
    +        * Context is applied to the last non-whitespace, non-comment token
    +        * recognized.
    +        *
    +        * Shortcut is an optional string of characters, any of which, if the first
    +        * character, gurantee that this pattern and only this pattern matches.
    +        *
    +        * @param {Array} shortcutStylePatterns patterns that always start with
    +        *   a known character.  Must have a shortcut string.
    +        * @param {Array} fallthroughStylePatterns patterns that will be tried in
    +        *   order if the shortcut ones fail.  May have shortcuts.
    +        *
    +        * @return {function (JobT)} a function that takes an undecorated job and
    +        *   attaches a list of decorations.
    +        */
    +      function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    +        var shortcuts = {};
    +        var tokenizer;
    +        (function () {
    +          var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    +          var allRegexs = [];
    +          var regexKeys = {};
    +          for (var i = 0, n = allPatterns.length; i < n; ++i) {
    +            var patternParts = allPatterns[i];
    +            var shortcutChars = patternParts[3];
    +            if (shortcutChars) {
    +              for (var c = shortcutChars.length; --c >= 0;) {
    +                shortcuts[shortcutChars.charAt(c)] = patternParts;
    +              }
    +            }
    +            var regex = patternParts[1];
    +            var k = '' + regex;
    +            if (!regexKeys.hasOwnProperty(k)) {
    +              allRegexs.push(regex);
    +              regexKeys[k] = null;
    +            }
    +          }
    +          allRegexs.push(/[\0-\uffff]/);
    +          tokenizer = combinePrefixPatterns(allRegexs);
    +        })();
    +    
    +        var nPatterns = fallthroughStylePatterns.length;
    +    
    +        /**
    +         * Lexes job.sourceCode and attaches an output array job.decorations of
    +         * style classes preceded by the position at which they start in
    +         * job.sourceCode in order.
    +         *
    +         * @type{function (JobT)}
    +         */
    +        var decorate = function (job) {
    +          var sourceCode = job.sourceCode, basePos = job.basePos;
    +          var sourceNode = job.sourceNode;
    +          /** Even entries are positions in source in ascending order.  Odd enties
    +            * are style markers (e.g., PR_COMMENT) that run from that position until
    +            * the end.
    +            * @type {DecorationsT}
    +            */
    +          var decorations = [basePos, PR_PLAIN];
    +          var pos = 0;  // index into sourceCode
    +          var tokens = sourceCode.match(tokenizer) || [];
    +          var styleCache = {};
    +    
    +          for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    +            var token = tokens[ti];
    +            var style = styleCache[token];
    +            var match = void 0;
    +    
    +            var isEmbedded;
    +            if (typeof style === 'string') {
    +              isEmbedded = false;
    +            } else {
    +              var patternParts = shortcuts[token.charAt(0)];
    +              if (patternParts) {
    +                match = token.match(patternParts[1]);
    +                style = patternParts[0];
    +              } else {
    +                for (var i = 0; i < nPatterns; ++i) {
    +                  patternParts = fallthroughStylePatterns[i];
    +                  match = token.match(patternParts[1]);
    +                  if (match) {
    +                    style = patternParts[0];
    +                    break;
    +                  }
    +                }
    +    
    +                if (!match) {  // make sure that we make progress
    +                  style = PR_PLAIN;
    +                }
    +              }
    +    
    +              isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    +              if (isEmbedded && !(match && typeof match[1] === 'string')) {
    +                isEmbedded = false;
    +                style = PR_SOURCE;
    +              }
    +    
    +              if (!isEmbedded) { styleCache[token] = style; }
    +            }
    +    
    +            var tokenStart = pos;
    +            pos += token.length;
    +    
    +            if (!isEmbedded) {
    +              decorations.push(basePos + tokenStart, style);
    +            } else {  // Treat group 1 as an embedded block of source code.
    +              var embeddedSource = match[1];
    +              var embeddedSourceStart = token.indexOf(embeddedSource);
    +              var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    +              if (match[2]) {
    +                // If embeddedSource can be blank, then it would match at the
    +                // beginning which would cause us to infinitely recurse on the
    +                // entire token, so we catch the right context in match[2].
    +                embeddedSourceEnd = token.length - match[2].length;
    +                embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    +              }
    +              var lang = style.substring(5);
    +              // Decorate the left of the embedded source
    +              appendDecorations(
    +                  sourceNode,
    +                  basePos + tokenStart,
    +                  token.substring(0, embeddedSourceStart),
    +                  decorate, decorations);
    +              // Decorate the embedded source
    +              appendDecorations(
    +                  sourceNode,
    +                  basePos + tokenStart + embeddedSourceStart,
    +                  embeddedSource,
    +                  langHandlerForExtension(lang, embeddedSource),
    +                  decorations);
    +              // Decorate the right of the embedded section
    +              appendDecorations(
    +                  sourceNode,
    +                  basePos + tokenStart + embeddedSourceEnd,
    +                  token.substring(embeddedSourceEnd),
    +                  decorate, decorations);
    +            }
    +          }
    +          job.decorations = decorations;
    +        };
    +        return decorate;
    +      }
    +    
    +      /** returns a function that produces a list of decorations from source text.
    +        *
    +        * This code treats ", ', and ` as string delimiters, and \ as a string
    +        * escape.  It does not recognize perl's qq() style strings.
    +        * It has no special handling for double delimiter escapes as in basic, or
    +        * the tripled delimiters used in python, but should work on those regardless
    +        * although in those cases a single string literal may be broken up into
    +        * multiple adjacent string literals.
    +        *
    +        * It recognizes C, C++, and shell style comments.
    +        *
    +        * @param {Object} options a set of optional parameters.
    +        * @return {function (JobT)} a function that examines the source code
    +        *     in the input job and builds a decoration list which it attaches to
    +        *     the job.
    +        */
    +      function sourceDecorator(options) {
    +        var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    +        if (options['tripleQuotedStrings']) {
    +          // '''multi-line-string''', 'single-line-string', and double-quoted
    +          shortcutStylePatterns.push(
    +              [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    +               null, '\'"']);
    +        } else if (options['multiLineStrings']) {
    +          // 'multi-line-string', "multi-line-string"
    +          shortcutStylePatterns.push(
    +              [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    +               null, '\'"`']);
    +        } else {
    +          // 'single-line-string', "single-line-string"
    +          shortcutStylePatterns.push(
    +              [PR_STRING,
    +               /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    +               null, '"\'']);
    +        }
    +        if (options['verbatimStrings']) {
    +          // verbatim-string-literal production from the C# grammar.  See issue 93.
    +          fallthroughStylePatterns.push(
    +              [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    +        }
    +        var hc = options['hashComments'];
    +        if (hc) {
    +          if (options['cStyleComments']) {
    +            if (hc > 1) {  // multiline hash comments
    +              shortcutStylePatterns.push(
    +                  [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
    +            } else {
    +              // Stop C preprocessor declarations at an unclosed open comment
    +              shortcutStylePatterns.push(
    +                  [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
    +                   null, '#']);
    +            }
    +            // #include <stdio.h>
    +            fallthroughStylePatterns.push(
    +                [PR_STRING,
    +                 /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
    +                 null]);
    +          } else {
    +            shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    +          }
    +        }
    +        if (options['cStyleComments']) {
    +          fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    +          fallthroughStylePatterns.push(
    +              [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    +        }
    +        var regexLiterals = options['regexLiterals'];
    +        if (regexLiterals) {
    +          /**
    +           * @const
    +           */
    +          var regexExcls = regexLiterals > 1
    +            ? ''  // Multiline regex literals
    +            : '\n\r';
    +          /**
    +           * @const
    +           */
    +          var regexAny = regexExcls ? '.' : '[\\S\\s]';
    +          /**
    +           * @const
    +           */
    +          var REGEX_LITERAL = (
    +              // A regular expression literal starts with a slash that is
    +              // not followed by * or / so that it is not confused with
    +              // comments.
    +              '/(?=[^/*' + regexExcls + '])'
    +              // and then contains any number of raw characters,
    +              + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
    +              // escape sequences (\x5C),
    +              +    '|\\x5C' + regexAny
    +              // or non-nesting character sets (\x5B\x5D);
    +              +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
    +              +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
    +              // finally closed by a /.
    +              + '/');
    +          fallthroughStylePatterns.push(
    +              ['lang-regex',
    +               RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    +               ]);
    +        }
    +    
    +        var types = options['types'];
    +        if (types) {
    +          fallthroughStylePatterns.push([PR_TYPE, types]);
    +        }
    +    
    +        var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
    +        if (keywords.length) {
    +          fallthroughStylePatterns.push(
    +              [PR_KEYWORD,
    +               new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
    +               null]);
    +        }
    +    
    +        shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    +    
    +        var punctuation =
    +          // The Bash man page says
    +    
    +          // A word is a sequence of characters considered as a single
    +          // unit by GRUB. Words are separated by metacharacters,
    +          // which are the following plus space, tab, and newline: { }
    +          // | & $ ; < >
    +          // ...
    +    
    +          // A word beginning with # causes that word and all remaining
    +          // characters on that line to be ignored.
    +    
    +          // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
    +          // comment but empirically
    +          // $ echo {#}
    +          // {#}
    +          // $ echo \$#
    +          // $#
    +          // $ echo }#
    +          // }#
    +    
    +          // so /(?:^|[|&;<>\s])/ is more appropriate.
    +    
    +          // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
    +          // suggests that this definition is compatible with a
    +          // default mode that tries to use a single token definition
    +          // to recognize both bash/python style comments and C
    +          // preprocessor directives.
    +    
    +          // This definition of punctuation does not include # in the list of
    +          // follow-on exclusions, so # will not be broken before if preceeded
    +          // by a punctuation character.  We could try to exclude # after
    +          // [|&;<>] but that doesn't seem to cause many major problems.
    +          // If that does turn out to be a problem, we should change the below
    +          // when hc is truthy to include # in the run of punctuation characters
    +          // only when not followint [|&;<>].
    +          '^.[^\\s\\w.$@\'"`/\\\\]*';
    +        if (options['regexLiterals']) {
    +          punctuation += '(?!\s*\/)';
    +        }
    +    
    +        fallthroughStylePatterns.push(
    +            // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    +            [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    +            [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
    +            [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    +            [PR_LITERAL,
    +             new RegExp(
    +                 '^(?:'
    +                 // A hex number
    +                 + '0x[a-f0-9]+'
    +                 // or an octal or decimal number,
    +                 + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    +                 // possibly in scientific notation
    +                 + '(?:e[+\\-]?\\d+)?'
    +                 + ')'
    +                 // with an optional modifier like UL for unsigned long
    +                 + '[a-z]*', 'i'),
    +             null, '0123456789'],
    +            // Don't treat escaped quotes in bash as starting strings.
    +            // See issue 144.
    +            [PR_PLAIN,       /^\\[\s\S]?/, null],
    +            [PR_PUNCTUATION, new RegExp(punctuation), null]);
    +    
    +        return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    +      }
    +    
    +      var decorateSource = sourceDecorator({
    +            'keywords': ALL_KEYWORDS,
    +            'hashComments': true,
    +            'cStyleComments': true,
    +            'multiLineStrings': true,
    +            'regexLiterals': true
    +          });
    +    
    +      /**
    +       * Given a DOM subtree, wraps it in a list, and puts each line into its own
    +       * list item.
    +       *
    +       * @param {Node} node modified in place.  Its content is pulled into an
    +       *     HTMLOListElement, and each line is moved into a separate list item.
    +       *     This requires cloning elements, so the input might not have unique
    +       *     IDs after numbering.
    +       * @param {number|null|boolean} startLineNum
    +       *     If truthy, coerced to an integer which is the 1-indexed line number
    +       *     of the first line of code.  The number of the first line will be
    +       *     attached to the list.
    +       * @param {boolean} isPreformatted true iff white-space in text nodes should
    +       *     be treated as significant.
    +       */
    +      function numberLines(node, startLineNum, isPreformatted) {
    +        var nocode = /(?:^|\s)nocode(?:\s|$)/;
    +        var lineBreak = /\r\n?|\n/;
    +      
    +        var document = node.ownerDocument;
    +      
    +        var li = document.createElement('li');
    +        while (node.firstChild) {
    +          li.appendChild(node.firstChild);
    +        }
    +        // An array of lines.  We split below, so this is initialized to one
    +        // un-split line.
    +        var listItems = [li];
    +      
    +        function walk(node) {
    +          var type = node.nodeType;
    +          if (type == 1 && !nocode.test(node.className)) {  // Element
    +            if ('br' === node.nodeName) {
    +              breakAfter(node);
    +              // Discard the <BR> since it is now flush against a </LI>.
    +              if (node.parentNode) {
    +                node.parentNode.removeChild(node);
    +              }
    +            } else {
    +              for (var child = node.firstChild; child; child = child.nextSibling) {
    +                walk(child);
    +              }
    +            }
    +          } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
    +            var text = node.nodeValue;
    +            var match = text.match(lineBreak);
    +            if (match) {
    +              var firstLine = text.substring(0, match.index);
    +              node.nodeValue = firstLine;
    +              var tail = text.substring(match.index + match[0].length);
    +              if (tail) {
    +                var parent = node.parentNode;
    +                parent.insertBefore(
    +                  document.createTextNode(tail), node.nextSibling);
    +              }
    +              breakAfter(node);
    +              if (!firstLine) {
    +                // Don't leave blank text nodes in the DOM.
    +                node.parentNode.removeChild(node);
    +              }
    +            }
    +          }
    +        }
    +      
    +        // Split a line after the given node.
    +        function breakAfter(lineEndNode) {
    +          // If there's nothing to the right, then we can skip ending the line
    +          // here, and move root-wards since splitting just before an end-tag
    +          // would require us to create a bunch of empty copies.
    +          while (!lineEndNode.nextSibling) {
    +            lineEndNode = lineEndNode.parentNode;
    +            if (!lineEndNode) { return; }
    +          }
    +      
    +          function breakLeftOf(limit, copy) {
    +            // Clone shallowly if this node needs to be on both sides of the break.
    +            var rightSide = copy ? limit.cloneNode(false) : limit;
    +            var parent = limit.parentNode;
    +            if (parent) {
    +              // We clone the parent chain.
    +              // This helps us resurrect important styling elements that cross lines.
    +              // E.g. in <i>Foo<br>Bar</i>
    +              // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
    +              var parentClone = breakLeftOf(parent, 1);
    +              // Move the clone and everything to the right of the original
    +              // onto the cloned parent.
    +              var next = limit.nextSibling;
    +              parentClone.appendChild(rightSide);
    +              for (var sibling = next; sibling; sibling = next) {
    +                next = sibling.nextSibling;
    +                parentClone.appendChild(sibling);
    +              }
    +            }
    +            return rightSide;
    +          }
    +      
    +          var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
    +      
    +          // Walk the parent chain until we reach an unattached LI.
    +          for (var parent;
    +               // Check nodeType since IE invents document fragments.
    +               (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
    +            copiedListItem = parent;
    +          }
    +          // Put it on the list of lines for later processing.
    +          listItems.push(copiedListItem);
    +        }
    +      
    +        // Split lines while there are lines left to split.
    +        for (var i = 0;  // Number of lines that have been split so far.
    +             i < listItems.length;  // length updated by breakAfter calls.
    +             ++i) {
    +          walk(listItems[i]);
    +        }
    +      
    +        // Make sure numeric indices show correctly.
    +        if (startLineNum === (startLineNum|0)) {
    +          listItems[0].setAttribute('value', startLineNum);
    +        }
    +      
    +        var ol = document.createElement('ol');
    +        ol.className = 'linenums';
    +        var offset = Math.max(0, ((startLineNum - 1 /* zero index */)) | 0) || 0;
    +        for (var i = 0, n = listItems.length; i < n; ++i) {
    +          li = listItems[i];
    +          // Stick a class on the LIs so that stylesheets can
    +          // color odd/even rows, or any other row pattern that
    +          // is co-prime with 10.
    +          li.className = 'L' + ((i + offset) % 10);
    +          if (!li.firstChild) {
    +            li.appendChild(document.createTextNode('\xA0'));
    +          }
    +          ol.appendChild(li);
    +        }
    +      
    +        node.appendChild(ol);
    +      }
    +    
    +      /**
    +       * Breaks {@code job.sourceCode} around style boundaries in
    +       * {@code job.decorations} and modifies {@code job.sourceNode} in place.
    +       * @param {JobT} job
    +       * @private
    +       */
    +      function recombineTagsAndDecorations(job) {
    +        var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
    +        isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
    +        var newlineRe = /\n/g;
    +      
    +        var source = job.sourceCode;
    +        var sourceLength = source.length;
    +        // Index into source after the last code-unit recombined.
    +        var sourceIndex = 0;
    +      
    +        var spans = job.spans;
    +        var nSpans = spans.length;
    +        // Index into spans after the last span which ends at or before sourceIndex.
    +        var spanIndex = 0;
    +      
    +        var decorations = job.decorations;
    +        var nDecorations = decorations.length;
    +        // Index into decorations after the last decoration which ends at or before
    +        // sourceIndex.
    +        var decorationIndex = 0;
    +      
    +        // Remove all zero-length decorations.
    +        decorations[nDecorations] = sourceLength;
    +        var decPos, i;
    +        for (i = decPos = 0; i < nDecorations;) {
    +          if (decorations[i] !== decorations[i + 2]) {
    +            decorations[decPos++] = decorations[i++];
    +            decorations[decPos++] = decorations[i++];
    +          } else {
    +            i += 2;
    +          }
    +        }
    +        nDecorations = decPos;
    +      
    +        // Simplify decorations.
    +        for (i = decPos = 0; i < nDecorations;) {
    +          var startPos = decorations[i];
    +          // Conflate all adjacent decorations that use the same style.
    +          var startDec = decorations[i + 1];
    +          var end = i + 2;
    +          while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
    +            end += 2;
    +          }
    +          decorations[decPos++] = startPos;
    +          decorations[decPos++] = startDec;
    +          i = end;
    +        }
    +      
    +        nDecorations = decorations.length = decPos;
    +      
    +        var sourceNode = job.sourceNode;
    +        var oldDisplay = "";
    +        if (sourceNode) {
    +          oldDisplay = sourceNode.style.display;
    +          sourceNode.style.display = 'none';
    +        }
    +        try {
    +          var decoration = null;
    +          while (spanIndex < nSpans) {
    +            var spanStart = spans[spanIndex];
    +            var spanEnd = /** @type{number} */ (spans[spanIndex + 2])
    +                || sourceLength;
    +      
    +            var decEnd = decorations[decorationIndex + 2] || sourceLength;
    +      
    +            var end = Math.min(spanEnd, decEnd);
    +      
    +            var textNode = /** @type{Node} */ (spans[spanIndex + 1]);
    +            var styledText;
    +            if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
    +                // Don't introduce spans around empty text nodes.
    +                && (styledText = source.substring(sourceIndex, end))) {
    +              // This may seem bizarre, and it is.  Emitting LF on IE causes the
    +              // code to display with spaces instead of line breaks.
    +              // Emitting Windows standard issue linebreaks (CRLF) causes a blank
    +              // space to appear at the beginning of every line but the first.
    +              // Emitting an old Mac OS 9 line separator makes everything spiffy.
    +              if (isIE8OrEarlier) {
    +                styledText = styledText.replace(newlineRe, '\r');
    +              }
    +              textNode.nodeValue = styledText;
    +              var document = textNode.ownerDocument;
    +              var span = document.createElement('span');
    +              span.className = decorations[decorationIndex + 1];
    +              var parentNode = textNode.parentNode;
    +              parentNode.replaceChild(span, textNode);
    +              span.appendChild(textNode);
    +              if (sourceIndex < spanEnd) {  // Split off a text node.
    +                spans[spanIndex + 1] = textNode
    +                    // TODO: Possibly optimize by using '' if there's no flicker.
    +                    = document.createTextNode(source.substring(end, spanEnd));
    +                parentNode.insertBefore(textNode, span.nextSibling);
    +              }
    +            }
    +      
    +            sourceIndex = end;
    +      
    +            if (sourceIndex >= spanEnd) {
    +              spanIndex += 2;
    +            }
    +            if (sourceIndex >= decEnd) {
    +              decorationIndex += 2;
    +            }
    +          }
    +        } finally {
    +          if (sourceNode) {
    +            sourceNode.style.display = oldDisplay;
               }
             }
           }
    -      if (k < elements.length) {
    -        // finish up in a continuation
    -        win.setTimeout(doWork, 250);
    -      } else if ('function' === typeof opt_whenDone) {
    -        opt_whenDone();
    +    
    +      /** Maps language-specific file extensions to handlers. */
    +      var langHandlerRegistry = {};
    +      /** Register a language handler for the given file extensions.
    +        * @param {function (JobT)} handler a function from source code to a list
    +        *      of decorations.  Takes a single argument job which describes the
    +        *      state of the computation and attaches the decorations to it.
    +        * @param {Array.<string>} fileExtensions
    +        */
    +      function registerLangHandler(handler, fileExtensions) {
    +        for (var i = fileExtensions.length; --i >= 0;) {
    +          var ext = fileExtensions[i];
    +          if (!langHandlerRegistry.hasOwnProperty(ext)) {
    +            langHandlerRegistry[ext] = handler;
    +          } else if (win['console']) {
    +            console['warn']('cannot override language handler %s', ext);
    +          }
    +        }
           }
    +      function langHandlerForExtension(extension, source) {
    +        if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    +          // Treat it as markup if the first non whitespace character is a < and
    +          // the last non-whitespace character is a >.
    +          extension = /^\s*</.test(source)
    +              ? 'default-markup'
    +              : 'default-code';
    +        }
    +        return langHandlerRegistry[extension];
    +      }
    +      registerLangHandler(decorateSource, ['default-code']);
    +      registerLangHandler(
    +          createSimpleLexer(
    +              [],
    +              [
    +               [PR_PLAIN,       /^[^<?]+/],
    +               [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    +               [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    +               // Unescaped content in an unknown language
    +               ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    +               ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    +               [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    +               ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    +               // Unescaped content in javascript.  (Or possibly vbscript).
    +               ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    +               // Contains unescaped stylesheet content
    +               ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    +               ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    +              ]),
    +          ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    +      registerLangHandler(
    +          createSimpleLexer(
    +              [
    +               [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    +               [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    +               ],
    +              [
    +               [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    +               [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    +               ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    +               [PR_PUNCTUATION,  /^[=<>\/]+/],
    +               ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    +               ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    +               ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    +               ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    +               ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    +               ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    +               ]),
    +          ['in.tag']);
    +      registerLangHandler(
    +          createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': CPP_KEYWORDS,
    +              'hashComments': true,
    +              'cStyleComments': true,
    +              'types': C_TYPES
    +            }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': 'null,true,false'
    +            }), ['json']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': CSHARP_KEYWORDS,
    +              'hashComments': true,
    +              'cStyleComments': true,
    +              'verbatimStrings': true,
    +              'types': C_TYPES
    +            }), ['cs']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': JAVA_KEYWORDS,
    +              'cStyleComments': true
    +            }), ['java']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': SH_KEYWORDS,
    +              'hashComments': true,
    +              'multiLineStrings': true
    +            }), ['bash', 'bsh', 'csh', 'sh']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': PYTHON_KEYWORDS,
    +              'hashComments': true,
    +              'multiLineStrings': true,
    +              'tripleQuotedStrings': true
    +            }), ['cv', 'py', 'python']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': PERL_KEYWORDS,
    +              'hashComments': true,
    +              'multiLineStrings': true,
    +              'regexLiterals': 2  // multiline regex literals
    +            }), ['perl', 'pl', 'pm']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': RUBY_KEYWORDS,
    +              'hashComments': true,
    +              'multiLineStrings': true,
    +              'regexLiterals': true
    +            }), ['rb', 'ruby']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': JSCRIPT_KEYWORDS,
    +              'cStyleComments': true,
    +              'regexLiterals': true
    +            }), ['javascript', 'js', 'ts', 'typescript']);
    +      registerLangHandler(sourceDecorator({
    +              'keywords': COFFEE_KEYWORDS,
    +              'hashComments': 3,  // ### style block comments
    +              'cStyleComments': true,
    +              'multilineStrings': true,
    +              'tripleQuotedStrings': true,
    +              'regexLiterals': true
    +            }), ['coffee']);
    +      registerLangHandler(
    +          createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    +    
    +      /** @param {JobT} job */
    +      function applyDecorator(job) {
    +        var opt_langExtension = job.langExtension;
    +    
    +        try {
    +          // Extract tags, and convert the source code to plain text.
    +          var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
    +          /** Plain text. @type {string} */
    +          var source = sourceAndSpans.sourceCode;
    +          job.sourceCode = source;
    +          job.spans = sourceAndSpans.spans;
    +          job.basePos = 0;
    +    
    +          // Apply the appropriate language handler
    +          langHandlerForExtension(opt_langExtension, source)(job);
    +    
    +          // Integrate the decorations and tags back into the source code,
    +          // modifying the sourceNode in place.
    +          recombineTagsAndDecorations(job);
    +        } catch (e) {
    +          if (win['console']) {
    +            console['log'](e && e['stack'] || e);
    +          }
    +        }
    +      }
    +    
    +      /**
    +       * Pretty print a chunk of code.
    +       * @param sourceCodeHtml {string} The HTML to pretty print.
    +       * @param opt_langExtension {string} The language name to use.
    +       *     Typically, a filename extension like 'cpp' or 'java'.
    +       * @param opt_numberLines {number|boolean} True to number lines,
    +       *     or the 1-indexed number of the first line in sourceCodeHtml.
    +       */
    +      function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
    +        /** @type{number|boolean} */
    +        var nl = opt_numberLines || false;
    +        /** @type{string|null} */
    +        var langExtension = opt_langExtension || null;
    +        /** @type{!Element} */
    +        var container = document.createElement('div');
    +        // This could cause images to load and onload listeners to fire.
    +        // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
    +        // We assume that the inner HTML is from a trusted source.
    +        // The pre-tag is required for IE8 which strips newlines from innerHTML
    +        // when it is injected into a <pre> tag.
    +        // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
    +        // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
    +        container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
    +        container = /** @type{!Element} */(container.firstChild);
    +        if (nl) {
    +          numberLines(container, nl, true);
    +        }
    +    
    +        /** @type{JobT} */
    +        var job = {
    +          langExtension: langExtension,
    +          numberLines: nl,
    +          sourceNode: container,
    +          pre: 1,
    +          sourceCode: null,
    +          basePos: null,
    +          spans: null,
    +          decorations: null
    +        };
    +        applyDecorator(job);
    +        return container.innerHTML;
    +      }
    +    
    +       /**
    +        * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    +        * {@code class=prettyprint} and prettify them.
    +        *
    +        * @param {Function} opt_whenDone called when prettifying is done.
    +        * @param {HTMLElement|HTMLDocument} opt_root an element or document
    +        *   containing all the elements to pretty print.
    +        *   Defaults to {@code document.body}.
    +        */
    +      function $prettyPrint(opt_whenDone, opt_root) {
    +        var root = opt_root || document.body;
    +        var doc = root.ownerDocument || document;
    +        function byTagName(tn) { return root.getElementsByTagName(tn); }
    +        // fetch a list of nodes to rewrite
    +        var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
    +        var elements = [];
    +        for (var i = 0; i < codeSegments.length; ++i) {
    +          for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    +            elements.push(codeSegments[i][j]);
    +          }
    +        }
    +        codeSegments = null;
    +    
    +        var clock = Date;
    +        if (!clock['now']) {
    +          clock = { 'now': function () { return +(new Date); } };
    +        }
    +    
    +        // The loop is broken into a series of continuations to make sure that we
    +        // don't make the browser unresponsive when rewriting a large page.
    +        var k = 0;
    +    
    +        var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
    +        var prettyPrintRe = /\bprettyprint\b/;
    +        var prettyPrintedRe = /\bprettyprinted\b/;
    +        var preformattedTagNameRe = /pre|xmp/i;
    +        var codeRe = /^code$/i;
    +        var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
    +        var EMPTY = {};
    +    
    +        function doWork() {
    +          var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
    +                         clock['now']() + 250 /* ms */ :
    +                         Infinity);
    +          for (; k < elements.length && clock['now']() < endTime; k++) {
    +            var cs = elements[k];
    +    
    +            // Look for a preceding comment like
    +            // <?prettify lang="..." linenums="..."?>
    +            var attrs = EMPTY;
    +            {
    +              for (var preceder = cs; (preceder = preceder.previousSibling);) {
    +                var nt = preceder.nodeType;
    +                // <?foo?> is parsed by HTML 5 to a comment node (8)
    +                // like <!--?foo?-->, but in XML is a processing instruction
    +                var value = (nt === 7 || nt === 8) && preceder.nodeValue;
    +                if (value
    +                    ? !/^\??prettify\b/.test(value)
    +                    : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
    +                  // Skip over white-space text nodes but not others.
    +                  break;
    +                }
    +                if (value) {
    +                  attrs = {};
    +                  value.replace(
    +                      /\b(\w+)=([\w:.%+-]+)/g,
    +                    function (_, name, value) { attrs[name] = value; });
    +                  break;
    +                }
    +              }
    +            }
    +    
    +            var className = cs.className;
    +            if ((attrs !== EMPTY || prettyPrintRe.test(className))
    +                // Don't redo this if we've already done it.
    +                // This allows recalling pretty print to just prettyprint elements
    +                // that have been added to the page since last call.
    +                && !prettyPrintedRe.test(className)) {
    +    
    +              // make sure this is not nested in an already prettified element
    +              var nested = false;
    +              for (var p = cs.parentNode; p; p = p.parentNode) {
    +                var tn = p.tagName;
    +                if (preCodeXmpRe.test(tn)
    +                    && p.className && prettyPrintRe.test(p.className)) {
    +                  nested = true;
    +                  break;
    +                }
    +              }
    +              if (!nested) {
    +                // Mark done.  If we fail to prettyprint for whatever reason,
    +                // we shouldn't try again.
    +                cs.className += ' prettyprinted';
    +    
    +                // If the classes includes a language extensions, use it.
    +                // Language extensions can be specified like
    +                //     <pre class="prettyprint lang-cpp">
    +                // the language extension "cpp" is used to find a language handler
    +                // as passed to PR.registerLangHandler.
    +                // HTML5 recommends that a language be specified using "language-"
    +                // as the prefix instead.  Google Code Prettify supports both.
    +                // http://dev.w3.org/html5/spec-author-view/the-code-element.html
    +                var langExtension = attrs['lang'];
    +                if (!langExtension) {
    +                  langExtension = className.match(langExtensionRe);
    +                  // Support <pre class="prettyprint"><code class="language-c">
    +                  var wrapper;
    +                  if (!langExtension && (wrapper = childContentWrapper(cs))
    +                      && codeRe.test(wrapper.tagName)) {
    +                    langExtension = wrapper.className.match(langExtensionRe);
    +                  }
    +    
    +                  if (langExtension) { langExtension = langExtension[1]; }
    +                }
    +    
    +                var preformatted;
    +                if (preformattedTagNameRe.test(cs.tagName)) {
    +                  preformatted = 1;
    +                } else {
    +                  var currentStyle = cs['currentStyle'];
    +                  var defaultView = doc.defaultView;
    +                  var whitespace = (
    +                      currentStyle
    +                      ? currentStyle['whiteSpace']
    +                      : (defaultView
    +                         && defaultView.getComputedStyle)
    +                      ? defaultView.getComputedStyle(cs, null)
    +                      .getPropertyValue('white-space')
    +                      : 0);
    +                  preformatted = whitespace
    +                      && 'pre' === whitespace.substring(0, 3);
    +                }
    +    
    +                // Look for a class like linenums or linenums:<n> where <n> is the
    +                // 1-indexed number of the first line.
    +                var lineNums = attrs['linenums'];
    +                if (!(lineNums = lineNums === 'true' || +lineNums)) {
    +                  lineNums = className.match(/\blinenums\b(?::(\d+))?/);
    +                  lineNums =
    +                    lineNums
    +                    ? lineNums[1] && lineNums[1].length
    +                      ? +lineNums[1] : true
    +                    : false;
    +                }
    +                if (lineNums) { numberLines(cs, lineNums, preformatted); }
    +    
    +                // do the pretty printing
    +                var prettyPrintingJob = {
    +                  langExtension: langExtension,
    +                  sourceNode: cs,
    +                  numberLines: lineNums,
    +                  pre: preformatted,
    +                  sourceCode: null,
    +                  basePos: null,
    +                  spans: null,
    +                  decorations: null
    +                };
    +                applyDecorator(prettyPrintingJob);
    +              }
    +            }
    +          }
    +          if (k < elements.length) {
    +            // finish up in a continuation
    +            win.setTimeout(doWork, 250);
    +          } else if ('function' === typeof opt_whenDone) {
    +            opt_whenDone();
    +          }
    +        }
    +    
    +        doWork();
    +      }
    +    
    +      /**
    +       * Contains functions for creating and registering new language handlers.
    +       * @type {Object}
    +       */
    +      var PR = win['PR'] = {
    +            'createSimpleLexer': createSimpleLexer,
    +            'registerLangHandler': registerLangHandler,
    +            'sourceDecorator': sourceDecorator,
    +            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    +            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    +            'PR_COMMENT': PR_COMMENT,
    +            'PR_DECLARATION': PR_DECLARATION,
    +            'PR_KEYWORD': PR_KEYWORD,
    +            'PR_LITERAL': PR_LITERAL,
    +            'PR_NOCODE': PR_NOCODE,
    +            'PR_PLAIN': PR_PLAIN,
    +            'PR_PUNCTUATION': PR_PUNCTUATION,
    +            'PR_SOURCE': PR_SOURCE,
    +            'PR_STRING': PR_STRING,
    +            'PR_TAG': PR_TAG,
    +            'PR_TYPE': PR_TYPE,
    +            'prettyPrintOne':
    +               IN_GLOBAL_SCOPE
    +                 ? (win['prettyPrintOne'] = $prettyPrintOne)
    +                 : (prettyPrintOne = $prettyPrintOne),
    +            'prettyPrint': prettyPrint =
    +               IN_GLOBAL_SCOPE
    +                 ? (win['prettyPrint'] = $prettyPrint)
    +                 : (prettyPrint = $prettyPrint)
    +          };
    +    
    +      // Make PR available via the Asynchronous Module Definition (AMD) API.
    +      // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
    +      // The Asynchronous Module Definition (AMD) API specifies a
    +      // mechanism for defining modules such that the module and its
    +      // dependencies can be asynchronously loaded.
    +      // ...
    +      // To allow a clear indicator that a global define function (as
    +      // needed for script src browser loading) conforms to the AMD API,
    +      // any global define function SHOULD have a property called "amd"
    +      // whose value is an object. This helps avoid conflict with any
    +      // other existing JavaScript code that could have defined a define()
    +      // function that does not conform to the AMD API.
    +      var define = win['define'];
    +      if (typeof define === "function" && define['amd']) {
    +        define("google-code-prettify", [], function () {
    +          return PR;
    +        });
    +      }
    +    })();
    +    return prettyPrint;
    +  })();
    +
    +  // If this script is deferred or async and the document is already
    +  // loaded we need to wait for language handlers to load before performing
    +  // any autorun.
    +  function onLangsLoaded() {
    +    if (autorun) {
    +      contentLoaded(
    +        function () {
    +          var n = callbacks.length;
    +          var callback = n ? function () {
    +            for (var i = 0; i < n; ++i) {
    +              (function (i) {
    +                win.setTimeout(
    +                   function () {
    +                     win['exports'][callbacks[i]].apply(win, arguments);
    +                   }, 0);
    +               })(i);
    +            }
    +          } : void 0;
    +          prettyPrint(callback);
    +        });
         }
    -
    -    doWork();
       }
    +  checkPendingLanguages();
     
    -  /**
    -   * Contains functions for creating and registering new language handlers.
    -   * @type {Object}
    -   */
    -  var PR = win['PR'] = {
    -        'createSimpleLexer': createSimpleLexer,
    -        'registerLangHandler': registerLangHandler,
    -        'sourceDecorator': sourceDecorator,
    -        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    -        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    -        'PR_COMMENT': PR_COMMENT,
    -        'PR_DECLARATION': PR_DECLARATION,
    -        'PR_KEYWORD': PR_KEYWORD,
    -        'PR_LITERAL': PR_LITERAL,
    -        'PR_NOCODE': PR_NOCODE,
    -        'PR_PLAIN': PR_PLAIN,
    -        'PR_PUNCTUATION': PR_PUNCTUATION,
    -        'PR_SOURCE': PR_SOURCE,
    -        'PR_STRING': PR_STRING,
    -        'PR_TAG': PR_TAG,
    -        'PR_TYPE': PR_TYPE,
    -        'prettyPrintOne':
    -           IN_GLOBAL_SCOPE
    -             ? (win['prettyPrintOne'] = $prettyPrintOne)
    -             : (prettyPrintOne = $prettyPrintOne),
    -        'prettyPrint': prettyPrint =
    -           IN_GLOBAL_SCOPE
    -             ? (win['prettyPrint'] = $prettyPrint)
    -             : (prettyPrint = $prettyPrint)
    -      };
    -
    -  // Make PR available via the Asynchronous Module Definition (AMD) API.
    -  // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
    -  // The Asynchronous Module Definition (AMD) API specifies a
    -  // mechanism for defining modules such that the module and its
    -  // dependencies can be asynchronously loaded.
    -  // ...
    -  // To allow a clear indicator that a global define function (as
    -  // needed for script src browser loading) conforms to the AMD API,
    -  // any global define function SHOULD have a property called "amd"
    -  // whose value is an object. This helps avoid conflict with any
    -  // other existing JavaScript code that could have defined a define()
    -  // function that does not conform to the AMD API.
    -  var define = win['define'];
    -  if (typeof define === "function" && define['amd']) {
    -    define("google-code-prettify", [], function () {
    -      return PR;
    -    });
    -  }
    -})();
    \ No newline at end of file
    +}());
    diff --git a/app/src/main/assets/highlight/styles/prettify.css b/app/src/main/assets/highlight/styles/prettify.css
    index af016d1a..2974a100 100644
    --- a/app/src/main/assets/highlight/styles/prettify.css
    +++ b/app/src/main/assets/highlight/styles/prettify.css
    @@ -1,32 +1,32 @@
     .prettyprint {
    -  font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    -  border: 0 !important;
    +    font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace !important;
    +    border: 0 !important;
     }
     
     .pln {
    -  color: #333;
    +    color: #333 !important;
     }
     
     ol.linenums {
    -  margin-top: 0;
    -  margin-bottom: 0;
    -  color: #727272;
    +    margin-top: 0 !important;
    +    margin-bottom: 0 !important;
    +    color: #727272 !important;
     }
     
     ol {
    -    margin-left: 0;
    -    padding-left: 0.2em;
    +    margin-left: 0 !important;
    +    padding-left: 0.2em !important;
         counter-reset: ol-item
     }
     
     ol li:nth-child(-n+9) {
    -	padding-left: 8px;
    +    padding-left: 8px !important;
     }
     
     ol li {
    -    margin-left: 0;
    -    padding-left: 0;
    -    list-style-type: none;
    +    margin-left: 0 !important;
    +    padding-left: 0 !important;
    +    list-style-type: none !important;
         counter-increment: ol-item
     }
     
    @@ -34,7 +34,6 @@ ol li:before {
         content: counter(ol-item) " "
     }
     
    -
     li.L0,
     li.L1,
     li.L2,
    @@ -44,91 +43,79 @@ li.L5,
     li.L6,
     li.L7,
     li.L8,
    -li.L9 {}
    +li.L9 {
    +    background: transparent !important;
    +}
     
     @media screen {
     
    -  /* string content */
    +    /* string content */
    +    .str {
    +        color: #183691 !important;
    +    }
     
    -  .str {
    -    color: #183691;
    -  }
    +    /* keyword */
    +    .kwd {
    +        color: #a71d5d !important;
    +    }
     
    -  /* keyword */
    +    /* comment */
    +    .com {
    +        color: #969896 !important;
    +    }
     
    -  .kwd {
    -    color: #a71d5d;
    -  }
    +    /* type name */
    +    .typ {
    +        color: #0086b3 !important;
    +    }
     
    -  /* comment */
    +    /* literal value */
    +    .lit {
    +        color: #0086b3 !important;
    +    }
     
    -  .com {
    -    color: #969896;
    -  }
    +    /* punctuation */
    +    .pun {
    +        color: #333 !important;
    +    }
     
    -  /* type name */
    +    /* lisp open bracket */
    +    .opn {
    +        color: #333 !important;
    +    }
     
    -  .typ {
    -    color: #0086b3;
    -  }
    +    /* lisp close bracket */
    +    .clo {
    +        color: #333 !important;
    +    }
     
    -  /* literal value */
    +    /* markup tag name */
    +    .tag {
    +        color: #000080 !important;
    +    }
     
    -  .lit {
    -    color: #0086b3;
    -  }
    +    /* markup attribute name */
    +    .atn {
    +        color: #795da3 !important;
    +    }
     
    -  /* punctuation */
    +    /* markup attribute value */
    +    .atv {
    +        color: #183691 !important;
    +    }
     
    -  .pun {
    -    color: #333;
    -  }
    +    /* declaration */
    +    .dec {
    +        color: #333 !important;
    +    }
     
    -  /* lisp open bracket */
    +    /* variable name */
    +    .var {
    +        color: #008080 !important;
    +    }
     
    -  .opn {
    -    color: #333;
    -  }
    -
    -  /* lisp close bracket */
    -
    -  .clo {
    -    color: #333;
    -  }
    -
    -  /* markup tag name */
    -
    -  .tag {
    -    color: #000080;
    -  }
    -
    -  /* markup attribute name */
    -
    -  .atn {
    -    color: #795da3;
    -  }
    -
    -  /* markup attribute value */
    -
    -  .atv {
    -    color: #183691;
    -  }
    -
    -  /* declaration */
    -
    -  .dec {
    -    color: #333;
    -  }
    -
    -  /* variable name */
    -
    -  .var {
    -    color: #008080;
    -  }
    -
    -  /* function name */
    -
    -  .fun {
    -    color: #900;
    -  }
    +    /* function name */
    +    .fun {
    +        color: #900 !important;
    +    }
     }
    \ No newline at end of file
    diff --git a/app/src/main/assets/highlight/styles/prettify_dark.css b/app/src/main/assets/highlight/styles/prettify_dark.css
    index 032fd28f..fdb6687f 100644
    --- a/app/src/main/assets/highlight/styles/prettify_dark.css
    +++ b/app/src/main/assets/highlight/styles/prettify_dark.css
    @@ -1,33 +1,33 @@
     .prettyprint {
    -  font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace;
    -  border: 0 !important;
    +    font-family: Menlo, "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, Consolas, monospace !important;
    +    border: 0 !important;
     }
     
     .pln {
    -  color: #e6e9ed;
    +    color: #e6e9ed !important;
     }
     
     /* Specify class=linenums on a pre to get line numbering */
     ol.linenums {
    -  margin-top: 0;
    -  margin-bottom: 0;
    -  color: #656d78;
    +    margin-top: 0 !important;
    +    margin-bottom: 0 !important;
    +    color: #656d78 !important;
     }
     
     ol {
    -    margin-left: 0;
    -    padding-left: 0.2em;
    +    margin-left: 0 !important;
    +    padding-left: 0.2em !important;
         counter-reset: ol-item
     }
     
     ol li:nth-child(-n+9) {
    -	padding-left: 8px;
    +    padding-left: 8px !important;
     }
     
     ol li {
    -    margin-left: 0;
    -    padding-left: 0;
    -    list-style-type: none;
    +    margin-left: 0 !important;
    +    padding-left: 0 !important;
    +    list-style-type: none !important;
         counter-increment: ol-item
     }
     
    @@ -44,91 +44,79 @@ li.L5,
     li.L6,
     li.L7,
     li.L8,
    -li.L9 {}
    +li.L9 {
    +    background: transparent !important;
    +}
     
     @media screen {
     
    -  /* string content */
    +    /* string content */
    +    .str {
    +        color: #ffce54 !important;
    +    }
     
    -  .str {
    -    color: #ffce54;
    -  }
    +    /* keyword */
    +    .kwd {
    +        color: #4fc1e9 !important;
    +    }
     
    -  /* keyword */
    +    /* comment */
    +    .com {
    +        color: #656d78 !important;
    +    }
     
    -  .kwd {
    -    color: #4fc1e9;
    -  }
    +    /* type name */
    +    .typ {
    +        color: #4fc1e9 !important;
    +    }
     
    -  /* comment */
    +    /* literal value */
    +    .lit {
    +        color: #ac92ec !important;
    +    }
     
    -  .com {
    -    color: #656d78;
    -  }
    +    /* punctuation */
    +    .pun {
    +        color: #e6e9ed !important;
    +    }
     
    -  /* type name */
    +    /* lisp open bracket */
    +    .opn {
    +        color: #e6e9ed !important;
    +    }
     
    -  .typ {
    -    color: #4fc1e9;
    -  }
    +    /* lisp close bracket */
    +    .clo {
    +        color: #e6e9ed !important;
    +    }
     
    -  /* literal value */
    +    /* markup tag name */
    +    .tag {
    +        color: #ed5565 !important;
    +    }
     
    -  .lit {
    -    color: #ac92ec;
    -  }
    +    /* markup attribute name */
    +    .atn {
    +        color: #a0d468 !important;
    +    }
     
    -  /* punctuation */
    +    /* markup attribute value */
    +    .atv {
    +        color: #ffce54 !important;
    +    }
     
    -  .pun {
    -    color: #e6e9ed;
    -  }
    +    /* declaration */
    +    .dec {
    +        color: #ac92ec !important;
    +    }
     
    -  /* lisp open bracket */
    +    /* variable name */
    +    .var {
    +        color: #e6e9ed !important;
    +    }
     
    -  .opn {
    -    color: #e6e9ed;
    -  }
    -
    -  /* lisp close bracket */
    -
    -  .clo {
    -    color: #e6e9ed;
    -  }
    -
    -  /* markup tag name */
    -
    -  .tag {
    -    color: #ed5565;
    -  }
    -
    -  /* markup attribute name */
    -
    -  .atn {
    -    color: #a0d468;
    -  }
    -
    -  /* markup attribute value */
    -
    -  .atv {
    -    color: #ffce54;
    -  }
    -
    -  /* declaration */
    -
    -  .dec {
    -    color: #ac92ec;
    -  }
    -
    -  /* variable name */
    -
    -  .var {
    -    color: #e6e9ed;
    -  }
    -
    -  /* function name */
    -
    -  .fun {
    -    color: #e6e9ed;
    -  }
    +    /* function name */
    +    .fun {
    +        color: #e6e9ed !important;
    +    }
     }
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/data/dao/FragmentPagerAdapterModel.java b/app/src/main/java/com/fastaccess/data/dao/FragmentPagerAdapterModel.java
    index 32a1985a..37bf4f56 100644
    --- a/app/src/main/java/com/fastaccess/data/dao/FragmentPagerAdapterModel.java
    +++ b/app/src/main/java/com/fastaccess/data/dao/FragmentPagerAdapterModel.java
    @@ -9,7 +9,6 @@ import com.annimon.stream.Stream;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.model.Commit;
     import com.fastaccess.data.dao.model.Gist;
    -import com.fastaccess.data.dao.model.Issue;
     import com.fastaccess.data.dao.model.Login;
     import com.fastaccess.data.dao.model.PullRequest;
     import com.fastaccess.data.dao.types.IssueState;
    @@ -21,6 +20,7 @@ import com.fastaccess.ui.modules.main.issues.MyIssuesFragment;
     import com.fastaccess.ui.modules.main.pullrequests.MyPullRequestFragment;
     import com.fastaccess.ui.modules.notification.all.AllNotificationsFragment;
     import com.fastaccess.ui.modules.notification.unread.UnreadNotificationsFragment;
    +import com.fastaccess.ui.modules.profile.events.ProfileEventsFragment;
     import com.fastaccess.ui.modules.profile.followers.ProfileFollowersFragment;
     import com.fastaccess.ui.modules.profile.following.ProfileFollowingFragment;
     import com.fastaccess.ui.modules.profile.gists.ProfileGistsFragment;
    @@ -74,6 +74,7 @@ import lombok.Setter;
     
         @NonNull public static List<FragmentPagerAdapterModel> buildForProfile(@NonNull Context context, @NonNull String login) {
             return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.overview), ProfileOverviewFragment.newInstance(login)),
    +                new FragmentPagerAdapterModel(context.getString(R.string.feed), ProfileEventsFragment.Companion.newInstance(login)),
                     new FragmentPagerAdapterModel(context.getString(R.string.repos), ProfileReposFragment.newInstance(login)),
                     new FragmentPagerAdapterModel(context.getString(R.string.starred), ProfileStarredFragment.newInstance(login)),
                     new FragmentPagerAdapterModel(context.getString(R.string.gists), ProfileGistsFragment.newInstance(login)),
    @@ -86,7 +87,8 @@ import lombok.Setter;
                                                                        @NonNull String login, @NonNull String url,
                                                                        @NonNull String defaultBranch) {
             return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.readme), ViewerFragment.newInstance(url, true)),
    -                new FragmentPagerAdapterModel(context.getString(R.string.files), RepoFilePathFragment.newInstance(login, repoId, null, defaultBranch)),
    +                new FragmentPagerAdapterModel(context.getString(R.string.files), RepoFilePathFragment.newInstance(login, repoId, null,
    +                        defaultBranch)),
                     new FragmentPagerAdapterModel(context.getString(R.string.commits), RepoCommitsFragment.newInstance(repoId, login, defaultBranch)),
                     new FragmentPagerAdapterModel(context.getString(R.string.releases), RepoReleasesFragment.newInstance(repoId, login)),
                     new FragmentPagerAdapterModel(context.getString(R.string.contributors), RepoContributorsFragment.newInstance(repoId, login)))
    @@ -101,8 +103,8 @@ import lombok.Setter;
                     .collect(Collectors.toList());
         }
     
    -    @NonNull public static List<FragmentPagerAdapterModel> buildForIssues(@NonNull Context context, @NonNull Issue issueModel) {
    -        return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), IssueTimelineFragment.newInstance(issueModel)))
    +    @NonNull public static List<FragmentPagerAdapterModel> buildForIssues(@NonNull Context context) {
    +        return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), IssueTimelineFragment.newInstance()))
                     .collect(Collectors.toList());
         }
     
    @@ -111,7 +113,7 @@ import lombok.Setter;
             String login = pullRequest.getLogin();
             String repoId = pullRequest.getRepoId();
             int number = pullRequest.getNumber();
    -        return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), PullRequestTimelineFragment.newInstance(pullRequest)),
    +        return Stream.of(new FragmentPagerAdapterModel(context.getString(R.string.details), PullRequestTimelineFragment.newInstance()),
                     new FragmentPagerAdapterModel(context.getString(R.string.commits), PullRequestCommitsFragment.newInstance(repoId, login, number)),
                     new FragmentPagerAdapterModel(context.getString(R.string.files), PullRequestFilesFragment.newInstance(repoId, login, number)))
                     .collect(Collectors.toList());
    diff --git a/app/src/main/java/com/fastaccess/data/dao/GitCommitModel.java b/app/src/main/java/com/fastaccess/data/dao/GitCommitModel.java
    index 80454f87..3da841ab 100644
    --- a/app/src/main/java/com/fastaccess/data/dao/GitCommitModel.java
    +++ b/app/src/main/java/com/fastaccess/data/dao/GitCommitModel.java
    @@ -49,8 +49,8 @@ public class GitCommitModel implements Parcelable {
             this.committer = in.readParcelable(User.class.getClassLoader());
             this.tree = in.readParcelable(User.class.getClassLoader());
             this.distincted = in.readByte() != 0;
    -        in.readList(parents, parents.getClass().getClassLoader());
    -        in.readList(this.parents, GitCommitModel.class.getClassLoader());
    +        this.parents = new GitCommitListModel();
    +        in.readList(this.parents, this.parents.getClass().getClassLoader());
             this.commentCount = in.readInt();
         }
     
    diff --git a/app/src/main/java/com/fastaccess/data/dao/Pageable.java b/app/src/main/java/com/fastaccess/data/dao/Pageable.java
    index e7c9233c..cbfafe6c 100644
    --- a/app/src/main/java/com/fastaccess/data/dao/Pageable.java
    +++ b/app/src/main/java/com/fastaccess/data/dao/Pageable.java
    @@ -17,12 +17,12 @@ import lombok.Setter;
     @Getter @Setter @NoArgsConstructor
     public class Pageable<M extends Parcelable> implements Parcelable {
     
    -    private int first;
    -    private int next;
    -    private int prev;
    -    private int last;
    -    private int totalCount;
    -    private boolean incompleteResults;
    +    public int first;
    +    public int next;
    +    public int prev;
    +    public int last;
    +    public int totalCount;
    +    public boolean incompleteResults;
         public List<M> items;
     
         @Override public int describeContents() { return 0; }
    diff --git a/app/src/main/java/com/fastaccess/data/dao/PayloadModel.java b/app/src/main/java/com/fastaccess/data/dao/PayloadModel.java
    index 7d6b39ac..0e5ac668 100644
    --- a/app/src/main/java/com/fastaccess/data/dao/PayloadModel.java
    +++ b/app/src/main/java/com/fastaccess/data/dao/PayloadModel.java
    @@ -22,17 +22,17 @@ import lombok.Setter;
     @Getter @Setter @NoArgsConstructor
     public class PayloadModel implements Parcelable {
     
    -    private String action;
    -    private Repo forkee;
    -    private Issue issue;
    -    private PullRequest pullRequest;
    -    private String ref;
    -    private String refType;
    -    private Comment comment;
    -    private User target;
    -    private User member;
    -    private String head;
    -    private TeamsModel team;
    +    public String action;
    +    public Repo forkee;
    +    public Issue issue;
    +    public PullRequest pullRequest;
    +    public String ref;
    +    public String refType;
    +    public Comment comment;
    +    public User target;
    +    public User member;
    +    public String head;
    +    public TeamsModel team;
     
         @Override public int describeContents() { return 0; }
     
    diff --git a/app/src/main/java/com/fastaccess/data/dao/SimpleUrlsModel.java b/app/src/main/java/com/fastaccess/data/dao/SimpleUrlsModel.java
    index cbbf08c7..ddff012b 100644
    --- a/app/src/main/java/com/fastaccess/data/dao/SimpleUrlsModel.java
    +++ b/app/src/main/java/com/fastaccess/data/dao/SimpleUrlsModel.java
    @@ -14,8 +14,9 @@ import lombok.Setter;
     @Getter @Setter
     public class SimpleUrlsModel implements Parcelable {
     
    -    private String item;
    -    private String url;
    +    public String item;
    +    public String url;
    +
         public SimpleUrlsModel(String item, String url) {
             this.item = item;
             this.url = url;
    diff --git a/app/src/main/java/com/fastaccess/data/dao/TimelineModel.java b/app/src/main/java/com/fastaccess/data/dao/TimelineModel.java
    index 9b9f2dfc..98b15d70 100644
    --- a/app/src/main/java/com/fastaccess/data/dao/TimelineModel.java
    +++ b/app/src/main/java/com/fastaccess/data/dao/TimelineModel.java
    @@ -280,6 +280,7 @@ import static com.annimon.stream.Collectors.toList;
             return comment != null ? (int) comment.getId() : 0;
         }
     
    +
         @Override public int describeContents() { return 0; }
     
         @Override public void writeToParcel(Parcel dest, int flags) {
    @@ -290,6 +291,8 @@ import static com.annimon.stream.Collectors.toList;
             dest.writeParcelable(this.pullRequest, flags);
             dest.writeParcelable(this.status, flags);
             dest.writeParcelable(this.review, flags);
    +        dest.writeParcelable(this.groupedReview, flags);
    +        dest.writeParcelable(this.reviewComment, flags);
             dest.writeLong(this.sortedDate != null ? this.sortedDate.getTime() : -1);
         }
     
    @@ -301,6 +304,8 @@ import static com.annimon.stream.Collectors.toList;
             this.pullRequest = in.readParcelable(PullRequest.class.getClassLoader());
             this.status = in.readParcelable(PullRequestStatusModel.class.getClassLoader());
             this.review = in.readParcelable(ReviewModel.class.getClassLoader());
    +        this.groupedReview = in.readParcelable(GroupedReviewModel.class.getClassLoader());
    +        this.reviewComment = in.readParcelable(ReviewCommentModel.class.getClassLoader());
             long tmpSortedDate = in.readLong();
             this.sortedDate = tmpSortedDate == -1 ? null : new Date(tmpSortedDate);
         }
    diff --git a/app/src/main/java/com/fastaccess/data/dao/TrendingModel.kt b/app/src/main/java/com/fastaccess/data/dao/TrendingModel.kt
    new file mode 100644
    index 00000000..db430dbc
    --- /dev/null
    +++ b/app/src/main/java/com/fastaccess/data/dao/TrendingModel.kt
    @@ -0,0 +1,39 @@
    +package com.fastaccess.data.dao
    +
    +import android.os.Parcel
    +import android.os.Parcelable
    +
    +data class TrendingModel(
    +        val title: String? = null,
    +        val description: String? = null,
    +        val language: String? = null,
    +        val stars: String? = null,
    +        val forks: String? = null,
    +        val todayStars: String? = null) : Parcelable {
    +    companion object {
    +        @JvmField val CREATOR: Parcelable.Creator<TrendingModel> = object : Parcelable.Creator<TrendingModel> {
    +            override fun createFromParcel(source: Parcel): TrendingModel = TrendingModel(source)
    +            override fun newArray(size: Int): Array<TrendingModel?> = arrayOfNulls(size)
    +        }
    +    }
    +
    +    constructor(source: Parcel) : this(
    +            source.readString(),
    +            source.readString(),
    +            source.readString(),
    +            source.readString(),
    +            source.readString(),
    +            source.readString()
    +    )
    +
    +    override fun describeContents() = 0
    +
    +    override fun writeToParcel(dest: Parcel, flags: Int) {
    +        dest.writeString(title)
    +        dest.writeString(description)
    +        dest.writeString(language)
    +        dest.writeString(stars)
    +        dest.writeString(forks)
    +        dest.writeString(todayStars)
    +    }
    +}
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/data/dao/TrendingResponse.java b/app/src/main/java/com/fastaccess/data/dao/TrendingResponse.java
    deleted file mode 100644
    index dcab0e58..00000000
    --- a/app/src/main/java/com/fastaccess/data/dao/TrendingResponse.java
    +++ /dev/null
    @@ -1,47 +0,0 @@
    -package com.fastaccess.data.dao;
    -
    -import android.os.Parcel;
    -import android.os.Parcelable;
    -
    -import com.github.florent37.retrojsoup.annotations.JsoupText;
    -
    -import lombok.ToString;
    -
    -/**
    - * Created by Kosh on 02 Jun 2017, 1:06 PM
    - */
    -
    -@ToString public class TrendingResponse implements Parcelable { // retroSoup doesn't like it to be kolin class.
    -
    -    @JsoupText(".repo-list > li > .d-inline-block > h3 > a") public String title;
    -    @JsoupText(".repo-list > li > .py-1 > p") public String description;
    -    @JsoupText(".repo-list > li > .f6 > a[href*=/stargazers]") public String stars;
    -    @JsoupText(".repo-list > li > .f6 > a[href*=/network]") public String forks;
    -    @JsoupText(".repo-list > li > .f6 > span.float-right") public String todayStars;
    -
    -    @Override public int describeContents() { return 0; }
    -
    -    @Override public void writeToParcel(Parcel dest, int flags) {
    -        dest.writeString(this.title);
    -        dest.writeString(this.description);
    -        dest.writeString(this.stars);
    -        dest.writeString(this.forks);
    -        dest.writeString(this.todayStars);
    -    }
    -
    -    public TrendingResponse() {}
    -
    -    protected TrendingResponse(Parcel in) {
    -        this.title = in.readString();
    -        this.description = in.readString();
    -        this.stars = in.readString();
    -        this.forks = in.readString();
    -        this.todayStars = in.readString();
    -    }
    -
    -    public static final Parcelable.Creator<TrendingResponse> CREATOR = new Parcelable.Creator<TrendingResponse>() {
    -        @Override public TrendingResponse createFromParcel(Parcel source) {return new TrendingResponse(source);}
    -
    -        @Override public TrendingResponse[] newArray(int size) {return new TrendingResponse[size];}
    -    };
    -}
    diff --git a/app/src/main/java/com/fastaccess/data/dao/model/AbstractGist.java b/app/src/main/java/com/fastaccess/data/dao/model/AbstractGist.java
    index 6432b5e3..ffc64f35 100644
    --- a/app/src/main/java/com/fastaccess/data/dao/model/AbstractGist.java
    +++ b/app/src/main/java/com/fastaccess/data/dao/model/AbstractGist.java
    @@ -12,7 +12,6 @@ import com.fastaccess.data.dao.GithubFileModel;
     import com.fastaccess.data.dao.converters.GitHubFilesConverter;
     import com.fastaccess.data.dao.converters.UserConverter;
     import com.fastaccess.helper.InputHelper;
    -import com.fastaccess.helper.ObjectsCompat;
     import com.fastaccess.helper.RxHelper;
     import com.fastaccess.ui.widgets.SpannableBuilder;
     import com.google.gson.annotations.SerializedName;
    @@ -35,7 +34,7 @@ import lombok.NoArgsConstructor;
      * Created by Kosh on 16 Mar 2017, 7:32 PM
      */
     
    -@Entity @NoArgsConstructor public abstract class AbstractGist implements Parcelable {
    +@Entity() @NoArgsConstructor public abstract class AbstractGist implements Parcelable {
         @SerializedName("nooope") @Key long id;
         String url;
         String forksUrl;
    @@ -79,11 +78,11 @@ import lombok.NoArgsConstructor;
                     .single()
                     .toObservable()
                     .flatMap(integer -> Observable.fromIterable(gists))
    -                .filter(ObjectsCompat::nonNull)
    -                .flatMap(gist -> {
    +                .map(gist -> {
                         gist.setOwnerName(ownerName);
    -                    return gist.save(gist).toObservable();
    -                }));
    +                    return gist;
    +                })
    +                .flatMap(gist -> gist.save(gist).toObservable()));
         }
     
         @NonNull public static Single<List<Gist>> getMyGists(@NonNull String ownerName) {
    @@ -168,7 +167,16 @@ import lombok.NoArgsConstructor;
                 spannableBuilder.append(description);
             }
             if (InputHelper.isEmpty(spannableBuilder.toString())) {
    -            if (isFromProfile) spannableBuilder.bold("N/A");
    +            if (isFromProfile) {
    +                List<FilesListModel> files = getFilesAsList();
    +                if (!files.isEmpty()) {
    +                    FilesListModel filesListModel = files.get(0);
    +                    if (!InputHelper.isEmpty(filesListModel.getFilename()) && filesListModel.getFilename().trim().length() > 2) {
    +                        spannableBuilder.append(" ")
    +                                .append(filesListModel.getFilename());
    +                    }
    +                }
    +            }
             }
             return spannableBuilder;
         }
    diff --git a/app/src/main/java/com/fastaccess/data/service/GistService.java b/app/src/main/java/com/fastaccess/data/service/GistService.java
    index eb6a8a70..bc088be4 100644
    --- a/app/src/main/java/com/fastaccess/data/service/GistService.java
    +++ b/app/src/main/java/com/fastaccess/data/service/GistService.java
    @@ -8,6 +8,7 @@ import com.fastaccess.data.dao.Pageable;
     import com.fastaccess.data.dao.model.Comment;
     import com.fastaccess.data.dao.model.Gist;
     
    +import io.reactivex.Observable;
     import retrofit2.Response;
     import retrofit2.http.Body;
     import retrofit2.http.DELETE;
    @@ -19,7 +20,6 @@ import retrofit2.http.PUT;
     import retrofit2.http.Path;
     import retrofit2.http.Query;
     import retrofit2.http.Url;
    -import io.reactivex.Observable;
     
     /**
      * Created by Kosh on 20 Nov 2016, 10:28 AM
    @@ -38,11 +38,10 @@ public interface GistService {
     
         @GET("gists/public") Observable<Pageable<Gist>> getPublicGists(@Query("per_page") int perPage, @Query("page") int page);
     
    -    @GET("gists") Observable<Pageable<Gist>> getMyGists(@Query("per_page") int perPage, @Query("page") int page);
    +    @GET("gists") Observable<Pageable<Gist>> getMyGists(@Query("page") int page);
     
         @GET("users/{username}/gists")
    -    Observable<Pageable<Gist>> getUserGists(@NonNull @Path("username") String username,
    -                                            @Query("per_page") int perPage, @Query("page") int page);
    +    Observable<Pageable<Gist>> getUserGists(@NonNull @Path("username") String username, @Query("page") int page);
     
         @GET("gists/{id}")
         Observable<Gist> getGist(@Path("id") String id);
    diff --git a/app/src/main/java/com/fastaccess/data/service/TrendingService.java b/app/src/main/java/com/fastaccess/data/service/TrendingService.java
    index 5f39e54c..ebec9ebe 100644
    --- a/app/src/main/java/com/fastaccess/data/service/TrendingService.java
    +++ b/app/src/main/java/com/fastaccess/data/service/TrendingService.java
    @@ -1,9 +1,12 @@
     package com.fastaccess.data.service;
     
    -import com.fastaccess.data.dao.TrendingResponse;
    -import com.github.florent37.retrojsoup.annotations.Select;
    +
    +import android.support.annotation.Nullable;
     
     import io.reactivex.Observable;
    +import retrofit2.http.GET;
    +import retrofit2.http.Path;
    +import retrofit2.http.Query;
     
     /**
      * Created by Kosh on 02 Jun 2017, 12:58 PM
    @@ -11,5 +14,5 @@ import io.reactivex.Observable;
     
     public interface TrendingService {
     
    -    @Select(".repo-list") Observable<TrendingResponse> getTrending();
    +    @GET("{lan}") Observable<String> getTrending(@Path("lan") @Nullable String lan, @Nullable @Query("since") String since);
     }
    diff --git a/app/src/main/java/com/fastaccess/data/service/UserRestService.java b/app/src/main/java/com/fastaccess/data/service/UserRestService.java
    index b935d97e..520d5806 100644
    --- a/app/src/main/java/com/fastaccess/data/service/UserRestService.java
    +++ b/app/src/main/java/com/fastaccess/data/service/UserRestService.java
    @@ -34,15 +34,22 @@ public interface UserRestService {
         @GET("users/{username}/received_events")
         Observable<Pageable<Event>> getReceivedEvents(@NonNull @Path("username") String userName, @Query("page") int page);
     
    -    @GET("/users/{username}/repos")
    -    Observable<Pageable<Repo>> getRepos(@Path("username") @NonNull String username, @QueryMap(encoded=true) Map<String, String> filterParams, @Query("page") int page);
    +    @GET("users/{username}/events")
    +    Observable<Pageable<Event>> getUserEvents(@NonNull @Path("username") String userName, @Query("page") int page);
     
    -    @GET("/user/repos")
    -    Observable<Pageable<Repo>> getRepos(@QueryMap(encoded=true) Map<String, String> filterParams, @Query(value = "page") int page);
    +    @GET("users/{username}/repos")
    +    Observable<Pageable<Repo>> getRepos(@Path("username") @NonNull String username, @QueryMap(encoded = true) Map<String, String> filterParams,
    +                                        @Query("page") int page);
    +
    +    @GET("user/repos")
    +    Observable<Pageable<Repo>> getRepos(@QueryMap(encoded = true) Map<String, String> filterParams, @Query(value = "page") int page);
     
         @GET("users/{username}/starred") Observable<Pageable<Repo>>
         getStarred(@Path("username") @NonNull String username, @Query("page") int page);
     
    +    @GET("users/{username}/starred?per_page=1") Observable<Pageable<Repo>>
    +    getStarredCount(@Path("username") @NonNull String username);
    +
         @GET("users/{username}/following")
         Observable<Pageable<User>> getFollowing(@Path("username") @NonNull String username, @Query("page") int page);
     
    @@ -52,10 +59,10 @@ public interface UserRestService {
         @GET("user/following/{username}")
         Observable<Response<Boolean>> getFollowStatus(@Path("username") @NonNull String username);
     
    -    @PUT("/user/following/{username}")
    +    @PUT("user/following/{username}")
         Observable<Response<Boolean>> followUser(@Path("username") @NonNull String username);
     
    -    @DELETE("/user/following/{username}")
    +    @DELETE("user/following/{username}")
         Observable<Response<Boolean>> unfollowUser(@Path("username") @NonNull String username);
     
         @GET Observable<String> getContributions(@Url String url);
    diff --git a/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java b/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java
    index 6b97b7d6..d828b4ba 100644
    --- a/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java
    +++ b/app/src/main/java/com/fastaccess/helper/ParseDateFormat.java
    @@ -60,7 +60,7 @@ public class ParseDateFormat {
             return INSTANCE;
         }
     
    -    public static String getDateByDays(int days) {
    +    private static String getDateByDays(int days) {
             Calendar cal = Calendar.getInstance();
             SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
             cal.add(Calendar.DAY_OF_YEAR, days);
    diff --git a/app/src/main/java/com/fastaccess/helper/RxHelper.java b/app/src/main/java/com/fastaccess/helper/RxHelper.java
    index 502f18a7..daf6431e 100644
    --- a/app/src/main/java/com/fastaccess/helper/RxHelper.java
    +++ b/app/src/main/java/com/fastaccess/helper/RxHelper.java
    @@ -21,7 +21,6 @@ public class RxHelper {
     
         public static <T> Observable<T> safeObservable(@NonNull Observable<T> observable) {
             return getObserver(observable)
    -                .onErrorReturn(throwable -> (T) new Object())
                     .doOnError(Throwable::printStackTrace);
         }
     
    diff --git a/app/src/main/java/com/fastaccess/provider/colors/ColorsProvider.java b/app/src/main/java/com/fastaccess/provider/colors/ColorsProvider.java
    index 8490b5ea..37a30713 100644
    --- a/app/src/main/java/com/fastaccess/provider/colors/ColorsProvider.java
    +++ b/app/src/main/java/com/fastaccess/provider/colors/ColorsProvider.java
    @@ -23,6 +23,7 @@ import java.io.InputStreamReader;
     import java.lang.reflect.Type;
     import java.util.ArrayList;
     import java.util.LinkedHashMap;
    +import java.util.List;
     import java.util.Map;
     
     import io.reactivex.Observable;
    @@ -33,6 +34,9 @@ import io.reactivex.Observable;
     
     public class ColorsProvider {
     
    +    private static List<String> popularLanguages = Stream.of("Java", "Kotlin", "JavaScript", "Python", "CSS", "PHP",
    +            "Ruby", "C++", "C", "GO", "Swift").toList();//predefined languages.
    +
         private static Map<String, LanguageColorModel> colors = new LinkedHashMap<>();
     
         public static void load() {
    @@ -57,10 +61,14 @@ public class ColorsProvider {
         }
     
         @NonNull public static ArrayList<String> languages() {
    -        return Stream.of(colors)
    +        ArrayList<String> lang = new ArrayList<>();
    +        lang.add("All Language");
    +        lang.addAll(Stream.of(colors)
                     .filter(value -> value != null && !InputHelper.isEmpty(value.getKey()))
                     .map(Map.Entry::getKey)
    -                .collect(Collectors.toCollection(ArrayList::new));
    +                .sortBy(s -> !popularLanguages.contains(s))
    +                .collect(Collectors.toCollection(ArrayList::new)));
    +        return lang;
         }
     
         @Nullable public static LanguageColorModel getColor(@NonNull String lang) {
    diff --git a/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java b/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java
    index 467b0e3d..13645339 100644
    --- a/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java
    +++ b/app/src/main/java/com/fastaccess/provider/rest/RestProvider.java
    @@ -60,7 +60,7 @@ public class RestProvider {
                 .setPrettyPrinting()
                 .create();
     
    -    public static OkHttpClient provideOkHttpClient(boolean isRawString) {
    +    private static OkHttpClient provideOkHttpClient(boolean isRawString) {
             if (okHttpClient == null) {
                 OkHttpClient.Builder client = new OkHttpClient.Builder();
                 if (BuildConfig.DEBUG) {
    diff --git a/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java b/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java
    index 273d6acb..214f302c 100644
    --- a/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java
    +++ b/app/src/main/java/com/fastaccess/provider/rest/interceptors/AuthenticationInterceptor.java
    @@ -1,24 +1,36 @@
     package com.fastaccess.provider.rest.interceptors;
     
    +import android.support.annotation.NonNull;
    +
     import com.fastaccess.data.service.NotificationService;
     import com.fastaccess.helper.InputHelper;
     
     import java.io.IOException;
     import java.net.URI;
     
    -import lombok.AllArgsConstructor;
     import okhttp3.HttpUrl;
     import okhttp3.Interceptor;
     import okhttp3.Request;
     import okhttp3.Response;
     
    -@AllArgsConstructor
     public class AuthenticationInterceptor implements Interceptor {
     
         private String authToken;
         private String otp;
    +    private boolean isScrapping;
     
    -    @Override public Response intercept(Chain chain) throws IOException {
    +    public AuthenticationInterceptor(String authToken, String otp) {
    +        this.authToken = authToken;
    +        this.otp = otp;
    +    }
    +
    +    public AuthenticationInterceptor(String authToken, String otp, boolean isScrapping) {
    +        this.authToken = authToken;
    +        this.otp = otp;
    +        this.isScrapping = isScrapping;
    +    }
    +
    +    @Override public Response intercept(@NonNull Chain chain) throws IOException {
             Request original = chain.request();
             if (original.url() != HttpUrl.get(URI.create(NotificationService.SUBSCRIPTION_URL))) {
                 Request.Builder builder = original.newBuilder();
    @@ -28,6 +40,7 @@ public class AuthenticationInterceptor implements Interceptor {
                 if (!InputHelper.isEmpty(otp)) {
                     builder.addHeader("X-GitHub-OTP", otp.trim());
                 }
    +            if (!isScrapping) builder.addHeader("User-Agent", "FastHub");
                 Request request = builder.build();
                 return chain.proceed(request);
             }
    diff --git a/app/src/main/java/com/fastaccess/provider/rest/jsoup/RetroJsoupProvider.java b/app/src/main/java/com/fastaccess/provider/rest/jsoup/JsoupProvider.java
    similarity index 64%
    rename from app/src/main/java/com/fastaccess/provider/rest/jsoup/RetroJsoupProvider.java
    rename to app/src/main/java/com/fastaccess/provider/rest/jsoup/JsoupProvider.java
    index db899bb7..3bff2123 100644
    --- a/app/src/main/java/com/fastaccess/provider/rest/jsoup/RetroJsoupProvider.java
    +++ b/app/src/main/java/com/fastaccess/provider/rest/jsoup/JsoupProvider.java
    @@ -1,23 +1,22 @@
     package com.fastaccess.provider.rest.jsoup;
     
    -import android.support.annotation.NonNull;
    -import android.support.annotation.Nullable;
    -
     import com.fastaccess.BuildConfig;
     import com.fastaccess.data.service.TrendingService;
    -import com.fastaccess.helper.InputHelper;
     import com.fastaccess.helper.PrefGetter;
    +import com.fastaccess.provider.rest.converters.GithubResponseConverter;
     import com.fastaccess.provider.rest.interceptors.AuthenticationInterceptor;
    -import com.github.florent37.retrojsoup.RetroJsoup;
    +import com.google.gson.Gson;
     
     import okhttp3.OkHttpClient;
     import okhttp3.logging.HttpLoggingInterceptor;
    +import retrofit2.Retrofit;
    +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
     
     /**
      * Created by Kosh on 02 Jun 2017, 12:47 PM
      */
     
    -public class RetroJsoupProvider {
    +public class JsoupProvider {
     
         private static OkHttpClient okHttpClient;
     
    @@ -28,16 +27,18 @@ public class RetroJsoupProvider {
                     client.addInterceptor(new HttpLoggingInterceptor()
                             .setLevel(HttpLoggingInterceptor.Level.BODY));
                 }
    -            client.addInterceptor(new AuthenticationInterceptor(PrefGetter.getToken(), PrefGetter.getOtpCode()));
    +            client.addInterceptor(new AuthenticationInterceptor(PrefGetter.getToken(), PrefGetter.getOtpCode(), true));
                 okHttpClient = client.build();
             }
             return okHttpClient;
         }
     
    -    public static TrendingService getTrendingService(@NonNull String since, @Nullable String lang) {
    -        return new RetroJsoup.Builder()
    -                .url("https://github.com/trending/" + (!InputHelper.isEmpty(lang) ? lang : "") + "?since=" + since)
    +    public static TrendingService getTrendingService() {
    +        return new Retrofit.Builder()
    +                .baseUrl("https://github.com/trending/")
                     .client(provideOkHttpClient())
    +                .addConverterFactory(new GithubResponseConverter(new Gson()))
    +                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                     .build()
                     .create(TrendingService.class);
         }
    diff --git a/app/src/main/java/com/fastaccess/provider/scheme/LinkParserHelper.java b/app/src/main/java/com/fastaccess/provider/scheme/LinkParserHelper.java
    index 37f7c8b3..d71193ac 100644
    --- a/app/src/main/java/com/fastaccess/provider/scheme/LinkParserHelper.java
    +++ b/app/src/main/java/com/fastaccess/provider/scheme/LinkParserHelper.java
    @@ -23,7 +23,7 @@ class LinkParserHelper {
         static final String API_AUTHORITY = "api.github.com";
         static final String PROTOCOL_HTTPS = "https";
         static final ArrayList<String> IGNORED_LIST = Stream.of("notifications", "settings", "blog", "explore",
    -            "dashboard", "repositories", "logout", "sessions", "site", "security", "contact", "about", "logos", "login", "trending", "")
    +            "dashboard", "repositories", "logout", "sessions", "site", "security", "contact", "about", "logos", "login", "")
                 .collect(Collectors.toCollection(ArrayList::new));
     
     
    diff --git a/app/src/main/java/com/fastaccess/provider/scheme/SchemeParser.java b/app/src/main/java/com/fastaccess/provider/scheme/SchemeParser.java
    index 0254213e..bc99fe2e 100644
    --- a/app/src/main/java/com/fastaccess/provider/scheme/SchemeParser.java
    +++ b/app/src/main/java/com/fastaccess/provider/scheme/SchemeParser.java
    @@ -23,6 +23,7 @@ import com.fastaccess.ui.modules.repos.code.releases.ReleasesListActivity;
     import com.fastaccess.ui.modules.repos.issues.create.CreateIssueActivity;
     import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerActivity;
     import com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.PullRequestPagerActivity;
    +import com.fastaccess.ui.modules.trending.TrendingActivity;
     import com.fastaccess.ui.modules.user.UserPagerActivity;
     
     import java.util.List;
    @@ -108,6 +109,7 @@ public class SchemeParser {
                 String authority = data.getAuthority();
                 if (TextUtils.equals(authority, HOST_DEFAULT) || TextUtils.equals(authority, RAW_AUTHORITY) ||
                         TextUtils.equals(authority, API_AUTHORITY)) {
    +                Intent trending = getTrending(context, data);
                     Intent userIntent = getUser(context, data);
                     Intent repoIssues = getRepoIssueIntent(context, data);
                     Intent repoPulls = getRepoPullRequestIntent(context, data);
    @@ -119,7 +121,7 @@ public class SchemeParser {
                     Intent commit = getCommit(context, data, showRepoBtn);
                     Intent commits = getCommits(context, data, showRepoBtn);
                     Intent blob = getBlob(context, data);
    -                Optional<Intent> intentOptional = returnNonNull(userIntent, repoIssues, repoPulls, pullRequestIntent, commit, commits,
    +                Optional<Intent> intentOptional = returnNonNull(trending, userIntent, repoIssues, repoPulls, pullRequestIntent, commit, commits,
                             createIssueIntent, issueIntent, releasesIntent, repoIntent, blob);
                     Optional<Intent> empty = Optional.empty();
                     if (intentOptional != null && intentOptional.isPresent() && intentOptional != empty) {
    @@ -324,6 +326,25 @@ public class SchemeParser {
             return null;
         }
     
    +    @Nullable private static Intent getTrending(@NonNull Context context, @NonNull Uri uri) {
    +        List<String> segments = uri.getPathSegments();
    +        if (segments != null && !segments.isEmpty()) {
    +            if (uri.getPathSegments().get(0).equals("trending")) {
    +                String query = "";
    +                String lang = "";
    +                if (uri.getPathSegments().size() > 1) {
    +                    lang = uri.getPathSegments().get(1);
    +                }
    +                if (uri.getQueryParameterNames() != null && !uri.getQueryParameterNames().isEmpty()) {
    +                    query = uri.getQueryParameter("since");
    +                }
    +                return TrendingActivity.Companion.getTrendingIntent(context, lang, query);
    +            }
    +            return null;
    +        }
    +        return null;
    +    }
    +
         /**
          * https://github.com/owner/repo/issues/new
          */
    diff --git a/app/src/main/java/com/fastaccess/provider/tasks/notification/NotificationSchedulerJobTask.java b/app/src/main/java/com/fastaccess/provider/tasks/notification/NotificationSchedulerJobTask.java
    index 5f931419..be0f2c4b 100644
    --- a/app/src/main/java/com/fastaccess/provider/tasks/notification/NotificationSchedulerJobTask.java
    +++ b/app/src/main/java/com/fastaccess/provider/tasks/notification/NotificationSchedulerJobTask.java
    @@ -5,6 +5,7 @@ import android.app.PendingIntent;
     import android.content.Context;
     import android.content.Intent;
     import android.graphics.Bitmap;
    +import android.graphics.BitmapFactory;
     import android.support.annotation.NonNull;
     import android.support.annotation.Nullable;
     import android.support.v4.app.NotificationCompat;
    @@ -18,6 +19,7 @@ import com.fastaccess.data.dao.model.Login;
     import com.fastaccess.data.dao.model.Notification;
     import com.fastaccess.helper.AppHelper;
     import com.fastaccess.helper.InputHelper;
    +import com.fastaccess.helper.Logger;
     import com.fastaccess.helper.ParseDateFormat;
     import com.fastaccess.helper.PrefGetter;
     import com.fastaccess.helper.RxHelper;
    @@ -33,6 +35,7 @@ import com.firebase.jobdispatcher.RetryStrategy;
     import com.firebase.jobdispatcher.Trigger;
     import com.nostra13.universalimageloader.core.ImageLoader;
     import com.nostra13.universalimageloader.core.assist.FailReason;
    +import com.nostra13.universalimageloader.core.assist.ImageSize;
     import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
     
     import java.util.List;
    @@ -125,25 +128,42 @@ public class NotificationSchedulerJobTask extends JobService {
             }
             Context context = getApplicationContext();
             int accentColor = ContextCompat.getColor(this, R.color.material_blue_700);
    -        String[] url = new String[1];
             Notification first = notificationThreadModels.get(0);
             Observable.fromIterable(notificationThreadModels)
                     .subscribeOn(Schedulers.io())
                     .filter(notification -> notification.isUnread() && first.getId() != notification.getId())
                     .take(10)
    -                .flatMap(notification -> RestProvider.getNotificationService()
    -                        .getComment(notification.getSubject().getLatestCommentUrl())
    -                        .subscribeOn(Schedulers.io()), (thread, comment) -> {
    -                    url[0] = comment.getUser().getAvatarUrl();
    -                    if (!InputHelper.isEmpty(thread.getSubject().getLatestCommentUrl())) {
    -                        getNotificationWithComment(context, accentColor, thread, comment, url[0]);
    -                        return null;
    +                .flatMap(notification -> {
    +                    Logger.e(notification.getSubject().getTitle());
    +                    if (notification.getSubject() != null && notification.getSubject().getLatestCommentUrl() != null) {
    +                        return RestProvider.getNotificationService()
    +                                .getComment(notification.getSubject().getLatestCommentUrl())
    +                                .subscribeOn(Schedulers.io());
    +                    } else {
    +                        return Observable.empty();
                         }
    -                    showNotificationWithoutComment(context, accentColor, thread, url[0]);
    -                    return thread;
    +                }, (thread, comment) -> {
    +                    CustomNotificationModel customNotificationModel = new CustomNotificationModel();
    +                    String url;
    +                    if (comment != null && comment.getUser() != null) {
    +                        url = comment.getUser().getAvatarUrl();
    +                        if (!InputHelper.isEmpty(thread.getSubject().getLatestCommentUrl())) {
    +                            customNotificationModel.comment = comment;
    +                            customNotificationModel.url = url;
    +                        }
    +                    }
    +                    customNotificationModel.notification = thread;
    +                    return customNotificationModel;
                     })
                     .subscribeOn(Schedulers.io())
    -                .subscribe(thread -> {/*do nothing in here*/}, throwable -> jobFinished(job, true), () -> {
    +                .subscribe(custom -> {
    +                    if (custom.comment != null) {
    +                        getNotificationWithComment(context, accentColor, custom.notification, custom.comment, custom.url);
    +                    } else {
    +                        showNotificationWithoutComment(context, accentColor, custom.notification, custom.url);
    +                    }
    +
    +                }, throwable -> finishJob(job), () -> {
                         android.app.Notification grouped = getSummaryGroupNotification(first, accentColor);
                         showNotification(first.getId(), grouped);
                         finishJob(job);
    @@ -155,134 +175,84 @@ public class NotificationSchedulerJobTask extends JobService {
         }
     
         private void showNotificationWithoutComment(Context context, int accentColor, Notification thread, String iconUrl) {
    -        ImageLoader.getInstance().loadImage(iconUrl, new ImageLoadingListener() {
    -            @Override
    -            public void onLoadingStarted(String s, View view) {
    +        if (!InputHelper.isEmpty(iconUrl)) {
    +            withoutComments(null, thread, context, accentColor);
    +        } else {
    +            ImageLoader.getInstance().loadImage(iconUrl, new ImageSize(50, 50), new ImageLoadingListener() {
    +                @Override public void onLoadingStarted(String s, View view) {}
     
    -            }
    +                @Override public void onLoadingFailed(String s, View view, FailReason failReason) {
    +                    withoutComments(null, thread, context, accentColor);
    +                }
     
    -            @Override
    -            public void onLoadingFailed(String s, View view, FailReason failReason) {
    -                android.app.Notification toAdd = getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName())
    -                        .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(), thread
    -                                .getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(), thread
    -                                .getSubject().getUrl()))
    -                        .setWhen(thread.getUpdatedAt() != null ? thread.getUpdatedAt().getTime() : System.currentTimeMillis())
    -                        .setShowWhen(true)
    -                        .setColor(accentColor)
    -                        .setGroup(NOTIFICATION_GROUP_ID)
    -                        .build();
    -                showNotification(thread.getId(), toAdd);
    -            }
    +                @Override public void onLoadingComplete(String s, View view, Bitmap bitmap) {
    +                    withoutComments(bitmap, thread, context, accentColor);
    +                }
     
    -            @Override
    -            public void onLoadingComplete(String s, View view, Bitmap bitmap) {
    -                android.app.Notification toAdd = getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName())
    -                        .setLargeIcon(bitmap)
    -                        .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(), thread
    -                                .getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(), thread
    -                                .getSubject().getUrl()))
    -                        .setWhen(thread.getUpdatedAt() != null ? thread.getUpdatedAt().getTime() : System.currentTimeMillis())
    -                        .setShowWhen(true)
    -                        .setColor(accentColor)
    -                        .setGroup(NOTIFICATION_GROUP_ID)
    -                        .build();
    -                showNotification(thread.getId(), toAdd);
    -            }
    +                @Override public void onLoadingCancelled(String s, View view) {
    +                    withoutComments(null, thread, context, accentColor);
     
    -            @Override
    -            public void onLoadingCancelled(String s, View view) {
    -
    -                android.app.Notification toAdd = getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName())
    -                        .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(), thread
    -                                .getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(), thread
    -                                .getSubject().getUrl()))
    -                        .setWhen(thread.getUpdatedAt() != null ? thread.getUpdatedAt().getTime() : System.currentTimeMillis())
    -                        .setShowWhen(true)
    -                        .setColor(accentColor)
    -                        .setGroup(NOTIFICATION_GROUP_ID)
    -                        .build();
    -                showNotification(thread.getId(), toAdd);
    -
    -            }
    -        });
    +                }
    +            });
    +        }
         }
     
    -    private void getNotificationWithComment(Context context, int accentColor,
    -                                            Notification thread, Comment comment, String url) {
    -        ImageLoader.getInstance().loadImage(url, new ImageLoadingListener() {
    -            @Override
    -            public void onLoadingStarted(String s, View view) {
    +    private void withoutComments(Bitmap bitmap, Notification thread, Context context, int accentColor) {
    +        android.app.Notification toAdd = getNotification(thread.getSubject().getTitle(), thread.getRepository().getFullName())
    +                .setLargeIcon(bitmap == null ? BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher) : bitmap)
    +                .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    +                .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(), thread
    +                        .getSubject().getUrl()))
    +                .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(), thread
    +                        .getSubject().getUrl()))
    +                .setWhen(thread.getUpdatedAt() != null ? thread.getUpdatedAt().getTime() : System.currentTimeMillis())
    +                .setShowWhen(true)
    +                .setColor(accentColor)
    +                .setGroup(NOTIFICATION_GROUP_ID)
    +                .build();
    +        showNotification(thread.getId(), toAdd);
    +    }
     
    -            }
    +    private void getNotificationWithComment(Context context, int accentColor, Notification thread, Comment comment, String url) {
    +        if (!InputHelper.isEmpty(url)) {
    +            ImageLoader.getInstance().loadImage(url, new ImageSize(50, 50), new ImageLoadingListener() {
    +                @Override public void onLoadingStarted(String s, View view) {}
     
    -            @Override
    -            public void onLoadingFailed(String s, View view, FailReason failReason) {
    -                android.app.Notification toAdd = getNotification(comment.getUser() != null ? comment.getUser().getLogin() : "", comment.getBody())
    -                        .setSmallIcon(R.drawable.ic_notification)
    -                        .setStyle(new NotificationCompat.BigTextStyle()
    -                                .setBigContentTitle(comment.getUser() != null ? comment.getUser().getLogin() : "")
    -                                .bigText(comment.getBody()))
    -                        .setWhen(comment.getCreatedAt().getTime())
    -                        .setShowWhen(true)
    -                        .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(),
    -                                thread.getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(),
    -                                thread.getSubject().getUrl()))
    -                        .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    -                        .setColor(accentColor)
    -                        .setGroup(NOTIFICATION_GROUP_ID)
    -                        .build();
    -                showNotification(thread.getId(), toAdd);
    -            }
    +                @Override public void onLoadingFailed(String s, View view, FailReason failReason) {
    +                    withComments(null, comment, context, thread, accentColor);
    +                }
     
    -            @Override
    -            public void onLoadingComplete(String s, View view, Bitmap bitmap) {
    -                android.app.Notification toAdd = getNotification(comment.getUser() != null ? comment.getUser().getLogin() : "", comment.getBody())
    -                        .setLargeIcon(bitmap)
    -                        .setSmallIcon(R.drawable.ic_notification)
    -                        .setStyle(new NotificationCompat.BigTextStyle()
    -                                .setBigContentTitle(comment.getUser() != null ? comment.getUser().getLogin() : "")
    -                                .bigText(comment.getBody()))
    -                        .setWhen(comment.getCreatedAt().getTime())
    -                        .setShowWhen(true)
    -                        .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(),
    -                                thread.getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(),
    -                                thread.getSubject().getUrl()))
    -                        .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    -                        .setColor(accentColor)
    -                        .setGroup(NOTIFICATION_GROUP_ID)
    -                        .build();
    -                showNotification(thread.getId(), toAdd);
    -            }
    +                @Override public void onLoadingComplete(String s, View view, Bitmap bitmap) {
    +                    withComments(bitmap, comment, context, thread, accentColor);
    +                }
     
    -            @Override
    -            public void onLoadingCancelled(String s, View view) {
    -                android.app.Notification toAdd = getNotification(comment.getUser() != null ? comment.getUser().getLogin() : "", comment.getBody())
    -                        .setSmallIcon(R.drawable.ic_notification)
    -                        .setStyle(new NotificationCompat.BigTextStyle()
    -                                .setBigContentTitle(comment.getUser() != null ? comment.getUser().getLogin() : "")
    -                                .bigText(comment.getBody()))
    -                        .setWhen(comment.getCreatedAt().getTime())
    -                        .setShowWhen(true)
    -                        .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(),
    -                                thread.getSubject().getUrl()))
    -                        .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(),
    -                                thread.getSubject().getUrl()))
    -                        .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    -                        .setColor(accentColor)
    -                        .setGroup(NOTIFICATION_GROUP_ID)
    -                        .build();
    -                showNotification(thread.getId(), toAdd);
    -            }
    -        });
    +                @Override public void onLoadingCancelled(String s, View view) {
    +                    withComments(null, comment, context, thread, accentColor);
    +                }
    +            });
    +        } else {
    +            withComments(null, comment, context, thread, accentColor);
    +        }
    +    }
    +
    +    private void withComments(Bitmap bitmap, Comment comment, Context context, Notification thread, int accentColor) {
    +        android.app.Notification toAdd = getNotification(comment.getUser() != null ? comment.getUser().getLogin() : "", comment.getBody())
    +                .setLargeIcon(bitmap == null ? BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher) : bitmap)
    +                .setSmallIcon(R.drawable.ic_notification)
    +                .setStyle(new NotificationCompat.BigTextStyle()
    +                        .setBigContentTitle(comment.getUser() != null ? comment.getUser().getLogin() : "")
    +                        .bigText(comment.getBody()))
    +                .setWhen(comment.getCreatedAt().getTime())
    +                .setShowWhen(true)
    +                .addAction(R.drawable.ic_github, context.getString(R.string.open), getPendingIntent(thread.getId(),
    +                        thread.getSubject().getUrl()))
    +                .addAction(R.drawable.ic_eye_off, context.getString(R.string.mark_as_read), getReadOnlyPendingIntent(thread.getId(),
    +                        thread.getSubject().getUrl()))
    +                .setContentIntent(getPendingIntent(thread.getId(), thread.getSubject().getUrl()))
    +                .setColor(accentColor)
    +                .setGroup(NOTIFICATION_GROUP_ID)
    +                .build();
    +        showNotification(thread.getId(), toAdd);
         }
     
         private android.app.Notification getSummaryGroupNotification(@NonNull Notification thread, int accentColor) {
    @@ -325,4 +295,10 @@ public class NotificationSchedulerJobTask extends JobService {
             return PendingIntent.getService(getApplicationContext(), InputHelper.getSafeIntId(id), intent,
                     PendingIntent.FLAG_UPDATE_CURRENT);
         }
    +
    +    private static class CustomNotificationModel {
    +        public String url;
    +        public Notification notification;
    +        public Comment comment;
    +    }
     }
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/provider/timeline/HtmlHelper.java b/app/src/main/java/com/fastaccess/provider/timeline/HtmlHelper.java
    index ddc64214..a30d215b 100644
    --- a/app/src/main/java/com/fastaccess/provider/timeline/HtmlHelper.java
    +++ b/app/src/main/java/com/fastaccess/provider/timeline/HtmlHelper.java
    @@ -90,12 +90,6 @@ public class HtmlHelper {
             return mySpanner;
         }
     
    -    private static final String TAG_ROOT = "githubroot";
    -
    -    private static final String ROOT_START = '<' + TAG_ROOT + '>';
    -
    -    private static final String ROOT_END = "</" + TAG_ROOT + '>';
    -
         private static final String TOGGLE_START = "<span class=\"email-hidden-toggle\">";
     
         private static final String TOGGLE_END = "</span>";
    @@ -122,23 +116,16 @@ public class HtmlHelper {
     
         private static final String PARAGRAPH_END = "</p>";
     
    -    private static final String BLOCKQUOTE_START = "<blockquote>";
    -
    -    private static final String BLOCKQUOTE_END = "</blockquote>";
    -
         //https://github.com/k0shk0sh/GitHubSdk/blob/master/library/src/main/java/com/meisolsson/githubsdk/core/HtmlUtils.java
         @NonNull public static CharSequence format(final String html) {
             if (html == null || html.length() == 0) return "";
             StringBuilder formatted = new StringBuilder(html);
             strip(formatted, TOGGLE_START, TOGGLE_END);
             strip(formatted, SIGNATURE_START, SIGNATURE_END);
    -        replace(formatted, REPLY_START, REPLY_END, BLOCKQUOTE_START, BLOCKQUOTE_END);
    +        strip(formatted, REPLY_START, REPLY_END);
             strip(formatted, HIDDEN_REPLY_START, HIDDEN_REPLY_END);
             if (replace(formatted, PARAGRAPH_START, BREAK)) replace(formatted, PARAGRAPH_END, BREAK);
    -        formatEmailFragments(formatted);
             trim(formatted);
    -        formatted.insert(0, ROOT_START);
    -        formatted.append(ROOT_END);
             return formatted;
         }
     
    @@ -165,65 +152,15 @@ public class HtmlHelper {
             return true;
         }
     
    -    private static void replace(final StringBuilder input, final String fromStart, final String fromEnd,
    -                                final String toStart, final String toEnd) {
    -        int start = input.indexOf(fromStart);
    -        if (start == -1)
    -            return;
    -        final int fromStartLength = fromStart.length();
    -        final int fromEndLength = fromEnd.length();
    -        final int toStartLength = toStart.length();
    -        while (start != -1) {
    -            input.replace(start, start + fromStartLength, toStart);
    -            int end = input.indexOf(fromEnd, start + toStartLength);
    -            if (end != -1)
    -                input.replace(end, end + fromEndLength, toEnd);
    -
    -            start = input.indexOf(fromStart);
    -        }
    -    }
    -
    -    private static void formatEmailFragments(final StringBuilder input) {
    -        int emailStart = input.indexOf(EMAIL_START);
    -        int breakAdvance = BREAK.length() - 1;
    -        while (emailStart != -1) {
    -            int startLength = EMAIL_START.length();
    -            int emailEnd = input.indexOf(EMAIL_END, emailStart + startLength);
    -            if (emailEnd == -1)
    -                break;
    -
    -            input.delete(emailEnd, emailEnd + EMAIL_END.length());
    -            input.delete(emailStart, emailStart + startLength);
    -
    -            int fullEmail = emailEnd - startLength;
    -            for (int i = emailStart; i < fullEmail; i++)
    -                if (input.charAt(i) == '\n') {
    -                    input.deleteCharAt(i);
    -                    input.insert(i, BREAK);
    -                    i += breakAdvance;
    -                    fullEmail += breakAdvance;
    -                }
    -
    -            emailStart = input.indexOf(EMAIL_START, fullEmail);
    -        }
    -    }
    -
         private static void trim(final StringBuilder input) {
             int length = input.length();
             int breakLength = BREAK.length();
    -
             while (length > 0) {
    -            if (input.indexOf(BREAK) == 0)
    -                input.delete(0, breakLength);
    -            else if (length >= breakLength
    -                    && input.lastIndexOf(BREAK) == length - breakLength)
    -                input.delete(length - breakLength, length);
    -            else if (Character.isWhitespace(input.charAt(0)))
    -                input.deleteCharAt(0);
    -            else if (Character.isWhitespace(input.charAt(length - 1)))
    -                input.deleteCharAt(length - 1);
    -            else
    -                break;
    +            if (input.indexOf(BREAK) == 0) input.delete(0, breakLength);
    +            else if (length >= breakLength && input.lastIndexOf(BREAK) == length - breakLength) input.delete(length - breakLength, length);
    +            else if (Character.isWhitespace(input.charAt(0))) input.deleteCharAt(0);
    +            else if (Character.isWhitespace(input.charAt(length - 1))) input.deleteCharAt(length - 1);
    +            else break;
                 length = input.length();
             }
         }
    diff --git a/app/src/main/java/com/fastaccess/provider/timeline/handler/ListsHandler.java b/app/src/main/java/com/fastaccess/provider/timeline/handler/ListsHandler.java
    index 1b210377..f9cc16e8 100644
    --- a/app/src/main/java/com/fastaccess/provider/timeline/handler/ListsHandler.java
    +++ b/app/src/main/java/com/fastaccess/provider/timeline/handler/ListsHandler.java
    @@ -4,7 +4,6 @@ import android.graphics.drawable.Drawable;
     import android.support.annotation.Nullable;
     import android.text.SpannableStringBuilder;
     
    -import com.fastaccess.helper.Logger;
     import com.fastaccess.ui.widgets.SpannableBuilder;
     
     import net.nightwhistler.htmlspanner.TagNodeHandler;
    @@ -47,7 +46,6 @@ import lombok.NoArgsConstructor;
             TodoItems todoItem = null;
             if (node.getChildTags() != null && node.getChildTags().length > 0) {
                 for (TagNode tagNode : node.getChildTags()) {
    -                Logger.e(tagNode.getName(), tagNode.getAttributes(), tagNode.getText());
                     if (tagNode.getName() != null && tagNode.getName().equals("input")) {
                         todoItem = new TodoItems();
                         todoItem.isChecked = tagNode.getAttributeByName("checked") != null;
    diff --git a/app/src/main/java/com/fastaccess/ui/adapter/FeedsAdapter.java b/app/src/main/java/com/fastaccess/ui/adapter/FeedsAdapter.java
    index d6e35821..43cf047e 100644
    --- a/app/src/main/java/com/fastaccess/ui/adapter/FeedsAdapter.java
    +++ b/app/src/main/java/com/fastaccess/ui/adapter/FeedsAdapter.java
    @@ -16,12 +16,19 @@ import java.util.ArrayList;
     
     public class FeedsAdapter extends BaseRecyclerAdapter<Event, FeedsViewHolder, BaseViewHolder.OnItemClickListener<Event>> {
     
    -    public FeedsAdapter(@NonNull ArrayList<Event> Events) {
    -        super(Events);
    +    private boolean noImage;
    +
    +    public FeedsAdapter(@NonNull ArrayList<Event> events) {
    +        this(events, false);
    +    }
    +
    +    public FeedsAdapter(@NonNull ArrayList<Event> events, boolean noImage) {
    +        super(events);
    +        this.noImage = noImage;
         }
     
         @Override protected FeedsViewHolder viewHolder(ViewGroup parent, int viewType) {
    -        return new FeedsViewHolder(FeedsViewHolder.getView(parent), this);
    +        return new FeedsViewHolder(FeedsViewHolder.getView(parent, noImage), this);
         }
     
         @Override protected void onBindView(FeedsViewHolder holder, int position) {
    diff --git a/app/src/main/java/com/fastaccess/ui/adapter/IssuePullsTimelineAdapter.java b/app/src/main/java/com/fastaccess/ui/adapter/IssuePullsTimelineAdapter.java
    index 69fae96a..6ba0b835 100644
    --- a/app/src/main/java/com/fastaccess/ui/adapter/IssuePullsTimelineAdapter.java
    +++ b/app/src/main/java/com/fastaccess/ui/adapter/IssuePullsTimelineAdapter.java
    @@ -66,11 +66,7 @@ public class IssuePullsTimelineAdapter extends BaseRecyclerAdapter<TimelineModel
         @Override protected void onBindView(BaseViewHolder holder, int position) {
             TimelineModel model = getItem(position);
             if (model.getType() == TimelineModel.HEADER) {
    -            if (model.getIssue() != null) {
    -                ((IssueDetailsViewHolder) holder).bind(model);
    -            } else if (model.getPullRequest() != null) {
    -                ((IssueDetailsViewHolder) holder).bind(model);
    -            }
    +            ((IssueDetailsViewHolder) holder).bind(model);
             } else if (model.getType() == TimelineModel.EVENT) {
                 ((IssueTimelineViewHolder) holder).bind(model);
             } else if (model.getType() == TimelineModel.COMMENT) {
    diff --git a/app/src/main/java/com/fastaccess/ui/adapter/TrendingAdapter.kt b/app/src/main/java/com/fastaccess/ui/adapter/TrendingAdapter.kt
    index e94be765..fe60ffb8 100644
    --- a/app/src/main/java/com/fastaccess/ui/adapter/TrendingAdapter.kt
    +++ b/app/src/main/java/com/fastaccess/ui/adapter/TrendingAdapter.kt
    @@ -2,7 +2,7 @@ package com.fastaccess.ui.adapter
     
     import android.view.ViewGroup
     import com.fastaccess.R
    -import com.fastaccess.data.dao.TrendingResponse
    +import com.fastaccess.data.dao.TrendingModel
     import com.fastaccess.ui.adapter.viewholder.TrendingViewHolder
     import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
     import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
    @@ -11,9 +11,8 @@ import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
      * Created by Kosh on 02 Jun 2017, 1:36 PM
      */
     
    -class TrendingAdapter(data: MutableList<TrendingResponse>) : BaseRecyclerAdapter<TrendingResponse,
    -        TrendingViewHolder, BaseViewHolder.OnItemClickListener<TrendingResponse>>(data) {
    -
    +class TrendingAdapter(data: MutableList<TrendingModel>) : BaseRecyclerAdapter<TrendingModel,
    +        TrendingViewHolder, BaseViewHolder.OnItemClickListener<TrendingModel>>(data) {
         override fun viewHolder(parent: ViewGroup?, viewType: Int): TrendingViewHolder {
             return TrendingViewHolder(BaseViewHolder.getView(parent!!, R.layout.trending_row_item), this)
         }
    diff --git a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/FeedsViewHolder.java b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/FeedsViewHolder.java
    index c4a9a0d3..65820405 100644
    --- a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/FeedsViewHolder.java
    +++ b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/FeedsViewHolder.java
    @@ -11,7 +11,6 @@ import com.fastaccess.R;
     import com.fastaccess.data.dao.PayloadModel;
     import com.fastaccess.data.dao.model.Event;
     import com.fastaccess.data.dao.types.EventsType;
    -import com.fastaccess.helper.InputHelper;
     import com.fastaccess.helper.ParseDateFormat;
     import com.fastaccess.provider.markdown.MarkDownProvider;
     import com.fastaccess.ui.widgets.AvatarLayout;
    @@ -29,7 +28,7 @@ import butterknife.BindView;
     
     public class FeedsViewHolder extends BaseViewHolder<Event> {
     
    -    @BindView(R.id.avatarLayout) AvatarLayout avatar;
    +    @Nullable @BindView(R.id.avatarLayout) AvatarLayout avatar;
         @BindView(R.id.description) FontTextView description;
         @BindView(R.id.title) FontTextView title;
         @BindView(R.id.date) FontTextView date;
    @@ -40,15 +39,21 @@ public class FeedsViewHolder extends BaseViewHolder<Event> {
             super(itemView, adapter);
         }
     
    -    public static View getView(@NonNull ViewGroup viewGroup) {
    -        return getView(viewGroup, R.layout.feeds_row_item);
    +    public static View getView(@NonNull ViewGroup viewGroup, boolean noImage) {
    +        if (noImage) {
    +            return getView(viewGroup, R.layout.feeds_row_no_image_item);
    +        } else {
    +            return getView(viewGroup, R.layout.feeds_row_item);
    +        }
         }
     
         @Override public void bind(@NonNull Event eventsModel) {
    -        if (eventsModel.getActor() != null) {
    -            avatar.setUrl(eventsModel.getActor().getAvatarUrl(), eventsModel.getActor().getLogin(), eventsModel.getActor().isOrganizationType());
    -        } else {
    -            avatar.setUrl(null, null);
    +        if (avatar != null) {
    +            if (eventsModel.getActor() != null) {
    +                avatar.setUrl(eventsModel.getActor().getAvatarUrl(), eventsModel.getActor().getLogin(), eventsModel.getActor().isOrganizationType());
    +            } else {
    +                avatar.setUrl(null, null);
    +            }
             }
             SpannableBuilder spannableBuilder = SpannableBuilder.builder();
             spannableBuilder.append(eventsModel.getActor() != null ? eventsModel.getActor().getLogin() : "N/A").append(" ");
    @@ -76,12 +81,13 @@ public class FeedsViewHolder extends BaseViewHolder<Event> {
                 spannableBuilder.bold(action != null ? action.toLowerCase() : "")
                         .append(eventsModel.getPayload() != null && eventsModel.getPayload().getAction() != null ? " " : "");
                 if (type != EventsType.WatchEvent) {
    -                if (type == EventsType.CreateEvent && !InputHelper.isEmpty(eventsModel.getPayload().getRef())) {
    +                if (type == EventsType.CreateEvent && eventsModel.getPayload() != null && eventsModel.getPayload().getRefType() != null) {
                         spannableBuilder
                                 .bold(itemView.getResources().getString(type.getType()).toLowerCase())
                                 .append(" ")
                                 .bold(eventsModel.getPayload().getRefType())
                                 .append(" ")
    +                            .append(eventsModel.getPayload().getRef() != null ? eventsModel.getPayload().getRef() + " " : "")
                                 .append(in)
                                 .append(" ");
                     } else if ((type == EventsType.PushEvent || type == EventsType.DeleteEvent) && eventsModel.getPayload() != null) {
    diff --git a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/GistsViewHolder.java b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/GistsViewHolder.java
    index 4cbbdcb6..0fbe7522 100644
    --- a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/GistsViewHolder.java
    +++ b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/GistsViewHolder.java
    @@ -7,6 +7,7 @@ import android.view.ViewGroup;
     
     import com.fastaccess.R;
     import com.fastaccess.data.dao.model.Gist;
    +import com.fastaccess.helper.Logger;
     import com.fastaccess.helper.ParseDateFormat;
     import com.fastaccess.ui.widgets.AvatarLayout;
     import com.fastaccess.ui.widgets.FontTextView;
    @@ -26,6 +27,7 @@ public class GistsViewHolder extends BaseViewHolder<Gist> {
         @BindView(R.id.date) FontTextView date;
         private boolean isFromProfile;
     
    +
         private GistsViewHolder(@NonNull View itemView, @Nullable BaseRecyclerAdapter adapter, boolean isFromProfile) {
             super(itemView, adapter);
             title.setMaxLines(2);
    @@ -40,7 +42,6 @@ public class GistsViewHolder extends BaseViewHolder<Gist> {
             }
         }
     
    -
         @Override public void bind(@NonNull Gist item) {
             if (!isFromProfile) {
                 if (avatar != null) {
    diff --git a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/IssueDetailsViewHolder.java b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/IssueDetailsViewHolder.java
    index 2f6afbfb..a81e1739 100644
    --- a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/IssueDetailsViewHolder.java
    +++ b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/IssueDetailsViewHolder.java
    @@ -13,6 +13,7 @@ import com.fastaccess.data.dao.ReactionsModel;
     import com.fastaccess.data.dao.TimelineModel;
     import com.fastaccess.data.dao.model.Issue;
     import com.fastaccess.data.dao.model.PullRequest;
    +import com.fastaccess.data.dao.model.User;
     import com.fastaccess.helper.InputHelper;
     import com.fastaccess.helper.Logger;
     import com.fastaccess.helper.ParseDateFormat;
    @@ -26,6 +27,8 @@ import com.fastaccess.ui.widgets.SpannableBuilder;
     import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter;
     import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder;
     
    +import java.util.Date;
    +
     import butterknife.BindView;
     
     /**
    @@ -159,30 +162,34 @@ public class IssueDetailsViewHolder extends BaseViewHolder<TimelineModel> {
         }
     
         private void bind(@NonNull Issue issueModel) {
    -        avatar.setUrl(issueModel.getUser().getAvatarUrl(), issueModel.getUser().getLogin());
    -        name.setText(issueModel.getUser().getLogin());
    -        date.setText(ParseDateFormat.getTimeAgo(issueModel.getCreatedAt()));
    -        if (!InputHelper.isEmpty(issueModel.getBodyHtml())) {
    -            HtmlHelper.htmlIntoTextView(comment, issueModel.getBodyHtml());
    -        } else {
    -            comment.setText(R.string.no_description_provided);
    -        }
    -        if (issueModel.getReactions() != null) {
    -            appendEmojies(issueModel.getReactions());
    -        }
    +        setup(issueModel.getUser(), issueModel.getBodyHtml(), issueModel.getReactions());
    +        setupDate(issueModel.getCreatedAt(), issueModel.getUpdatedAt());
         }
     
         private void bind(@NonNull PullRequest pullRequest) {
    -        avatar.setUrl(pullRequest.getUser().getAvatarUrl(), pullRequest.getUser().getLogin());
    -        name.setText(pullRequest.getUser().getLogin());
    -        date.setText(ParseDateFormat.getTimeAgo(pullRequest.getCreatedAt()));
    -        if (!InputHelper.isEmpty(pullRequest.getBodyHtml())) {
    -            HtmlHelper.htmlIntoTextView(comment, pullRequest.getBodyHtml());
    +        setup(pullRequest.getUser(), pullRequest.getBodyHtml(), pullRequest.getReactions());
    +        setupDate(pullRequest.getCreatedAt(), pullRequest.getUpdatedAt());
    +    }
    +
    +    private void setup(User user, String description, ReactionsModel reactionsModel) {
    +        avatar.setUrl(user.getAvatarUrl(), user.getLogin(), user.isOrganizationType());
    +        name.setText(user.getLogin());
    +        if (reactionsModel != null) {
    +            appendEmojies(reactionsModel);
    +        }
    +        if (!InputHelper.isEmpty(description)) {
    +            HtmlHelper.htmlIntoTextView(comment, description);
             } else {
                 comment.setText(R.string.no_description_provided);
             }
    -        if (pullRequest.getReactions() != null) {
    -            appendEmojies(pullRequest.getReactions());
    +    }
    +
    +    private void setupDate(@NonNull Date createdDate, @NonNull Date updated) {
    +        if (createdDate.before(updated)) {
    +            date.setText(String.format("%s %s", ParseDateFormat.getTimeAgo(updated),
    +                    date.getResources().getString(R.string.edited)));
    +        } else {
    +            date.setText(ParseDateFormat.getTimeAgo(createdDate));
             }
         }
     
    diff --git a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/TrendingViewHolder.kt b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/TrendingViewHolder.kt
    index 0ee181cf..5d9e5bc0 100644
    --- a/app/src/main/java/com/fastaccess/ui/adapter/viewholder/TrendingViewHolder.kt
    +++ b/app/src/main/java/com/fastaccess/ui/adapter/viewholder/TrendingViewHolder.kt
    @@ -2,7 +2,8 @@ package com.fastaccess.ui.adapter.viewholder
     
     import android.view.View
     import com.fastaccess.R
    -import com.fastaccess.data.dao.TrendingResponse
    +import com.fastaccess.data.dao.TrendingModel
    +import com.fastaccess.provider.colors.ColorsProvider
     import com.fastaccess.provider.emoji.EmojiParser
     import com.fastaccess.ui.widgets.FontTextView
     import com.fastaccess.ui.widgets.recyclerview.BaseRecyclerAdapter
    @@ -12,16 +13,17 @@ import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
      * Created by Kosh on 02 Jun 2017, 1:27 PM
      */
     
    -open class TrendingViewHolder(itemView: View, adapter: BaseRecyclerAdapter<TrendingResponse,
    -        TrendingViewHolder, OnItemClickListener<TrendingResponse>>) : BaseViewHolder<TrendingResponse>(itemView, adapter) {
    +open class TrendingViewHolder(itemView: View, adapter: BaseRecyclerAdapter<TrendingModel,
    +        TrendingViewHolder, OnItemClickListener<TrendingModel>>) : BaseViewHolder<TrendingModel>(itemView, adapter) {
     
         val title by lazy { itemView.findViewById(R.id.title) as FontTextView }
         val description by lazy { itemView.findViewById(R.id.description) as FontTextView }
         val todayStars by lazy { itemView.findViewById(R.id.todayStars) as FontTextView }
         val stars by lazy { itemView.findViewById(R.id.stars) as FontTextView }
         val fork by lazy { itemView.findViewById(R.id.forks) as FontTextView }
    +    val lang by lazy { itemView.findViewById(R.id.language) as FontTextView }
     
    -    override fun bind(t: TrendingResponse) {
    +    override fun bind(t: TrendingModel) {
             title.text = t.title
             if (!t.description.isNullOrEmpty()) {
                 val descriptionValue: String = EmojiParser.parseToUnicode(t.description)
    @@ -33,6 +35,12 @@ open class TrendingViewHolder(itemView: View, adapter: BaseRecyclerAdapter<Trend
             todayStars.text = t.todayStars
             stars.text = t.stars
             fork.text = t.forks
    +        lang.text = t.language
    +        if (!t.language.isNullOrEmpty()) {
    +            lang.tintDrawables(ColorsProvider.getColorAsColor(t.language!!, itemView.context))
    +            lang.setTextColor(ColorsProvider.getColorAsColor(t.language, itemView.context))
    +        }
    +        lang.visibility = if (t.language.isNullOrEmpty()) View.GONE else View.VISIBLE
         }
     
     }
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/ui/base/BaseActivity.java b/app/src/main/java/com/fastaccess/ui/base/BaseActivity.java
    index 28b87b52..9c9a8d16 100644
    --- a/app/src/main/java/com/fastaccess/ui/base/BaseActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/base/BaseActivity.java
    @@ -161,12 +161,7 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
         @Override public void showMessage(@NonNull String titleRes, @NonNull String msgRes) {
             hideProgress();
             if (toast != null) toast.cancel();
    -        Context context;
    -        if (!isFinishing()) {
    -            context = this;
    -        } else {
    -            context = App.getInstance();
    -        }
    +        Context context = App.getInstance(); // WindowManager$BadTokenException
             toast = titleRes.equals(context.getString(R.string.error))
                     ? Toasty.error(context, msgRes, Toast.LENGTH_LONG)
                     : Toasty.info(context, msgRes, Toast.LENGTH_LONG);
    @@ -186,7 +181,7 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
             if (resId != 0) {
                 msg = getString(resId);
             }
    -        if (!isProgressShowing) {
    +        if (!isProgressShowing && !isFinishing()) {
                 ProgressDialogFragment fragment = (ProgressDialogFragment) AppHelper.getFragmentByTag(getSupportFragmentManager(),
                         ProgressDialogFragment.TAG);
                 if (fragment == null) {
    @@ -207,7 +202,7 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
         }
     
         @Override public void onRequireLogin() {
    -        Toasty.warning(this, getString(R.string.unauthorized_user), Toast.LENGTH_LONG).show();
    +        Toasty.warning(App.getInstance(), getString(R.string.unauthorized_user), Toast.LENGTH_LONG).show();
             ImageLoader.getInstance().clearDiskCache();
             ImageLoader.getInstance().clearMemoryCache();
             PrefHelper.clearKey("token");
    @@ -340,6 +335,13 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
             }
         }
     
    +    protected void onSelectTrending() {
    +        if (extraNav != null) {
    +            extraNav.getMenu().findItem(R.id.trending).setCheckable(true);
    +            extraNav.getMenu().findItem(R.id.trending).setChecked(true);
    +        }
    +    }
    +
         protected void onOpenOrgsDialog() {
             OrgListDialogFragment.newInstance().show(getSupportFragmentManager(), "OrgListDialogFragment");
         }
    @@ -575,7 +577,7 @@ public abstract class BaseActivity<V extends BaseMvp.FAView, P extends BasePrese
             if (backPressTimer + 2000 > System.currentTimeMillis()) {
                 return true;
             } else {
    -            Toast.makeText(getBaseContext(), R.string.press_again_to_exit, Toast.LENGTH_SHORT).show();
    +            Toast.makeText(App.getInstance(), R.string.press_again_to_exit, Toast.LENGTH_SHORT).show();
             }
             backPressTimer = System.currentTimeMillis();
             return false;
    diff --git a/app/src/main/java/com/fastaccess/ui/base/BaseFragment.java b/app/src/main/java/com/fastaccess/ui/base/BaseFragment.java
    index dff26516..70cbe91c 100644
    --- a/app/src/main/java/com/fastaccess/ui/base/BaseFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/base/BaseFragment.java
    @@ -114,13 +114,9 @@ public abstract class BaseFragment<V extends BaseMvp.FAView, P extends BasePrese
             callback.onRequireLogin();
         }
     
    -    @Override public void onMessageDialogActionClicked(boolean isOk, @Nullable Bundle bundle) {
    +    @Override public void onMessageDialogActionClicked(boolean isOk, @Nullable Bundle bundle) {}
     
    -    }
    -
    -    @Override public void onDialogDismissed() {
    -
    -    }
    +    @Override public void onDialogDismissed() {}
     
         @Override public void onLogoutPressed() {
             callback.onLogoutPressed();
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/about/FastHubAboutActivity.java b/app/src/main/java/com/fastaccess/ui/modules/about/FastHubAboutActivity.java
    index 6b797d1a..cb7efcff 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/about/FastHubAboutActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/about/FastHubAboutActivity.java
    @@ -2,7 +2,6 @@ package com.fastaccess.ui.modules.about;
     
     import android.content.Context;
     import android.content.Intent;
    -import android.content.pm.PackageManager;
     import android.os.Bundle;
     import android.support.annotation.Nullable;
     import android.support.v4.content.ContextCompat;
    @@ -15,11 +14,14 @@ import com.danielstone.materialaboutlibrary.MaterialAboutActivity;
     import com.danielstone.materialaboutlibrary.items.MaterialAboutActionItem;
     import com.danielstone.materialaboutlibrary.model.MaterialAboutCard;
     import com.danielstone.materialaboutlibrary.model.MaterialAboutList;
    +import com.fastaccess.BuildConfig;
     import com.fastaccess.R;
    +import com.fastaccess.data.dao.model.Release;
     import com.fastaccess.helper.ActivityHelper;
     import com.fastaccess.helper.AppHelper;
     import com.fastaccess.helper.BundleConstant;
     import com.fastaccess.helper.PrefGetter;
    +import com.fastaccess.ui.modules.changelog.ChangelogBottomSheetDialog;
     import com.fastaccess.ui.modules.repos.RepoPagerActivity;
     import com.fastaccess.ui.modules.repos.issues.create.CreateIssueActivity;
     import com.fastaccess.ui.modules.user.UserPagerActivity;
    @@ -27,13 +29,16 @@ import com.mikepenz.aboutlibraries.Libs;
     import com.mikepenz.aboutlibraries.LibsBuilder;
     
     import es.dmoral.toasty.Toasty;
    +import io.reactivex.disposables.Disposable;
     
     /**
      * Created by danielstone on 12 Mar 2017, 1:57 AM
      */
     public class FastHubAboutActivity extends MaterialAboutActivity {
     
    -    View malRecyclerview;
    +    private View malRecyclerview;
    +    private Disposable disposable;
    +
     
         @Override protected void onCreate(@Nullable Bundle savedInstanceState) {
             int themeMode = PrefGetter.getThemeType(getApplicationContext());
    @@ -48,70 +53,14 @@ public class FastHubAboutActivity extends MaterialAboutActivity {
     
         @Override protected MaterialAboutList getMaterialAboutList(Context context) {
             MaterialAboutCard.Builder appCardBuilder = new MaterialAboutCard.Builder();
    -        try {
    -            appCardBuilder.addItem(ConvenienceBuilder.createVersionActionItem(context, ContextCompat.getDrawable(context, R.drawable.ic_issues),
    -                    getString(R.string.version), false));
    -        } catch (PackageManager.NameNotFoundException e) {
    -            e.printStackTrace();
    -        }
    -
    -        appCardBuilder.addItem(ConvenienceBuilder.createRateActionItem(context, ContextCompat.getDrawable(context, R.drawable.ic_star_filled),
    -                getString(R.string.rate_app), null));
    -
    -        appCardBuilder.addItem(new MaterialAboutActionItem.Builder()
    -                .text(R.string.report_issue)
    -                .subText(R.string.report_issue_here)
    -                .icon(ContextCompat.getDrawable(context, R.drawable.ic_bug))
    -                .setOnClickListener(b -> CreateIssueActivity.startForResult(this, CreateIssueActivity.startForResult(this), malRecyclerview))
    -                .build());
    -        appCardBuilder.addItem(new MaterialAboutActionItem.Builder()
    -                .text(R.string.open_source_libs)
    -                .icon(R.drawable.ic_github)
    -                .setOnClickListener(b -> new LibsBuilder()
    -                        .withActivityStyle(AppHelper.isNightMode(getResources()) ? Libs.ActivityStyle.DARK : Libs.ActivityStyle.LIGHT)
    -                        .withAutoDetect(true)
    -                        .withAboutIconShown(true)
    -                        .withAboutVersionShown(true)
    -                        .start(this))
    -                .build());
    -
    +        buildApp(context, appCardBuilder);
    +        MaterialAboutCard.Builder miscCardBuilder = new MaterialAboutCard.Builder();
    +        buildMisc(context, miscCardBuilder);
             MaterialAboutCard.Builder authorCardBuilder = new MaterialAboutCard.Builder();
    -        authorCardBuilder.title(R.string.author);
    -        authorCardBuilder.addItem(new MaterialAboutActionItem.Builder()
    -                .text("Kosh")
    -                .subText("k0shk0sh")
    -                .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile))
    -                .setOnClickListener(b -> UserPagerActivity.startActivity(context, "k0shk0sh"))
    -                .build());
    -        authorCardBuilder.addItem(new MaterialAboutActionItem.Builder()
    -                .text(R.string.fork_github)
    -                .icon(ContextCompat.getDrawable(context, R.drawable.ic_github))
    -                .setOnClickListener(b -> startActivity(RepoPagerActivity.createIntent(this, "FastHub", "k0shk0sh")))
    -                .build());
    -
    -        authorCardBuilder.addItem(ConvenienceBuilder.createEmailItem(context, ContextCompat.getDrawable(context, R.drawable.ic_email),
    -                getString(R.string.send_email), true, getString(R.string.email_address), getString(R.string.question_concerning_fasthub)));
    -
    +        buildAuthor(context, authorCardBuilder);
             MaterialAboutCard.Builder logoAuthor = new MaterialAboutCard.Builder();
    -        logoAuthor.title(getString(R.string.logo_designer, "Kevin Aguilar"));
    -        logoAuthor.addItem(new MaterialAboutActionItem.Builder()
    -                .text(R.string.google_plus)
    -                .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile))
    -                .setOnClickListener(b -> ActivityHelper.startCustomTab(this, "https://plus.google.com/+KevinAguilarC"))
    -                .build());
    -        logoAuthor.addItem(new MaterialAboutActionItem.Builder()
    -                .text(R.string.twitter)
    -                .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile))
    -                .setOnClickListener(b -> ActivityHelper.startCustomTab(this, "https://twitter.com/kevttob"))
    -                .build());
    -        logoAuthor.addItem(new MaterialAboutActionItem.Builder()
    -                .text(R.string.website)
    -                .icon(ContextCompat.getDrawable(context, R.drawable.ic_brower))
    -                .setOnClickListener(b -> ActivityHelper.startCustomTab(this, "https://www.221pixels.com/"))
    -                .build());
    -
    -
    -        return new MaterialAboutList(appCardBuilder.build(), authorCardBuilder.build(), logoAuthor.build());
    +        buildLogo(context, logoAuthor);
    +        return new MaterialAboutList(appCardBuilder.build(), miscCardBuilder.build(), authorCardBuilder.build(), logoAuthor.build());
         }
     
         @Override protected CharSequence getActivityTitle() {
    @@ -131,4 +80,96 @@ public class FastHubAboutActivity extends MaterialAboutActivity {
             }
             return false;//override
         }
    +
    +    @Override protected void onDestroy() {
    +        if (disposable != null && !disposable.isDisposed()) {
    +            disposable.dispose();
    +        }
    +        super.onDestroy();
    +    }
    +
    +    private void buildLogo(Context context, MaterialAboutCard.Builder logoAuthor) {
    +        logoAuthor.title(getString(R.string.logo_designer, "Kevin Aguilar"));
    +        logoAuthor.addItem(new MaterialAboutActionItem.Builder()
    +                .text(R.string.google_plus)
    +                .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile))
    +                .setOnClickListener(b -> ActivityHelper.startCustomTab(this, "https://plus.google.com/+KevinAguilarC"))
    +                .build())
    +                .addItem(new MaterialAboutActionItem.Builder()
    +                        .text(R.string.twitter)
    +                        .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile))
    +                        .setOnClickListener(b -> ActivityHelper.startCustomTab(this, "https://twitter.com/kevttob"))
    +                        .build())
    +                .addItem(new MaterialAboutActionItem.Builder()
    +                        .text(R.string.website)
    +                        .icon(ContextCompat.getDrawable(context, R.drawable.ic_brower))
    +                        .setOnClickListener(b -> ActivityHelper.startCustomTab(this, "https://www.221pixels.com/"))
    +                        .build());
    +    }
    +
    +    private void buildAuthor(Context context, MaterialAboutCard.Builder authorCardBuilder) {
    +        authorCardBuilder.title(R.string.author);
    +        authorCardBuilder.addItem(new MaterialAboutActionItem.Builder()
    +                .text("Kosh Sergani")
    +                .subText("k0shk0sh")
    +                .icon(ContextCompat.getDrawable(context, R.drawable.ic_profile))
    +                .setOnClickListener(b -> UserPagerActivity.startActivity(context, "k0shk0sh"))
    +                .build())
    +                .addItem(new MaterialAboutActionItem.Builder()
    +                        .text(R.string.fork_github)
    +                        .icon(ContextCompat.getDrawable(context, R.drawable.ic_github))
    +                        .setOnClickListener(b -> startActivity(RepoPagerActivity.createIntent(this, "FastHub", "k0shk0sh")))
    +                        .build())
    +                .addItem(ConvenienceBuilder.createEmailItem(context, ContextCompat.getDrawable(context, R.drawable.ic_email),
    +                        getString(R.string.send_email), true, getString(R.string.email_address), getString(R.string.question_concerning_fasthub)));
    +    }
    +
    +    private void buildMisc(Context context, MaterialAboutCard.Builder miscCardBuilder) {
    +        miscCardBuilder.title(R.string.about)
    +                .addItem(new MaterialAboutActionItem.Builder()
    +                        .text(R.string.changelog)
    +                        .icon(ContextCompat.getDrawable(context, R.drawable.ic_track_changes))
    +                        .setOnClickListener(b -> new ChangelogBottomSheetDialog().show(getSupportFragmentManager(), "ChangelogBottomSheetDialog"))
    +                        .build())
    +                .addItem(new MaterialAboutActionItem.Builder()
    +                        .text(R.string.join_slack)
    +                        .icon(ContextCompat.getDrawable(context, R.drawable.ic_slack))
    +                        .setOnClickListener(b -> ActivityHelper.startCustomTab(this, "http://rebrand.ly/fasthub"))
    +                        .build())
    +                .addItem(new MaterialAboutActionItem.Builder()
    +                        .text(R.string.open_source_libs)
    +                        .icon(ContextCompat.getDrawable(context, R.drawable.ic_github))
    +                        .setOnClickListener(b -> new LibsBuilder()
    +                                .withActivityStyle(AppHelper.isNightMode(getResources()) ? Libs.ActivityStyle.DARK : Libs.ActivityStyle.LIGHT)
    +                                .withAutoDetect(true)
    +                                .withAboutIconShown(true)
    +                                .withAboutVersionShown(true)
    +                                .start(this))
    +                        .build());
    +    }
    +
    +    private void buildApp(Context context, MaterialAboutCard.Builder appCardBuilder) {
    +        appCardBuilder.addItem(new MaterialAboutActionItem.Builder()
    +                .text(getString(R.string.version))
    +                .icon(ContextCompat.getDrawable(context, R.drawable.ic_update))
    +                .subText(BuildConfig.VERSION_NAME)
    +                .setOnClickListener(b -> disposable = Release.get("FastHub", "k0shk0sh")
    +                        .subscribe(releases -> {
    +                            if (releases != null && !releases.isEmpty()) {
    +                                if (releases.get(0).getTagName().contains(BuildConfig.VERSION_NAME))
    +                                    Toasty.success(context, getString(R.string.up_to_date)).show();
    +                                else
    +                                    Toasty.warning(context, getString(R.string.new_version)).show();
    +                            }
    +                        }))
    +                .build())
    +                .addItem(ConvenienceBuilder.createRateActionItem(context, ContextCompat.getDrawable(context, R.drawable.ic_star_filled),
    +                        getString(R.string.rate_app), null))
    +                .addItem(new MaterialAboutActionItem.Builder()
    +                        .text(R.string.report_issue)
    +                        .subText(R.string.report_issue_here)
    +                        .icon(ContextCompat.getDrawable(context, R.drawable.ic_bug))
    +                        .setOnClickListener(b -> CreateIssueActivity.startForResult(this, CreateIssueActivity.startForResult(this), malRecyclerview))
    +                        .build());
    +    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/editor/EditorActivity.java b/app/src/main/java/com/fastaccess/ui/modules/editor/EditorActivity.java
    index 5c209f5e..ac0dfb02 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/editor/EditorActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/editor/EditorActivity.java
    @@ -18,6 +18,7 @@ import android.widget.CheckBox;
     import android.widget.LinearLayout;
     import android.widget.ListView;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.BuildConfig;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.EditReviewCommentModel;
    @@ -46,7 +47,6 @@ import butterknife.OnClick;
     import butterknife.OnItemClick;
     import butterknife.OnTextChanged;
     import es.dmoral.toasty.Toasty;
    -import com.evernote.android.state.State;
     import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
     
     import static android.view.View.GONE;
    @@ -70,16 +70,15 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
         @BindView(R.id.sentVia) CheckBox sentVia;
         @BindView(R.id.list_divider) View listDivider;
         @BindView(R.id.parentView) View parentView;
    -    @State @BundleConstant.ExtraTYpe String extraType;
    +    @BindView(R.id.autocomplete) ListView mention;
     
    +    @State @BundleConstant.ExtraTYpe String extraType;
         @State String itemId;
         @State String login;
         @State int issueNumber;
         @State long commentId = 0;
         @State String sha;
         @State EditReviewCommentModel reviewComment;
    -    @BindView(R.id.autocomplete)
    -    ListView mention;
     
         @Override protected int layout() {
             return R.layout.editor_layout;
    @@ -239,36 +238,6 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
             editText.requestFocus();
         }
     
    -    private void onCreate() {
    -        Intent intent = getIntent();
    -        if (intent != null && intent.getExtras() != null) {
    -            Bundle bundle = intent.getExtras();
    -            //noinspection WrongConstant
    -            extraType = bundle.getString(BundleConstant.EXTRA_TYPE);
    -            reviewComment = bundle.getParcelable(BundleConstant.REVIEW_EXTRA);
    -            itemId = bundle.getString(BundleConstant.ID);
    -            login = bundle.getString(BundleConstant.EXTRA_TWO);
    -            if (extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.EDIT_COMMIT_COMMENT_EXTRA) ||
    -                    extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.NEW_COMMIT_COMMENT_EXTRA)) {
    -                sha = bundle.getString(BundleConstant.EXTRA_THREE);
    -            } else {
    -                issueNumber = bundle.getInt(BundleConstant.EXTRA_THREE);
    -            }
    -            commentId = bundle.getLong(BundleConstant.EXTRA_FOUR);
    -            String textToUpdate = bundle.getString(BundleConstant.EXTRA);
    -            if (!InputHelper.isEmpty(textToUpdate)) {
    -                editText.setText(String.format("%s ", textToUpdate));
    -                editText.setSelection(InputHelper.toString(editText).length());
    -            }
    -            if (bundle.getString("message", "").isEmpty())
    -                replyQuote.setVisibility(GONE);
    -            else {
    -                MarkDownProvider.setMdText(quote, bundle.getString("message", ""));
    -            }
    -            participants = bundle.getStringArrayList("participants");
    -        }
    -    }
    -
         @Override public void onSendResultAndFinish(@NonNull Comment commentModel, boolean isNew) {
             hideProgress();
             Intent intent = new Intent();
    @@ -307,7 +276,7 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
             if (item.getItemId() == R.id.submit) {
                 if (PrefGetter.isSentViaEnabled()) {
                     String temp = savedText.toString();
    -                if (!temp.contains(sentFromFastHub) && !InputHelper.isEmpty(savedText)) {
    +                if (!temp.contains(sentFromFastHub)) {
                         savedText = savedText + sentFromFastHub;
                     }
                 }
    @@ -361,6 +330,36 @@ public class EditorActivity extends BaseActivity<EditorMvp.View, EditorPresenter
             }
         }
     
    +    private void onCreate() {
    +        Intent intent = getIntent();
    +        if (intent != null && intent.getExtras() != null) {
    +            Bundle bundle = intent.getExtras();
    +            //noinspection WrongConstant
    +            extraType = bundle.getString(BundleConstant.EXTRA_TYPE);
    +            reviewComment = bundle.getParcelable(BundleConstant.REVIEW_EXTRA);
    +            itemId = bundle.getString(BundleConstant.ID);
    +            login = bundle.getString(BundleConstant.EXTRA_TWO);
    +            if (extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.EDIT_COMMIT_COMMENT_EXTRA) ||
    +                    extraType.equalsIgnoreCase(BundleConstant.ExtraTYpe.NEW_COMMIT_COMMENT_EXTRA)) {
    +                sha = bundle.getString(BundleConstant.EXTRA_THREE);
    +            } else {
    +                issueNumber = bundle.getInt(BundleConstant.EXTRA_THREE);
    +            }
    +            commentId = bundle.getLong(BundleConstant.EXTRA_FOUR);
    +            String textToUpdate = bundle.getString(BundleConstant.EXTRA);
    +            if (!InputHelper.isEmpty(textToUpdate)) {
    +                editText.setText(String.format("%s ", textToUpdate));
    +                editText.setSelection(InputHelper.toString(editText).length());
    +            }
    +            if (bundle.getString("message", "").isEmpty())
    +                replyQuote.setVisibility(GONE);
    +            else {
    +                MarkDownProvider.setMdText(quote, bundle.getString("message", ""));
    +            }
    +            participants = bundle.getStringArrayList("participants");
    +        }
    +    }
    +
         private void updateMentionList(@NonNull String mentioning) {
             if (participants != null) {
                 ArrayList<String> mentions = new ArrayList<>();
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsFragment.java b/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsFragment.java
    index f494fbb3..cebf29c4 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/feeds/FeedsFragment.java
    @@ -11,7 +11,6 @@ import android.view.View;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.SimpleUrlsModel;
     import com.fastaccess.data.dao.model.Event;
    -import com.fastaccess.helper.ActivityHelper;
     import com.fastaccess.helper.PrefGetter;
     import com.fastaccess.provider.rest.loadmore.OnLoadMore;
     import com.fastaccess.provider.scheme.SchemeParser;
    @@ -82,8 +81,7 @@ public class FeedsFragment extends BaseFragment<FeedsMvp.View, FeedsPresenter> i
         }
     
         @Override public void showProgress(@StringRes int resId) {
    -
    -refresh.setRefreshing(true);
    +        refresh.setRefreshing(true);
             stateLayout.showProgress();
         }
     
    @@ -133,45 +131,7 @@ refresh.setRefreshing(true);
         }
     
         @Override public void onShowGuide(@NonNull View itemView, @NonNull Event model) {
    -        if (!PrefGetter.isUserIconGuideShowed()) {
    -            final boolean[] dismissed = {false};
    -            /*new MaterialTapTargetPrompt.Builder(getActivity())
    -                    .setTarget(itemView.findViewById(R.id.avatarLayout))
    -                    .setPrimaryText(R.string.users)
    -                    .setSecondaryText(R.string.avatar_click_hint)
    -                    .setBackgroundColourAlpha(244)
    -                    .setBackgroundColour(ViewHelper.getAccentColor(getContext()))
    -                    .setOnHidePromptListener(new MaterialTapTargetPrompt.OnHidePromptListener() {
    -                        @Override public void onHidePrompt(MotionEvent event, boolean tappedTarget) {}
    -
    -                        @Override public void onHidePromptComplete() {
    -                            if (!dismissed[0])
    -                                new MaterialTapTargetPrompt.Builder(getActivity())
    -                                        .setTarget(itemView)
    -                                        .setPrimaryText(R.string.fork)
    -                                        .setSecondaryText(R.string.feeds_fork_hint)
    -                                        .setCaptureTouchEventOutsidePrompt(true)
    -                                        .setBackgroundColourAlpha(244)
    -                                        .setBackgroundColour(ViewHelper.getAccentColor(getContext()))
    -                                        .setOnHidePromptListener(new MaterialTapTargetPrompt.OnHidePromptListener() {
    -                                            @Override
    -                                            public void onHidePrompt(MotionEvent motionEvent, boolean b) {
    -                                                ActivityHelper.hideDismissHints(FeedsFragment.this.getContext());
    -                                            }
    -
    -                                            @Override
    -                                            public void onHidePromptComplete() {
    -
    -                                            }
    -                                        })
    -                                        .show();
    -                            ActivityHelper.bringDismissAllToFront(getContext());
    -                        }
    -                    })
    -                    .setCaptureTouchEventOutsidePrompt(true)
    -                    .show();*/
    -            ActivityHelper.showDismissHints(getContext(), () -> dismissed[0] = true);
    -        }
    +        if (!PrefGetter.isUserIconGuideShowed()) {}
         }
     
         private void showReload() {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/filter/issues/FilterIssuesActivity.java b/app/src/main/java/com/fastaccess/ui/modules/filter/issues/FilterIssuesActivity.java
    index fb76baa8..8861bdf6 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/filter/issues/FilterIssuesActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/filter/issues/FilterIssuesActivity.java
    @@ -6,6 +6,7 @@ import android.content.Intent;
     import android.content.res.Resources;
     import android.graphics.drawable.ColorDrawable;
     import android.os.Bundle;
    +import android.os.Handler;
     import android.support.annotation.NonNull;
     import android.text.Editable;
     import android.view.KeyEvent;
    @@ -15,6 +16,7 @@ import android.view.inputmethod.EditorInfo;
     import android.widget.PopupWindow;
     import android.widget.Toast;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.LabelModel;
     import com.fastaccess.data.dao.MilestoneModel;
    @@ -49,7 +51,6 @@ import butterknife.OnClick;
     import butterknife.OnEditorAction;
     import butterknife.OnTextChanged;
     import es.dmoral.toasty.Toasty;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 09 Apr 2017, 6:23 PM
    @@ -174,52 +175,37 @@ public class FilterIssuesActivity extends BaseActivity<FilterIssuesActivityMvp.V
         }
     
         @SuppressLint("InflateParams") @OnClick(R.id.labels) public void onLabelsClicked() {
    -        if (hideWindow()) return;
    +        if (labels.getTag() != null) return;
    +        labels.setTag(true);
             ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
    -        popupWindow = new PopupWindow(this);
    -        popupWindow.setContentView(viewHolder.view);
    -        popupWindow.setOutsideTouchable(true);
    -        popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
    -        popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
    +        setupPopupWindow(viewHolder);
             viewHolder.recycler.setAdapter(getLabelsAdapter());
             AnimHelper.revealPopupWindow(popupWindow, labels);
         }
     
         @SuppressLint("InflateParams") @OnClick(R.id.milestone) public void onMilestoneClicked() {
    -        if (hideWindow()) return;
    +        if (milestone.getTag() != null) return;
    +        milestone.setTag(true);
             ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
    -        popupWindow = new PopupWindow(this);
    -        popupWindow.setContentView(viewHolder.view);
    -        popupWindow.setOutsideTouchable(true);
    -        popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_micro));
    -        popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
    -        popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
    +        setupPopupWindow(viewHolder);
             viewHolder.recycler.setAdapter(getMilestonesAdapter());
             AnimHelper.revealPopupWindow(popupWindow, milestone);
         }
     
         @SuppressLint("InflateParams") @OnClick(R.id.assignee) public void onAssigneeClicked() {
    -        if (hideWindow()) return;
    +        if (assignee.getTag() != null) return;
    +        assignee.setTag(true);
             ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
    -        popupWindow = new PopupWindow(this);
    -        popupWindow.setContentView(viewHolder.view);
    -        popupWindow.setOutsideTouchable(true);
    -        popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_micro));
    -        popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
    -        popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
    +        setupPopupWindow(viewHolder);
             viewHolder.recycler.setAdapter(getAssigneesAdapter());
             AnimHelper.revealPopupWindow(popupWindow, assignee);
         }
     
         @SuppressLint("InflateParams") @OnClick(R.id.sort) public void onSortClicked() {
    -        if (hideWindow()) return;
    +        if (sort.getTag() != null) return;
    +        sort.setTag(true);
             ViewHolder viewHolder = new ViewHolder(LayoutInflater.from(this).inflate(R.layout.simple_list_dialog, null));
    -        popupWindow = new PopupWindow(this);
    -        popupWindow.setContentView(viewHolder.view);
    -        popupWindow.setOutsideTouchable(true);
    -        popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_micro));
    -        popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
    -        popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
    +        setupPopupWindow(viewHolder);
             ArrayList<String> lists = new ArrayList<>();
             Collections.addAll(lists, getResources().getStringArray(R.array.sort_prs_issues));
             lists.add(CommentsHelper.getThumbsUp());
    @@ -301,12 +287,23 @@ public class FilterIssuesActivity extends BaseActivity<FilterIssuesActivityMvp.V
             }
         }
     
    -    private boolean hideWindow() {
    -        if (popupWindow != null && popupWindow.isShowing()) {
    -            popupWindow.dismiss();
    -            return true;
    +    private void setupPopupWindow(@NonNull ViewHolder viewHolder) {
    +        if (popupWindow == null) {
    +            popupWindow = new PopupWindow(this);
    +            popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_micro));
    +            popupWindow.setOutsideTouchable(true);
    +            popupWindow.setBackgroundDrawable(new ColorDrawable(ViewHelper.getWindowBackground(this)));
    +            popupWindow.setElevation(getResources().getDimension(R.dimen.spacing_normal));
    +            popupWindow.setOnDismissListener(() -> new Handler().postDelayed(() -> {
    +                //hacky way to dismiss on re-selecting tab.
    +                if (assignee == null || milestone == null || sort == null || labels == null) return;
    +                assignee.setTag(null);
    +                milestone.setTag(null);
    +                sort.setTag(null);
    +                labels.setTag(null);
    +            }, 100));
             }
    -        return false;
    +        popupWindow.setContentView(viewHolder.view);
         }
     
         private void onSearch() {
    @@ -470,7 +467,7 @@ public class FilterIssuesActivity extends BaseActivity<FilterIssuesActivityMvp.V
             onSearch();
         }
     
    -    private void appendSort(String item)  {
    +    private void appendSort(String item) {
             dismissPopup();
             appendIfEmpty();
             Resources resources = getResources();
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/gists/GistsListActivity.java b/app/src/main/java/com/fastaccess/ui/modules/gists/GistsListActivity.java
    index 0106f2d6..402b523c 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/gists/GistsListActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/gists/GistsListActivity.java
    @@ -8,6 +8,7 @@ import android.support.design.widget.FloatingActionButton;
     import android.support.design.widget.TabLayout;
     import android.support.v4.app.Fragment;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.FragmentPagerAdapterModel;
     import com.fastaccess.helper.ActivityHelper;
    @@ -24,7 +25,6 @@ import net.grandcentrix.thirtyinch.TiPresenter;
     
     import butterknife.BindView;
     import butterknife.OnClick;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 25 Mar 2017, 11:28 PM
    @@ -92,15 +92,7 @@ public class GistsListActivity extends BaseActivity {
             ActivityHelper.startReveal(this, new Intent(this, CreateGistActivity.class), fab);
         }
     
    -    private TabLayout.Tab getTab(int titleId) {
    -        return tabs.newTab().setText(titleId);
    -    }
    -
         private void setupTabs() {
    -        TabLayout.Tab tab1 = getTab(R.string.my_gists);
    -        TabLayout.Tab tab2 = getTab(R.string.public_gists);
    -        tabs.addTab(tab1);
    -        tabs.addTab(tab2);
             pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(),
                     FragmentPagerAdapterModel.buildForGists(this)));
             tabs.setupWithViewPager(pager);
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistActivity.java b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistActivity.java
    index c85ee38e..cc8efeb0 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistActivity.java
    @@ -78,22 +78,24 @@ public class GistActivity extends BaseActivity<GistMvp.View, GistPresenter>
                         .show(getSupportFragmentManager(), MessageDialogView.TAG);
         }
     
    -    @OnClick({R.id.startGist, R.id.forkGist}) public void onGistActions(View view) {
    -        view.setEnabled(false);
    +    @OnClick({R.id.startGist, R.id.forkGist, R.id.browser}) public void onGistActions(View view) {
    +        if (getPresenter().getGist() == null) return;
    +        if (view.getId() != R.id.browser) {
    +            view.setEnabled(false);
    +        }
             switch (view.getId()) {
                 case R.id.startGist:
    -                if (getPresenter().getGist() != null) {
    -                    GithubActionService.startForGist(this, getPresenter().getGist().getGistId(),
    -                            getPresenter().isStarred() ? GithubActionService.UNSTAR_GIST : GithubActionService.STAR_GIST);
    -                    getPresenter().onStarGist();
    -                }
    +                GithubActionService.startForGist(this, getPresenter().getGist().getGistId(),
    +                        getPresenter().isStarred() ? GithubActionService.UNSTAR_GIST : GithubActionService.STAR_GIST);
    +                getPresenter().onStarGist();
                     break;
                 case R.id.forkGist:
    -                if (getPresenter().getGist() != null) {
    -                    GithubActionService.startForGist(this, getPresenter().getGist().getGistId(),
    -                            GithubActionService.FORK_GIST);
    -                    getPresenter().onForkGist();
    -                }
    +                GithubActionService.startForGist(this, getPresenter().getGist().getGistId(),
    +                        GithubActionService.FORK_GIST);
    +                getPresenter().onForkGist();
    +                break;
    +            case R.id.browser:
    +                ActivityHelper.startCustomTab(this, getPresenter().getGist().getHtmlUrl());
                     break;
             }
         }
    @@ -198,7 +200,6 @@ public class GistActivity extends BaseActivity<GistMvp.View, GistPresenter>
             hideProgress();
             Gist gistsModel = getPresenter().getGist();
             if (gistsModel == null) {
    -            finish();
                 return;
             }
             String url = gistsModel.getOwner() != null ? gistsModel.getOwner().getAvatarUrl() :
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistPresenter.java
    index 54ceaa07..47f61386 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/GistPresenter.java
    @@ -8,6 +8,7 @@ import android.support.annotation.Nullable;
     import com.fastaccess.data.dao.model.Gist;
     import com.fastaccess.data.dao.model.Login;
     import com.fastaccess.helper.BundleConstant;
    +import com.fastaccess.helper.Logger;
     import com.fastaccess.helper.RxHelper;
     import com.fastaccess.provider.rest.RestProvider;
     import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
    @@ -36,18 +37,18 @@ class GistPresenter extends BasePresenter<GistMvp.View> implements GistMvp.Prese
             }
             Bundle bundle = intent.getExtras();
             gistId = bundle.getString(BundleConstant.EXTRA);
    +        Logger.e(gistId);
             if (gist != null) {
                 checkStarring(gist.getGistId());
                 sendToView(GistMvp.View::onSetupDetails);
             } else if (gistId != null) {
                 checkStarring(gistId);
    -            makeRestCall(RestProvider.getGistService().getGist(gistId),
    -                    gistsModel -> {
    -                        this.gist = gistsModel;
    -                        sendToView(GistMvp.View::onSetupDetails);
    -                    });
    +            makeRestCall(RestProvider.getGistService().getGist(gistId), gistsModel -> {
    +                this.gist = gistsModel;
    +                sendToView(GistMvp.View::onSetupDetails);
    +            });
             } else {
    -            sendToView(GistMvp.View::onSetupDetails); // tell the activity to finish!
    +            sendToView(GistMvp.View::onSetupDetails);
             }
         }
     
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/files/GistFilesListFragment.java b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/files/GistFilesListFragment.java
    index 7dd9cec5..dfd4a173 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/gists/gist/files/GistFilesListFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/gists/gist/files/GistFilesListFragment.java
    @@ -41,8 +41,7 @@ public class GistFilesListFragment extends BaseFragment<GistFilesListMvp.View, G
         public static GistFilesListFragment newInstance(@NonNull GithubFileModel gistsModel) {
             GistFilesListFragment view = new GistFilesListFragment();
             view.setArguments(Bundler.start()
    -                .putParcelableArrayList(BundleConstant.ITEM,
    -                        gistsModel.values() != null ? new ArrayList<>(gistsModel.values()) : new ArrayList<FilesListModel>())
    +                .putParcelableArrayList(BundleConstant.ITEM, new ArrayList<>(gistsModel.values()))
                     .end());
             return view;
         }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/banner/BannerInfoPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/profile/banner/BannerInfoPresenter.java
    index 63766bf6..f85d6d0c 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/banner/BannerInfoPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/banner/BannerInfoPresenter.java
    @@ -2,71 +2,56 @@ package com.fastaccess.ui.modules.profile.banner;
     
     import android.support.annotation.NonNull;
     
    -import com.fastaccess.data.dao.CreateGistModel;
    -import com.fastaccess.data.dao.FilesListModel;
    -import com.fastaccess.data.dao.model.Login;
    -import com.fastaccess.helper.PrefGetter;
    -import com.fastaccess.helper.RxHelper;
    -import com.fastaccess.provider.rest.ImgurProvider;
    -import com.fastaccess.provider.rest.RestProvider;
     import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
    -import com.fastaccess.ui.modules.profile.overview.ProfileOverviewMvp;
    -
    -import java.io.File;
    -import java.util.HashMap;
    -
    -import okhttp3.MediaType;
    -import okhttp3.RequestBody;
    -import io.reactivex.Observable;
     
     /**
      * Created by JediB on 5/25/2017.
      */
     
     public class BannerInfoPresenter extends BasePresenter<BannerInfoMvp.View> implements BannerInfoMvp.Presenter {
    -    @NonNull private Observable<String> getHeaderGist() {
    -        return RxHelper.getObserver(RestProvider.getGistService(true).getGistFile(ProfileOverviewMvp.HEADER_FST_URL));
    -    }
    +//    @NonNull private Observable<String> getHeaderGist() {
    +//        return RxHelper.getObserver(RestProvider.getGistService(true).getGistFile(ProfileOverviewMvp.HEADER_FST_URL));
    +//    }
     
         @Override public void onPostImage(@NonNull String path) {
    -        Login login = Login.getUser();
    -        RequestBody image = RequestBody.create(MediaType.parse("image/*"), new File(path));
    -        ImgurProvider.getImgurService().postImage("", image);
    -        makeRestCall(RxHelper.getObserver(ImgurProvider.getImgurService().postImage("", image))
    -                        .filter(imgurReponseModel -> imgurReponseModel != null && imgurReponseModel.getData() != null)
    -                        .map(imgurReponseModel -> imgurReponseModel.getData().getLink())
    -                        .flatMap(link -> getHeaderGist(), (imageLink, gistContent) -> {
    -                            boolean isReplace = false;
    -                            if (gistContent.contains(login.getLogin() + "->")) {
    -                                String[] splitByNewLine = gistContent.split("\n");
    -                                for (String s : splitByNewLine) {
    -                                    String[] splitByUser = s.split("->");
    -                                    if (login.getLogin().equalsIgnoreCase(splitByUser[0])) {
    -                                        gistContent = gistContent.replaceFirst(splitByUser[0] + "->" +
    -                                                splitByUser[1], login.getLogin() + "->" + imageLink);
    -                                        isReplace = true;
    -                                        break;
    -                                    }
    -                                }
    -                            }
    -                            PrefGetter.setProfileBackgroundUrl(imageLink);
    -                            if (!isReplace) {
    -                                gistContent += "\n" + login.getLogin() + "->" + imageLink;
    -                            }
    -                            return gistContent;
    -                        })
    -                        .map(s -> {
    -                            CreateGistModel createGistModel = new CreateGistModel();
    -                            createGistModel.setPublicGist(true);
    -                            HashMap<String, FilesListModel> modelHashMap = new HashMap<>();
    -                            FilesListModel file = new FilesListModel();
    -                            file.setFilename("header.fst");
    -                            file.setContent(s);
    -                            modelHashMap.put("header.fst", file);
    -                            createGistModel.setFiles(modelHashMap);
    -                            return createGistModel;
    -                        })
    -                        .flatMap(body -> RxHelper.getObserver(RestProvider.getGistService().editGist(body, ProfileOverviewMvp.HEADER_GIST_ID))),
    -                gist -> sendToView(BannerInfoMvp.View::onFinishedUploading));
    +//        Login login = Login.getUser();
    +//        RequestBody image = RequestBody.create(MediaType.parse("image/*"), new File(path));
    +//        ImgurProvider.getImgurService().postImage("", image);
    +//        makeRestCall(RxHelper.getObserver(ImgurProvider.getImgurService().postImage("", image))
    +//                        .filter(imgurReponseModel -> imgurReponseModel != null && imgurReponseModel.getData() != null)
    +//                        .map(imgurReponseModel -> imgurReponseModel.getData().getLink())
    +//                        .flatMap(link -> getHeaderGist(), (imageLink, gistContent) -> {
    +//                            boolean isReplace = false;
    +//                            if (gistContent.contains(login.getLogin() + "->")) {
    +//                                String[] splitByNewLine = gistContent.split("\n");
    +//                                for (String s : splitByNewLine) {
    +//                                    String[] splitByUser = s.split("->");
    +//                                    if (login.getLogin().equalsIgnoreCase(splitByUser[0])) {
    +//                                        gistContent = gistContent.replaceFirst(splitByUser[0] + "->" +
    +//                                                splitByUser[1], login.getLogin() + "->" + imageLink);
    +//                                        isReplace = true;
    +//                                        break;
    +//                                    }
    +//                                }
    +//                            }
    +//                            PrefGetter.setProfileBackgroundUrl(imageLink);
    +//                            if (!isReplace) {
    +//                                gistContent += "\n" + login.getLogin() + "->" + imageLink;
    +//                            }
    +//                            return gistContent;
    +//                        })
    +//                        .map(s -> {
    +//                            CreateGistModel createGistModel = new CreateGistModel();
    +//                            createGistModel.setPublicGist(true);
    +//                            HashMap<String, FilesListModel> modelHashMap = new HashMap<>();
    +//                            FilesListModel file = new FilesListModel();
    +//                            file.setFilename("header.fst");
    +//                            file.setContent(s);
    +//                            modelHashMap.put("header.fst", file);
    +//                            createGistModel.setFiles(modelHashMap);
    +//                            return createGistModel;
    +//                        })
    +//                        .flatMap(body -> RxHelper.getObserver(RestProvider.getGistService().editGist(body, ProfileOverviewMvp.HEADER_GIST_ID))),
    +//                gist -> sendToView(BannerInfoMvp.View::onFinishedUploading));
         }
     }
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEvents.kt b/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEvents.kt
    new file mode 100644
    index 00000000..9e867ccb
    --- /dev/null
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEvents.kt
    @@ -0,0 +1,32 @@
    +package com.fastaccess.ui.modules.profile.events
    +
    +import android.support.v4.widget.SwipeRefreshLayout
    +import com.fastaccess.data.dao.SimpleUrlsModel
    +import com.fastaccess.data.dao.model.Event
    +import com.fastaccess.provider.rest.loadmore.OnLoadMore
    +import com.fastaccess.ui.base.mvp.BaseMvp
    +import com.fastaccess.ui.widgets.dialog.ListDialogView
    +import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
    +
    +/**
    + * Created by Kosh on 03 Jun 2017, 4:49 PM
    + */
    +interface ProfileEvents {
    +
    +    interface View : BaseMvp.FAView, SwipeRefreshLayout.OnRefreshListener,
    +            android.view.View.OnClickListener, ListDialogView.onSimpleItemSelection<SimpleUrlsModel> {
    +        fun onNotifyAdapter(events: List<Event>?, page: Int)
    +
    +        fun onOpenRepoChooser(models: ArrayList<SimpleUrlsModel>)
    +
    +        fun getLoadMore(): OnLoadMore<String>
    +    }
    +
    +    interface Presenter : BaseMvp.FAPresenter,
    +            BaseViewHolder.OnItemClickListener<Event>,
    +            BaseMvp.PaginationListener<String> {
    +        fun getEvents(): ArrayList<Event>
    +
    +        fun onWorkOffline()
    +    }
    +}
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEventsFragment.kt b/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEventsFragment.kt
    new file mode 100644
    index 00000000..cb325afc
    --- /dev/null
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEventsFragment.kt
    @@ -0,0 +1,138 @@
    +package com.fastaccess.ui.modules.profile.events
    +
    +import android.net.Uri
    +import android.os.Bundle
    +import android.support.annotation.StringRes
    +import android.support.v4.widget.SwipeRefreshLayout
    +import android.view.View
    +import com.fastaccess.R
    +import com.fastaccess.data.dao.SimpleUrlsModel
    +import com.fastaccess.data.dao.model.Event
    +import com.fastaccess.helper.BundleConstant
    +import com.fastaccess.helper.Bundler
    +import com.fastaccess.provider.rest.loadmore.OnLoadMore
    +import com.fastaccess.provider.scheme.SchemeParser
    +import com.fastaccess.ui.adapter.FeedsAdapter
    +import com.fastaccess.ui.base.BaseFragment
    +import com.fastaccess.ui.widgets.StateLayout
    +import com.fastaccess.ui.widgets.dialog.ListDialogView
    +import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView
    +import java.util.*
    +
    +/**
    + * Created by Kosh on 11 Nov 2016, 12:36 PM
    + */
    +
    +open class ProfileEventsFragment : BaseFragment<ProfileEvents.View, ProfileEventsPresenter>(), ProfileEvents.View {
    +
    +    val recycler by lazy { view!!.findViewById(R.id.recycler) as DynamicRecyclerView }
    +    val refresh by lazy { view!!.findViewById(R.id.refresh) as SwipeRefreshLayout }
    +    val stateLayout by lazy { view!!.findViewById(R.id.stateLayout) as StateLayout }
    +    val adapter by lazy { FeedsAdapter(presenter.getEvents(), true) }
    +    private var onLoadMore: OnLoadMore<String>? = null
    +
    +    override fun fragmentLayout(): Int {
    +        return R.layout.micro_grid_refresh_list
    +    }
    +
    +    override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
    +        stateLayout.setEmptyText(R.string.no_feeds)
    +        stateLayout.setOnReloadListener(this)
    +        refresh.setOnRefreshListener(this)
    +        recycler.setEmptyView(stateLayout, refresh)
    +        adapter.listener = presenter
    +        getLoadMore().setCurrent_page(presenter.currentPage, presenter.previousTotal)
    +        recycler.adapter = adapter
    +        recycler.addOnScrollListener(getLoadMore())
    +        recycler.addDivider()
    +        if (presenter.getEvents().isEmpty() && !presenter.isApiCalled) {
    +            onRefresh()
    +        }
    +    }
    +
    +    override fun onRefresh() {
    +        presenter.onCallApi(1, arguments.getString(BundleConstant.EXTRA))
    +    }
    +
    +    override fun onNotifyAdapter(events: List<Event>?, page: Int) {
    +        hideProgress()
    +        if (events == null || events.isEmpty()) {
    +            adapter.clear()
    +            return
    +        }
    +        if (page <= 1) {
    +            adapter.insertItems(events)
    +        } else {
    +            adapter.addItems(events)
    +        }
    +    }
    +
    +    override fun showProgress(@StringRes resId: Int) {
    +        refresh.isRefreshing = true
    +        stateLayout.showProgress()
    +    }
    +
    +    override fun hideProgress() {
    +        refresh.isRefreshing = false
    +        stateLayout.hideProgress()
    +    }
    +
    +    override fun showErrorMessage(message: String) {
    +        showReload()
    +        super.showErrorMessage(message)
    +    }
    +
    +    override fun showMessage(titleRes: Int, msgRes: Int) {
    +        showReload()
    +        super.showMessage(titleRes, msgRes)
    +    }
    +
    +    override fun onOpenRepoChooser(models: ArrayList<SimpleUrlsModel>) {
    +        val dialogView = ListDialogView<SimpleUrlsModel>()
    +        dialogView.initArguments(getString(R.string.repo_chooser), models)
    +        dialogView.show(childFragmentManager, "ListDialogView")
    +    }
    +
    +    override fun providePresenter(): ProfileEventsPresenter {
    +        return ProfileEventsPresenter()
    +    }
    +
    +    override fun getLoadMore(): OnLoadMore<String> {
    +        if (onLoadMore == null) {
    +            onLoadMore = OnLoadMore(presenter)
    +        }
    +        onLoadMore!!.parameter = arguments.getString(BundleConstant.EXTRA)
    +        return onLoadMore as OnLoadMore<String>
    +    }
    +
    +    override fun onDestroyView() {
    +        recycler.removeOnScrollListener(getLoadMore())
    +        super.onDestroyView()
    +    }
    +
    +    override fun onClick(view: View) {
    +        onRefresh()
    +    }
    +
    +    override fun onItemSelected(item: SimpleUrlsModel) {
    +        SchemeParser.launchUri(context, Uri.parse(item.item))
    +    }
    +
    +    override fun onScrollTop(index: Int) {
    +        super.onScrollTop(index)
    +        recycler.scrollToPosition(0)
    +    }
    +
    +    private fun showReload() {
    +        hideProgress()
    +        stateLayout.showReload(adapter.itemCount)
    +    }
    +
    +    companion object {
    +        fun newInstance(login: String): ProfileEventsFragment {
    +            val fragment = ProfileEventsFragment()
    +            fragment.arguments = Bundler.start().put(BundleConstant.EXTRA, login).end()
    +            return fragment
    +        }
    +    }
    +}
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEventsPresenter.kt b/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEventsPresenter.kt
    new file mode 100644
    index 00000000..30eea674
    --- /dev/null
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/events/ProfileEventsPresenter.kt
    @@ -0,0 +1,119 @@
    +package com.fastaccess.ui.modules.profile.events
    +
    +import android.net.Uri
    +import android.view.View
    +import com.annimon.stream.Collectors
    +import com.annimon.stream.Stream
    +import com.fastaccess.data.dao.NameParser
    +import com.fastaccess.data.dao.Pageable
    +import com.fastaccess.data.dao.SimpleUrlsModel
    +import com.fastaccess.data.dao.model.Event
    +import com.fastaccess.data.dao.types.EventsType
    +import com.fastaccess.helper.RxHelper
    +import com.fastaccess.provider.rest.RestProvider
    +import com.fastaccess.provider.scheme.SchemeParser
    +import com.fastaccess.ui.base.mvp.presenter.BasePresenter
    +import com.fastaccess.ui.modules.repos.RepoPagerActivity
    +import com.fastaccess.ui.modules.repos.code.commit.details.CommitPagerActivity
    +import java.util.*
    +
    +/**
    + * Created by Kosh on 11 Nov 2016, 12:36 PM
    + */
    +
    +class ProfileEventsPresenter : BasePresenter<ProfileEvents.View>(), ProfileEvents.Presenter {
    +    private val eventsModels = ArrayList<Event>()
    +    private var page: Int = 0
    +    private var previousTotal: Int = 0
    +    private var lastPage = Integer.MAX_VALUE
    +
    +    override fun getCurrentPage(): Int {
    +        return page
    +    }
    +
    +    override fun getPreviousTotal(): Int {
    +        return previousTotal
    +    }
    +
    +    override fun setCurrentPage(page: Int) {
    +        this.page = page
    +    }
    +
    +    override fun setPreviousTotal(previousTotal: Int) {
    +        this.previousTotal = previousTotal
    +    }
    +
    +    override fun onCallApi(page: Int, parameter: String?) {
    +        if (page == 1 || parameter.isNullOrEmpty()) {
    +            lastPage = Integer.MAX_VALUE
    +            sendToView { view -> view.getLoadMore().reset() }
    +        }
    +        if (page > lastPage || lastPage == 0) {
    +            sendToView({ it.hideProgress() })
    +            return
    +        }
    +        currentPage = page
    +        makeRestCall<Pageable<Event>>(RestProvider.getUserService().getUserEvents(parameter!!, page)) { response ->
    +            lastPage = response.last
    +            sendToView { view -> view.onNotifyAdapter(response.items, page) }
    +        }
    +    }
    +
    +    override fun onSubscribed() {
    +        sendToView { view -> view.showProgress(0) }
    +    }
    +
    +    override fun onError(throwable: Throwable) {
    +        onWorkOffline()
    +        super.onError(throwable)
    +    }
    +
    +    override fun getEvents(): ArrayList<Event> {
    +        return eventsModels
    +    }
    +
    +    override fun onWorkOffline() {
    +        //TODO
    +        sendToView({ it.hideProgress() })
    +    }
    +
    +    override fun onItemClick(position: Int, v: View, item: Event) {
    +        if (item.type == EventsType.ForkEvent) {
    +            val parser = NameParser(item.payload.forkee.htmlUrl)
    +            RepoPagerActivity.startRepoPager(v.context, parser)
    +        } else {
    +            val payloadModel = item.payload
    +            if (payloadModel != null) {
    +                if (payloadModel.head != null) {
    +                    val repoModel = item.repo
    +                    val uri = Uri.parse(repoModel.name)
    +                    if (uri == null || uri.pathSegments.size < 1) return
    +                    val intent = CommitPagerActivity.createIntent(v.context, uri.lastPathSegment, uri.pathSegments[0],
    +                            payloadModel.head, true)
    +                    v.context.startActivity(intent)
    +                } else if (item.payload.issue != null) {
    +                    SchemeParser.launchUri(v.context, Uri.parse(item.payload.issue.htmlUrl), true)
    +                } else if (item.payload.pullRequest != null) {
    +                    SchemeParser.launchUri(v.context, Uri.parse(item.payload.pullRequest.htmlUrl), true)
    +                } else if (item.payload.comment != null) {
    +                    SchemeParser.launchUri(v.context, Uri.parse(item.payload.comment.htmlUrl), true)
    +                } else {
    +                    val repoModel = item.repo
    +                    if (item.repo != null) SchemeParser.launchUri(v.context, Uri.parse(repoModel.name), true)
    +                }
    +            }
    +        }
    +    }
    +
    +    override fun onItemLongClick(position: Int, v: View, item: Event) {
    +        if (item.type == EventsType.ForkEvent) {
    +            if (view != null) {
    +                view!!.onOpenRepoChooser(Stream.of(SimpleUrlsModel(item.repo.name, item.repo.url),
    +                        SimpleUrlsModel(item.payload.forkee.fullName, item.payload.forkee.htmlUrl))
    +                        .collect(Collectors.toCollection(::arrayListOf)))
    +            }
    +        } else {
    +            onItemClick(position, v, item)
    +        }
    +    }
    +}
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsFragment.java b/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsFragment.java
    index 11f6ed16..4ec5386f 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsFragment.java
    @@ -59,7 +59,6 @@ public class ProfileGistsFragment extends BaseFragment<ProfileGistsMvp.View, Pro
             adapter.setListener(getPresenter());
             getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal());
             recycler.setAdapter(adapter);
    -        recycler.addKeyLineDivider();
             recycler.addOnScrollListener(getLoadMore());
             recycler.addDivider();
             if (getPresenter().getGists().isEmpty() && !getPresenter().isApiCalled()) {
    @@ -85,9 +84,7 @@ public class ProfileGistsFragment extends BaseFragment<ProfileGistsMvp.View, Pro
         }
     
         @Override public void showProgress(@StringRes int resId) {
    -
    -refresh.setRefreshing(true);
    -
    +        refresh.setRefreshing(true);
             stateLayout.showProgress();
         }
     
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsPresenter.java
    index db7669fe..58488ee4 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/gists/ProfileGistsPresenter.java
    @@ -4,10 +4,12 @@ import android.support.annotation.NonNull;
     import android.support.annotation.Nullable;
     import android.view.View;
     
    +import com.annimon.stream.Stream;
     import com.fastaccess.data.dao.model.Gist;
     import com.fastaccess.helper.RxHelper;
     import com.fastaccess.provider.rest.RestProvider;
     import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
    +import com.fastaccess.ui.modules.gists.gist.GistActivity;
     
     import java.util.ArrayList;
     
    @@ -59,13 +61,11 @@ class ProfileGistsPresenter extends BasePresenter<ProfileGistsMvp.View> implemen
                 sendToView(ProfileGistsMvp.View::hideProgress);
                 return;
             }
    -        makeRestCall(RestProvider.getGistService().getUserGists(parameter, RestProvider.PAGE_SIZE, page),
    +        makeRestCall(RestProvider.getGistService().getUserGists(parameter, page),
                     listResponse -> {
                         lastPage = listResponse.getLast();
    -                    if (getCurrentPage() == 1) {
    -                        manageObservable(Gist.save(listResponse.getItems(), parameter));
    -                    }
                         sendToView(view -> view.onNotifyAdapter(listResponse.getItems(), page));
    +                    manageObservable(Gist.save(Stream.of(listResponse.getItems()).toList()));
                     });
         }
     
    @@ -83,7 +83,7 @@ class ProfileGistsPresenter extends BasePresenter<ProfileGistsMvp.View> implemen
         }
     
         @Override public void onItemClick(int position, View v, Gist item) {
    -        if (getView() != null) getView().onStartGistView(item.getGistId());
    +        v.getContext().startActivity(GistActivity.createIntent(v.getContext(), item.getGistId()));
         }
     
         @Override public void onItemLongClick(int position, View v, Gist item) {}
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewFragment.java b/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewFragment.java
    index 04edacfa..1da21478 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewFragment.java
    @@ -1,10 +1,7 @@
     package com.fastaccess.ui.modules.profile.overview;
     
    -import android.Manifest;
    -import android.app.Activity;
    +import android.annotation.SuppressLint;
     import android.content.Context;
    -import android.content.Intent;
    -import android.content.pm.PackageManager;
     import android.graphics.Bitmap;
     import android.graphics.drawable.BitmapDrawable;
     import android.os.Build;
    @@ -15,6 +12,7 @@ import android.support.annotation.StringRes;
     import android.support.v4.widget.NestedScrollView;
     import android.support.v7.widget.CardView;
     import android.util.DisplayMetrics;
    +import android.view.MotionEvent;
     import android.view.View;
     import android.view.ViewGroup;
     import android.widget.Button;
    @@ -23,16 +21,15 @@ import android.widget.LinearLayout;
     import android.widget.LinearLayout.LayoutParams;
     import android.widget.RelativeLayout;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.model.Login;
     import com.fastaccess.data.dao.model.User;
     import com.fastaccess.helper.ActivityHelper;
     import com.fastaccess.helper.BundleConstant;
     import com.fastaccess.helper.Bundler;
    -import com.fastaccess.helper.FileHelper;
     import com.fastaccess.helper.InputHelper;
     import com.fastaccess.helper.ParseDateFormat;
    -import com.fastaccess.helper.PrefGetter;
     import com.fastaccess.provider.emoji.EmojiParser;
     import com.fastaccess.ui.adapter.ProfileOrgsAdapter;
     import com.fastaccess.ui.base.BaseFragment;
    @@ -51,8 +48,6 @@ import java.util.List;
     
     import butterknife.BindView;
     import butterknife.OnClick;
    -import es.dmoral.toasty.Toasty;
    -import com.evernote.android.state.State;
     
     import static android.view.Gravity.TOP;
     import static android.view.View.GONE;
    @@ -91,8 +86,6 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
         @BindView(R.id.contributionCard) CardView contributionCard;
         private ProfilePagerMvp.View profileCallback;
     
    -    private static int READ_REQUEST_CODE = 256;
    -
         public static ProfileOverviewFragment newInstance(@NonNull String login) {
             ProfileOverviewFragment view = new ProfileOverviewFragment();
             view.setArguments(Bundler.start().put(BundleConstant.EXTRA, login).end());
    @@ -114,12 +107,6 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
             if (userModel != null) ActivityHelper.startCustomTab(getActivity(), userModel.getAvatarUrl());
         }
     
    -    @OnClick({R.id.chooseBanner, R.id.banner_edit}) public void chooseBanner() {
    -        if (ActivityHelper.checkAndRequestReadWritePermission(getActivity())) {
    -            showFileChooser();
    -        }
    -    }
    -
         @Override public void onAttach(Context context) {
             super.onAttach(context);
             if (getParentFragment() instanceof ProfilePagerMvp.View) {
    @@ -154,18 +141,13 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
             if (isMeOrOrganization()) {
                 followBtn.setVisibility(GONE);
             }
    -//        if (getPresenter().getLogin().equals(Login.getUser().getLogin()) && PrefHelper.getBoolean("banner_learned"))
    -//            chooseBanner.setVisibility(VISIBLE);
    -//        if (Login.getUser().getLogin().equalsIgnoreCase(getPresenter().getLogin())) {
    -//            onImagePosted(PrefGetter.getProfileBackgroundUrl());
    -//        }
         }
     
         @NonNull @Override public ProfileOverviewPresenter providePresenter() {
             return new ProfileOverviewPresenter();
         }
     
    -    @Override public void onInitViews(@Nullable User userModel) {
    +    @SuppressLint("ClickableViewAccessibility") @Override public void onInitViews(@Nullable User userModel) {
             progress.setVisibility(GONE);
             if (userModel == null) return;
             this.userModel = userModel;
    @@ -178,11 +160,18 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
                 description.setVisibility(GONE);
             }
             avatarLayout.setUrl(userModel.getAvatarUrl(), null);
    +        avatarLayout.findViewById(R.id.avatar).setOnTouchListener((v, event) -> {
    +            if (event.getAction() == MotionEvent.ACTION_UP) {
    +                ActivityHelper.startCustomTab(getActivity(), userModel.getAvatarUrl());
    +                return true;
    +            }
    +            return false;
    +        });
             organization.setText(InputHelper.toNA(userModel.getCompany()));
             location.setText(InputHelper.toNA(userModel.getLocation()));
             email.setText(InputHelper.toNA(userModel.getEmail()));
             link.setText(InputHelper.toNA(userModel.getBlog()));
    -        joined.setText(userModel.getCreatedAt() != null ? ParseDateFormat.getTimeAgo(userModel.getCreatedAt()) : "N/A");
    +        joined.setText(ParseDateFormat.getTimeAgo(userModel.getCreatedAt()));
             ViewGroup parent = (ViewGroup) organization.getParent();
             if (organization.getText().equals("N/A")) {
                 int i = parent.indexOfChild(organization);
    @@ -215,18 +204,6 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
                     .append(getString(R.string.following))
                     .append("\n")
                     .bold(String.valueOf(userModel.getFollowing())));
    -//        if (userModel.getLogin().equals(Login.getUser().getLogin()))
    -//            if (headerImage.getVisibility() == GONE) {
    -//                if (PrefHelper.getBoolean("banner_learned")) return;
    -//                headerImage.setBackground(getResources().getDrawable(R.drawable.header));
    -//                headerImage.setVisibility(VISIBLE);
    -//                headerImage.setOnClickListener(view -> {
    -//                    PrefHelper.set("banner_learned", true);
    -//                    Intent intent = new Intent(getContext(), BannerInfoActivity.class);
    -//                    startActivityForResult(intent, BundleConstant.REVIEW_REQUEST_CODE);
    -//                });
    -//            }
    -
         }
     
         @Override public void invalidateFollowBtn() {
    @@ -258,8 +235,8 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
                 orgsList.setAdapter(adapter);
                 orgsCard.setVisibility(VISIBLE);
                 organizationsCaption.setVisibility(VISIBLE);
    -            ((GridManager) orgsList.getLayoutManager()).setIconSize(getResources().getDimensionPixelSize(R.dimen.header_icon_zie) +
    -                    getResources().getDimensionPixelSize(R.dimen.spacing_xs_large));
    +            ((GridManager) orgsList.getLayoutManager()).setIconSize(getResources().getDimensionPixelSize(R.dimen.header_icon_zie) + getResources()
    +                    .getDimensionPixelSize(R.dimen.spacing_xs_large));
             } else {
                 organizationsCaption.setVisibility(GONE);
                 orgsCard.setVisibility(GONE);
    @@ -334,36 +311,6 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
             }
         }
     
    -    @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
    -        if (resultCode == Activity.RESULT_OK) {
    -            if (requestCode == BundleConstant.REQUEST_CODE) {
    -                if (data != null) {
    -                    String path = FileHelper.getPath(getContext(), data.getData());
    -                    if (path == null) {
    -                        showMessage(R.string.error, R.string.image_error);
    -                        return;
    -                    }
    -                    getPresenter().onPostImage(path);
    -                }
    -            } else {
    -                onImagePosted(PrefGetter.getProfileBackgroundUrl());
    -            }
    -        }
    -    }
    -
    -    @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    -        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    -        if (requestCode == READ_REQUEST_CODE) {
    -            if (permissions[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
    -                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    -                    showFileChooser();
    -                } else {
    -                    Toasty.error(getContext(), getString(R.string.permission_failed)).show();
    -                }
    -            }
    -        }
    -    }
    -
         private void onHideProgress() {
             hideProgress();
         }
    @@ -373,11 +320,4 @@ public class ProfileOverviewFragment extends BaseFragment<ProfileOverviewMvp.Vie
                     (userModel != null && userModel.getType() != null && !userModel.getType().equalsIgnoreCase("user"));
         }
     
    -    private void showFileChooser() {
    -        Intent intent = new Intent();
    -        intent.setType("image/*");
    -        intent.setAction(Intent.ACTION_GET_CONTENT);
    -        startActivityForResult(Intent.createChooser(intent, getString(R.string.select_picture)), BundleConstant.REQUEST_CODE);
    -    }
    -
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewMvp.java b/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewMvp.java
    index e316c415..9af84dd0 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewMvp.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewMvp.java
    @@ -18,10 +18,6 @@ import java.util.List;
     
     public interface ProfileOverviewMvp {
     
    -    String HEADER_FST_URL = "https://gist.githubusercontent" +
    -            ".com/k0shk0sh/44c5d0ba29d179c9e78bc892e8573138/raw/4d443b23dda00c568fc6905b3c28103d55d00b51/header.fst";
    -    String HEADER_GIST_ID = "44c5d0ba29d179c9e78bc892e8573138";
    -
         interface View extends BaseMvp.FAView {
             void onInitViews(@Nullable User userModel);
     
    @@ -59,7 +55,5 @@ public interface ProfileOverviewMvp {
             @NonNull ArrayList<ContributionsDay> getContributions();
     
             @NonNull String getLogin();
    -
    -        void onPostImage(@NonNull String path);
         }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewPresenter.java
    index 61f69e77..b4d0e62e 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/overview/ProfileOverviewPresenter.java
    @@ -5,26 +5,18 @@ import android.support.annotation.NonNull;
     import android.support.annotation.Nullable;
     import android.text.TextUtils;
     
    -import com.fastaccess.data.dao.CreateGistModel;
    -import com.fastaccess.data.dao.FilesListModel;
     import com.fastaccess.data.dao.model.Login;
     import com.fastaccess.data.dao.model.User;
     import com.fastaccess.helper.BundleConstant;
     import com.fastaccess.helper.InputHelper;
    -import com.fastaccess.helper.PrefGetter;
     import com.fastaccess.helper.RxHelper;
    -import com.fastaccess.provider.rest.ImgurProvider;
     import com.fastaccess.provider.rest.RestProvider;
     import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
     import com.fastaccess.ui.widgets.contributions.ContributionsDay;
     import com.fastaccess.ui.widgets.contributions.ContributionsProvider;
     
    -import java.io.File;
     import java.util.ArrayList;
    -import java.util.HashMap;
     
    -import okhttp3.MediaType;
    -import okhttp3.RequestBody;
     import io.reactivex.Observable;
     
     /**
    @@ -126,52 +118,6 @@ class ProfileOverviewPresenter extends BasePresenter<ProfileOverviewMvp.View> im
             return login;
         }
     
    -    @Override public void onPostImage(@NonNull String path) {
    -        Login login = Login.getUser();
    -        RequestBody image = RequestBody.create(MediaType.parse("image/*"), new File(path));
    -        ImgurProvider.getImgurService().postImage("", image);
    -        makeRestCall(RxHelper.getObserver(ImgurProvider.getImgurService().postImage("", image))
    -                        .filter(imgurReponseModel -> imgurReponseModel != null && imgurReponseModel.getData() != null)
    -                        .map(imgurReponseModel -> imgurReponseModel.getData().getLink())
    -                        .flatMap(link -> getHeaderGist(), (imageLink, gistContent) -> {
    -                            boolean isReplace = false;
    -                            if (gistContent.contains(login.getLogin() + "->")) {
    -                                String[] splitByNewLine = gistContent.split("\n");
    -                                for (String s : splitByNewLine) {
    -                                    String[] splitByUser = s.split("->");
    -                                    if (login.getLogin().equalsIgnoreCase(splitByUser[0])) {
    -                                        gistContent = gistContent.replaceFirst(splitByUser[0] + "->" +
    -                                                splitByUser[1], login.getLogin() + "->" + imageLink);
    -                                        isReplace = true;
    -                                        break;
    -                                    }
    -                                }
    -                            }
    -                            PrefGetter.setProfileBackgroundUrl(imageLink);
    -                            if (!isReplace) {
    -                                gistContent += "\n" + login.getLogin() + "->" + imageLink;
    -                            }
    -                            return gistContent;
    -                        })
    -                        .map(s -> {
    -                            CreateGistModel createGistModel = new CreateGistModel();
    -                            createGistModel.setPublicGist(true);
    -                            HashMap<String, FilesListModel> modelHashMap = new HashMap<>();
    -                            FilesListModel file = new FilesListModel();
    -                            file.setFilename("header.fst");
    -                            file.setContent(s);
    -                            modelHashMap.put("header.fst", file);
    -                            createGistModel.setFiles(modelHashMap);
    -                            return createGistModel;
    -                        })
    -                        .flatMap(body -> RxHelper.getObserver(RestProvider.getGistService().editGist(body, ProfileOverviewMvp.HEADER_GIST_ID))),
    -                gist -> sendToView(view -> view.onImagePosted(PrefGetter.getProfileBackgroundUrl())));
    -    }
    -
    -    @NonNull private Observable<String> getHeaderGist() {
    -        return RxHelper.getObserver(RestProvider.getGistService(true).getGistFile(ProfileOverviewMvp.HEADER_FST_URL));
    -    }
    -
         private void loadContributions() {
             String url = String.format(URL, login);
             manageDisposable(RxHelper.getObserver(RestProvider.getContribution().getContributions(url))
    @@ -194,26 +140,4 @@ class ProfileOverviewPresenter extends BasePresenter<ProfileOverviewMvp.View> im
                         sendToView(view -> view.onInitOrgs(userOrgs));
                     }, Throwable::printStackTrace));
         }
    -
    -    private void loadUrlBackgroundImage() {
    -        if (Login.getUser().getLogin().equalsIgnoreCase(login)) {
    -            if (PrefGetter.getProfileBackgroundUrl() == null) {
    -                manageDisposable(getHeaderGist()
    -                        .flatMap(s -> RxHelper.getObserver(Observable.fromArray(s.split("\n"))))
    -                        .flatMap(s -> RxHelper.getObserver(Observable.just(s.split("->"))))
    -                        .filter(strings -> strings != null && strings[0].equalsIgnoreCase(login))
    -                        .map(strings -> strings[1])
    -                        .subscribe(s -> sendToView(view -> view.onImagePosted(s)), Throwable::printStackTrace));
    -            } else {
    -                sendToView(view -> view.onImagePosted(PrefGetter.getProfileBackgroundUrl()));
    -            }
    -        } else {
    -            manageDisposable(getHeaderGist()
    -                    .flatMap(s -> RxHelper.getObserver(Observable.fromArray(s.split("\n"))))
    -                    .flatMap(s -> RxHelper.getObserver(Observable.just(s.split("->"))))
    -                    .filter(strings -> strings != null && strings[0].equalsIgnoreCase(login))
    -                    .map(strings -> strings[1])
    -                    .subscribe(s -> sendToView(view -> view.onImagePosted(s)), Throwable::printStackTrace));
    -        }
    -    }
     }
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredFragment.java b/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredFragment.java
    index 92ddf34c..c5d51b2c 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredFragment.java
    @@ -1,5 +1,6 @@
     package com.fastaccess.ui.modules.profile.starred;
     
    +import android.content.Context;
     import android.os.Bundle;
     import android.support.annotation.NonNull;
     import android.support.annotation.Nullable;
    @@ -14,6 +15,7 @@ import com.fastaccess.helper.Bundler;
     import com.fastaccess.provider.rest.loadmore.OnLoadMore;
     import com.fastaccess.ui.adapter.ReposAdapter;
     import com.fastaccess.ui.base.BaseFragment;
    +import com.fastaccess.ui.modules.repos.RepoPagerMvp;
     import com.fastaccess.ui.widgets.StateLayout;
     import com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView;
     
    @@ -32,6 +34,7 @@ public class ProfileStarredFragment extends BaseFragment<ProfileStarredMvp.View,
         @BindView(R.id.stateLayout) StateLayout stateLayout;
         private OnLoadMore<String> onLoadMore;
         private ReposAdapter adapter;
    +    private RepoPagerMvp.TabsBadgeListener tabsBadgeListener;
     
         public static ProfileStarredFragment newInstance(@NonNull String username) {
             ProfileStarredFragment view = new ProfileStarredFragment();
    @@ -39,6 +42,21 @@ public class ProfileStarredFragment extends BaseFragment<ProfileStarredMvp.View,
             return view;
         }
     
    +
    +    @Override public void onAttach(Context context) {
    +        super.onAttach(context);
    +        if (getParentFragment() instanceof RepoPagerMvp.TabsBadgeListener) {
    +            tabsBadgeListener = (RepoPagerMvp.TabsBadgeListener) getParentFragment();
    +        } else if (context instanceof RepoPagerMvp.TabsBadgeListener) {
    +            tabsBadgeListener = (RepoPagerMvp.TabsBadgeListener) context;
    +        }
    +    }
    +
    +    @Override public void onDetach() {
    +        tabsBadgeListener = null;
    +        super.onDetach();
    +    }
    +
         @Override public void onNotifyAdapter(@Nullable List<Repo> items, int page) {
             hideProgress();
             if (items == null || items.isEmpty()) {
    @@ -81,9 +99,7 @@ public class ProfileStarredFragment extends BaseFragment<ProfileStarredMvp.View,
         }
     
         @Override public void showProgress(@StringRes int resId) {
    -
             refresh.setRefreshing(true);
    -
             stateLayout.showProgress();
         }
     
    @@ -109,6 +125,12 @@ public class ProfileStarredFragment extends BaseFragment<ProfileStarredMvp.View,
             return onLoadMore;
         }
     
    +    @Override public void onUpdateCount(int starredCount) {
    +        if (tabsBadgeListener != null) {
    +            tabsBadgeListener.onSetBadge(3, starredCount);
    +        }
    +    }
    +
         @Override public void onRefresh() {
             getPresenter().onCallApi(1, getArguments().getString(BundleConstant.EXTRA));
         }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredMvp.java b/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredMvp.java
    index 379c4b82..939bd74a 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredMvp.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredMvp.java
    @@ -22,6 +22,8 @@ interface ProfileStarredMvp {
             void onNotifyAdapter(@Nullable List<Repo> items, int page);
     
             @NonNull OnLoadMore<String> getLoadMore();
    +
    +        void onUpdateCount(int starredCount);
         }
     
         interface Presenter extends BaseMvp.FAPresenter,
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredPresenter.java
    index 9c8bb7fb..26cba3da 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/profile/starred/ProfileStarredPresenter.java
    @@ -5,6 +5,7 @@ import android.support.annotation.Nullable;
     import android.view.View;
     
     import com.fastaccess.data.dao.NameParser;
    +import com.fastaccess.data.dao.Pageable;
     import com.fastaccess.data.dao.model.Repo;
     import com.fastaccess.helper.RxHelper;
     import com.fastaccess.provider.rest.RestProvider;
    @@ -13,12 +14,15 @@ import com.fastaccess.ui.modules.repos.RepoPagerActivity;
     
     import java.util.ArrayList;
     
    +import io.reactivex.Observable;
    +
     /**
      * Created by Kosh on 03 Dec 2016, 3:48 PM
      */
     
     class ProfileStarredPresenter extends BasePresenter<ProfileStarredMvp.View> implements ProfileStarredMvp.Presenter {
     
    +    @com.evernote.android.state.State int starredCount = -1;
         private ArrayList<Repo> repos = new ArrayList<>();
         private int page;
         private int previousTotal;
    @@ -62,14 +66,28 @@ class ProfileStarredPresenter extends BasePresenter<ProfileStarredMvp.View> impl
                 sendToView(ProfileStarredMvp.View::hideProgress);
                 return;
             }
    -        makeRestCall(RestProvider.getUserService().getStarred(parameter, page),
    -                repoModelPageable -> {
    -                    lastPage = repoModelPageable.getLast();
    -                    if (getCurrentPage() == 1) {
    -                        manageObservable(Repo.saveStarred(repoModelPageable.getItems(), parameter));
    -                    }
    -                    sendToView(view -> view.onNotifyAdapter(repoModelPageable.getItems(), page));
    -                });
    +        Observable<Pageable<Repo>> observable;
    +        if (starredCount == -1) {
    +            observable = Observable.zip(RestProvider.getUserService().getStarred(parameter, page),
    +                    RestProvider.getUserService().getStarredCount(parameter), (repoPageable, count) -> {
    +                        if (count != null) {
    +                            starredCount = count.getLast();
    +                        }
    +                        return repoPageable;
    +                    });
    +        } else {
    +            observable = RestProvider.getUserService().getStarred(parameter, page);
    +        }
    +        makeRestCall(observable, repoModelPageable -> {
    +            lastPage = repoModelPageable.getLast();
    +            if (getCurrentPage() == 1) {
    +                manageObservable(Repo.saveStarred(repoModelPageable.getItems(), parameter));
    +            }
    +            sendToView(view -> {
    +                view.onUpdateCount(starredCount);
    +                view.onNotifyAdapter(repoModelPageable.getItems(), page);
    +            });
    +        });
         }
     
         @NonNull @Override public ArrayList<Repo> getRepos() {
    @@ -79,7 +97,11 @@ class ProfileStarredPresenter extends BasePresenter<ProfileStarredMvp.View> impl
         @Override public void onWorkOffline(@NonNull String login) {
             if (repos.isEmpty()) {
                 manageDisposable(RxHelper.getObserver(Repo.getStarred(login).toObservable()).subscribe(repoModels ->
    -                    sendToView(view -> view.onNotifyAdapter(repoModels, 1))));
    +                    sendToView(view -> {
    +                        starredCount = -1;
    +                        view.onUpdateCount(repoModels != null ? repoModels.size() : 0);
    +                        view.onNotifyAdapter(repoModels, 1);
    +                    })));
             } else {
                 sendToView(ProfileStarredMvp.View::hideProgress);
             }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/RepoPagerActivity.java b/app/src/main/java/com/fastaccess/ui/modules/repos/RepoPagerActivity.java
    index 97211b97..dd44fcda 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/RepoPagerActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/RepoPagerActivity.java
    @@ -20,6 +20,7 @@ import android.view.MotionEvent;
     import android.view.View;
     import android.widget.CheckBox;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.LicenseModel;
     import com.fastaccess.data.dao.NameParser;
    @@ -58,7 +59,6 @@ import butterknife.BindView;
     import butterknife.OnCheckedChanged;
     import butterknife.OnClick;
     import butterknife.OnLongClick;
    -import com.evernote.android.state.State;
     import it.sephiroth.android.library.bottomnavigation.BottomNavigation;
     import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
     
    @@ -313,7 +313,7 @@ public class RepoPagerActivity extends BaseActivity<RepoPagerMvp.View, RepoPager
         }
     
         @Override public void onFinishActivity() {
    -//        finish();
    +        //do nothing here, github might return 404 if even the repo don't have anything but issues.
         }
     
         @Override public void onInitRepo() {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/RepoCommitsPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/RepoCommitsPresenter.java
    index 815a85d6..9ad02dbf 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/RepoCommitsPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/RepoCommitsPresenter.java
    @@ -93,14 +93,14 @@ class RepoCommitsPresenter extends BasePresenter<RepoCommitsMvp.View> implements
                         RestProvider.getRepoService().getTags(login, repoId),
                         (branchPageable, tags) -> {
                             ArrayList<BranchesModel> branchesModels = new ArrayList<>();
    -                        if (branchPageable.getItems() != null) {
    +                        if (branchPageable != null && branchPageable.getItems() != null) {
                                 branchesModels.addAll(Stream.of(branchPageable.getItems())
                                         .map(branchesModel -> {
                                             branchesModel.setTag(false);
                                             return branchesModel;
                                         }).collect(Collectors.toList()));
                             }
    -                        if (tags != null) {
    +                        if (tags != null && tags.getItems() != null) {
                                 branchesModels.addAll(Stream.of(tags.getItems())
                                         .map(branchesModel -> {
                                             branchesModel.setTag(true);
    @@ -112,12 +112,11 @@ class RepoCommitsPresenter extends BasePresenter<RepoCommitsMvp.View> implements
                         }));
                 manageDisposable(observable
                         .doOnSubscribe(disposable -> sendToView(RepoCommitsMvp.View::showBranchesProgress))
    -                    .doOnNext(branchesModels -> {
    +                    .subscribe(branchesModels -> {
                             branches.clear();
                             branches.addAll(branchesModels);
                             sendToView(view -> view.setBranchesData(branches, true));
    -                    })
    -                    .subscribe(branchesModels -> {/**/}, throwable -> sendToView(view -> view.setBranchesData(branches, true))));
    +                    }, throwable -> sendToView(view -> view.setBranchesData(branches, true))));
             }
             if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
                 onCallApi(1, null);
    @@ -166,6 +165,6 @@ class RepoCommitsPresenter extends BasePresenter<RepoCommitsMvp.View> implements
                         if (response != null) {
                             sendToView(view -> view.onShowCommitCount(response.getLast()));
                         }
    -                }));
    +                }, Throwable::printStackTrace));
         }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerActivity.java b/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerActivity.java
    index b791f774..86e7c1bd 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerActivity.java
    @@ -32,6 +32,7 @@ import com.fastaccess.ui.modules.repos.RepoPagerActivity;
     import com.fastaccess.ui.modules.repos.code.commit.details.comments.CommitCommentsFragments;
     import com.fastaccess.ui.widgets.AvatarLayout;
     import com.fastaccess.ui.widgets.FontTextView;
    +import com.fastaccess.ui.widgets.SpannableBuilder;
     import com.fastaccess.ui.widgets.ViewPagerView;
     import com.fastaccess.ui.widgets.dialog.MessageDialogView;
     
    @@ -162,7 +163,9 @@ public class CommitPagerActivity extends BaseActivity<CommitPagerMvp.View, Commi
             HtmlHelper.htmlIntoTextView(title, commit.getGitCommit().getMessage());
             detailsIcon.setVisibility(View.VISIBLE);
             size.setVisibility(View.GONE);
    -        date.setText(ParseDateFormat.getTimeAgo(dateValue));
    +        date.setText(SpannableBuilder.builder().append(ParseDateFormat.getTimeAgo(dateValue))
    +                .append(" ")
    +                .bold(getPresenter().repoId));
             avatarLayout.setUrl(avatar, login);
             addition.setText(String.valueOf(commit.getStats() != null ? commit.getStats().getAdditions() : 0));
             deletion.setText(String.valueOf(commit.getStats() != null ? commit.getStats().getDeletions() : 0));
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerPresenter.java
    index 565d341f..b1dd13d7 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/code/commit/details/CommitPagerPresenter.java
    @@ -49,29 +49,27 @@ class CommitPagerPresenter extends BasePresenter<CommitPagerMvp.View> implements
                     return;
                 } else if (!InputHelper.isEmpty(sha) && !InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
                     makeRestCall(RestProvider.getRepoService()
    -                                .getCommit(login, repoId, sha)
    -                                .flatMap(commit -> {
    -                                    if (commit.getGitCommit() != null && commit.getGitCommit().getMessage() != null) {
    -                                        MarkdownModel markdownModel = new MarkdownModel();
    -                                        markdownModel.setContext(login + "/" + repoId);
    -                                        markdownModel.setText(commit.getGitCommit().getMessage());
    -                                        return RestProvider.getRepoService().convertReadmeToHtml(markdownModel)
    -                                                .onErrorReturn(throwable -> null);
    -                                    }
    -                                    return Observable.just(commit);
    -                                }, (commit, u) -> {
    -                                    if (!InputHelper.isEmpty(u) && u instanceof String) {
    -                                        commit.getGitCommit().setMessage(u.toString());
    -                                    }
    -                                    return commit;
    -                                }),
    -                        commit -> {
    -                            commitModel = commit;
    -                            commitModel.setRepoId(repoId);
    -                            commitModel.setLogin(login);
    -                            sendToView(CommitPagerMvp.View::onSetup);
    -                            manageObservable(commitModel.save(commitModel).toObservable());
    -                        });
    +                        .getCommit(login, repoId, sha)
    +                        .flatMap(commit -> {
    +                            if (commit.getGitCommit() != null && commit.getGitCommit().getMessage() != null) {
    +                                MarkdownModel markdownModel = new MarkdownModel();
    +                                markdownModel.setContext(login + "/" + repoId);
    +                                markdownModel.setText(commit.getGitCommit().getMessage());
    +                                return RestProvider.getRepoService().convertReadmeToHtml(markdownModel);
    +                            }
    +                            return Observable.just(commit);
    +                        }, (commit, u) -> {
    +                            if (!InputHelper.isEmpty(u) && u instanceof String) {
    +                                commit.getGitCommit().setMessage(u.toString());
    +                            }
    +                            return commit;
    +                        }), commit -> {
    +                    commitModel = commit;
    +                    commitModel.setRepoId(repoId);
    +                    commitModel.setLogin(login);
    +                    sendToView(CommitPagerMvp.View::onSetup);
    +                    manageObservable(commitModel.save(commitModel).toObservable());
    +                });
                     return;
                 }
             }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/code/files/RepoFilesPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/code/files/RepoFilesPresenter.java
    index b27e6770..34c3505c 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/code/files/RepoFilesPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/code/files/RepoFilesPresenter.java
    @@ -59,10 +59,9 @@ class RepoFilesPresenter extends BasePresenter<RepoFilesMvp.View> implements Rep
                     })
                     .toList()
                     .subscribe(models -> {
    -                            files.addAll(models);
    -                            sendToView(RepoFilesMvp.View::onNotifyAdapter);
    -                        }
    -                ));
    +                    files.addAll(models);
    +                    sendToView(RepoFilesMvp.View::onNotifyAdapter);
    +                }));
         }
     
         @Override public void onCallApi(@Nullable RepoFile toAppend) {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerFragment.java b/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerFragment.java
    index 3f2eaeda..5e1c09fd 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerFragment.java
    @@ -10,6 +10,7 @@ import android.view.MenuItem;
     import android.view.View;
     import android.widget.ProgressBar;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.helper.ActivityHelper;
     import com.fastaccess.helper.BundleConstant;
    @@ -22,7 +23,6 @@ import com.fastaccess.ui.widgets.StateLayout;
     import com.prettifier.pretty.PrettifyWebView;
     
     import butterknife.BindView;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 28 Nov 2016, 9:27 PM
    @@ -143,7 +143,7 @@ public class ViewerFragment extends BaseFragment<ViewerMvp.View, ViewerPresenter
                 getPresenter().onHandleIntent(getArguments());
             } else {
                 if (getPresenter().isMarkDown()) {
    -                onSetMdText(getPresenter().downloadedStream(), getArguments().getString(BundleConstant.EXTRA));
    +                onSetMdText(getPresenter().downloadedStream(), getPresenter().url());
                 } else {
                     onSetCode(getPresenter().downloadedStream());
                 }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerPresenter.java
    index ae896f41..7b0e7e06 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/code/prettifier/ViewerPresenter.java
    @@ -103,45 +103,44 @@ class ViewerPresenter extends BasePresenter<ViewerMvp.View> implements ViewerMvp
                                                   ? RestProvider.getRepoService(true).getFileAsHtmlStream(url)
                                                   : RestProvider.getRepoService(true).getFileAsStream(url);
             makeRestCall(isRepo ? RestProvider.getRepoService(true).getReadmeHtml(url)
    -                            : streamObservable,
    -                content -> {
    -                    downloadedStream = content;
    -                    ViewerFile fileModel = new ViewerFile();
    -                    fileModel.setContent(downloadedStream);
    -                    fileModel.setFullUrl(url);
    -                    fileModel.setRepo(isRepo);
    -                    if (isRepo) {
    -                        fileModel.setMarkdown(true);
    -                        isMarkdown = true;
    -                        isRepo = true;
    -                        sendToView(view -> view.onSetMdText(downloadedStream, url));
    +                            : streamObservable, content -> {
    +            downloadedStream = content;
    +            ViewerFile fileModel = new ViewerFile();
    +            fileModel.setContent(downloadedStream);
    +            fileModel.setFullUrl(url);
    +            fileModel.setRepo(isRepo);
    +            if (isRepo) {
    +                fileModel.setMarkdown(true);
    +                isMarkdown = true;
    +                isRepo = true;
    +                sendToView(view -> view.onSetMdText(downloadedStream, url));
    +            } else {
    +                isMarkdown = MarkDownProvider.isMarkdown(url);
    +                if (isMarkdown) {
    +                    MarkdownModel model = new MarkdownModel();
    +                    model.setText(downloadedStream);
    +                    NameParser parser = new NameParser(url);
    +                    if (parser.getUsername() != null && parser.getName() != null) {
    +                        model.setContext(parser.getUsername() + "/" + parser.getName());
                         } else {
    -                        isMarkdown = MarkDownProvider.isMarkdown(url);
    -                        if (isMarkdown) {
    -                            MarkdownModel model = new MarkdownModel();
    -                            model.setText(downloadedStream);
    -                            NameParser parser = new NameParser(url);
    -                            if (parser.getUsername() != null && parser.getName() != null) {
    -                                model.setContext(parser.getUsername() + "/" + parser.getName());
    -                            } else {
    -                                model.setContext("");
    -                            }
    -                            Logger.e(model.getContext());
    -                            makeRestCall(RestProvider.getRepoService().convertReadmeToHtml(model), string -> {
    -                                isMarkdown = true;
    -                                downloadedStream = string;
    -                                fileModel.setMarkdown(true);
    -                                fileModel.setContent(downloadedStream);
    -                                manageObservable(fileModel.save(fileModel).toObservable());
    -                                sendToView(view -> view.onSetMdText(downloadedStream, url));
    -                            });
    -                            return;
    -                        }
    -                        fileModel.setMarkdown(false);
    -                        sendToView(view -> view.onSetCode(downloadedStream));
    +                        model.setContext("");
                         }
    -                    manageObservable(fileModel.save(fileModel).toObservable());
    -                });
    +                    Logger.e(model.getContext());
    +                    makeRestCall(RestProvider.getRepoService().convertReadmeToHtml(model), string -> {
    +                        isMarkdown = true;
    +                        downloadedStream = string;
    +                        fileModel.setMarkdown(true);
    +                        fileModel.setContent(downloadedStream);
    +                        manageObservable(fileModel.save(fileModel).toObservable());
    +                        sendToView(view -> view.onSetMdText(downloadedStream, url));
    +                    });
    +                    return;
    +                }
    +                fileModel.setMarkdown(false);
    +                sendToView(view -> view.onSetCode(downloadedStream));
    +            }
    +            manageObservable(fileModel.save(fileModel).toObservable());
    +        });
         }
     
         @Override public boolean isRepo() {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/code/releases/RepoReleasesPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/code/releases/RepoReleasesPresenter.java
    index 0dd0af81..63378544 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/code/releases/RepoReleasesPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/code/releases/RepoReleasesPresenter.java
    @@ -71,14 +71,6 @@ class RepoReleasesPresenter extends BasePresenter<RepoReleasesMvp.View> implemen
     
         }
     
    -    private void onResponse(Pageable<Release> response) {
    -        lastPage = response.getLast();
    -        if (getCurrentPage() == 1) {
    -            manageObservable(Release.save(response.getItems(), repoId, login));
    -        }
    -        sendToView(view -> view.onNotifyAdapter(response.getItems(), getCurrentPage()));
    -    }
    -
         @Override public void onFragmentCreated(@NonNull Bundle bundle) {
             repoId = bundle.getString(BundleConstant.ID);
             login = bundle.getString(BundleConstant.EXTRA);
    @@ -110,4 +102,12 @@ class RepoReleasesPresenter extends BasePresenter<RepoReleasesMvp.View> implemen
         }
     
         @Override public void onItemLongClick(int position, View v, Release item) {}
    +
    +    private void onResponse(Pageable<Release> response) {
    +        lastPage = response.getLast();
    +        if (getCurrentPage() == 1) {
    +            manageObservable(Release.save(response.getItems(), repoId, login));
    +        }
    +        sendToView(view -> view.onNotifyAdapter(response.getItems(), getCurrentPage()));
    +    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/assignees/AssigneesDialogFragment.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/assignees/AssigneesDialogFragment.java
    index b3a94a6b..5f63f19d 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/assignees/AssigneesDialogFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/assignees/AssigneesDialogFragment.java
    @@ -5,10 +5,12 @@ import android.os.Bundle;
     import android.support.annotation.NonNull;
     import android.support.annotation.Nullable;
     import android.support.annotation.StringRes;
    +import android.support.v4.widget.SwipeRefreshLayout;
     import android.view.View;
     
     import com.annimon.stream.Collectors;
     import com.annimon.stream.Stream;
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.model.User;
     import com.fastaccess.helper.BundleConstant;
    @@ -27,7 +29,6 @@ import java.util.Map;
     
     import butterknife.BindView;
     import butterknife.OnClick;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 22 Feb 2017, 7:23 PM
    @@ -38,6 +39,7 @@ public class AssigneesDialogFragment extends BaseDialogFragment<AssigneesMvp.Vie
         @BindView(R.id.title) FontTextView title;
         @BindView(R.id.recycler) DynamicRecyclerView recycler;
         @BindView(R.id.stateLayout) StateLayout stateLayout;
    +    @BindView(R.id.refresh) SwipeRefreshLayout refresh;
         @State HashMap<Integer, User> selectionMap;
     
         private AssigneesAdapter adapter;
    @@ -75,16 +77,13 @@ public class AssigneesDialogFragment extends BaseDialogFragment<AssigneesMvp.Vie
     
         @Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
             if (savedInstanceState == null) {
    -            if (getArguments() != null) {
    -                //noinspection ConstantConditions
    -                getPresenter().onCallApi(getArguments().getString(BundleConstant.EXTRA),
    -                        getArguments().getString(BundleConstant.ID),
    -                        getArguments().getBoolean(BundleConstant.EXTRA_TWO));
    -            }
    +            callApi();
             }
    +        refresh.setOnRefreshListener(this::callApi);
    +        stateLayout.setOnReloadListener(v -> callApi());
             boolean isAssinees = getArguments().getBoolean(BundleConstant.EXTRA_TWO);
             stateLayout.setEmptyText(isAssinees ? R.string.no_assignees : R.string.no_reviewers);
    -        recycler.setEmptyView(stateLayout);
    +        recycler.setEmptyView(stateLayout, refresh);
             recycler.addKeyLineDivider();
             title.setText(isAssinees ? R.string.assignees : R.string.reviewers);
             adapter = new AssigneesAdapter(getPresenter().getList(), this);
    @@ -137,10 +136,12 @@ public class AssigneesDialogFragment extends BaseDialogFragment<AssigneesMvp.Vie
     
         @Override public void showProgress(@StringRes int resId) {
             stateLayout.showProgress();
    +        refresh.setRefreshing(true);
         }
     
         @Override public void hideProgress() {
             stateLayout.hideProgress();
    +        refresh.setRefreshing(false);
         }
     
         @Override public void showErrorMessage(@NonNull String message) {
    @@ -164,4 +165,11 @@ public class AssigneesDialogFragment extends BaseDialogFragment<AssigneesMvp.Vie
             }
             return selectionMap;
         }
    +
    +    private void callApi() {
    +        //noinspection ConstantConditions
    +        getPresenter().onCallApi(getArguments().getString(BundleConstant.EXTRA),
    +                getArguments().getString(BundleConstant.ID),
    +                getArguments().getBoolean(BundleConstant.EXTRA_TWO));
    +    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/labels/LabelsDialogFragment.java b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/labels/LabelsDialogFragment.java
    index 15358fb7..d421345f 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/extras/labels/LabelsDialogFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/extras/labels/LabelsDialogFragment.java
    @@ -5,10 +5,12 @@ import android.os.Bundle;
     import android.os.Parcelable;
     import android.support.annotation.NonNull;
     import android.support.annotation.Nullable;
    +import android.support.v4.widget.SwipeRefreshLayout;
     import android.view.View;
     
     import com.annimon.stream.Collectors;
     import com.annimon.stream.Stream;
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.LabelListModel;
     import com.fastaccess.data.dao.LabelModel;
    @@ -30,7 +32,6 @@ import java.util.Map;
     
     import butterknife.BindView;
     import butterknife.OnClick;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 22 Feb 2017, 7:23 PM
    @@ -40,6 +41,7 @@ public class LabelsDialogFragment extends BaseDialogFragment<LabelsMvp.View, Lab
     
         @BindView(R.id.title) FontTextView title;
         @BindView(R.id.recycler) DynamicRecyclerView recycler;
    +    @BindView(R.id.refresh) SwipeRefreshLayout refresh;
         @BindView(R.id.add) View add;
         @BindView(R.id.stateLayout) StateLayout stateLayout;
         @State HashMap<Integer, LabelModel> selectionMap;
    @@ -87,8 +89,9 @@ public class LabelsDialogFragment extends BaseDialogFragment<LabelsMvp.View, Lab
         }
     
         @Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    +        refresh.setEnabled(false);
             stateLayout.setEmptyText(R.string.no_labels);
    -        recycler.setEmptyView(stateLayout);
    +        recycler.setEmptyView(stateLayout, refresh);
             recycler.addKeyLineDivider();
             title.setText(R.string.labels);
             add.setVisibility(View.VISIBLE);
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssueActivity.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssueActivity.java
    index 149eac9c..064e4fa5 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssueActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssueActivity.java
    @@ -11,6 +11,7 @@ import android.support.v4.app.Fragment;
     import android.view.MotionEvent;
     import android.view.View;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.model.Issue;
     import com.fastaccess.data.dao.model.PullRequest;
    @@ -27,7 +28,6 @@ import com.fastaccess.ui.widgets.FontTextView;
     import butterknife.BindView;
     import butterknife.OnClick;
     import butterknife.OnTouch;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 19 Feb 2017, 12:33 PM
    @@ -127,7 +127,7 @@ public class CreateIssueActivity extends BaseActivity<CreateIssueMvp.View, Creat
     
         @Override public void onSetCode(@NonNull CharSequence charSequence) {
             this.savedText = charSequence;
    -        MarkDownProvider.setMdText(description, InputHelper.toString(charSequence));
    +        MarkDownProvider.setMdText(description, InputHelper.toString(savedText));
         }
     
         @Override public void onTitleError(boolean isEmptyTitle) {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssuePresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssuePresenter.java
    index c016baaf..5ba655dd 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssuePresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/create/CreateIssuePresenter.java
    @@ -12,6 +12,7 @@ import com.fastaccess.data.dao.model.Issue;
     import com.fastaccess.data.dao.model.PullRequest;
     import com.fastaccess.helper.BundleConstant;
     import com.fastaccess.helper.InputHelper;
    +import com.fastaccess.helper.Logger;
     import com.fastaccess.provider.rest.RestProvider;
     import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
     
    @@ -26,6 +27,7 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
                 if (intent != null && intent.getExtras() != null) {
                     CharSequence charSequence = intent.getExtras().getCharSequence(BundleConstant.EXTRA);
                     if (!InputHelper.isEmpty(charSequence)) {
    +                    Logger.e(charSequence);
                         sendToView(view -> view.onSetCode(charSequence));
                     }
                 }
    @@ -61,6 +63,7 @@ public class CreateIssuePresenter extends BasePresenter<CreateIssueMvp.View> imp
                         makeRestCall(RestProvider.getIssueService().editIssue(login, repo, number, requestModel),
                                 issueModel -> {
                                     if (issueModel != null) {
    +                                    Logger.e(issueModel.getBodyHtml());
                                         sendToView(view -> view.onSuccessSubmission(issueModel));
                                     } else {
                                         sendToView(view -> view.showMessage(R.string.error, R.string.error_creating_issue));
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerActivity.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerActivity.java
    index 5310ee01..d78497d8 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerActivity.java
    @@ -13,6 +13,7 @@ import android.view.Menu;
     import android.view.MenuItem;
     import android.view.View;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.FragmentPagerAdapterModel;
     import com.fastaccess.data.dao.LabelModel;
    @@ -47,7 +48,6 @@ import java.util.List;
     
     import butterknife.BindView;
     import butterknife.OnClick;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 10 Dec 2016, 9:23 AM
    @@ -126,7 +126,7 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
             if (savedInstanceState == null) {
                 getPresenter().onActivityCreated(getIntent());
             } else {
    -            if (getPresenter().getIssue() != null) onSetupIssue();
    +            if (getPresenter().getIssue() != null) onSetupIssue(false);
             }
             startGist.setVisibility(View.GONE);
             forkGist.setVisibility(View.GONE);
    @@ -139,7 +139,9 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
                 if (requestCode == BundleConstant.REQUEST_CODE) {
                     Bundle bundle = data.getExtras();
                     Issue issueModel = bundle.getParcelable(BundleConstant.ITEM);
    -                if (issueModel != null) getPresenter().onUpdateIssue(issueModel);
    +                if (issueModel != null) {
    +                    getPresenter().onUpdateIssue(issueModel);
    +                }
                 }
             }
         }
    @@ -222,59 +224,44 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
             labels.setVisible(isCollaborator || isRepoOwner);
             assignees.setVisible(isCollaborator || isRepoOwner);
             edit.setVisible(isCollaborator || isRepoOwner || isOwner);
    -        menu.findItem(R.id.closeIssue).setVisible(isOwner || isCollaborator);
    -        menu.findItem(R.id.lockIssue).setVisible(isOwner || isCollaborator);
    -        menu.findItem(R.id.labels).setVisible(getPresenter().isRepoOwner() || isCollaborator);
    -        if (isOwner || isCollaborator) {
    -            if (getPresenter().getIssue() == null) return super.onPrepareOptionsMenu(menu);
    +        lockIssue.setVisible(isOwner || isCollaborator);
    +        labels.setVisible(getPresenter().isRepoOwner() || isCollaborator);
    +        closeIssue.setVisible(isOwner || isCollaborator);
    +        if (getPresenter().getIssue() != null) {
    +            closeIssue.setTitle(getPresenter().getIssue().getState() == IssueState.closed ? getString(R.string.re_open) : getString(R.string.close));
                 lockIssue.setTitle(isLocked ? getString(R.string.unlock_issue) : getString(R.string.lock_issue));
             }
             return super.onPrepareOptionsMenu(menu);
         }
     
    -    @Override public void onSetupIssue() {
    +    @Override public void onSetupIssue(boolean isUpdate) {
             hideProgress();
             if (getPresenter().getIssue() == null) {
                 return;
             }
    +        onUpdateMenu();
             Issue issueModel = getPresenter().getIssue();
    -        invalidateOptionsMenu();
             setTitle(String.format("#%s", issueModel.getNumber()));
    -        User userModel = issueModel.getUser();
    -        title.setText(issueModel.getTitle());
    -        detailsIcon.setVisibility(InputHelper.isEmpty(issueModel.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
    -        if (userModel != null) {
    -            size.setVisibility(View.GONE);
    -            String username;
    -            CharSequence parsedDate;
    -            if (issueModel.getState() == IssueState.closed) {
    -                username = issueModel.getClosedBy() != null ? issueModel.getClosedBy().getLogin() : "N/A";
    -                parsedDate = issueModel.getClosedAt() != null ? ParseDateFormat.getTimeAgo(issueModel.getClosedAt()) : "N/A";
    -            } else {
    -                parsedDate = ParseDateFormat.getTimeAgo(issueModel.getCreatedAt());
    -                username = issueModel.getUser() != null ? issueModel.getUser().getLogin() : "N/A";
    -            }
    -            date.setText(SpannableBuilder.builder()
    -                    .append(ContextCompat.getDrawable(this,
    -                            issueModel.getState() == IssueState.open ? R.drawable.ic_issue_opened_small : R.drawable.ic_issue_closed_small))
    -                    .append(" ")
    -                    .append(getString(issueModel.getState().getStatus()))
    -                    .append(" ").append(getString(R.string.by)).append(" ").append(username).append(" ")
    -                    .append(parsedDate).append("\n").append(issueModel.getRepoId()));
    -            avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
    -        }
    -        if (pager.getAdapter() == null) {
    -            pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForIssues(this, issueModel)));
    -            if (!getPresenter().isLocked() || getPresenter().isOwner()) {
    -                pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    -                    @Override public void onPageSelected(int position) {
    -                        super.onPageSelected(position);
    -                        hideShowFab();
    -                    }
    -                });
    +        updateViews(issueModel);
    +        if (isUpdate) {
    +            IssueTimelineFragment issueDetailsView = (IssueTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
    +            if (issueDetailsView != null && getPresenter().getIssue() != null) {
    +                issueDetailsView.onUpdateHeader();
                 }
             } else {
    -            onUpdateTimeline();
    +            if (pager.getAdapter() == null) {
    +                pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForIssues(this)));
    +            } else {
    +                onUpdateTimeline();
    +            }
    +        }
    +        if (!getPresenter().isLocked() || getPresenter().isOwner()) {
    +            pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    +                @Override public void onPageSelected(int position) {
    +                    super.onPageSelected(position);
    +                    hideShowFab();
    +                }
    +            });
             }
             hideShowFab();
         }
    @@ -309,15 +296,15 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
         }
     
         @Override public void onUpdateTimeline() {
    -        showMessage(R.string.success, R.string.labels_added_successfully);
    +        if (pager == null || pager.getAdapter() == null) return;
             IssueTimelineFragment issueDetailsView = (IssueTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
             if (issueDetailsView != null && getPresenter().getIssue() != null) {
    -            issueDetailsView.onRefresh(getPresenter().getIssue());
    +            issueDetailsView.onRefresh();
             }
         }
     
         @Override public void onUpdateMenu() {
    -        supportInvalidateOptionsMenu();
    +        invalidateOptionsMenu();
         }
     
         @Override public void onMileStoneSelected(@NonNull MilestoneModel milestoneModel) {
    @@ -329,6 +316,10 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
             finish();
         }
     
    +    @Nullable @Override public Issue getData() {
    +        return getPresenter().getIssue();
    +    }
    +
         @Override public void onMessageDialogActionClicked(boolean isOk, @Nullable Bundle bundle) {
             super.onMessageDialogActionClicked(isOk, bundle);
             if (isOk) {
    @@ -370,4 +361,30 @@ public class IssuePagerActivity extends BaseActivity<IssuePagerMvp.View, IssuePa
             }
             fab.show();
         }
    +
    +    private void updateViews(@NonNull Issue issueModel) {
    +        User userModel = issueModel.getUser();
    +        title.setText(issueModel.getTitle());
    +        detailsIcon.setVisibility(InputHelper.isEmpty(issueModel.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
    +        if (userModel != null) {
    +            size.setVisibility(View.GONE);
    +            String username;
    +            CharSequence parsedDate;
    +            if (issueModel.getState() == IssueState.closed) {
    +                username = issueModel.getClosedBy() != null ? issueModel.getClosedBy().getLogin() : "N/A";
    +                parsedDate = issueModel.getClosedAt() != null ? ParseDateFormat.getTimeAgo(issueModel.getClosedAt()) : "N/A";
    +            } else {
    +                parsedDate = ParseDateFormat.getTimeAgo(issueModel.getCreatedAt());
    +                username = issueModel.getUser() != null ? issueModel.getUser().getLogin() : "N/A";
    +            }
    +            date.setText(SpannableBuilder.builder()
    +                    .append(ContextCompat.getDrawable(this,
    +                            issueModel.getState() == IssueState.open ? R.drawable.ic_issue_opened_small : R.drawable.ic_issue_closed_small))
    +                    .append(" ")
    +                    .append(getString(issueModel.getState().getStatus()))
    +                    .append(" ").append(getString(R.string.by)).append(" ").append(username).append(" ")
    +                    .append(parsedDate).append(" ").bold(issueModel.getRepoId()));
    +            avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
    +        }
    +    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java
    index 391f51cc..2fd591bc 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerMvp.java
    @@ -23,8 +23,8 @@ import java.util.List;
     public interface IssuePagerMvp {
     
         interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener,
    -            AssigneesMvp.SelectedAssigneesListener {
    -        void onSetupIssue();
    +            AssigneesMvp.SelectedAssigneesListener, IssuePrCallback<Issue> {
    +        void onSetupIssue(boolean isUpdate);
     
             void showSuccessIssueActionMsg(boolean isClose);
     
    @@ -39,6 +39,7 @@ public interface IssuePagerMvp {
             void onMileStoneSelected(@NonNull MilestoneModel milestoneModel);
     
             void onFinishActivity();
    +
         }
     
         interface Presenter extends BaseMvp.FAPresenter {
    @@ -82,4 +83,8 @@ public interface IssuePagerMvp {
             void onSubscribeOrMute(boolean mute);
         }
     
    +    interface IssuePrCallback<T> {
    +        @Nullable T getData();
    +    }
    +
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java
    index 13540a67..f84b0cd8 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/IssuePagerPresenter.java
    @@ -70,31 +70,14 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                 showToRepoBtn = intent.getExtras().getBoolean(BundleConstant.EXTRA_THREE);
                 if (issueModel != null) {
                     issueNumber = issueModel.getNumber();
    -                sendToView(IssuePagerMvp.View::onSetupIssue);
    +                sendToView(view -> view.onSetupIssue(false));
                     return;
                 } else if (issueNumber > 0 && !InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
                     getIssueFromApi();
                     return;
                 }
             }
    -        sendToView(IssuePagerMvp.View::onSetupIssue);
    -    }
    -
    -    private void getIssueFromApi() {
    -        Observable<Issue> observable = RestProvider.getIssueService().getIssue(login, repoId, issueNumber)
    -                .flatMap(issue -> RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
    -                        (issue, booleanResponse) -> {
    -                            isCollaborator = booleanResponse.code() == 204;
    -                            return issue;
    -                        });
    -        makeRestCall(observable, this::setupIssue);
    -    }
    -
    -    private void setupIssue(Issue issue) {
    -        issueModel = issue;
    -        issueModel.setRepoId(repoId);
    -        issueModel.setLogin(login);
    -        sendToView(IssuePagerMvp.View::onSetupIssue);
    +        sendToView(view -> view.onSetupIssue(false));
         }
     
         @Override public void onWorkOffline(long issueNumber, @NonNull String repoId, @NonNull String login) {
    @@ -103,7 +86,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                         .subscribe(issueModel1 -> {
                             if (issueModel1 != null) {
                                 issueModel = issueModel1;
    -                            sendToView(IssuePagerMvp.View::onSetupIssue);
    +                            sendToView(view -> view.onSetupIssue(false));
                             }
                         }));
             } else {
    @@ -163,7 +146,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                                 issue.setRepoId(issueModel.getRepoId());
                                 issue.setLogin(issueModel.getLogin());
                                 issueModel = issue;
    -                            sendToView(IssuePagerMvp.View::onSetupIssue);
    +                            sendToView(view -> view.onSetupIssue(true));
                             }
                         })
                         .subscribe(issue -> {/**/},
    @@ -184,7 +167,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                 int code = booleanResponse.code();
                 if (code == 204) {
                     issueModel.setLocked(!isLocked());
    -                sendToView(IssuePagerMvp.View::onSetupIssue);
    +                sendToView(view -> view.onSetupIssue(true));
                 }
                 sendToView(IssuePagerMvp.View::hideProgress);
             });
    @@ -217,7 +200,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                         issueModel.setLogin(login);
                         issueModel.setRepoId(repoId);
                         manageObservable(issue.save(issueModel).toObservable());
    -                    sendToView(IssuePagerMvp.View::onUpdateTimeline);
    +                    sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
                     });
     
         }
    @@ -227,7 +210,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                     Stream.of(labels).filter(value -> value != null && value.getName() != null)
                             .map(LabelModel::getName).collect(Collectors.toList())),
                     labelModels -> {
    -                    sendToView(IssuePagerMvp.View::onUpdateTimeline);
    +                    sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
                         LabelListModel listModel = new LabelListModel();
                         listModel.addAll(labels);
                         issueModel.setLabels(listModel);
    @@ -249,7 +232,7 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                         assignee.addAll(users);
                         issueModel.setAssignees(assignee);
                         manageObservable(issueModel.save(issueModel).toObservable());
    -                    sendToView(IssuePagerMvp.View::onUpdateTimeline);
    +                    sendToView(view -> updateTimeline(view, R.string.assignee_added));
                     }
             );
         }
    @@ -263,11 +246,13 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
         }
     
         @Override public void onUpdateIssue(@NonNull Issue issue) {
    -        this.issueModel = issue;
    +        this.issueModel.setBody(issue.getBody());
    +        this.issueModel.setBodyHtml(issue.getBodyHtml());
    +        this.issueModel.setTitle(issue.getTitle());
             this.issueModel.setLogin(login);
             this.issueModel.setRepoId(repoId);
             manageObservable(issueModel.save(issueModel).toObservable());
    -        sendToView(IssuePagerMvp.View::onSetupIssue);
    +        sendToView(view -> view.onSetupIssue(true));
         }
     
         @Override public void onSubscribeOrMute(boolean mute) {
    @@ -288,4 +273,25 @@ class IssuePagerPresenter extends BasePresenter<IssuePagerMvp.View> implements I
                         }
                     });
         }
    +
    +    private void getIssueFromApi() {
    +        makeRestCall(RxHelper.getObserver(Observable.zip(RestProvider.getIssueService().getIssue(login, repoId, issueNumber),
    +                RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
    +                (issue, booleanResponse) -> {
    +                    isCollaborator = booleanResponse.code() == 204;
    +                    return issue;
    +                })), this::setupIssue);
    +    }
    +
    +    private void setupIssue(Issue issue) {
    +        issueModel = issue;
    +        issueModel.setRepoId(repoId);
    +        issueModel.setLogin(login);
    +        sendToView(view -> view.onSetupIssue(false));
    +    }
    +
    +    private void updateTimeline(IssuePagerMvp.View view, int assignee_added) {
    +        view.showMessage(R.string.success, assignee_added);
    +        view.onUpdateTimeline();
    +    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineFragment.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineFragment.java
    index 2a73a6d6..a73d0441 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineFragment.java
    @@ -1,6 +1,7 @@
     package com.fastaccess.ui.modules.repos.issues.issue.details.timeline;
     
     import android.app.Activity;
    +import android.content.Context;
     import android.content.Intent;
     import android.os.Bundle;
     import android.support.annotation.NonNull;
    @@ -8,6 +9,7 @@ import android.support.annotation.Nullable;
     import android.support.annotation.StringRes;
     import android.view.View;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.TimelineModel;
     import com.fastaccess.data.dao.model.Comment;
    @@ -24,6 +26,7 @@ import com.fastaccess.ui.adapter.IssuePullsTimelineAdapter;
     import com.fastaccess.ui.adapter.viewholder.TimelineCommentsViewHolder;
     import com.fastaccess.ui.base.BaseFragment;
     import com.fastaccess.ui.modules.editor.EditorActivity;
    +import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerMvp;
     import com.fastaccess.ui.modules.repos.reactions.ReactionsDialogFragment;
     import com.fastaccess.ui.widgets.AppbarRefreshLayout;
     import com.fastaccess.ui.widgets.StateLayout;
    @@ -36,7 +39,6 @@ import java.util.LinkedHashMap;
     import java.util.List;
     
     import butterknife.BindView;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 31 Mar 2017, 7:35 PM
    @@ -50,16 +52,32 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
         @BindView(R.id.stateLayout) StateLayout stateLayout;
         @State HashMap<Long, Boolean> toggleMap = new LinkedHashMap<>();
         private IssuePullsTimelineAdapter adapter;
    -    private OnLoadMore onLoadMore;
    +    private OnLoadMore<Issue> onLoadMore;
    +    private IssuePagerMvp.IssuePrCallback<Issue> issueCallback;
     
    -    public static IssueTimelineFragment newInstance(@NonNull Issue issueModel) {
    -        IssueTimelineFragment view = new IssueTimelineFragment();
    -        view.setArguments(Bundler.start().put(BundleConstant.ITEM, issueModel).end());//TODO fix this
    -        return view;
    +    @NonNull public static IssueTimelineFragment newInstance() {
    +        return new IssueTimelineFragment();
    +    }
    +
    +    @SuppressWarnings("unchecked") @Override public void onAttach(Context context) {
    +        super.onAttach(context);
    +        if (getParentFragment() instanceof IssuePagerMvp.IssuePrCallback) {
    +            issueCallback = (IssuePagerMvp.IssuePrCallback) getParentFragment();
    +        } else if (context instanceof IssuePagerMvp.IssuePrCallback) {
    +            issueCallback = (IssuePagerMvp.IssuePrCallback) context;
    +        } else {
    +            throw new IllegalArgumentException(String.format("%s or parent fragment must implement IssuePagerMvp.IssuePrCallback", context.getClass()
    +                    .getSimpleName()));
    +        }
    +    }
    +
    +    @Override public void onDetach() {
    +        issueCallback = null;
    +        super.onDetach();
         }
     
         @Override public void onRefresh() {
    -        getPresenter().onCallApi(1, null);
    +        getPresenter().onCallApi(1, getIssue());
         }
     
         @Override public void onNotifyAdapter(@Nullable List<TimelineModel> items, int page) {
    @@ -69,17 +87,16 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
                 return;
             }
             if (page == 1) {
    -            items.add(0, TimelineModel.constructHeader(getPresenter().getIssue()));
    -            adapter.insertItems(items);
    -        } else {
    -            adapter.addItems(items);
    +            adapter.subList(1, adapter.getItemCount());
             }
    +        adapter.addItems(items);
         }
     
    -    @SuppressWarnings("unchecked") @NonNull @Override public OnLoadMore getLoadMore() {
    +    @NonNull @Override public OnLoadMore<Issue> getLoadMore() {
             if (onLoadMore == null) {
    -            onLoadMore = new OnLoadMore(getPresenter());
    +            onLoadMore = new OnLoadMore<>(getPresenter());
             }
    +        onLoadMore.setParameter(getIssue());
             return onLoadMore;
         }
     
    @@ -88,22 +105,27 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
         }
     
         @Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    +        if (getIssue() == null) {
    +            throw new NullPointerException("Issue went missing!!!");
    +        }
    +        adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this);
             recycler.setVerticalScrollBarEnabled(false);
             stateLayout.setEmptyText(R.string.no_events);
             recycler.setEmptyView(stateLayout, refresh);
             refresh.setOnRefreshListener(this);
             stateLayout.setOnReloadListener(this);
    -        adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this);
             adapter.setListener(getPresenter());
             recycler.setAdapter(adapter);
    +        fastScroller.setOnLoadMore(getLoadMore());
             fastScroller.setVisibility(View.VISIBLE);
             fastScroller.attachRecyclerView(recycler);
             recycler.addDivider(TimelineCommentsViewHolder.class);
             getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal());
             recycler.addOnScrollListener(getLoadMore());
             if (savedInstanceState == null) {
    -            getPresenter().onFragmentCreated(getArguments());
    -        } else if (getPresenter().getEvents().size() == 1 && !getPresenter().isApiCalled()) {
    +            onSetHeader(TimelineModel.constructHeader(getIssue()));
    +            onRefresh();
    +        } else if (getPresenter().getEvents().isEmpty() || getPresenter().getEvents().size() == 1) {
                 onRefresh();
             }
         }
    @@ -135,12 +157,13 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
         }
     
         @Override public void onEditComment(@NonNull Comment item) {
    +        if (getIssue() == null) return;
             Intent intent = new Intent(getContext(), EditorActivity.class);
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getIssue().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getIssue().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getIssue().getNumber())
                     .put(BundleConstant.EXTRA_FOUR, item.getId())
                     .put(BundleConstant.EXTRA, item.getBody())
                     .put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.EDIT_ISSUE_COMMENT_EXTRA)
    @@ -169,12 +192,13 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
         }
     
         @Override public void onTagUser(@Nullable User user) {
    +        if (getIssue() == null) return;
             Intent intent = new Intent(getContext(), EditorActivity.class);
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getIssue().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getIssue().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getIssue().getNumber())
                     .put(BundleConstant.EXTRA, user != null ? "@" + user.getLogin() : "")
                     .put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
                     .putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
    @@ -184,12 +208,13 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
         }
     
         @Override public void onReply(User user, String message) {
    +        if (getIssue() == null) return;
             Intent intent = new Intent(getContext(), EditorActivity.class);
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getIssue().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getIssue().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getIssue().getNumber())
                     .put(BundleConstant.EXTRA, "@" + user.getLogin())
                     .put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
                     .putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
    @@ -206,14 +231,22 @@ public class IssueTimelineFragment extends BaseFragment<IssueTimelineMvp.View, I
         }
     
         @Override public void onSetHeader(@NonNull TimelineModel timelineModel) {
    -        if (adapter != null && adapter.isEmpty()) {
    -            adapter.addItem(timelineModel, 0);
    +        if (adapter != null) {
    +            if (adapter.isEmpty()) {
    +                adapter.addItem(timelineModel, 0);
    +            } else {
    +                adapter.swapItem(timelineModel, 0);
    +            }
             }
         }
     
    -    @Override public void onRefresh(@NonNull Issue issue) {
    -        getPresenter().onUpdateIssue(issue);
    -        onRefresh();
    +    @Nullable @Override public Issue getIssue() {
    +        return issueCallback.getData();
    +    }
    +
    +    @Override public void onUpdateHeader() {
    +        if (getIssue() == null) return;
    +        onSetHeader(TimelineModel.constructHeader(getIssue()));
         }
     
         @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineMvp.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineMvp.java
    index 89172af1..970069a8 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineMvp.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelineMvp.java
    @@ -32,7 +32,7 @@ public interface IssueTimelineMvp {
     
             void onNotifyAdapter(@Nullable List<TimelineModel> items, int page);
     
    -        @NonNull OnLoadMore getLoadMore();
    +        @NonNull OnLoadMore<Issue> getLoadMore();
     
             void onEditComment(@NonNull Comment item);
     
    @@ -50,32 +50,24 @@ public interface IssueTimelineMvp {
     
             void onSetHeader(@NonNull TimelineModel timelineModel);
     
    -        void onRefresh(@NonNull Issue issue);
    +        @Nullable Issue getIssue();
    +
    +        void onUpdateHeader();
         }
     
         interface Presenter extends BaseMvp.FAPresenter, BaseViewHolder.OnItemClickListener<TimelineModel>,
    -            BaseMvp.PaginationListener {
    +            BaseMvp.PaginationListener<Issue> {
     
             boolean isPreviouslyReacted(long commentId, int vId);
     
             @NonNull ArrayList<TimelineModel> getEvents();
     
    -        void onFragmentCreated(@Nullable Bundle bundle);
    -
             void onWorkOffline();
     
             void onHandleDeletion(@Nullable Bundle bundle);
     
    -        @Nullable String repoId();
    -
    -        @Nullable String login();
    -
    -        int number();
    -
             void onHandleReaction(@IdRes int viewId, long id, @ReactionsProvider.ReactionType int reactionType);
     
             boolean isCallingApi(long id, int vId);
    -
    -        void onUpdateIssue(@NonNull Issue issue);
         }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelinePresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelinePresenter.java
    index f8c0e5da..513e73a7 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelinePresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/issues/issue/details/timeline/IssueTimelinePresenter.java
    @@ -37,7 +37,6 @@ import lombok.Getter;
      */
     
     @Getter public class IssueTimelinePresenter extends BasePresenter<IssueTimelineMvp.View> implements IssueTimelineMvp.Presenter {
    -    @com.evernote.android.state.State Issue issue;
         private ArrayList<TimelineModel> timeline = new ArrayList<>();
         private ReactionsProvider reactionsProvider;
         private int page;
    @@ -51,12 +50,13 @@ import lombok.Getter;
         @Override public void onItemClick(int position, View v, TimelineModel item) {
             if (getView() != null) {
                 if (item.getType() == TimelineModel.COMMENT) {
    -                if (getHeader() == null) return;
    +                if (getView().getIssue() == null) return;
    +                Issue issue = getView().getIssue();
                     if (v.getId() == R.id.commentMenu) {
                         PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
                         popupMenu.inflate(R.menu.comments_menu);
                         String username = Login.getUser().getLogin();
    -                    boolean isOwner = CommentsHelper.isOwner(username, getHeader().getLogin(), item.getComment().getUser().getLogin());
    +                    boolean isOwner = CommentsHelper.isOwner(username, issue.getLogin(), item.getComment().getUser().getLogin());
                         popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
                         popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
                         popupMenu.setOnMenuItemClickListener(item1 -> {
    @@ -113,8 +113,10 @@ import lombok.Getter;
         @Override public void onItemLongClick(int position, View v, TimelineModel item) {
             if (getView() == null) return;
             if (item.getType() == TimelineModel.COMMENT || item.getType() == TimelineModel.HEADER) {
    -            String login = login();
    -            String repoId = repoId();
    +            if (getView().getIssue() == null) return;
    +            Issue issue = getView().getIssue();
    +            String login = issue.getLogin();
    +            String repoId = issue.getRepoId();
                 if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
                     ReactionTypes type = ReactionTypes.get(v.getId());
                     if (type != null) {
    @@ -136,23 +138,6 @@ import lombok.Getter;
             return timeline;
         }
     
    -    @Override protected void onCreate() {
    -        super.onCreate();
    -        if (issue != null && timeline.isEmpty()) {
    -            sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(issue)));
    -            onCallApi(1, null);
    -        }
    -    }
    -
    -    @Override public void onFragmentCreated(@Nullable Bundle bundle) {
    -        if (bundle == null) throw new NullPointerException("Bundle is null?");
    -        issue = bundle.getParcelable(BundleConstant.ITEM);
    -        if (timeline.isEmpty() && issue != null) {
    -            sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(issue)));
    -            onCallApi(1, null);
    -        }
    -    }
    -
         @Override public void onWorkOffline() {
             //TODO
         }
    @@ -161,7 +146,9 @@ import lombok.Getter;
             if (bundle != null) {
                 long commId = bundle.getLong(BundleConstant.EXTRA, 0);
                 if (commId != 0) {
    -                makeRestCall(RestProvider.getIssueService().deleteIssueComment(login(), repoId(), commId),
    +                if (getView() == null || getView().getIssue() == null) return;
    +                Issue issue = getView().getIssue();
    +                makeRestCall(RestProvider.getIssueService().deleteIssueComment(issue.getLogin(), issue.getRepoId(), commId),
                             booleanResponse -> sendToView(view -> {
                                 if (booleanResponse.code() == 204) {
                                     Comment comment = new Comment();
    @@ -175,25 +162,11 @@ import lombok.Getter;
             }
         }
     
    -    @Nullable @Override public String repoId() {
    -        return getHeader() != null ? getHeader().getRepoId() : null;
    -    }
    -
    -    @Nullable @Override public String login() {
    -        return getHeader() != null ? getHeader().getLogin() : null;
    -    }
    -
    -    @Override public int number() {
    -        return getHeader() != null ? getHeader().getNumber() : -1;
    -    }
    -
    -    @Nullable private Issue getHeader() {
    -        return issue;
    -    }
    -
         @Override public void onHandleReaction(int viewId, long id, @ReactionsProvider.ReactionType int reactionType) {
    -        String login = login();
    -        String repoId = repoId();
    +        if (getView() == null || getView().getIssue() == null) return;
    +        Issue issue = getView().getIssue();
    +        String login = issue.getLogin();
    +        String repoId = issue.getRepoId();
             Observable observable = getReactionsProvider().onHandleReaction(viewId, id, login, repoId, reactionType);
             if (observable != null) manageObservable(observable);
         }
    @@ -202,10 +175,6 @@ import lombok.Getter;
             return getReactionsProvider().isCallingApi(id, vId);
         }
     
    -    @Override public void onUpdateIssue(@NonNull Issue issue) {
    -        this.issue = issue;
    -    }
    -
         @NonNull private ReactionsProvider getReactionsProvider() {
             if (reactionsProvider == null) {
                 reactionsProvider = new ReactionsProvider();
    @@ -229,8 +198,8 @@ import lombok.Getter;
             this.previousTotal = previousTotal;
         }
     
    -    @Override public void onCallApi(int page, @Nullable Object parameter) {
    -        if (getHeader() == null) {
    +    @Override public void onCallApi(int page, @Nullable Issue parameter) {
    +        if (parameter == null) {
                 sendToView(BaseMvp.FAView::hideProgress);
                 return;
             }
    @@ -243,19 +212,19 @@ import lombok.Getter;
                 return;
             }
             setCurrentPage(page);
    -        String login = getHeader().getLogin();
    -        String repoID = getHeader().getRepoId();
    -        int number = getHeader().getNumber();
    +        String login = parameter.getLogin();
    +        String repoId = parameter.getRepoId();
    +        int number = parameter.getNumber();
             Observable<List<TimelineModel>> observable;
             if (page > 1) {
    -            observable = RestProvider.getIssueService().getIssueComments(login, repoID, number, page)
    +            observable = RestProvider.getIssueService().getIssueComments(login, repoId, number, page)
                         .map(comments -> {
                             lastPage = comments != null ? comments.getLast() : 0;
                             return TimelineModel.construct(comments != null ? comments.getItems() : null);
                         });
             } else {
    -            observable = Observable.zip(RestProvider.getIssueService().getTimeline(login, repoID, number),
    -                    RestProvider.getIssueService().getIssueComments(login, repoID, number, page),
    +            observable = Observable.zip(RestProvider.getIssueService().getTimeline(login, repoId, number),
    +                    RestProvider.getIssueService().getIssueComments(login, repoId, number, page),
                         (issueEventPageable, commentPageable) -> {
                             lastPage = commentPageable != null ? commentPageable.getLast() : 0;
                             return TimelineModel.construct(commentPageable != null ? commentPageable.getItems() : null,
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerActivity.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerActivity.java
    index b49a550b..8d2cf11a 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerActivity.java
    @@ -13,6 +13,7 @@ import android.view.Menu;
     import android.view.MenuItem;
     import android.view.View;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.FragmentPagerAdapterModel;
     import com.fastaccess.data.dao.LabelModel;
    @@ -49,7 +50,6 @@ import java.util.List;
     
     import butterknife.BindView;
     import butterknife.OnClick;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 10 Dec 2016, 9:23 AM
    @@ -127,7 +127,7 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
             if (savedInstanceState == null) {
                 getPresenter().onActivityCreated(getIntent());
             } else {
    -            if (getPresenter().getPullRequest() != null) onSetupIssue();
    +            if (getPresenter().getPullRequest() != null) onSetupIssue(false);
             }
             startGist.setVisibility(View.GONE);
             forkGist.setVisibility(View.GONE);
    @@ -140,7 +140,11 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
                 if (requestCode == BundleConstant.REQUEST_CODE) {
                     Bundle bundle = data.getExtras();
                     PullRequest pullRequest = bundle.getParcelable(BundleConstant.ITEM);
    -                if (pullRequest != null) getPresenter().onUpdatePullRequest(pullRequest);
    +                if (pullRequest != null) {
    +                    getPresenter().onUpdatePullRequest(pullRequest);
    +                } else {
    +                    getPresenter().onRefresh();
    +                }
                 }
             }
         }
    @@ -241,72 +245,44 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
             return super.onPrepareOptionsMenu(menu);
         }
     
    -    @Override public void onSetupIssue() {
    +    @Override public void onSetupIssue(boolean update) {
             hideProgress();
             if (getPresenter().getPullRequest() == null) {
                 return;
             }
    -        supportInvalidateOptionsMenu();
    +        invalidateOptionsMenu();
             PullRequest pullRequest = getPresenter().getPullRequest();
    -        setTitle(String.format("#%s", pullRequest.getNumber()));
    -        date.setText(String.format("%s\n%s", getPresenter().getMergeBy(pullRequest, getApplicationContext()), pullRequest.getRepoId()));
    -        size.setVisibility(View.GONE);
    -        User userModel = pullRequest.getUser();
    -        if (userModel != null) {
    -            title.setText(SpannableBuilder.builder().append(userModel.getLogin()).append("/").append(pullRequest.getTitle()));
    -            avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
    +        updateViews(pullRequest);
    +        Logger.e(pullRequest.getBodyHtml());
    +        if (update) {
    +            PullRequestTimelineFragment issueDetailsView = (PullRequestTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
    +            if (issueDetailsView != null && getPresenter().getPullRequest() != null) {
    +                issueDetailsView.onUpdateHeader();
    +            }
             } else {
    -            title.setText(SpannableBuilder.builder().append(pullRequest.getTitle()));
    -        }
    -        detailsIcon.setVisibility(InputHelper.isEmpty(pullRequest.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
    -        if (pager.getAdapter() == null) {
    -            pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForPullRequest(this,
    -                    pullRequest)));
    -            tabs.setupWithViewPager(pager);
    -            if (!getPresenter().isLocked() || getPresenter().isOwner()) {
    -                pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    -                    @Override public void onPageSelected(int position) {
    -                        super.onPageSelected(position);
    -
    +            if (pager.getAdapter() == null) {
    +                pager.setAdapter(new FragmentsPagerAdapter(getSupportFragmentManager(), FragmentPagerAdapterModel.buildForPullRequest(this,
    +                        pullRequest)));
    +                tabs.setupWithViewPager(pager);
    +                tabs.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager) {
    +                    @Override public void onTabReselected(TabLayout.Tab tab) {
    +                        super.onTabReselected(tab);
    +                        onScrollTop(tab.getPosition());
                         }
                     });
    +            } else {
    +                onUpdateTimeline();
                 }
    -            tabs.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager) {
    -                @Override public void onTabReselected(TabLayout.Tab tab) {
    -                    super.onTabReselected(tab);
    -                    onScrollTop(tab.getPosition());
    +        }
    +        if (!getPresenter().isLocked() || getPresenter().isOwner()) {
    +            pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    +                @Override public void onPageSelected(int position) {
    +                    super.onPageSelected(position);
    +
                     }
                 });
    -            if (tabs.getTabAt(2) != null) {
    -                tabs.getTabAt(2)
    -                        .setText(SpannableBuilder.builder()
    -                                .append(getString(R.string.files))
    -                                .append(" ")
    -                                .append("(")
    -                                .append(String.valueOf(pullRequest.getChangedFiles()))
    -                                .append(")"));
    -            }
    -            if (tabs.getTabAt(1) != null) {
    -                tabs.getTabAt(1)
    -                        .setText(SpannableBuilder.builder()
    -                                .append(getString(R.string.commits))
    -                                .append(" ")
    -                                .append("(")
    -                                .append(String.valueOf(pullRequest.getCommits()))
    -                                .append(")"));
    -            }
    -            if (tabs.getTabAt(0) != null) {
    -                tabs.getTabAt(0)
    -                        .setText(SpannableBuilder.builder()
    -                                .append(getString(R.string.details))
    -                                .append(" ")
    -                                .append("(")
    -                                .append(String.valueOf(pullRequest.getComments()))
    -                                .append(")"));
    -            }
    -        } else {
    -            onUpdateTimeline();
             }
    +        initTabs(pullRequest);
             hideShowFab();
         }
     
    @@ -332,10 +308,6 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
                     .show(getSupportFragmentManager(), "LabelsDialogFragment");
         }
     
    -    @Override public void onUpdateMenu() {
    -        supportInvalidateOptionsMenu();
    -    }
    -
         @Override public void onSelectedLabels(@NonNull ArrayList<LabelModel> labels) {
             Logger.e(labels, labels.size());
             getPresenter().onPutLabels(labels);
    @@ -364,10 +336,9 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
         }
     
         @Override public void onUpdateTimeline() {
    -        showMessage(R.string.success, R.string.labels_added_successfully);
             PullRequestTimelineFragment pullRequestDetailsView = (PullRequestTimelineFragment) pager.getAdapter().instantiateItem(pager, 0);
             if (pullRequestDetailsView != null && getPresenter().getPullRequest() != null) {
    -            pullRequestDetailsView.onRefresh(getPresenter().getPullRequest());
    +            pullRequestDetailsView.onRefresh();
             }
         }
     
    @@ -404,6 +375,56 @@ public class PullRequestPagerActivity extends BaseActivity<PullRequestPagerMvp.V
             getPresenter().onPutAssignees(users, isAssignees);
         }
     
    +    @Nullable @Override public PullRequest getData() {
    +        return getPresenter().getPullRequest();
    +    }
    +
    +    private void initTabs(@NonNull PullRequest pullRequest) {
    +        TabLayout.Tab tab1 = tabs.getTabAt(0);
    +        TabLayout.Tab tab2 = tabs.getTabAt(1);
    +        TabLayout.Tab tab3 = tabs.getTabAt(2);
    +        if (tab3 != null) {
    +            tab3.setText(SpannableBuilder.builder()
    +                    .append(getString(R.string.files))
    +                    .append(" ")
    +                    .append("(")
    +                    .append(String.valueOf(pullRequest.getChangedFiles()))
    +                    .append(")"));
    +        }
    +        if (tab2 != null) {
    +            tab2.setText(SpannableBuilder.builder()
    +                    .append(getString(R.string.commits))
    +                    .append(" ")
    +                    .append("(")
    +                    .append(String.valueOf(pullRequest.getCommits()))
    +                    .append(")"));
    +        }
    +        if (tab1 != null) {
    +            tab1.setText(SpannableBuilder.builder()
    +                    .append(getString(R.string.details))
    +                    .append(" ")
    +                    .append("(")
    +                    .append(String.valueOf(pullRequest.getComments()))
    +                    .append(")"));
    +        }
    +    }
    +
    +    private void updateViews(@NonNull PullRequest pullRequest) {
    +        setTitle(String.format("#%s", pullRequest.getNumber()));
    +        date.setText(SpannableBuilder.builder().append(getPresenter().getMergeBy(pullRequest, getApplicationContext()))
    +                .append(" ")
    +                .bold(pullRequest.getRepoId()));
    +        size.setVisibility(View.GONE);
    +        User userModel = pullRequest.getUser();
    +        if (userModel != null) {
    +            title.setText(SpannableBuilder.builder().append(userModel.getLogin()).append("/").append(pullRequest.getTitle()));
    +            avatarLayout.setUrl(userModel.getAvatarUrl(), userModel.getLogin());
    +        } else {
    +            title.setText(SpannableBuilder.builder().append(pullRequest.getTitle()));
    +        }
    +        detailsIcon.setVisibility(InputHelper.isEmpty(pullRequest.getTitle()) || !ViewHelper.isEllipsed(title) ? View.GONE : View.VISIBLE);
    +    }
    +
         private void hideShowFab() {
             if (getPresenter().isLocked() && !getPresenter().isOwner()) {
                 fab.hide();
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerMvp.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerMvp.java
    index 961d315c..85af2a09 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerMvp.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerMvp.java
    @@ -13,6 +13,7 @@ import com.fastaccess.data.dao.model.User;
     import com.fastaccess.ui.base.mvp.BaseMvp;
     import com.fastaccess.ui.modules.repos.extras.assignees.AssigneesMvp;
     import com.fastaccess.ui.modules.repos.extras.labels.LabelsMvp;
    +import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerMvp;
     import com.fastaccess.ui.modules.repos.pull_requests.pull_request.merge.MergePullReqeustMvp;
     import com.fastaccess.ui.widgets.SpannableBuilder;
     
    @@ -26,14 +27,13 @@ import java.util.List;
     public interface PullRequestPagerMvp {
     
         interface View extends BaseMvp.FAView, LabelsMvp.SelectedLabelsListener,
    -            AssigneesMvp.SelectedAssigneesListener, MergePullReqeustMvp.MergeCallback {
    +            AssigneesMvp.SelectedAssigneesListener, MergePullReqeustMvp.MergeCallback,
    +            IssuePagerMvp.IssuePrCallback<PullRequest> {
     
    -        void onSetupIssue();
    +        void onSetupIssue(boolean update);
     
             void onLabelsRetrieved(@NonNull List<LabelModel> items);
     
    -        void onUpdateMenu();
    -
             void showSuccessIssueActionMsg(boolean isClose);
     
             void showErrorIssueActionMsg(boolean isClose);
    @@ -88,6 +88,8 @@ public interface PullRequestPagerMvp {
             boolean isCollaborator();
     
             void onUpdatePullRequest(@NonNull PullRequest pullRequestModel);
    +
    +        void onRefresh();
         }
     
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java
    index 5fe17e59..696478de 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/PullRequestPagerPresenter.java
    @@ -67,33 +67,14 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                 repoId = intent.getExtras().getString(BundleConstant.EXTRA_TWO);
                 showToRepoBtn = intent.getExtras().getBoolean(BundleConstant.EXTRA_THREE);
                 if (pullRequest != null) {
    -                sendToView(PullRequestPagerMvp.View::onSetupIssue);
    +                sendToView(view -> view.onSetupIssue(false));
                     return;
                 } else if (issueNumber > 0 && !InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
    -                makeRestCall(RestProvider.getPullRequestService()
    -                        .getPullRequest(login, repoId, issueNumber)
    -                        .flatMap(pullRequest1 -> RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
    -                                (pullRequest1, booleanResponse) -> {
    -                                    isCollaborator = booleanResponse.code() == 204;
    -                                    return pullRequest1;
    -                                })
    -                        .flatMap(pullRequest1 -> RestProvider.getIssueService().getIssue(login, repoId, issueNumber),
    -                                (pullRequest1, issue) -> {//hack to get reactions from issue api
    -                                    if (issue != null) {
    -                                        pullRequest1.setReactions(issue.getReactions());
    -                                    }
    -                                    return pullRequest1;
    -                                }), pullRequestModelResponse -> {
    -                    pullRequest = pullRequestModelResponse;
    -                    pullRequest.setRepoId(repoId);
    -                    pullRequest.setLogin(login);
    -                    sendToView(PullRequestPagerMvp.View::onSetupIssue);
    -                    manageObservable(pullRequest.save(pullRequest).toObservable());
    -                });
    +                callApi();
                     return;
                 }
             }
    -        sendToView(PullRequestPagerMvp.View::onSetupIssue);
    +        sendToView(view -> view.onSetupIssue(false));
         }
     
         @Override public void onWorkOffline() {
    @@ -102,7 +83,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                         .subscribe(pullRequestModel -> {
                             if (pullRequestModel != null) {
                                 pullRequest = pullRequestModel;
    -                            sendToView(PullRequestPagerMvp.View::onSetupIssue);
    +                            sendToView(view -> view.onSetupIssue(false));
                             }
                         }));
             }
    @@ -158,7 +139,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                 int code = booleanResponse.code();
                 if (code == 204) {
                     pullRequest.setLocked(!isLocked());
    -                sendToView(PullRequestPagerMvp.View::onSetupIssue);
    +                sendToView(view -> view.onSetupIssue(false));
                 }
             });
         }
    @@ -175,7 +156,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                                 issue.setRepoId(getPullRequest().getRepoId());
                                 issue.setLogin(getPullRequest().getLogin());
                                 pullRequest = issue;
    -                            sendToView(PullRequestPagerMvp.View::onSetupIssue);
    +                            sendToView(view -> view.onSetupIssue(false));
                             }
                         }, throwable -> sendToView(view -> view.showErrorIssueActionMsg(getPullRequest().getState() == IssueState.open))));
             }
    @@ -195,9 +176,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                                 } else {
                                     sendToView(view -> view.showMessage(R.string.error, R.string.no_labels));
                                 }
    -                        }, throwable -> {
    -                            sendToView(view -> view.showMessage(R.string.error, R.string.no_labels));
    -                        })
    +                        }, throwable -> sendToView(view -> view.showMessage(R.string.error, R.string.no_labels)))
             );
         }
     
    @@ -206,7 +185,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                     Stream.of(labels).filter(value -> value != null && value.getName() != null)
                             .map(LabelModel::getName).collect(Collectors.toList())),
                     labelModels -> {
    -                    sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
    +                    sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
                         LabelListModel listModel = new LabelListModel();
                         listModel.addAll(labels);
                         pullRequest.setLabels(listModel);
    @@ -223,7 +202,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                         pullRequest.setLogin(login);
                         pullRequest.setRepoId(repoId);
                         manageObservable(pr.save(pullRequest).toObservable());
    -                    sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
    +                    sendToView(view -> updateTimeline(view, R.string.labels_added_successfully));
                     });
     
         }
    @@ -244,13 +223,13 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                             assignee.addAll(users);
                             pullRequest.setAssignees(assignee);
                             manageObservable(pullRequest.save(pullRequest).toObservable());
    -                        sendToView(PullRequestPagerMvp.View::onUpdateTimeline);
    +                        sendToView(view -> updateTimeline(view, R.string.assignee_added));
                         }
                 );
             } else {
                 assigneesRequestModel.setReviewers(assignees);
                 makeRestCall(RestProvider.getPullRequestService().putReviewers(login, repoId, issueNumber, assigneesRequestModel),
    -                    pullRequestResponse -> sendToView(PullRequestPagerMvp.View::onUpdateTimeline)
    +                    pullRequestResponse -> sendToView(view -> updateTimeline(view, R.string.reviewer_added))
                 );
             }
         }
    @@ -266,10 +245,7 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
                                 .doOnSubscribe(disposable -> sendToView(view -> view.showProgress(0)))
                                 .subscribe(mergeResponseModel -> {
                                     if (mergeResponseModel.isMerged()) {
    -                                    sendToView(view -> {
    -                                        view.showMessage(R.string.success, R.string.success_merge);
    -                                        view.onUpdateTimeline();
    -                                    });
    +                                    sendToView(view -> updateTimeline(view, R.string.success_merge));
                                     } else {
                                         sendToView(view -> view.showErrorMessage(mergeResponseModel.getMessage()));
                                     }
    @@ -291,10 +267,44 @@ class PullRequestPagerPresenter extends BasePresenter<PullRequestPagerMvp.View>
         }
     
         @Override public void onUpdatePullRequest(@NonNull PullRequest pullRequestModel) {
    -        this.pullRequest = pullRequestModel;
    +        this.pullRequest.setTitle(pullRequestModel.getTitle());
    +        this.pullRequest.setBody(pullRequestModel.getBody());
    +        this.pullRequest.setBodyHtml(pullRequestModel.getBodyHtml());
             this.pullRequest.setLogin(login);
             this.pullRequest.setRepoId(repoId);
             manageObservable(pullRequest.save(pullRequest).toObservable());
    -        sendToView(PullRequestPagerMvp.View::onSetupIssue);
    +        sendToView(view -> view.onSetupIssue(true));
    +    }
    +
    +    @Override public void onRefresh() {
    +        callApi();
    +    }
    +
    +    private void callApi() {
    +        makeRestCall(RxHelper.getObserver(Observable.zip(RestProvider.getPullRequestService()
    +                        .getPullRequest(login, repoId, issueNumber),
    +                RestProvider.getRepoService().isCollaborator(login, repoId, Login.getUser().getLogin()),
    +                RestProvider.getIssueService().getIssue(login, repoId, issueNumber),
    +                (pullRequestModel, booleanResponse, issue) -> {
    +                    this.pullRequest = pullRequestModel;
    +                    if (issue != null) {
    +                        this.pullRequest.setReactions(issue.getReactions());
    +                        this.pullRequest.setTitle(issue.getTitle());
    +                        this.pullRequest.setBody(issue.getBody());
    +                        this.pullRequest.setBodyHtml(issue.getBodyHtml());
    +                    }
    +                    this.pullRequest.setLogin(login);
    +                    this.pullRequest.setRepoId(repoId);
    +                    isCollaborator = booleanResponse.code() == 204;
    +                    return pullRequest;
    +                })), pullRequest -> {
    +            sendToView(view -> view.onSetupIssue(false));
    +            manageObservable(pullRequest.save(pullRequest).toObservable());
    +        });
    +    }
    +
    +    private void updateTimeline(PullRequestPagerMvp.View view, int assignee_added) {
    +        view.showMessage(R.string.success, assignee_added);
    +        view.onUpdateTimeline();
         }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineFragment.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineFragment.java
    index cd27b7af..af60956e 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineFragment.java
    @@ -1,6 +1,7 @@
     package com.fastaccess.ui.modules.repos.pull_requests.pull_request.details.timeline.timeline;
     
     import android.app.Activity;
    +import android.content.Context;
     import android.content.Intent;
     import android.os.Bundle;
     import android.support.annotation.NonNull;
    @@ -8,6 +9,7 @@ import android.support.annotation.Nullable;
     import android.support.annotation.StringRes;
     import android.view.View;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.EditReviewCommentModel;
     import com.fastaccess.data.dao.ReviewCommentModel;
    @@ -25,6 +27,7 @@ import com.fastaccess.ui.adapter.IssuePullsTimelineAdapter;
     import com.fastaccess.ui.adapter.viewholder.TimelineCommentsViewHolder;
     import com.fastaccess.ui.base.BaseFragment;
     import com.fastaccess.ui.modules.editor.EditorActivity;
    +import com.fastaccess.ui.modules.repos.issues.issue.details.IssuePagerMvp;
     import com.fastaccess.ui.modules.repos.reactions.ReactionsDialogFragment;
     import com.fastaccess.ui.widgets.AppbarRefreshLayout;
     import com.fastaccess.ui.widgets.StateLayout;
    @@ -37,7 +40,6 @@ import java.util.LinkedHashMap;
     import java.util.List;
     
     import butterknife.BindView;
    -import com.evernote.android.state.State;
     
     /**
      * Created by Kosh on 31 Mar 2017, 7:35 PM
    @@ -52,16 +54,33 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
         @BindView(R.id.stateLayout) StateLayout stateLayout;
         @State HashMap<Long, Boolean> toggleMap = new LinkedHashMap<>();
         private IssuePullsTimelineAdapter adapter;
    -    private OnLoadMore onLoadMore;
    +    private OnLoadMore<PullRequest> onLoadMore;
     
    -    public static PullRequestTimelineFragment newInstance(@NonNull PullRequest pullRequest) {
    -        PullRequestTimelineFragment view = new PullRequestTimelineFragment();
    -        view.setArguments(Bundler.start().put(BundleConstant.ITEM, pullRequest).end());//TODO fix this
    -        return view;
    +    private IssuePagerMvp.IssuePrCallback<PullRequest> issueCallback;
    +
    +    @NonNull public static PullRequestTimelineFragment newInstance() {
    +        return new PullRequestTimelineFragment();
    +    }
    +
    +    @SuppressWarnings("unchecked") @Override public void onAttach(Context context) {
    +        super.onAttach(context);
    +        if (getParentFragment() instanceof IssuePagerMvp.IssuePrCallback) {
    +            issueCallback = (IssuePagerMvp.IssuePrCallback) getParentFragment();
    +        } else if (context instanceof IssuePagerMvp.IssuePrCallback) {
    +            issueCallback = (IssuePagerMvp.IssuePrCallback) context;
    +        } else {
    +            throw new IllegalArgumentException(String.format("%s or parent fragment must implement IssuePagerMvp.IssuePrCallback", context.getClass()
    +                    .getSimpleName()));
    +        }
    +    }
    +
    +    @Override public void onDetach() {
    +        issueCallback = null;
    +        super.onDetach();
         }
     
         @Override public void onRefresh() {
    -        getPresenter().onCallApi(1, null);
    +        getPresenter().onCallApi(1, getPullRequest());
         }
     
         @Override protected int fragmentLayout() {
    @@ -69,24 +88,28 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
         }
     
         @Override protected void onFragmentCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    +        if (getPullRequest() == null) {
    +            throw new NullPointerException("PullRequest went missing!!!");
    +        }
    +        boolean isMerged = getPresenter().isMerged(getPullRequest());
    +        adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this, isMerged, getPresenter());
             recycler.setVerticalScrollBarEnabled(false);
    -        getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal());
    -        recycler.addOnScrollListener(getLoadMore());
             stateLayout.setEmptyText(R.string.no_events);
             recycler.setEmptyView(stateLayout, refresh);
             refresh.setOnRefreshListener(this);
             stateLayout.setOnReloadListener(this);
    -        boolean isMerged = getPresenter().isMerged();
    -        adapter = new IssuePullsTimelineAdapter(getPresenter().getEvents(), this, true, this,
    -                isMerged, getPresenter());
             adapter.setListener(getPresenter());
    +        recycler.setAdapter(adapter);
    +        fastScroller.setOnLoadMore(getLoadMore());
             fastScroller.setVisibility(View.VISIBLE);
             fastScroller.attachRecyclerView(recycler);
    -        recycler.setAdapter(adapter);
             recycler.addDivider(TimelineCommentsViewHolder.class);
    +        getLoadMore().setCurrent_page(getPresenter().getCurrentPage(), getPresenter().getPreviousTotal());
    +        recycler.addOnScrollListener(getLoadMore());
             if (savedInstanceState == null) {
    -            getPresenter().onFragmentCreated(getArguments());
    -        } else if (getPresenter().getEvents().size() == 1 && !getPresenter().isApiCalled()) {
    +            onSetHeader(TimelineModel.constructHeader(getPullRequest()));
    +            onRefresh();
    +        } else if (getPresenter().getEvents().isEmpty() || getPresenter().getEvents().size() == 1) {
                 onRefresh();
             }
         }
    @@ -134,27 +157,27 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
                 return;
             }
             if (page == 1) {
    -            items.add(0, TimelineModel.constructHeader(getPresenter().pullRequest));
    -            adapter.insertItems(items);
    -        } else {
    -            adapter.addItems(items);
    +            adapter.subList(1, adapter.getItemCount());
             }
    +        adapter.addItems(items);
         }
     
    -    @SuppressWarnings("unchecked") @NonNull @Override public OnLoadMore getLoadMore() {
    +    @NonNull @Override public OnLoadMore<PullRequest> getLoadMore() {
             if (onLoadMore == null) {
    -            onLoadMore = new OnLoadMore(getPresenter());
    +            onLoadMore = new OnLoadMore<>(getPresenter());
             }
    +        onLoadMore.setParameter(getPullRequest());
             return onLoadMore;
         }
     
         @Override public void onEditComment(@NonNull Comment item) {
             Intent intent = new Intent(getContext(), EditorActivity.class);
    +        if (getPullRequest() == null) return;
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getPullRequest().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
                     .put(BundleConstant.EXTRA_FOUR, item.getId())
                     .put(BundleConstant.EXTRA, item.getBody())
                     .put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.EDIT_ISSUE_COMMENT_EXTRA)
    @@ -170,11 +193,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
             model.setGroupPosition(groupPosition);
             model.setInReplyTo(item.getId());
             Intent intent = new Intent(getContext(), EditorActivity.class);
    +        if (getPullRequest() == null) return;
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getPullRequest().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
                     .put(BundleConstant.EXTRA_FOUR, item.getId())
                     .put(BundleConstant.EXTRA, item.getBody())
                     .put(BundleConstant.REVIEW_EXTRA, model)
    @@ -192,11 +216,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
     
         @Override public void onStartNewComment() {
             Intent intent = new Intent(getContext(), EditorActivity.class);
    +        if (getPullRequest() == null) return;
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getPullRequest().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
                     .put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
                     .putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
                     .end());
    @@ -215,11 +240,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
     
         @Override public void onReply(User user, String message) {
             Intent intent = new Intent(getContext(), EditorActivity.class);
    +        if (getPullRequest() == null) return;
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getPullRequest().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
                     .put(BundleConstant.EXTRA, "@" + user.getLogin())
                     .put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_ISSUE_COMMENT_EXTRA)
                     .putStringArrayList("participants", CommentsHelper.getUsersByTimeline(adapter.getData()))
    @@ -232,11 +258,12 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
         @Override public void onReplyOrCreateReview(@Nullable User user, String message, int groupPosition, int childPosition,
                                                     @NonNull EditReviewCommentModel model) {
             Intent intent = new Intent(getContext(), EditorActivity.class);
    +        if (getPullRequest() == null) return;
             intent.putExtras(Bundler
                     .start()
    -                .put(BundleConstant.ID, getPresenter().repoId())
    -                .put(BundleConstant.EXTRA_TWO, getPresenter().login())
    -                .put(BundleConstant.EXTRA_THREE, getPresenter().number())
    +                .put(BundleConstant.ID, getPullRequest().getRepoId())
    +                .put(BundleConstant.EXTRA_TWO, getPullRequest().getLogin())
    +                .put(BundleConstant.EXTRA_THREE, getPullRequest().getNumber())
                     .put(BundleConstant.EXTRA, user != null ? "@" + user.getLogin() : "")
                     .put(BundleConstant.REVIEW_EXTRA, model)
                     .put(BundleConstant.EXTRA_TYPE, BundleConstant.ExtraTYpe.NEW_REVIEW_COMMENT_EXTRA)
    @@ -279,14 +306,22 @@ public class PullRequestTimelineFragment extends BaseFragment<PullRequestTimelin
         }
     
         @Override public void onSetHeader(@NonNull TimelineModel timelineModel) {
    -        if (adapter != null && adapter.isEmpty()) {
    -            adapter.addItem(timelineModel, 0);
    +        if (adapter != null) {
    +            if (adapter.isEmpty()) {
    +                adapter.addItem(timelineModel, 0);
    +            } else {
    +                adapter.swapItem(timelineModel, 0);
    +            }
             }
         }
     
    -    @Override public void onRefresh(@NonNull PullRequest pullRequest) {
    -        getPresenter().onUpdatePullRequest(pullRequest);
    -        onRefresh();
    +    @Nullable @Override public PullRequest getPullRequest() {
    +        return issueCallback.getData();
    +    }
    +
    +    @Override public void onUpdateHeader() {
    +        if (getPullRequest() == null) return;
    +        onSetHeader(TimelineModel.constructHeader(getPullRequest()));
         }
     
         @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineMvp.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineMvp.java
    index c958ec8c..0ccfaed3 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineMvp.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelineMvp.java
    @@ -40,7 +40,7 @@ public interface PullRequestTimelineMvp {
     
             void onNotifyAdapter(@Nullable List<TimelineModel> items, int page);
     
    -        @NonNull OnLoadMore getLoadMore();
    +        @NonNull OnLoadMore<PullRequest> getLoadMore();
     
             void onEditComment(@NonNull Comment item);
     
    @@ -66,34 +66,26 @@ public interface PullRequestTimelineMvp {
     
             void onSetHeader(@NonNull TimelineModel timelineModel);
     
    -        void onRefresh(@NonNull PullRequest pullRequest);
    +        @Nullable PullRequest getPullRequest();
    +
    +        void onUpdateHeader();
         }
     
         interface Presenter extends BaseMvp.FAPresenter, BaseViewHolder.OnItemClickListener<TimelineModel>,
    -            ReviewCommentCallback, BaseMvp.PaginationListener {
    +            ReviewCommentCallback, BaseMvp.PaginationListener<PullRequest> {
     
             @NonNull ArrayList<TimelineModel> getEvents();
     
    -        void onFragmentCreated(@Nullable Bundle bundle);
    -
             void onWorkOffline();
     
             void onHandleDeletion(@Nullable Bundle bundle);
     
    -        @Nullable String repoId();
    -
    -        @Nullable String login();
    -
    -        int number();
    -
             boolean isPreviouslyReacted(long commentId, int vId);
     
             void onHandleReaction(@IdRes int vId, long idOrNumber, @ReactionsProvider.ReactionType int reactionType);
     
    -        boolean isMerged();
    +        boolean isMerged(PullRequest pullRequest);
     
             boolean isCallingApi(long id, int vId);
    -
    -        void onUpdatePullRequest(@NonNull PullRequest pullRequest);
         }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelinePresenter.java b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelinePresenter.java
    index 1a03c564..ca89fca3 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelinePresenter.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/repos/pull_requests/pull_request/details/timeline/timeline/PullRequestTimelinePresenter.java
    @@ -41,20 +41,19 @@ import io.reactivex.Observable;
     public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimelineMvp.View> implements PullRequestTimelineMvp.Presenter {
         private ArrayList<TimelineModel> timeline = new ArrayList<>();
         private ReactionsProvider reactionsProvider;
    -    @com.evernote.android.state.State PullRequest pullRequest;
         private int page;
         private int previousTotal;
         private int lastPage = Integer.MAX_VALUE;
     
         @Override public void onItemClick(int position, View v, TimelineModel item) {
    -        if (getView() != null) {
    +        if (getView() != null && getView().getPullRequest() != null) {
                 if (item.getType() == TimelineModel.COMMENT) {
    -                if (getHeader() == null) return;
    +                PullRequest pullRequest = getView().getPullRequest();
                     if (v.getId() == R.id.commentMenu) {
                         PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
                         popupMenu.inflate(R.menu.comments_menu);
                         String username = Login.getUser().getLogin();
    -                    boolean isOwner = CommentsHelper.isOwner(username, getHeader().getLogin(), item.getComment().getUser().getLogin());
    +                    boolean isOwner = CommentsHelper.isOwner(username, pullRequest.getLogin(), item.getComment().getUser().getLogin());
                         popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
                         popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
                         popupMenu.setOnMenuItemClickListener(item1 -> {
    @@ -119,10 +118,11 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
         }
     
         @Override public void onItemLongClick(int position, View v, TimelineModel item) {
    -        if (getView() == null) return;
    +        if (getView() == null || getView().getPullRequest() == null) return;
             if (item.getType() == TimelineModel.COMMENT || item.getType() == TimelineModel.HEADER) {
    -            String login = login();
    -            String repoId = repoId();
    +            PullRequest pullRequest = getView().getPullRequest();
    +            String login = pullRequest.getLogin();
    +            String repoId = pullRequest.getRepoId();
                 if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
                     ReactionTypes type = ReactionTypes.get(v.getId());
                     if (type != null) {
    @@ -144,37 +144,20 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
             return timeline;
         }
     
    -    @Override protected void onCreate() {
    -        super.onCreate();
    -        if (pullRequest != null && timeline.isEmpty()) {
    -            sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(pullRequest)));
    -            onCallApi(1, null);
    -        }
    -    }
    -
    -    @Override public void onFragmentCreated(@Nullable Bundle bundle) {
    -        if (bundle == null) throw new NullPointerException("Bundle is null?");
    -        pullRequest = bundle.getParcelable(BundleConstant.ITEM);
    -        if (timeline.isEmpty() && pullRequest != null) {
    -            sendToView(view -> view.onSetHeader(TimelineModel.constructHeader(pullRequest)));
    -            onCallApi(1, null);
    -        }
    -    }
    -
         @Override public void onWorkOffline() {
             //TODO
         }
     
    -    @Nullable private PullRequest getHeader() {
    -        return pullRequest;
    -    }
    -
         @Override public void onHandleDeletion(@Nullable Bundle bundle) {
    +        if (getView() == null || getView().getPullRequest() == null) return;
             if (bundle != null) {
    +            PullRequest pullRequest = getView().getPullRequest();
    +            String login = pullRequest.getLogin();
    +            String repoId = pullRequest.getRepoId();
                 long commId = bundle.getLong(BundleConstant.EXTRA, 0);
                 boolean isReviewComment = bundle.getBoolean(BundleConstant.YES_NO_EXTRA);
                 if (commId != 0 && !isReviewComment) {
    -                makeRestCall(RestProvider.getIssueService().deleteIssueComment(login(), repoId(), commId),
    +                makeRestCall(RestProvider.getIssueService().deleteIssueComment(login, repoId, commId),
                             booleanResponse -> sendToView(view -> {
                                 if (booleanResponse.code() == 204) {
                                     Comment comment = new Comment();
    @@ -187,7 +170,7 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
                 } else {
                     int groupPosition = bundle.getInt(BundleConstant.EXTRA_TWO);
                     int commentPosition = bundle.getInt(BundleConstant.EXTRA_THREE);
    -                makeRestCall(RestProvider.getReviewService().deleteComment(login(), repoId(), commId),
    +                makeRestCall(RestProvider.getReviewService().deleteComment(login, repoId, commId),
                             booleanResponse -> sendToView(view -> {
                                 if (booleanResponse.code() == 204) {
                                     view.onRemoveReviewComment(groupPosition, commentPosition);
    @@ -199,38 +182,24 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
             }
         }
     
    -    @Nullable @Override public String repoId() {
    -        return getHeader() != null ? getHeader().getRepoId() : null;
    -    }
    -
    -    @Nullable @Override public String login() {
    -        return getHeader() != null ? getHeader().getLogin() : null;
    -    }
    -
    -    @Override public int number() {
    -        return getHeader() != null ? getHeader().getNumber() : -1;
    -    }
    -
         @Override public void onHandleReaction(int vId, long idOrNumber, @ReactionsProvider.ReactionType int reactionType) {
    -        String login = login();
    -        String repoId = repoId();
    +        if (getView() == null || getView().getPullRequest() == null) return;
    +        PullRequest pullRequest = getView().getPullRequest();
    +        String login = pullRequest.getLogin();
    +        String repoId = pullRequest.getRepoId();
             Observable observable = getReactionsProvider().onHandleReaction(vId, idOrNumber, login, repoId, reactionType);
             if (observable != null) //noinspection unchecked
                 manageObservable(observable);
         }
     
    -    @Override public boolean isMerged() {
    -        return getHeader() != null && (getHeader().isMerged() || !InputHelper.isEmpty(getHeader().getMergedAt()));
    +    @Override public boolean isMerged(PullRequest pullRequest) {
    +        return pullRequest != null && (pullRequest.isMerged() || !InputHelper.isEmpty(pullRequest.getMergedAt()));
         }
     
         @Override public boolean isCallingApi(long id, int vId) {
             return getReactionsProvider().isCallingApi(id, vId);
         }
     
    -    @Override public void onUpdatePullRequest(@NonNull PullRequest pullRequest) {
    -        this.pullRequest = pullRequest;
    -    }
    -
         @Override public boolean isPreviouslyReacted(long commentId, int vId) {
             return getReactionsProvider().isPreviouslyReacted(commentId, vId);
         }
    @@ -243,12 +212,12 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
         }
     
         @Override public void onClick(int groupPosition, int commentPosition, @NonNull View v, @NonNull ReviewCommentModel comment) {
    -        if (getHeader() == null || getView() == null) return;
    +        if (getView() == null || getView().getPullRequest() == null) return;
             if (v.getId() == R.id.commentMenu) {
                 PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
                 popupMenu.inflate(R.menu.comments_menu);
                 String username = Login.getUser().getLogin();
    -            boolean isOwner = CommentsHelper.isOwner(username, getHeader().getLogin(), comment.getUser().getLogin());
    +            boolean isOwner = CommentsHelper.isOwner(username, getView().getPullRequest().getLogin(), comment.getUser().getLogin());
                 popupMenu.getMenu().findItem(R.id.delete).setVisible(isOwner);
                 popupMenu.getMenu().findItem(R.id.edit).setVisible(isOwner);
                 popupMenu.setOnMenuItemClickListener(item1 -> {
    @@ -275,9 +244,10 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
         }
     
         @Override public void onLongClick(int groupPosition, int commentPosition, @NonNull View v, @NonNull ReviewCommentModel model) {
    -        if (getView() == null) return;
    -        String login = login();
    -        String repoId = repoId();
    +        if (getView() == null || getView().getPullRequest() == null) return;
    +        PullRequest pullRequest = getView().getPullRequest();
    +        String login = pullRequest.getLogin();
    +        String repoId = pullRequest.getRepoId();
             if (!InputHelper.isEmpty(login) && !InputHelper.isEmpty(repoId)) {
                 ReactionTypes type = ReactionTypes.get(v.getId());
                 if (type != null) {
    @@ -304,14 +274,14 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
             this.previousTotal = previousTotal;
         }
     
    -    @Override public void onCallApi(int page, @Nullable Object parameter) {
    -        if (getHeader() == null) {
    +    @Override public void onCallApi(int page, @Nullable PullRequest parameter) {
    +        if (parameter == null) {
                 sendToView(BaseMvp.FAView::hideProgress);
                 return;
             }
    -        String login = getHeader().getLogin();
    -        String repoId = getHeader().getRepoId();
    -        int number = getHeader().getNumber();
    +        String login = parameter.getLogin();
    +        String repoId = parameter.getRepoId();
    +        int number = parameter.getNumber();
             if (page <= 1) {
                 lastPage = Integer.MAX_VALUE;
                 sendToView(view -> view.getLoadMore().reset());
    @@ -321,7 +291,7 @@ public class PullRequestTimelinePresenter extends BasePresenter<PullRequestTimel
                 return;
             }
             setCurrentPage(page);
    -        loadEverything(login, repoId, number, getHeader().getHead().getSha(), getHeader().isMergeable(), page);
    +        loadEverything(login, repoId, number, parameter.getHead().getSha(), parameter.isMergeable(), page);
         }
     
         private void loadEverything(String login, String repoId, int number, @NonNull String sha, boolean isMergeable, int page) {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsActivity.java b/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsActivity.java
    index abf0ac87..2b409610 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsActivity.java
    @@ -9,14 +9,16 @@ import android.widget.ListView;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.SettingsModel;
     import com.fastaccess.helper.ActivityHelper;
    +import com.fastaccess.helper.BundleConstant;
    +import com.fastaccess.helper.Bundler;
     import com.fastaccess.ui.adapter.SettingsAdapter;
     import com.fastaccess.ui.base.BaseActivity;
    +import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
     import com.fastaccess.ui.modules.settings.category.SettingsCategoryActivity;
     
     import net.grandcentrix.thirtyinch.TiPresenter;
     
     import butterknife.BindView;
    -import butterknife.OnItemClick;
     
     public class SettingsActivity extends BaseActivity {
     
    @@ -25,23 +27,6 @@ public class SettingsActivity extends BaseActivity {
         private static int THEME_CHANGE = 32;
         private SettingsModel[] settings;
     
    -    @OnItemClick(R.id.settingsList) void onItemClick(int position) {
    -        Intent intent = new Intent(this, SettingsCategoryActivity.class);
    -        intent.putExtra("settings", position);
    -        intent.putExtra("title", settings[position].getTitle());
    -        switch (position) {
    -            case 1:
    -                ActivityHelper.startReveal(this, intent, settingsList, THEME_CHANGE);
    -                break;
    -            case 5:
    -                showLanguageList();
    -                break;
    -            default:
    -                ActivityHelper.startReveal(this, intent, settingsList);
    -                break;
    -        }
    -    }
    -
         @Override protected int layout() {
             return R.layout.activity_settings;
         }
    @@ -67,12 +52,37 @@ public class SettingsActivity extends BaseActivity {
                     SettingsModel.newInstance(R.drawable.ic_ring, getString(R.string.notifications), ""),
                     SettingsModel.newInstance(R.drawable.ic_settings, getString(R.string.behavior), ""),
                     SettingsModel.newInstance(R.drawable.ic_brush, getString(R.string.customization), ""),
    -                SettingsModel.newInstance(R.drawable.ic_info, getString(R.string.about), ""),
                     SettingsModel.newInstance(R.drawable.ic_backup, getString(R.string.backup), ""),
                     SettingsModel.newInstance(R.drawable.ic_language, getString(R.string.app_language), "")
             };
    -
             settingsList.setAdapter(new SettingsAdapter(this, settings));
    +        settingsList.setOnItemClickListener((parent, view, position, id) -> {
    +            Intent intent = new Intent(this, SettingsCategoryActivity.class);
    +            intent.putExtras(Bundler.start()
    +                    .put(BundleConstant.ITEM, position)
    +                    .put(BundleConstant.EXTRA, settings[position].getTitle())
    +                    .end());
    +            switch (position) {
    +                case 1:
    +                    ActivityHelper.startReveal(this, intent, settingsList, THEME_CHANGE);
    +                    break;
    +                case 4:
    +                    showLanguageList();
    +                    break;
    +                default:
    +                    ActivityHelper.startReveal(this, intent, settingsList);
    +                    break;
    +            }
    +        });
    +    }
    +
    +    @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    +        if (requestCode == THEME_CHANGE)
    +            setResult(resultCode);
    +    }
    +
    +    @NonNull @Override public TiPresenter providePresenter() {
    +        return new BasePresenter();
         }
     
         private void showLanguageList() {
    @@ -80,16 +90,4 @@ public class SettingsActivity extends BaseActivity {
             languageBottomSheetDialog.onAttach((Context) this);
             languageBottomSheetDialog.show(getSupportFragmentManager(), "LanguageBottomSheetDialog");
         }
    -
    -    @Override
    -    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    -        if (requestCode == THEME_CHANGE)
    -            setResult(resultCode);
    -    }
    -
    -    @NonNull
    -    @Override
    -    public TiPresenter providePresenter() {
    -        return new SettingsPresenter();
    -    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsMvp.java b/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsMvp.java
    deleted file mode 100644
    index 13d026d2..00000000
    --- a/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsMvp.java
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -package com.fastaccess.ui.modules.settings;
    -
    -import com.fastaccess.ui.base.mvp.BaseMvp;
    -
    -/**
    - * Created by JediB on 5/12/2017.
    - */
    -
    -public interface SettingsMvp {
    -	interface Presenter extends BaseMvp.FAPresenter {
    -
    -	}
    -}
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsPresenter.java b/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsPresenter.java
    deleted file mode 100644
    index ef93cb28..00000000
    --- a/app/src/main/java/com/fastaccess/ui/modules/settings/SettingsPresenter.java
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -package com.fastaccess.ui.modules.settings;
    -
    -import com.fastaccess.ui.base.mvp.presenter.BasePresenter;
    -
    -/**
    - * Created by JediB on 5/12/2017.
    - */
    -
    -class SettingsPresenter extends BasePresenter implements SettingsMvp.Presenter {}
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryActivity.java b/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryActivity.java
    index 55e14ad5..1a4cab5d 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryActivity.java
    @@ -3,16 +3,17 @@ package com.fastaccess.ui.modules.settings.category;
     import android.os.Bundle;
     import android.support.annotation.NonNull;
     
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
    +import com.fastaccess.helper.BundleConstant;
     import com.fastaccess.ui.base.BaseActivity;
     
     import net.grandcentrix.thirtyinch.TiPresenter;
     
    -import com.evernote.android.state.State;
    -
    -public class SettingsCategoryActivity extends BaseActivity {
    +public class SettingsCategoryActivity extends BaseActivity implements SettingsCategoryFragment.SettingsCallback {
     
         @State String title;
    +    @State int settingsIndex;
     
         @Override protected int layout() {
             return R.layout.activity_settings_category;
    @@ -34,11 +35,12 @@ public class SettingsCategoryActivity extends BaseActivity {
             super.onCreate(savedInstanceState);
             setResult(RESULT_CANCELED);
             if (savedInstanceState == null) {
    -            title = getIntent() != null ? getIntent().getStringExtra("title") : getString(R.string.settings);
    -            SettingsCategoryFragment settingsCategoryFragment = new SettingsCategoryFragment();
    +            Bundle bundle = getIntent().getExtras();
    +            title = bundle.getString(BundleConstant.EXTRA);
    +            settingsIndex = bundle.getInt(BundleConstant.ITEM);
                 getSupportFragmentManager()
                         .beginTransaction()
    -                    .replace(R.id.settingsContainer, settingsCategoryFragment)
    +                    .replace(R.id.settingsContainer, new SettingsCategoryFragment())
                         .commit();
             }
             setTitle(title);
    @@ -47,4 +49,8 @@ public class SettingsCategoryActivity extends BaseActivity {
         @NonNull @Override public TiPresenter providePresenter() {
             return new SettingsCategoryPresenter();
         }
    +
    +    @Override public int getSettingsType() {
    +        return settingsIndex;
    +    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryFragment.java b/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryFragment.java
    index 8f5e4bfb..e291599b 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryFragment.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/settings/category/SettingsCategoryFragment.java
    @@ -11,20 +11,14 @@ import android.support.v4.content.ContextCompat;
     import android.support.v7.preference.Preference;
     import android.support.v7.preference.PreferenceFragmentCompat;
     import android.util.Log;
    -import android.widget.FrameLayout;
     import android.widget.Toast;
     
    -import com.fastaccess.BuildConfig;
     import com.fastaccess.R;
    -import com.fastaccess.data.dao.model.Release;
    -import com.fastaccess.helper.ActivityHelper;
     import com.fastaccess.helper.InputHelper;
     import com.fastaccess.helper.PrefGetter;
     import com.fastaccess.helper.PrefHelper;
     import com.fastaccess.provider.tasks.notification.NotificationSchedulerJobTask;
     import com.fastaccess.ui.base.mvp.BaseMvp;
    -import com.fastaccess.ui.modules.changelog.ChangelogBottomSheetDialog;
    -import com.fastaccess.ui.widgets.SpannableBuilder;
     import com.google.gson.Gson;
     import com.google.gson.JsonElement;
     import com.google.gson.JsonObject;
    @@ -42,15 +36,15 @@ import java.util.Locale;
     import java.util.Map;
     import java.util.Set;
     
    -import butterknife.BindView;
     import es.dmoral.toasty.Toasty;
    -import io.reactivex.disposables.Disposable;
     
     import static android.app.Activity.RESULT_OK;
     
     public class SettingsCategoryFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener {
     
    -    @BindView(R.id.settingsContainer) FrameLayout settingsContainer;
    +    public interface SettingsCallback {
    +        int getSettingsType();
    +    }
     
         private static int PERMISSION_REQUEST_CODE = 128;
         private static int RESTORE_REQUEST_CODE = 256;
    @@ -64,19 +58,30 @@ public class SettingsCategoryFragment extends PreferenceFragmentCompat implement
         private Preference notificationTime;
         private Preference notificationRead;
         private Preference notificationSound;
    -    private Disposable disposable;
    +    private SettingsCallback settingsCallback;
    +
     
         @Override public void onAttach(Context context) {
             super.onAttach(context);
             this.callback = (BaseMvp.FAView) context;
    +        this.settingsCallback = (SettingsCallback) context;
             appTheme = PrefHelper.getString("appTheme");
             appColor = PrefHelper.getString("appColor");
             app_lauguage = PrefHelper.getString("app_language");
         }
     
    +    @Override public void onDetach() {
    +        callback = null;
    +        settingsCallback = null;
    +        super.onDetach();
    +    }
    +
    +    @Override public void onCreate(Bundle savedInstanceState) {
    +        super.onCreate(savedInstanceState);
    +    }
    +
         @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    -        int settings = getActivity().getIntent().getExtras().getInt("settings", 0);
    -        switch (settings) {
    +        switch (settingsCallback.getSettingsType()) {
                 case 0:
                     addPreferencesFromResource(R.xml.notification_settings);
                     notificationTime = findPreference("notificationTime");
    @@ -106,37 +111,8 @@ public class SettingsCategoryFragment extends PreferenceFragmentCompat implement
                     findPreference("appColor").setOnPreferenceChangeListener(this);
                     break;
                 case 3:
    -                addPreferencesFromResource(R.xml.about_settings);
    -                findPreference("showChangelog").setOnPreferenceClickListener(preference -> {
    -                    new ChangelogBottomSheetDialog().show(getChildFragmentManager(), "ChangelogBottomSheetDialog");
    -                    return true;
    -                });
    -                findPreference("joinSlack").setOnPreferenceClickListener(preference -> {
    -                    ActivityHelper.startCustomTab(getActivity(), "http://rebrand.ly/fasthub");
    -                    return true;
    -                });
    -                findPreference("currentVersion").setSummary(SpannableBuilder.builder()
    -                        .append(getString(R.string.current_version))
    -                        .append("(")
    -                        .bold(BuildConfig.VERSION_NAME)
    -                        .append(")"));
    -                findPreference("currentVersion").setOnPreferenceClickListener(preference -> {
    -                    disposable = Release.get("FastHub", "k0shk0sh").subscribe(releases -> {
    -                        if (releases != null) {
    -                            if (releases.get(0).getTagName().equals(BuildConfig.VERSION_NAME))
    -                                Toasty.success(getContext(), getString(R.string.up_to_date)).show();
    -                            else
    -                                Toasty.warning(getContext(), getString(R.string.new_version)).show();
    -                        }
    -                    });
    -                    return true;
    -                });
    -                break;
    -            case 4:
                     addPreferencesFromResource(R.xml.backup_settings);
                     findPreference("backup").setOnPreferenceClickListener((Preference preference) -> {
    -
    -
                         if (ContextCompat.checkSelfPermission(getActivity(),
                                 Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                             Map<String, ?> settings_ = PrefHelper.getAll();
    @@ -162,7 +138,7 @@ public class SettingsCategoryFragment extends PreferenceFragmentCompat implement
                                 Log.e(getTag(), "Couldn't backup: " + e.toString());
                             }
     
    -                        PrefHelper.set("backed_up", new SimpleDateFormat("MM/dd").format(new Date()));
    +                        PrefHelper.set("backed_up", new SimpleDateFormat("MM/dd", Locale.ENGLISH).format(new Date()));
                         } else {
                             requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
                         }
    @@ -184,9 +160,6 @@ public class SettingsCategoryFragment extends PreferenceFragmentCompat implement
                         return true;
                     });
                     break;
    -            default:
    -                addPreferencesFromResource(R.xml.fasthub_settings);
    -                break;
             }
         }
     
    @@ -244,7 +217,6 @@ public class SettingsCategoryFragment extends PreferenceFragmentCompat implement
     
         @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
             super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    -
             if (requestCode == PERMISSION_REQUEST_CODE) {
                 if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                     if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    @@ -323,13 +295,6 @@ public class SettingsCategoryFragment extends PreferenceFragmentCompat implement
             }
         }
     
    -    @Override public void onDestroyView() {
    -        super.onDestroyView();
    -        if (disposable != null && !disposable.isDisposed()) {
    -            disposable.dispose();
    -        }
    -    }
    -
         private void showFileChooser() {
             Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
             intent.setType("application/json");
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingActivity.kt b/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingActivity.kt
    index a79fa9e4..62da2fc1 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingActivity.kt
    +++ b/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingActivity.kt
    @@ -1,5 +1,7 @@
     package com.fastaccess.ui.modules.trending
     
    +import android.content.Context
    +import android.content.Intent
     import android.os.Bundle
     import android.support.design.widget.NavigationView
     import android.support.v4.widget.DrawerLayout
    @@ -9,10 +11,12 @@ import android.view.MenuItem
     import android.widget.TextView
     import com.evernote.android.state.State
     import com.fastaccess.R
    +import com.fastaccess.helper.BundleConstant
    +import com.fastaccess.helper.Bundler
     import com.fastaccess.helper.Logger
     import com.fastaccess.ui.base.BaseActivity
    +import com.fastaccess.ui.modules.main.MainActivity
     import com.fastaccess.ui.modules.trending.fragment.TrendingFragment
    -import es.dmoral.toasty.Toasty
     
     
     /**
    @@ -28,10 +32,20 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
         val monthly by lazy { findViewById(R.id.monthly) as TextView }
         val drawerLayout by lazy { findViewById(R.id.drawer) as DrawerLayout }
     
    -    @State var selectedTitle: String = ""
    +    @State var selectedTitle: String = "All Language"
    +
    +    companion object {
    +        fun getTrendingIntent(context: Context, lang: String?, query: String?): Intent {
    +            val intent = Intent(context, TrendingActivity::class.java)
    +            intent.putExtras(Bundler.start()
    +                    .put(BundleConstant.EXTRA, lang)
    +                    .put(BundleConstant.EXTRA_TWO, query)
    +                    .end())
    +            return intent
    +        }
    +    }
     
         fun onDailyClicked() {
    -        Toasty.info(applicationContext, "Hello").show()
             Logger.e()
             daily.isSelected = true
             weekly.isSelected = false
    @@ -40,7 +54,6 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
         }
     
         fun onWeeklyClicked() {
    -        Toasty.info(applicationContext, "Hello").show()
             weekly.isSelected = true
             daily.isSelected = false
             monthly.isSelected = false
    @@ -48,7 +61,6 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
         }
     
         fun onMonthlyClicked() {
    -        Toasty.info(applicationContext, "Hello").show()
             monthly.isSelected = true
             weekly.isSelected = false
             daily.isSelected = false
    @@ -77,17 +89,17 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
     
         override fun onCreate(savedInstanceState: Bundle?) {
             super.onCreate(savedInstanceState)
    -        Logger.e(selectedTitle)
             trendingFragment = supportFragmentManager.findFragmentById(R.id.trendingFragment) as TrendingFragment?
             daily.setOnClickListener { onDailyClicked() }
             weekly.setOnClickListener { onWeeklyClicked() }
             monthly.setOnClickListener { onMonthlyClicked() }
    +        navMenu.setNavigationItemSelectedListener({ item ->
    +            closeDrawerLayout()
    +            onItemClicked(item)
    +        })
    +        setupIntent(savedInstanceState)
             presenter.onLoadLanguage()
    -        navMenu.setNavigationItemSelectedListener(this)
    -        if (savedInstanceState == null) {
    -            daily.isSelected = true
    -            setValues()
    -        }
    +        onSelectTrending()
         }
     
         override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    @@ -96,36 +108,43 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
         }
     
         override fun onOptionsItemSelected(item: MenuItem?): Boolean {
    -        if (item?.itemId == R.id.menu) {
    -            drawerLayout.openDrawer(Gravity.END)
    -            return true
    +        when (item?.itemId) {
    +            R.id.menu -> {
    +                drawerLayout.openDrawer(Gravity.END)
    +                return true
    +            }
    +            android.R.id.home -> {
    +                startActivity(Intent(this, MainActivity::class.java))
    +                finish()
    +                return true
    +            }
    +            else -> return super.onOptionsItemSelected(item)
             }
    -        return super.onOptionsItemSelected(item)
         }
     
         override fun onAppend(title: String) {
             navMenu.menu.add(R.id.languageGroup, title.hashCode(), Menu.NONE, title)
                     .setCheckable(true)
    -                .isChecked = title == selectedTitle
    +                .isChecked = title.toLowerCase() == selectedTitle.toLowerCase()
         }
     
         private fun onItemClicked(item: MenuItem?): Boolean {
    -        selectedTitle = item?.title.toString()
    +        when (item?.title.toString()) {
    +            "All Language" -> selectedTitle = ""
    +            else -> selectedTitle = item?.title.toString()
    +        }
    +        Logger.e(selectedTitle)
             setValues()
             return true
         }
     
    -    override fun onNavigationItemSelected(item: MenuItem): Boolean {
    -        closeDrawerLayout()
    -        return onItemClicked(item)
    -    }
    -
         private fun closeDrawerLayout() {
             drawerLayout.closeDrawer(Gravity.END)
         }
     
         private fun setValues() {
             closeDrawerLayout()
    +        Logger.e(selectedTitle, getSince())
             trendingFragment?.onSetQuery(selectedTitle, getSince())
         }
     
    @@ -137,4 +156,33 @@ class TrendingActivity : BaseActivity<TrendingMvp.View, TrendingPresenter>(), Tr
                 else -> return "daily"
             }
         }
    -}
    +
    +    private fun setupIntent(savedInstanceState: Bundle?) {
    +        if (savedInstanceState == null) {
    +            if (intent != null && intent.extras != null) {
    +                val bundle = intent.extras
    +                if (bundle != null) {
    +                    val lang: String = bundle.getString(BundleConstant.EXTRA)
    +                    val query: String = bundle.getString(BundleConstant.EXTRA_TWO)
    +                    if (!lang.isNullOrEmpty()) {
    +                        selectedTitle = lang
    +                    }
    +                    if (!query.isNullOrEmpty()) {
    +                        when (query.toLowerCase()) {
    +                            "daily" -> daily.isSelected = true
    +                            "weekly" -> weekly.isSelected = true
    +                            "monthly" -> monthly.isSelected = true
    +                        }
    +                    } else {
    +                        daily.isSelected = true
    +                    }
    +                } else {
    +                    daily.isSelected = true
    +                }
    +            } else {
    +                daily.isSelected = true
    +            }
    +            setValues()
    +        }
    +    }
    +}
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingMvp.kt b/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingMvp.kt
    index 44cccfcd..57614628 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingMvp.kt
    +++ b/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingMvp.kt
    @@ -1,6 +1,5 @@
     package com.fastaccess.ui.modules.trending
     
    -import android.support.design.widget.NavigationView
     import com.fastaccess.ui.base.mvp.BaseMvp
     
     /**
    @@ -8,7 +7,7 @@ import com.fastaccess.ui.base.mvp.BaseMvp
      */
     
     interface TrendingMvp {
    -    interface View : BaseMvp.FAView, NavigationView.OnNavigationItemSelectedListener {
    +    interface View : BaseMvp.FAView{
             fun onAppend(title: String)
         }
     
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingPresenter.kt b/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingPresenter.kt
    index c4d46a99..a400d57a 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingPresenter.kt
    +++ b/app/src/main/java/com/fastaccess/ui/modules/trending/TrendingPresenter.kt
    @@ -1,5 +1,6 @@
     package com.fastaccess.ui.modules.trending
     
    +import com.fastaccess.helper.RxHelper
     import com.fastaccess.provider.colors.ColorsProvider
     import com.fastaccess.ui.base.mvp.presenter.BasePresenter
     import io.reactivex.Observable
    @@ -10,9 +11,7 @@ import io.reactivex.Observable
     
     class TrendingPresenter : BasePresenter<TrendingMvp.View>(), TrendingMvp.Presenter {
         override fun onLoadLanguage() {
    -        manageObservable(Observable.create<String> {
    -            ColorsProvider.languages().forEach({ t: String? -> it.onNext(t) })
    -            it.onComplete()
    -        }.doOnNext({ t: String -> sendToView({ it.onAppend(t) }) }))
    +        manageObservable(RxHelper.getObserver(Observable.fromIterable(ColorsProvider.languages()))
    +                .doOnNext({ t: String -> sendToView({ it.onAppend(t) }) }))
         }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragment.kt b/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragment.kt
    index 8385053c..8b8db048 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragment.kt
    +++ b/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragment.kt
    @@ -5,7 +5,7 @@ import android.support.v4.widget.SwipeRefreshLayout
     import android.view.View
     import com.evernote.android.state.State
     import com.fastaccess.R
    -import com.fastaccess.data.dao.TrendingResponse
    +import com.fastaccess.data.dao.TrendingModel
     import com.fastaccess.ui.adapter.TrendingAdapter
     import com.fastaccess.ui.base.BaseFragment
     import com.fastaccess.ui.widgets.StateLayout
    @@ -25,13 +25,12 @@ class TrendingFragment : BaseFragment<TrendingFragmentMvp.View, TrendingFragment
         @State var lang: String = ""
         @State var since: String = ""
     
    -
         override fun providePresenter(): TrendingFragmentPresenter {
             return TrendingFragmentPresenter()
         }
     
         override fun fragmentLayout(): Int {
    -        return R.layout.micro_grid_refresh_list
    +        return R.layout.small_grid_refresh_list
         }
     
         override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
    @@ -43,7 +42,7 @@ class TrendingFragment : BaseFragment<TrendingFragmentMvp.View, TrendingFragment
             recycler.adapter = adapter
         }
     
    -    override fun onNotifyAdapter(items: TrendingResponse) {
    +    override fun onNotifyAdapter(items: TrendingModel) {
             adapter.addItem(items)
         }
     
    @@ -62,9 +61,7 @@ class TrendingFragment : BaseFragment<TrendingFragmentMvp.View, TrendingFragment
         override fun hideProgress() {
             refresh.isRefreshing = false
             stateLayout.hideProgress()
    -        if (adapter.isEmpty) {
    -            stateLayout.showEmptyState()
    -        }
    +        stateLayout.showReload(adapter.itemCount)
         }
     
         override fun showMessage(titleRes: Int, msgRes: Int) {
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentMvp.kt b/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentMvp.kt
    index f9123ea6..735d27d4 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentMvp.kt
    +++ b/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentMvp.kt
    @@ -1,7 +1,7 @@
     package com.fastaccess.ui.modules.trending.fragment
     
     
    -import com.fastaccess.data.dao.TrendingResponse
    +import com.fastaccess.data.dao.TrendingModel
     import com.fastaccess.ui.base.mvp.BaseMvp
     import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
     
    @@ -11,13 +11,12 @@ import com.fastaccess.ui.widgets.recyclerview.BaseViewHolder
     
     interface TrendingFragmentMvp {
         interface View : BaseMvp.FAView {
    -        fun onNotifyAdapter(items: TrendingResponse)
    +        fun onNotifyAdapter(items: TrendingModel)
             fun onSetQuery(lang: String, since: String)
         }
     
    -    interface Presenter : BaseViewHolder.OnItemClickListener<TrendingResponse> {
    +    interface Presenter : BaseViewHolder.OnItemClickListener<TrendingModel> {
             fun onCallApi(lang: String, since: String)
    -
    -        fun getTendingList(): ArrayList<TrendingResponse>
    +        fun getTendingList(): ArrayList<TrendingModel>
         }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentPresenter.kt b/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentPresenter.kt
    index 46979792..337f334d 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentPresenter.kt
    +++ b/app/src/main/java/com/fastaccess/ui/modules/trending/fragment/TrendingFragmentPresenter.kt
    @@ -1,11 +1,16 @@
     package com.fastaccess.ui.modules.trending.fragment
     
     import android.view.View
    -import com.fastaccess.data.dao.TrendingResponse
    +import com.fastaccess.data.dao.TrendingModel
    +import com.fastaccess.helper.InputHelper
    +import com.fastaccess.helper.Logger
     import com.fastaccess.helper.RxHelper
    -import com.fastaccess.provider.rest.jsoup.RetroJsoupProvider
    +import com.fastaccess.provider.rest.jsoup.JsoupProvider
     import com.fastaccess.ui.base.mvp.presenter.BasePresenter
     import com.fastaccess.ui.modules.repos.RepoPagerActivity
    +import io.reactivex.Observable
    +import org.jsoup.Jsoup
    +import org.jsoup.nodes.Document
     
     /**
      * Created by Kosh on 30 May 2017, 11:04 PM
    @@ -13,25 +18,49 @@ import com.fastaccess.ui.modules.repos.RepoPagerActivity
     
     class TrendingFragmentPresenter : BasePresenter<TrendingFragmentMvp.View>(), TrendingFragmentMvp.Presenter {
     
    -    private val trendingList: ArrayList<TrendingResponse> = ArrayList()
    +    private val trendingList: ArrayList<TrendingModel> = ArrayList()
     
    -    override fun getTendingList(): ArrayList<TrendingResponse> {
    +    override fun getTendingList(): ArrayList<TrendingModel> {
             return trendingList
         }
     
    -    override fun onItemLongClick(position: Int, v: View?, item: TrendingResponse?) {}
    +    override fun onItemLongClick(position: Int, v: View?, item: TrendingModel?) {}
     
    -    override fun onItemClick(position: Int, v: View?, item: TrendingResponse?) {
    +    override fun onItemClick(position: Int, v: View?, item: TrendingModel?) {
             val split = item?.title?.trim()?.split("/")!!
             v?.context!!.startActivity(RepoPagerActivity.createIntent(v.context!!, split[1].trim(), split[0].trim()))
         }
     
         override fun onCallApi(lang: String, since: String) {
    -        manageViewDisposable(RxHelper.getObserver(RetroJsoupProvider.getTrendingService(since, lang).trending)
    +        manageViewDisposable(RxHelper.getObserver(JsoupProvider.getTrendingService().getTrending(
    +                (if (!InputHelper.isEmpty(lang)) lang.replace(" ".toRegex(), "-") else "").toLowerCase(), since))
    +                .flatMap { s -> RxHelper.getObserver(getTrendingObservable(s)) }
                     .doOnSubscribe { sendToView { it.showProgress(0) } }
                     .subscribe({ response -> sendToView { view -> view.onNotifyAdapter(response) } },
                             { throwable -> onError(throwable) }, { sendToView({ it.hideProgress() }) }))
         }
     
     
    +    fun getTrendingObservable(response: String): Observable<TrendingModel> {
    +        return Observable.fromPublisher { s ->
    +            val document: Document = Jsoup.parse(response, "")
    +            val repoList = document.select(".repo-list")
    +            if (repoList.isNotEmpty()) {
    +                val list = repoList.select("li")
    +                if (list.isNotEmpty()) {
    +                    list.onEach {
    +                        val title = it.select(".d-inline-block > h3 > a").text()
    +                        val description = it.select(".py-1 > p").text()
    +                        val stars = it.select(".f6 > a[href*=/stargazers]").text()
    +                        val forks = it.select(".f6 > a[href*=/network]").text()
    +                        val todayStars = it.select(".f6 > span.float-right").text()
    +                        val language = it.select(".f6 > span[itemprop=programmingLanguage]").text()
    +                        Logger.e(title, description, stars, forks, todayStars, language)
    +                        s.onNext(TrendingModel(title, description, language, stars, forks, todayStars))
    +                    }
    +                }
    +            }
    +            s.onComplete()
    +        }
    +    }
     }
    \ No newline at end of file
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerActivity.java b/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerActivity.java
    index a1bd9b2b..09ca6eb6 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerActivity.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerActivity.java
    @@ -1,32 +1,40 @@
     package com.fastaccess.ui.modules.user;
     
    +import android.app.Application;
    +import android.app.Service;
     import android.content.Context;
     import android.content.Intent;
     import android.os.Bundle;
     import android.support.annotation.NonNull;
     import android.support.design.widget.FloatingActionButton;
     import android.support.design.widget.TabLayout;
    -import android.support.v4.view.ViewPager;
     import android.support.v4.app.Fragment;
    +import android.support.v4.view.ViewPager;
    +import android.widget.TextView;
     
    +import com.annimon.stream.Stream;
    +import com.evernote.android.state.State;
     import com.fastaccess.R;
     import com.fastaccess.data.dao.FragmentPagerAdapterModel;
    +import com.fastaccess.data.dao.TabsCountStateModel;
     import com.fastaccess.data.dao.model.Login;
     import com.fastaccess.helper.BundleConstant;
     import com.fastaccess.helper.Bundler;
     import com.fastaccess.helper.InputHelper;
    +import com.fastaccess.helper.ViewHelper;
     import com.fastaccess.ui.adapter.FragmentsPagerAdapter;
     import com.fastaccess.ui.base.BaseActivity;
     import com.fastaccess.ui.base.BaseFragment;
     import com.fastaccess.ui.modules.main.MainActivity;
    -import com.fastaccess.ui.modules.changelog.ChangelogBottomSheetDialog;
     import com.fastaccess.ui.modules.profile.org.repos.OrgReposFragment;
     import com.fastaccess.ui.modules.profile.repos.ProfileReposFragment;
    +import com.fastaccess.ui.widgets.SpannableBuilder;
     import com.fastaccess.ui.widgets.ViewPagerView;
     
    +import java.util.HashSet;
    +
     import butterknife.BindView;
     import butterknife.OnClick;
    -import com.evernote.android.state.State;
     import shortbread.Shortcut;
     
     /**
    @@ -42,6 +50,7 @@ public class UserPagerActivity extends BaseActivity<UserPagerMvp.View, UserPager
         @BindView(R.id.fab) FloatingActionButton fab;
         @State String login;
         @State boolean isOrg;
    +    @State HashSet<TabsCountStateModel> counts = new HashSet<>();
     
         public static void startActivity(@NonNull Context context, @NonNull String login) {
             startActivity(context, login, false);
    @@ -61,6 +70,9 @@ public class UserPagerActivity extends BaseActivity<UserPagerMvp.View, UserPager
                     .put(BundleConstant.EXTRA, login)
                     .put(BundleConstant.EXTRA_TYPE, isOrg)
                     .end());
    +        if (context instanceof Service || context instanceof Application) {
    +            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    +        }
             return intent;
         }
     
    @@ -125,25 +137,18 @@ public class UserPagerActivity extends BaseActivity<UserPagerMvp.View, UserPager
                     onScrollTop(tab.getPosition());
                 }
             });
    -
    -        pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    -            @Override
    -            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    -            }
    -
    -            @Override
    -            public void onPageSelected(int position) {
    -                if (position == 1) {
    -                    fab.show();
    -                } else {
    -                    fab.hide();
    -                }
    -            }
    -
    -            @Override
    -            public void onPageScrollStateChanged(int state) {
    +        pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    +            @Override public void onPageSelected(int position) {
    +                super.onPageSelected(position);
    +                hideShowFab(position);
                 }
             });
    +        if (!isOrg) {
    +            if (savedInstanceState != null && !counts.isEmpty()) {
    +                Stream.of(counts).forEach(this::updateCount);
    +            }
    +        }
    +        hideShowFab(pager.getCurrentItem());
         }
     
         @Override public void onScrollTop(int index) {
    @@ -159,11 +164,11 @@ public class UserPagerActivity extends BaseActivity<UserPagerMvp.View, UserPager
         }
     
         @Override public void onNavigateToFollowers() {
    -        pager.setCurrentItem(4);
    +        pager.setCurrentItem(5);
         }
     
         @Override public void onNavigateToFollowing() {
    -        pager.setCurrentItem(5);
    +        pager.setCurrentItem(6);
         }
     
         @Override public void onInitOrg(boolean isMember) {
    @@ -176,14 +181,49 @@ public class UserPagerActivity extends BaseActivity<UserPagerMvp.View, UserPager
             tabs.setupWithViewPager(pager);
         }
     
    -    @OnClick (R.id.fab)
    -    public void onRepoFilterClicked() {
    +    @Override public void onSetBadge(int tabIndex, int count) {
    +        TabsCountStateModel model = new TabsCountStateModel();
    +        model.setTabIndex(tabIndex);
    +        model.setCount(count);
    +        counts.add(model);
    +        if (tabs != null) {
    +            updateCount(model);
    +        }
    +    }
    +
    +    @OnClick(R.id.fab) public void onRepoFilterClicked() {
             if (isOrg) {
                 OrgReposFragment fragment = ((OrgReposFragment) pager.getAdapter().instantiateItem(pager, 1));
                 fragment.onRepoFilterClicked();
             } else {
    -            ProfileReposFragment fragment = ((ProfileReposFragment) pager.getAdapter().instantiateItem(pager, 1));
    +            ProfileReposFragment fragment = ((ProfileReposFragment) pager.getAdapter().instantiateItem(pager, 2));
                 fragment.onRepoFilterClicked();
             }
         }
    +
    +    private void hideShowFab(int position) {
    +        if (isOrg) {
    +            if (position == 1) {
    +                fab.show();
    +            } else {
    +                fab.hide();
    +            }
    +        } else {
    +            if (position == 2) {
    +                fab.show();
    +            } else {
    +                fab.hide();
    +            }
    +        }
    +    }
    +
    +    private void updateCount(@NonNull TabsCountStateModel model) {
    +        TextView tv = ViewHelper.getTabTextView(tabs, model.getTabIndex());
    +        tv.setText(SpannableBuilder.builder()
    +                .append(getString(R.string.starred))
    +                .append("   ")
    +                .append("(")
    +                .bold(String.valueOf(model.getCount()))
    +                .append(")"));
    +    }
     }
    diff --git a/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerMvp.java b/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerMvp.java
    index 3fe513b4..827c5e89 100644
    --- a/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerMvp.java
    +++ b/app/src/main/java/com/fastaccess/ui/modules/user/UserPagerMvp.java
    @@ -4,6 +4,7 @@ import android.support.annotation.NonNull;
     
     import com.fastaccess.ui.base.mvp.BaseMvp;
     import com.fastaccess.ui.modules.profile.ProfilePagerMvp;
    +import com.fastaccess.ui.modules.repos.RepoPagerMvp;
     
     /**
      * Created by Kosh on 04 Dec 2016, 1:11 PM
    @@ -11,7 +12,7 @@ import com.fastaccess.ui.modules.profile.ProfilePagerMvp;
     
     public interface UserPagerMvp {
     
    -    interface View extends BaseMvp.FAView, ProfilePagerMvp.View {
    +    interface View extends BaseMvp.FAView, ProfilePagerMvp.View, RepoPagerMvp.TabsBadgeListener {
             void onInitOrg(boolean isMember);
         }
     
    diff --git a/app/src/main/java/com/fastaccess/ui/widgets/DiffLineSpan.java b/app/src/main/java/com/fastaccess/ui/widgets/DiffLineSpan.java
    index 0d654c91..139ffc45 100644
    --- a/app/src/main/java/com/fastaccess/ui/widgets/DiffLineSpan.java
    +++ b/app/src/main/java/com/fastaccess/ui/widgets/DiffLineSpan.java
    @@ -20,7 +20,6 @@ import android.text.style.TypefaceSpan;
     import com.fastaccess.App;
     import com.fastaccess.R;
     import com.fastaccess.helper.InputHelper;
    -import com.fastaccess.helper.Logger;
     
     public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundSpan {
         private Rect rect = new Rect();
    @@ -68,8 +67,8 @@ public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundS
                 String[] split = text.split("\\r?\\n|\\r");
                 if (split.length > 0) {
                     int lines = split.length;
    +                int index = -1;
                     for (int i = 0; i < lines; i++) {
    -                    Logger.e(lines, i, lines + i, lines - i);
                         if (truncate && (lines - i) > 3) continue;
                         String token = split[i];
                         if (i < (lines - 1)) {
    @@ -83,9 +82,10 @@ public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundS
                             color = patchDeletionColor;
                         } else if (token.startsWith("@@")) {
                             color = patchRefColor;
    -                    } else if (firstChar == '\\') {
    +                    }
    +                    if (token.startsWith("\\ No")) {
                             token = token.replace("\\ No newline at end of file", "");
    -                        noNewlineRemoved = true;
    +                        index = i;
                         }
                         SpannableString spannableDiff = new SpannableString(token);
                         if (color != Color.TRANSPARENT) {
    @@ -94,12 +94,12 @@ public class DiffLineSpan extends MetricAffectingSpan implements LineBackgroundS
                         }
                         builder.append(spannableDiff);
                     }
    +                if (index != -1) {
    +                    builder.insert(index, SpannableBuilder.builder()
    +                            .append(ContextCompat.getDrawable(App.getInstance(), R.drawable.ic_newline)));
    +                }
                 }
             }
    -        if (noNewlineRemoved) {
    -            builder.insert(builder.length() - 1, SpannableBuilder.builder()
    -                    .append(ContextCompat.getDrawable(App.getInstance(), R.drawable.ic_newline)));
    -        }
             builder.setSpan(new TypefaceSpan("monospace"), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
             return builder;
         }
    diff --git a/app/src/main/java/com/fastaccess/ui/widgets/SpannableBuilder.java b/app/src/main/java/com/fastaccess/ui/widgets/SpannableBuilder.java
    index a53b1f0e..026d1ad4 100644
    --- a/app/src/main/java/com/fastaccess/ui/widgets/SpannableBuilder.java
    +++ b/app/src/main/java/com/fastaccess/ui/widgets/SpannableBuilder.java
    @@ -3,7 +3,9 @@ package com.fastaccess.ui.widgets;
     import android.graphics.drawable.Drawable;
     import android.support.annotation.ColorInt;
     import android.text.SpannableStringBuilder;
    +import android.text.TextPaint;
     import android.text.style.BackgroundColorSpan;
    +import android.text.style.ClickableSpan;
     import android.text.style.ForegroundColorSpan;
     import android.text.style.ImageSpan;
     import android.text.style.StyleSpan;
    @@ -108,5 +110,19 @@ public class SpannableBuilder extends SpannableStringBuilder {
             return this;
         }
     
    +    public SpannableBuilder clickable(final CharSequence text, final View.OnClickListener listener) {
    +        if (!InputHelper.isEmpty(text)) return append(text, new ClickableSpan() {
    +            @Override public void updateDrawState(TextPaint ds) {
    +                ds.setColor(ds.linkColor);
    +                ds.setUnderlineText(false);
    +            }
    +
    +            @Override public void onClick(View widget) {
    +                listener.onClick(widget);
    +            }
    +        });
    +        return this;
    +    }
    +
     }
     
    diff --git a/app/src/main/java/com/fastaccess/ui/widgets/contributions/GitHubContributionsView.java b/app/src/main/java/com/fastaccess/ui/widgets/contributions/GitHubContributionsView.java
    index 6f2fc75c..9b4ac98e 100644
    --- a/app/src/main/java/com/fastaccess/ui/widgets/contributions/GitHubContributionsView.java
    +++ b/app/src/main/java/com/fastaccess/ui/widgets/contributions/GitHubContributionsView.java
    @@ -302,52 +302,54 @@ public class GitHubContributionsView extends View {
             }
         }
     
    +    Bitmap bitmap = null;
    +
         private Bitmap drawOnCanvas(Canvas canvas) {
    -        canvas.getClipBounds(rect);
    -        int width = rect.width();
    -        int verticalBlockNumber = 7;
    -        int horizontalBlockNumber = getHorizontalBlockNumber(contributionsFilter.size(), verticalBlockNumber);
    -        float marginBlock = (1.0F - 0.1F);
    -        float blockWidth = width / (float) horizontalBlockNumber * marginBlock;
    -        float spaceWidth = width / (float) horizontalBlockNumber - blockWidth;
    -        float topMargin = (displayMonth) ? 7f : 0;
    -        float monthTextHeight = (displayMonth) ? blockWidth * 1.5F : 0;
    -        int height = (int) ((blockWidth + spaceWidth) * 7 + topMargin + monthTextHeight);
    -        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    -        Canvas canvas1 = new Canvas(bitmap);
    -        // Background
    -        blockPaint.setColor(backgroundBaseColor);
    -        canvas1.drawRect(0, (topMargin + monthTextHeight), width, height + monthTextHeight, blockPaint);
    -        monthTextPaint.setColor(textColor);
    -        monthTextPaint.setTextSize(monthTextHeight);
    -        // draw the blocks
    -        int currentWeekDay = DatesUtils.getWeekDayFromDate(
    -                contributions.get(0).year,
    -                contributions.get(0).month,
    -                contributions.get(0).day);
    -        float x = 0;
    -        float y = (currentWeekDay - 7) % 7 * (blockWidth + spaceWidth) + (topMargin + monthTextHeight);
    -        for (ContributionsDay day : contributionsFilter) {
    -            blockPaint.setColor(ColorsUtils.calculateLevelColor(baseColor, baseEmptyColor, day.level));
    -            canvas1.drawRect(x, y, x + blockWidth, y + blockWidth, blockPaint);
    +        if (bitmap == null) {
    +            canvas.getClipBounds(rect);
    +            int width = rect.width();
    +            int verticalBlockNumber = 7;
    +            int horizontalBlockNumber = getHorizontalBlockNumber(contributionsFilter.size(), verticalBlockNumber);
    +            float marginBlock = (1.0F - 0.1F);
    +            float blockWidth = width / (float) horizontalBlockNumber * marginBlock;
    +            float spaceWidth = width / (float) horizontalBlockNumber - blockWidth;
    +            float topMargin = (displayMonth) ? 7f : 0;
    +            float monthTextHeight = (displayMonth) ? blockWidth * 1.5F : 0;
    +            int height = (int) ((blockWidth + spaceWidth) * 7 + topMargin + monthTextHeight);
    +            bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    +            Canvas canvas1 = new Canvas(bitmap);
    +            // Background
    +            blockPaint.setColor(backgroundBaseColor);
    +            canvas1.drawRect(0, (topMargin + monthTextHeight), width, height + monthTextHeight, blockPaint);
    +            monthTextPaint.setColor(textColor);
    +            monthTextPaint.setTextSize(monthTextHeight);
    +            // draw the blocks
    +            int currentWeekDay = DatesUtils.getWeekDayFromDate(
    +                    contributions.get(0).year,
    +                    contributions.get(0).month,
    +                    contributions.get(0).day);
    +            float x = 0;
    +            float y = (currentWeekDay - 7) % 7 * (blockWidth + spaceWidth) + (topMargin + monthTextHeight);
    +            for (ContributionsDay day : contributionsFilter) {
    +                blockPaint.setColor(ColorsUtils.calculateLevelColor(baseColor, baseEmptyColor, day.level));
    +                canvas1.drawRect(x, y, x + blockWidth, y + blockWidth, blockPaint);
    +                if (DatesUtils.isFirstDayOfWeek(day.year, day.month, day.day + 1)) {
    +                    // another column
    +                    x += blockWidth + spaceWidth;
    +                    y = topMargin + monthTextHeight;
     
    -            if (DatesUtils.isFirstDayOfWeek(day.year, day.month, day.day + 1)) {
    -                // another column
    -                x += blockWidth + spaceWidth;
    -                y = topMargin + monthTextHeight;
    +                    if (DatesUtils.isFirstWeekOfMount(day.year, day.month, day.day + 1)) {
    +                        canvas1.drawText(
    +                                DatesUtils.getShortMonthName(day.year, day.month, day.day + 1),
    +                                x, monthTextHeight, monthTextPaint);
    +                    }
     
    -                if (DatesUtils.isFirstWeekOfMount(day.year, day.month, day.day + 1)) {
    -                    canvas1.drawText(
    -                            DatesUtils.getShortMonthName(day.year, day.month, day.day + 1),
    -                            x, monthTextHeight, monthTextPaint);
    +                } else {
    +                    y += blockWidth + spaceWidth;
                     }
    -
    -            } else {
    -                y += blockWidth + spaceWidth;
                 }
    +            adjustHeight(height);
             }
    -
    -        adjustHeight(height);
             return bitmap;
         }
     
    diff --git a/app/src/main/java/com/fastaccess/ui/widgets/recyclerview/scroll/RecyclerFastScroller.java b/app/src/main/java/com/fastaccess/ui/widgets/recyclerview/scroll/RecyclerFastScroller.java
    index fc2eca51..7eb75884 100755
    --- a/app/src/main/java/com/fastaccess/ui/widgets/recyclerview/scroll/RecyclerFastScroller.java
    +++ b/app/src/main/java/com/fastaccess/ui/widgets/recyclerview/scroll/RecyclerFastScroller.java
    @@ -23,6 +23,7 @@ import android.view.ViewGroup;
     import android.widget.FrameLayout;
     
     import com.fastaccess.R;
    +import com.fastaccess.provider.rest.loadmore.OnLoadMore;
     
     /**
      * Created by thermatk on 17/04/2017.
    @@ -51,12 +52,11 @@ public class RecyclerFastScroller extends FrameLayout {
         private int mBarColor;
         private int mTouchTargetWidth;
         private int mBarInset;
    -
    +    private OnLoadMore onLoadMore;
         private boolean mHideOverride;
         private RecyclerView.Adapter mAdapter;
         private RecyclerView.AdapterDataObserver mAdapterObserver = new RecyclerView.AdapterDataObserver() {
    -        @Override
    -        public void onChanged() {
    +        @Override public void onChanged() {
                 super.onChanged();
                 requestLayout();
             }
    @@ -97,7 +97,7 @@ public class RecyclerFastScroller extends FrameLayout {
             }
     
             mBar.setLayoutParams(new LayoutParams(mTouchTargetWidth, ViewGroup.LayoutParams.MATCH_PARENT, GravityCompat.END));
    -        mHandle.setLayoutParams(new LayoutParams(mTouchTargetWidth, ViewGroup.LayoutParams.MATCH_PARENT, GravityCompat.END));
    +        mHandle.setLayoutParams(new LayoutParams(mTouchTargetWidth, convertDpToPx(context, 80), GravityCompat.END));
     
             updateHandleColorsAndInset();
             updateBarColorAndInset();
    @@ -125,44 +125,36 @@ public class RecyclerFastScroller extends FrameLayout {
                 private float mInitialBarHeight;
                 private float mLastPressedYAdjustedToInitial;
     
    -            @Override
    -            public boolean onTouch(View v, MotionEvent event) {
    +            @Override public boolean onTouch(View v, MotionEvent event) {
                     if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                         mHandle.setPressed(true);
                         mRecyclerView.stopScroll();
    -
                         mInitialBarHeight = mBar.getHeight();
                         mLastPressedYAdjustedToInitial = event.getY() + mHandle.getY() + mBar.getY();
                     } else if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
                         float newHandlePressedY = event.getY() + mHandle.getY() + mBar.getY();
                         int barHeight = mBar.getHeight();
    -                    float newHandlePressedYAdjustedToInitial =
    -                            newHandlePressedY + (mInitialBarHeight - barHeight);
    -
    -                    float deltaPressedYFromLastAdjustedToInitial =
    -                            newHandlePressedYAdjustedToInitial - mLastPressedYAdjustedToInitial;
    -
    -                    int dY = (int) ((deltaPressedYFromLastAdjustedToInitial / mInitialBarHeight) *
    -                            (mRecyclerView.computeVerticalScrollRange()));
    -
    +                    float newHandlePressedYAdjustedToInitial = newHandlePressedY + (mInitialBarHeight - barHeight);
    +                    float deltaPressedYFromLastAdjustedToInitial = newHandlePressedYAdjustedToInitial - mLastPressedYAdjustedToInitial;
    +                    int dY = (int) ((deltaPressedYFromLastAdjustedToInitial / mInitialBarHeight) * (mRecyclerView.computeVerticalScrollRange()));
                         if (mRecyclerView != null) {
                             try {
                                 mRecyclerView.scrollBy(0, dY);
    -                        } catch (Throwable t) {
    +                            if (onLoadMore != null) {
    +                                onLoadMore.onScrollStateChanged(mRecyclerView, RecyclerView.SCROLL_STATE_DRAGGING);
    +                            }
    +                        } catch (Exception t) {
                                 t.printStackTrace();
                             }
                         }
    -
                         mLastPressedYAdjustedToInitial = newHandlePressedYAdjustedToInitial;
                     } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                         mLastPressedYAdjustedToInitial = -1;
    -
                         mRecyclerView.stopNestedScroll();
    -
                         mHandle.setPressed(false);
                         postAutoHide();
                     }
    -
    +                updateScroller();
                     return true;
                 }
             });
    @@ -170,6 +162,36 @@ public class RecyclerFastScroller extends FrameLayout {
             setTranslationX(mHiddenTranslationX);
         }
     
    +    @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    +        super.onLayout(changed, left, top, right, bottom);
    +        updateScroller();
    +    }
    +
    +    private void updateScroller() {
    +        if (mRecyclerView == null) return;
    +        int scrollOffset = mRecyclerView.computeVerticalScrollOffset();
    +        int verticalScrollRange = mRecyclerView.computeVerticalScrollRange() + mRecyclerView.getPaddingBottom();
    +
    +        int barHeight = mBar.getHeight();
    +        float ratio = (float) scrollOffset / (verticalScrollRange - barHeight);
    +
    +        int calculatedHandleHeight = (int) ((float) barHeight / verticalScrollRange * barHeight);
    +        if (calculatedHandleHeight < mMinScrollHandleHeight) {
    +            calculatedHandleHeight = mMinScrollHandleHeight;
    +        }
    +
    +        if (calculatedHandleHeight >= barHeight) {
    +            setTranslationX(mHiddenTranslationX);
    +            mHideOverride = true;
    +            return;
    +        }
    +
    +        mHideOverride = false;
    +
    +        float y = ratio * (barHeight - calculatedHandleHeight);
    +        mHandle.setY(y);
    +    }
    +
         private void updateHandleColorsAndInset() {
             StateListDrawable drawable = new StateListDrawable();
     
    @@ -202,8 +224,7 @@ public class RecyclerFastScroller extends FrameLayout {
         public void attachRecyclerView(RecyclerView recyclerView) {
             mRecyclerView = recyclerView;
             mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    -            @Override
    -            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    +            @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                     super.onScrolled(recyclerView, dx, dy);
                     RecyclerFastScroller.this.show();
                 }
    @@ -217,9 +238,6 @@ public class RecyclerFastScroller extends FrameLayout {
             }
         }
     
    -    /**
    -     * Show the fast scroller and hide after delay
    -     */
         public void show() {
             requestLayout();
     
    @@ -262,48 +280,22 @@ public class RecyclerFastScroller extends FrameLayout {
             }
         }
     
    -    @Override
    -    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    -        super.onLayout(changed, left, top, right, bottom);
    -        if (mRecyclerView == null) return;
    -
    -        int scrollOffset = mRecyclerView.computeVerticalScrollOffset();
    -        int verticalScrollRange = mRecyclerView.computeVerticalScrollRange() + mRecyclerView.getPaddingBottom();
    -
    -        int barHeight = mBar.getHeight();
    -        float ratio = (float) scrollOffset / (verticalScrollRange - barHeight);
    -
    -        int calculatedHandleHeight = (int) ((float) barHeight / verticalScrollRange * barHeight);
    -        if (calculatedHandleHeight < mMinScrollHandleHeight) {
    -            calculatedHandleHeight = mMinScrollHandleHeight;
    -        }
    -
    -        if (calculatedHandleHeight >= barHeight) {
    -            setTranslationX(mHiddenTranslationX);
    -            mHideOverride = true;
    -            return;
    -        }
    -
    -        mHideOverride = false;
    -
    -        float y = ratio * (barHeight - calculatedHandleHeight);
    -
    -        mHandle.layout(mHandle.getLeft(), (int) y, mHandle.getRight(), (int) y + calculatedHandleHeight);
    -    }
    -
    -    private static boolean isRTL(Context context) {
    -        return context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
    -    }
    -
    -    @ColorInt
    -    public static int resolveColor(Context context, @AttrRes int color) {
    +    @ColorInt private int resolveColor(Context context, @AttrRes int color) {
             TypedArray a = context.obtainStyledAttributes(new int[]{color});
             int resId = a.getColor(0, 0);
             a.recycle();
             return resId;
         }
     
    -    public static int convertDpToPx(Context context, float dp) {
    +    private boolean isRTL(Context context) {
    +        return context.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
    +    }
    +
    +    private int convertDpToPx(Context context, float dp) {
             return (int) (dp * context.getResources().getDisplayMetrics().density + 0.5f);
         }
    +
    +    public void setOnLoadMore(OnLoadMore onLoadMore) {
    +        this.onLoadMore = onLoadMore;
    +    }
     }
    \ No newline at end of file
    diff --git a/app/src/main/java/com/prettifier/pretty/NestedWebView.java b/app/src/main/java/com/prettifier/pretty/NestedWebView.java
    index c6c3d800..500f3023 100644
    --- a/app/src/main/java/com/prettifier/pretty/NestedWebView.java
    +++ b/app/src/main/java/com/prettifier/pretty/NestedWebView.java
    @@ -42,7 +42,6 @@ public class NestedWebView extends WebView implements NestedScrollingChild {
     
         @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent ev) {
             boolean returnValue;
    -
             MotionEvent event = MotionEvent.obtain(ev);
             final int action = MotionEventCompat.getActionMasked(event);
             if (action == MotionEvent.ACTION_DOWN) {
    @@ -125,5 +124,7 @@ public class NestedWebView extends WebView implements NestedScrollingChild {
             return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
         }
     
    +
    +
     }
     
    diff --git a/app/src/main/java/com/prettifier/pretty/PrettifyWebView.java b/app/src/main/java/com/prettifier/pretty/PrettifyWebView.java
    index 99c1985f..bb4dd7df 100755
    --- a/app/src/main/java/com/prettifier/pretty/PrettifyWebView.java
    +++ b/app/src/main/java/com/prettifier/pretty/PrettifyWebView.java
    @@ -32,6 +32,7 @@ import com.prettifier.pretty.helper.PrettifyHelper;
     public class PrettifyWebView extends NestedWebView {
         private OnContentChangedListener onContentChangedListener;
         private boolean interceptTouch;
    +    private boolean enableNestedScrolling;
     
         public interface OnContentChangedListener {
             void onContentChanged(int progress);
    @@ -53,7 +54,7 @@ public class PrettifyWebView extends NestedWebView {
             initView(attrs);
         }
     
    -    @Override public boolean onInterceptTouchEvent(MotionEvent p_event) {
    +    @Override public boolean onInterceptTouchEvent(MotionEvent p) {
             return true;
         }
     
    @@ -174,6 +175,14 @@ public class PrettifyWebView extends NestedWebView {
             this.interceptTouch = interceptTouch;
         }
     
    +    public void setEnableNestedScrolling(boolean enableNestedScrolling) {
    +        if (this.enableNestedScrolling != enableNestedScrolling) {
    +            Logger.e(enableNestedScrolling);
    +            setNestedScrollingEnabled(enableNestedScrolling);
    +            this.enableNestedScrolling = enableNestedScrolling;
    +        }
    +    }
    +
         private void startActivity(@Nullable Uri url) {
             if (url == null) return;
             Logger.e(url);
    diff --git a/app/src/main/java/com/prettifier/pretty/callback/MarkDownInterceptorInterface.java b/app/src/main/java/com/prettifier/pretty/callback/MarkDownInterceptorInterface.java
    index 21d403c0..a328c003 100644
    --- a/app/src/main/java/com/prettifier/pretty/callback/MarkDownInterceptorInterface.java
    +++ b/app/src/main/java/com/prettifier/pretty/callback/MarkDownInterceptorInterface.java
    @@ -18,12 +18,14 @@ public class MarkDownInterceptorInterface {
         @JavascriptInterface public void startIntercept() {
             if (prettifyWebView != null) {
                 prettifyWebView.setInterceptTouch(true);
    +            prettifyWebView.setEnableNestedScrolling(false);
             }
         }
     
         @JavascriptInterface public void stopIntercept() {
             if (prettifyWebView != null) {
                 prettifyWebView.setInterceptTouch(false);
    +            prettifyWebView.setEnableNestedScrolling(true);
             }
         }
     }
    diff --git a/app/src/main/java/com/prettifier/pretty/helper/PrettifyHelper.java b/app/src/main/java/com/prettifier/pretty/helper/PrettifyHelper.java
    index d61fdb97..480c2d46 100755
    --- a/app/src/main/java/com/prettifier/pretty/helper/PrettifyHelper.java
    +++ b/app/src/main/java/com/prettifier/pretty/helper/PrettifyHelper.java
    @@ -8,29 +8,30 @@ import android.support.annotation.NonNull;
     
     public class PrettifyHelper {
     
    -    @NonNull private final static String HTML_CONTENT =
    -            "<!DOCTYPE html>\n" +
    -                    "<html>\n" +
    -                    "<head>\n" +
    -                    "    <meta charset=\"utf-8\">\n" +
    -                    "    <link rel=\"stylesheet\" href=\"./styles/%s\">\n" +
    -                    "    %s\n" +
    -                    "</head>\n" +
    -                    "<body onload=\"prettyPrint()\">\n" +
    -                    "<pre class=\"prettyprint linenums\">%s</pre>\n" +
    -                    "<script src=\"./js/prettify.js\"></script>\n" +
    -                    "<script>\n" +
    -                    "function scrollToLineNumber(lineNo) {\n" +
    -                    "    var normalizedLineNo = (lineNo - 1) %% 10;\n" +
    -                    "    var nthLineNo = Math.floor((lineNo - 1) / 10);\n" +
    -                    "    var elLines = document.querySelectorAll('li.L' + normalizedLineNo);\n" +
    -                    "    if (elLines[nthLineNo]) {\n" +
    -                    "        elLines[nthLineNo].scrollIntoView();\n" +
    -                    "    }\n" +
    -                    "}" +
    -                    "</script>" +
    -                    "</body>\n" +
    -                    "</html>";
    +    @NonNull private static String getHtmlContent(@NonNull String css, @NonNull String text, @NonNull String wrapStyle, boolean isDark) {
    +        return "<!DOCTYPE html>\n" +
    +                "<html>\n" +
    +                "<head>\n" +
    +                "    <meta charset=\"utf-8\">\n" +
    +                "    <link rel=\"stylesheet\" href=\"./styles/" + css + "\">\n" +
    +                "    " + wrapStyle + "\n" +
    +                "</head>\n" +
    +                "<body style=\"" + (isDark && textTooLarge(text) ? "color:white;" : "") + "\" onload=\"" + (textTooLarge(text) ? "" : "PR.prettyPrint()") + "\">\n" +
    +                "<pre class=\"prettyprint linenums\">" + text + "</pre>\n" +
    +                "<script src=\"./js/prettify.js\"></script>\n" +
    +                "<script>\n" +
    +                "function scrollToLineNumber(lineNo) {\n" +
    +                "    var normalizedLineNo = (lineNo - 1) %% 10;\n" +
    +                "    var nthLineNo = Math.floor((lineNo - 1) / 10);\n" +
    +                "    var elLines = document.querySelectorAll('li.L' + normalizedLineNo);\n" +
    +                "    if (elLines[nthLineNo]) {\n" +
    +                "        elLines[nthLineNo].scrollIntoView();\n" +
    +                "    }\n" +
    +                "}" +
    +                "</script>" +
    +                "</body>\n" +
    +                "</html>";
    +    }
     
         @NonNull private static final String WRAPPED_STYLE =
                 "<style>\n " +
    @@ -55,7 +56,7 @@ public class PrettifyHelper {
     
     
         @NonNull public static String generateContent(@NonNull String source, boolean isDark, boolean wrap) {
    -        return String.format(HTML_CONTENT, getStyle(isDark), wrap ? WRAPPED_STYLE : "", getFormattedSource(source));
    +        return getHtmlContent(getStyle(isDark), getFormattedSource(source), wrap ? WRAPPED_STYLE : "", isDark);
         }
     
         @NonNull private static String getFormattedSource(@NonNull String source) {
    @@ -67,4 +68,8 @@ public class PrettifyHelper {
             return !isDark ? "prettify.css" : "prettify_dark.css";
         }
     
    +    private static boolean textTooLarge(@NonNull String text) {
    +        return text.length() > 204800;//>200kb ? disable highlighting to avoid crash.
    +    }
    +
     }
    diff --git a/app/src/main/res/drawable/ic_language_small.xml b/app/src/main/res/drawable/ic_language_small.xml
    new file mode 100644
    index 00000000..73171be3
    --- /dev/null
    +++ b/app/src/main/res/drawable/ic_language_small.xml
    @@ -0,0 +1,11 @@
    +<vector xmlns:android="http://schemas.android.com/apk/res/android"
    +        xmlns:tools="http://schemas.android.com/tools"
    +        android:width="16dp"
    +        android:height="16dp"
    +        android:viewportHeight="24.0"
    +        android:viewportWidth="24.0">
    +    <path
    +        android:fillColor="?icon_color"
    +        android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z"
    +        tools:ignore="VectorPath"/>
    +</vector>
    diff --git a/app/src/main/res/header-.svg b/app/src/main/res/header-.svg
    deleted file mode 100644
    index 6c36b533..00000000
    --- a/app/src/main/res/header-.svg
    +++ /dev/null
    @@ -1 +0,0 @@
    -<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1280 384"><defs><style>.cls-1{fill:none;}.cls-2{fill:#2196f3;}.cls-3{opacity:0.8;}.cls-4{fill:#0d47a1;}.cls-5{opacity:0.6;}.cls-6{clip-path:url(#clip-path);}.cls-7{fill:#64b5f6;}</style><clipPath id="clip-path"><rect class="cls-1" width="1280" height="384"/></clipPath></defs><title>header-</title><rect class="cls-2" width="1280" height="384"/><g class="cls-3"><path class="cls-4" d="M60.76,60.8H67.2a1.33,1.33,0,0,1,1.47,1.47v38.11a1.33,1.33,0,0,1-1.47,1.47H60.76a1.33,1.33,0,0,1-1.47-1.47V62.27A1.33,1.33,0,0,1,60.76,60.8Z"/><path class="cls-4" d="M101.2,83.25v17.12a1.33,1.33,0,0,1-1.47,1.47H93.88a1.33,1.33,0,0,1-1.47-1.47V84c0-2.93-1.7-4.22-3.93-4.22-2.64,0-4.28,1.47-4.28,4.92v15.65a1.33,1.33,0,0,1-1.47,1.47H76.88a1.33,1.33,0,0,1-1.47-1.47V74a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,84.2,74V75.2c1.38-2,3.87-3.5,7.62-3.5C97.28,71.71,101.2,75.93,101.2,83.25Z"/><path class="cls-4" d="M122.72,74V79.5A1.33,1.33,0,0,1,121.25,81H118v19.4a1.33,1.33,0,0,1-1.47,1.47H110.7a1.33,1.33,0,0,1-1.47-1.47V81H106a1.33,1.33,0,0,1-1.47-1.47V74A1.33,1.33,0,0,1,106,72.53h3.22V64.61a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,118,64.61v7.91h3.22A1.33,1.33,0,0,1,122.72,74Z"/><path class="cls-4" d="M141.71,72.06c1-.18,1.52.47,1.52,1.41v6.92c0,.94-.41,1.41-1.17,1.41-3.28-.12-6.45,1.52-6.45,6.21v12.37a1.33,1.33,0,0,1-1.47,1.47h-5.86a1.33,1.33,0,0,1-1.47-1.47V74a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,135.61,74v3.17a7.13,7.13,0,0,1,6.1-5.1Z"/><path class="cls-4" d="M145,87.18a15.54,15.54,0,1,1,15.54,15.48A15.36,15.36,0,0,1,145,87.18Zm22.28,0a6.74,6.74,0,1,0-6.74,6.92A6.57,6.57,0,0,0,167.27,87.18Z"/><path class="cls-4" d="M211.11,62.27v38.11a1.33,1.33,0,0,1-1.47,1.47h-5.86a1.33,1.33,0,0,1-1.47-1.47V99.1c-2,2.23-4.81,3.56-8.73,3.56-7.68,0-14-6.74-14-15.48s6.33-15.48,14-15.48c3.92,0,6.77,1.32,8.73,3.56v-13a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,211.11,62.27Zm-8.79,24.92c0-4.4-2.93-7.15-7-7.15s-7,2.76-7,7.15,2.93,7.15,7,7.15S202.32,91.58,202.32,87.18Z"/><path class="cls-4" d="M242.59,74v26.38a1.33,1.33,0,0,1-1.47,1.47h-5.86a1.33,1.33,0,0,1-1.47-1.47V99.16c-1.38,2-3.87,3.5-7.62,3.5-5.45,0-9.38-4.22-9.38-11.55V74a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,225.59,74V90.35c0,2.93,1.7,4.22,3.93,4.22,2.64,0,4.28-1.47,4.28-4.92V74a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,242.59,74Z"/><path class="cls-4" d="M277.53,92.34a14.76,14.76,0,0,1-14.42,10.32,15.48,15.48,0,1,1,0-31A14.75,14.75,0,0,1,277.53,82c.35,1-.23,1.64-1.23,1.64h-6.45a2.06,2.06,0,0,1-1.76-1,6,6,0,0,0-5-2.29,6.8,6.8,0,0,0,0,13.6,6.1,6.1,0,0,0,5-2.23,1.93,1.93,0,0,1,1.76-1.06h6.45C277.29,90.7,277.88,91.34,277.53,92.34Z"/><path class="cls-4" d="M282,67.54V62.27a1.33,1.33,0,0,1,1.47-1.47h5.86a1.33,1.33,0,0,1,1.47,1.47v5.28A1.33,1.33,0,0,1,289.37,69H283.5A1.33,1.33,0,0,1,282,67.54Zm0,32.83V74a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,290.83,74v26.38a1.33,1.33,0,0,1-1.47,1.47H283.5A1.33,1.33,0,0,1,282,100.37Z"/><path class="cls-4" d="M323.07,83.25v17.12a1.33,1.33,0,0,1-1.47,1.47h-5.86a1.33,1.33,0,0,1-1.47-1.47V84c0-2.93-1.7-4.22-3.93-4.22-2.64,0-4.28,1.47-4.28,4.92v15.65a1.33,1.33,0,0,1-1.47,1.47h-5.86a1.33,1.33,0,0,1-1.47-1.47V74a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,306.07,74V75.2c1.38-2,3.87-3.5,7.62-3.5C319.15,71.71,323.07,75.93,323.07,83.25Z"/><path class="cls-4" d="M357.37,72.52A1.33,1.33,0,0,1,358.83,74v26.38c0,9.85-7.91,14-15.07,14S329.87,111,329,103.95a1.32,1.32,0,0,1,1.47-1.52h5.92c.88,0,1.29.47,1.58,1.29.65,1.76,2.58,2.93,5.8,2.93,3.93,0,6.51-2.11,6.51-6.27V97.71c-2,2.34-4.89,3.78-9,3.78-7.68,0-14-6.74-14-14.89s6.33-14.89,14-14.89c4.08,0,7,1.43,9,3.78V74a1.33,1.33,0,0,1,1.47-1.47h5.63Zm-7.09,14.07c0-4-2.93-6.8-7.09-6.8s-7.09,2.76-7.09,6.8,2.93,6.8,7.09,6.8S350.27,90.64,350.27,86.59Z"/><path class="cls-4" d="M410.71,62.27v38.11a1.33,1.33,0,0,1-1.47,1.47h-6.45a1.33,1.33,0,0,1-1.47-1.47V85.25H389.6v15.13a1.33,1.33,0,0,1-1.47,1.47h-6.45a1.33,1.33,0,0,1-1.47-1.47V62.27a1.33,1.33,0,0,1,1.47-1.47h6.45a1.33,1.33,0,0,1,1.47,1.47v14h11.72v-14a1.33,1.33,0,0,1,1.47-1.47h6.45A1.33,1.33,0,0,1,410.71,62.27Z"/><path class="cls-4" d="M446.47,87.18c0,.76-.06,1.47-.12,2.17a1.42,1.42,0,0,1-1.58,1.35H425.19c1.06,3.48,3.8,4.87,6.86,4.87a7,7,0,0,0,4.34-1.47,2.68,2.68,0,0,1,1.82-.76l5.63-.06c1.06,0,1.64.7,1.17,1.64-2.29,5.1-7.09,7.74-13.07,7.74-9.73,0-15.95-6.74-15.95-15.48s6.45-15.48,15.71-15.48C440.25,71.71,446.47,78.33,446.47,87.18ZM437.71,84a5.87,5.87,0,0,0-6.08-4.51c-3.3,0-5.58,1.59-6.48,4.51Z"/><path class="cls-4" d="M475.66,83.37v17a1.33,1.33,0,0,1-1.47,1.47h-5.63a1.33,1.33,0,0,1-1.47-1.47v-.84c-1.57,1.84-3.88,3.12-7.56,3.12-5.16,0-9.67-3-9.67-9.15s4.51-9.15,9.67-9.15a11.92,11.92,0,0,1,7.56,2.24V84c0-2.87-1.17-4.16-3.63-4.16-1.82,0-2.93.7-3.4,1.7-.35.82-.65,1.29-1.52,1.29h-5.75a1.32,1.32,0,0,1-1.47-1.52c.76-6.33,6.16-9.56,12.14-9.56C469.91,71.71,475.66,75.46,475.66,83.37ZM467.1,93.51c0-1.82-1.58-2.93-4.46-2.93-2.7,0-4,1.23-4,2.93s1.29,2.93,4,2.93C465.52,96.44,467.1,95.21,467.1,93.51Z"/><path class="cls-4" d="M511.41,62.27v38.11a1.33,1.33,0,0,1-1.47,1.47h-5.86a1.33,1.33,0,0,1-1.47-1.47V99.1c-2,2.23-4.81,3.56-8.73,3.56-7.68,0-14-6.74-14-15.48s6.33-15.48,14-15.48c3.92,0,6.77,1.32,8.73,3.56v-13a1.33,1.33,0,0,1,1.47-1.47h5.86A1.33,1.33,0,0,1,511.41,62.27Zm-8.79,24.92c0-4.4-2.93-7.15-7-7.15s-7,2.76-7,7.15,2.93,7.15,7,7.15S502.62,91.58,502.62,87.18Z"/><path class="cls-4" d="M546.88,87.18c0,.76-.06,1.47-.12,2.17a1.42,1.42,0,0,1-1.58,1.35H525.6c1.07,3.48,3.8,4.87,6.86,4.87a7,7,0,0,0,4.34-1.47,2.68,2.68,0,0,1,1.82-.76l5.63-.06c1.05,0,1.64.7,1.17,1.64-2.29,5.1-7.09,7.74-13.07,7.74-9.73,0-15.95-6.74-15.95-15.48s6.45-15.48,15.71-15.48C540.66,71.71,546.88,78.33,546.88,87.18ZM538.12,84A5.87,5.87,0,0,0,532,79.5c-3.3,0-5.58,1.59-6.48,4.51Z"/><path class="cls-4" d="M566.63,72.06c1-.18,1.52.47,1.52,1.41v6.92c0,.94-.41,1.41-1.17,1.41-3.28-.12-6.45,1.52-6.45,6.21v12.37a1.33,1.33,0,0,1-1.46,1.47h-5.86a1.33,1.33,0,0,1-1.46-1.47V74a1.33,1.33,0,0,1,1.46-1.47h5.86A1.33,1.33,0,0,1,560.53,74v3.17a7.13,7.13,0,0,1,6.1-5.1Z"/><path class="cls-4" d="M594.89,93c0,6.74-5.75,9.61-12.19,9.61-6,0-11.37-2.7-12.08-8.91A1.26,1.26,0,0,1,572,92.22h5.75c.88,0,1.17.47,1.58,1.23.47,1,1.58,1.58,3.34,1.58,2.46,0,3.4-.82,3.4-2,0-4.22-15.3-.35-15.3-11.73,0-6.62,5.75-9.61,11.9-9.61,5.45,0,10.79,2.7,11.49,8.91a1.26,1.26,0,0,1-1.41,1.52H587c-.88,0-1.17-.47-1.58-1.29a2.82,2.82,0,0,0-2.75-1.52c-2.17,0-3.11.82-3.11,2C579.58,85.66,594.89,81.61,594.89,93Z"/></g><g class="cls-3"><path class="cls-4" d="M57,311.69a14.45,14.45,0,0,1,14.82-14.82,14,14,0,0,1,13.72,10,.84.84,0,0,1-.9,1.14H79.84a1.17,1.17,0,0,1-1.14-.81,7.32,7.32,0,0,0-6.88-4c-5,0-8.31,3.38-8.31,8.47s3.26,8.47,8.31,8.47a7.32,7.32,0,0,0,6.88-4,1.17,1.17,0,0,1,1.14-.81h4.81c.69,0,1.06.41.9,1.06a14,14,0,0,1-13.72,10.1A14.45,14.45,0,0,1,57,311.69Z"/><path class="cls-4" d="M88.43,324.92V297.64a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v27.29a.92.92,0,0,1-1,1H89.45A.92.92,0,0,1,88.43,324.92Z"/><path class="cls-4" d="M99,302.11v-3.67a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v3.67a.92.92,0,0,1-1,1H100A.92.92,0,0,1,99,302.11Zm0,22.81V306.59a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v18.33a.92.92,0,0,1-1,1H100A.92.92,0,0,1,99,324.92Z"/><path class="cls-4" d="M129.4,319.34a10.25,10.25,0,0,1-10,7.17,10.75,10.75,0,1,1,0-21.5,10.25,10.25,0,0,1,10,7.17c.24.69-.16,1.14-.86,1.14h-4.48a1.43,1.43,0,0,1-1.22-.69,4.15,4.15,0,0,0-3.46-1.59,4.72,4.72,0,0,0,0,9.45,4.24,4.24,0,0,0,3.46-1.55,1.34,1.34,0,0,1,1.22-.73h4.48C129.24,318.2,129.64,318.65,129.4,319.34Z"/><path class="cls-4" d="M150.17,325.94h-4.64a1.35,1.35,0,0,1-1.22-.65L138.64,317v7.91a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V298.45a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v16l5.25-8.2a1.35,1.35,0,0,1,1.22-.65h4.68c.81,0,1.1.53.65,1.22l-6,9,6.31,9C151.27,325.41,151,325.94,150.17,325.94Z"/><path class="cls-4" d="M175.09,306.59v3.83a.92.92,0,0,1-1,1h-2.24v13.48a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V311.44h-2.24a.92.92,0,0,1-1-1v-3.83a.92.92,0,0,1,1-1h2.24v-5.5a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v5.5h2.24A.92.92,0,0,1,175.09,306.59Z"/><path class="cls-4" d="M176.51,315.76a10.79,10.79,0,1,1,10.79,10.75A10.67,10.67,0,0,1,176.51,315.76Zm15.48,0a4.69,4.69,0,1,0-4.68,4.81A4.57,4.57,0,0,0,192,315.76Z"/><path class="cls-4" d="M211.73,324.92V297.64a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v27.29a.92.92,0,0,1-1,1h-4.07A.92.92,0,0,1,211.73,324.92Z"/><path class="cls-4" d="M242.48,315.76c0,.53,0,1-.08,1.51a1,1,0,0,1-1.1.94H227.7a4.62,4.62,0,0,0,4.76,3.38,4.88,4.88,0,0,0,3-1,1.86,1.86,0,0,1,1.26-.53l3.91,0c.73,0,1.14.49.81,1.14-1.59,3.54-4.93,5.38-9.08,5.38-6.76,0-11.08-4.68-11.08-10.75A10.51,10.51,0,0,1,232.22,305C238.16,305,242.48,309.61,242.48,315.76Zm-6.08-2.2a4.08,4.08,0,0,0-4.22-3.14,4.33,4.33,0,0,0-4.5,3.14Z"/><path class="cls-4" d="M262.76,313.11v11.81a.92.92,0,0,1-1,1h-3.91a.92.92,0,0,1-1-1v-.58a6.44,6.44,0,0,1-5.25,2.17c-3.58,0-6.72-2.12-6.72-6.35s3.14-6.35,6.72-6.35a8.28,8.28,0,0,1,5.25,1.55v-1.84c0-2-.81-2.89-2.53-2.89a2.39,2.39,0,0,0-2.36,1.18c-.24.57-.45.9-1.06.9h-4a.92.92,0,0,1-1-1.06c.53-4.4,4.28-6.64,8.43-6.64C258.77,305,262.76,307.61,262.76,313.11Zm-5.95,7c0-1.26-1.1-2-3.1-2s-2.77.86-2.77,2,.9,2,2.77,2S256.81,321.34,256.81,320.16Z"/><path class="cls-4" d="M277.05,305.25c.69-.12,1.06.33,1.06,1V311c0,.65-.29,1-.81,1-2.28-.08-4.48,1.06-4.48,4.32v8.59a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V306.59a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v2.2a5,5,0,0,1,4.24-3.54Z"/><path class="cls-4" d="M298.68,313v11.89a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V313.56c0-2-1.18-2.93-2.73-2.93-1.83,0-3,1-3,3.42v10.87a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V306.59a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v.84a6,6,0,0,1,5.29-2.43C295.95,305,298.68,307.94,298.68,313Z"/><path class="cls-4" d="M333.78,305c4,0,6.31,2.52,6.31,7.21v12.71a.92.92,0,0,1-1,1H335a.92.92,0,0,1-1-1V312.74a1.89,1.89,0,0,0-2.12-2.12c-1.22,0-2.36.61-2.36,2.61v11.69a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V312.74a1.89,1.89,0,0,0-2.12-2.12c-1.22,0-2.36.61-2.36,2.61v11.69a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V306.6a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v.83A5.47,5.47,0,0,1,323.6,305a5.32,5.32,0,0,1,4.72,2.42,7.12,7.12,0,0,1,5.46-2.42Z"/><path class="cls-4" d="M343,315.76a10.79,10.79,0,1,1,10.79,10.75A10.67,10.67,0,0,1,343,315.76Zm15.48,0a4.69,4.69,0,1,0-4.68,4.81A4.57,4.57,0,0,0,358.49,315.76Z"/><path class="cls-4" d="M378.41,305.25c.69-.12,1.06.33,1.06,1V311c0,.65-.29,1-.81,1-2.28-.08-4.48,1.06-4.48,4.32v8.59a.92.92,0,0,1-1,1h-4.07a.92.92,0,0,1-1-1V306.59a.92.92,0,0,1,1-1h4.07a.92.92,0,0,1,1,1v2.2a5,5,0,0,1,4.24-3.54Z"/><path class="cls-4" d="M401.86,315.76c0,.53,0,1-.08,1.51a1,1,0,0,1-1.1.94h-13.6a4.62,4.62,0,0,0,4.76,3.38,4.88,4.88,0,0,0,3-1,1.86,1.86,0,0,1,1.26-.53l3.91,0c.73,0,1.14.49.81,1.14-1.59,3.54-4.93,5.38-9.08,5.38-6.76,0-11.08-4.68-11.08-10.75A10.51,10.51,0,0,1,391.6,305C397.55,305,401.86,309.61,401.86,315.76Zm-6.08-2.2a4.08,4.08,0,0,0-4.22-3.14,4.33,4.33,0,0,0-4.5,3.14Z"/><path class="cls-4" d="M404.63,324.92v-4.48a.92.92,0,0,1,1-1h4.48a.92.92,0,0,1,1,1v4.48a.92.92,0,0,1-1,1h-4.48A.92.92,0,0,1,404.63,324.92Z"/></g><g class="cls-5"><path class="cls-4" d="M65.73,126.73v3.72H71.5a.58.58,0,0,1,.64.64v2.67a.58.58,0,0,1-.64.64H65.73v5.69a.58.58,0,0,1-.64.64H62.27a.58.58,0,0,1-.64-.64V123.42a.58.58,0,0,1,.64-.64h9.36a.58.58,0,0,1,.64.64v2.67a.58.58,0,0,1-.64.64Z"/><path class="cls-4" d="M73.81,134.31a6.79,6.79,0,1,1,6.79,6.77A6.72,6.72,0,0,1,73.81,134.31Zm9.74,0a2.95,2.95,0,1,0-2.95,3A2.87,2.87,0,0,0,83.55,134.31Z"/><path class="cls-4" d="M96.08,127.7c.44-.08.67.21.67.62v3c0,.41-.18.62-.51.62a2.5,2.5,0,0,0-2.82,2.72v5.41a.58.58,0,0,1-.64.64H90.21a.58.58,0,0,1-.64-.64V128.55a.58.58,0,0,1,.64-.64h2.56a.58.58,0,0,1,.64.64v1.39a3.12,3.12,0,0,1,2.67-2.23Z"/><path class="cls-4" d="M109.06,126.73v3.72h5.77a.58.58,0,0,1,.64.64v2.67a.58.58,0,0,1-.64.64h-5.77v5.69a.58.58,0,0,1-.64.64H105.6a.58.58,0,0,1-.64-.64V123.42a.58.58,0,0,1,.64-.64H115a.58.58,0,0,1,.64.64v2.67a.58.58,0,0,1-.64.64Z"/><path class="cls-4" d="M128.28,132.65v7.43a.58.58,0,0,1-.64.64h-2.46a.58.58,0,0,1-.64-.64v-.37a4.05,4.05,0,0,1-3.31,1.37c-2.26,0-4.23-1.33-4.23-4s2-4,4.23-4a5.21,5.21,0,0,1,3.31,1V132.9c0-1.26-.51-1.82-1.59-1.82a1.51,1.51,0,0,0-1.49.74c-.15.36-.28.56-.67.56h-2.51a.58.58,0,0,1-.64-.67c.33-2.77,2.69-4.18,5.31-4.18C125.77,127.55,128.28,129.19,128.28,132.65Zm-3.74,4.43c0-.79-.69-1.28-1.95-1.28s-1.74.54-1.74,1.28.56,1.28,1.74,1.28S124.54,137.83,124.54,137.08Z"/><path class="cls-4" d="M140.92,136.88c0,2.95-2.51,4.2-5.33,4.2-2.62,0-5-1.18-5.28-3.9a.55.55,0,0,1,.62-.67h2.51c.38,0,.51.21.69.54a1.47,1.47,0,0,0,1.46.69c1.08,0,1.49-.36,1.49-.87,0-1.85-6.69-.15-6.69-5.13,0-2.9,2.51-4.2,5.2-4.2,2.38,0,4.72,1.18,5,3.9a.55.55,0,0,1-.62.67h-2.51c-.38,0-.51-.21-.69-.56a1.23,1.23,0,0,0-1.2-.67c-.95,0-1.36.36-1.36.87C134.23,133.65,140.92,131.88,140.92,136.88Z"/><path class="cls-4" d="M149.9,128.55V131a.58.58,0,0,1-.64.64h-1.41v8.48a.58.58,0,0,1-.64.64h-2.56a.58.58,0,0,1-.64-.64V131.6h-1.41A.58.58,0,0,1,142,131v-2.41a.58.58,0,0,1,.64-.64H144v-3.46a.58.58,0,0,1,.64-.64h2.56a.58.58,0,0,1,.64.64v3.46h1.41A.58.58,0,0,1,149.9,128.55Z"/><path class="cls-4" d="M165.15,123.42v16.66a.58.58,0,0,1-.64.64h-2.82a.58.58,0,0,1-.64-.64v-6.61h-5.13v6.61a.58.58,0,0,1-.64.64h-2.82a.58.58,0,0,1-.64-.64V123.42a.58.58,0,0,1,.64-.64h2.82a.58.58,0,0,1,.64.64v6.1H161v-6.1a.58.58,0,0,1,.64-.64h2.82A.58.58,0,0,1,165.15,123.42Z"/><path class="cls-4" d="M179,128.55v11.54a.58.58,0,0,1-.64.64h-2.56a.58.58,0,0,1-.64-.64v-.53a3.8,3.8,0,0,1-3.33,1.53c-2.38,0-4.1-1.85-4.1-5v-7.49a.58.58,0,0,1,.64-.64H171a.58.58,0,0,1,.64.64v7.15a1.63,1.63,0,0,0,1.72,1.85c1.15,0,1.87-.64,1.87-2.15v-6.84a.58.58,0,0,1,.64-.64h2.56A.58.58,0,0,1,179,128.55Z"/><path class="cls-4" d="M195.66,134.31c0,3.82-2.77,6.77-6.13,6.77a4.82,4.82,0,0,1-3.82-1.56v.56a.58.58,0,0,1-.64.64h-2.56a.58.58,0,0,1-.64-.64V123.42a.58.58,0,0,1,.64-.64h2.56a.58.58,0,0,1,.64.64v5.68a4.82,4.82,0,0,1,3.82-1.56C192.89,127.55,195.66,130.5,195.66,134.31Zm-3.85,0a3.05,3.05,0,1,0-3.05,3.13A2.93,2.93,0,0,0,191.81,134.31Z"/></g><g class="cls-6"><rect class="cls-7" x="579.19" y="145.62" width="746.87" height="138.24" transform="translate(127.17 736.5) rotate(-45)"/></g></svg>
    \ No newline at end of file
    diff --git a/app/src/main/res/layouts/main_layouts/layout-v26/login_form_layout.xml b/app/src/main/res/layouts/main_layouts/layout-v26/login_form_layout.xml
    deleted file mode 100644
    index bb724de0..00000000
    --- a/app/src/main/res/layouts/main_layouts/layout-v26/login_form_layout.xml
    +++ /dev/null
    @@ -1,168 +0,0 @@
    -<?xml version="1.0" encoding="utf-8"?>
    -<android.support.design.widget.CoordinatorLayout
    -    xmlns:android="http://schemas.android.com/apk/res/android"
    -    xmlns:app="http://schemas.android.com/apk/res-auto"
    -    xmlns:tools="http://schemas.android.com/tools"
    -    android:layout_width="match_parent"
    -    android:layout_height="match_parent"
    -    android:background="@color/material_indigo_700"
    -    android:fitsSystemWindows="true"
    -    android:orientation="vertical"
    -    app:statusBarBackground="@color/material_indigo_900"
    -    tools:context=".ui.modules.login.LoginActivity"
    -    tools:ignore="Overdraw">
    -
    -    <android.support.v4.widget.NestedScrollView
    -        android:layout_width="match_parent"
    -        android:layout_height="wrap_content"
    -        android:layout_gravity="center">
    -
    -        <android.support.v7.widget.CardView
    -            android:layout_width="wrap_content"
    -            android:layout_height="wrap_content"
    -            android:layout_gravity="center"
    -            android:layout_margin="@dimen/spacing_s_large"
    -            android:minHeight="350dp"
    -            android:minWidth="250dp"
    -            app:cardElevation="@dimen/spacing_normal">
    -
    -            <LinearLayout
    -                android:id="@+id/loginForm"
    -                android:layout_width="match_parent"
    -                android:layout_height="wrap_content"
    -                android:orientation="vertical">
    -
    -
    -                <com.fastaccess.ui.widgets.FontTextView
    -                    android:id="@+id/mainCard"
    -                    style="@style/TextAppearance.AppCompat.Title.Inverse"
    -                    android:layout_width="match_parent"
    -                    android:layout_height="wrap_content"
    -                    android:layout_gravity="center"
    -                    android:background="?colorAccent"
    -                    android:gravity="center"
    -                    android:paddingBottom="@dimen/spacing_large"
    -                    android:paddingEnd="@dimen/spacing_xs_large"
    -                    android:paddingStart="@dimen/spacing_xs_large"
    -                    android:paddingTop="@dimen/spacing_large"
    -                    android:text="@string/sign_in_to_github"/>
    -
    -                <LinearLayout
    -                    android:layout_width="match_parent"
    -                    android:layout_height="wrap_content"
    -                    android:layout_gravity="center"
    -                    android:layout_marginTop="@dimen/spacing_normal"
    -                    android:gravity="center"
    -                    android:orientation="vertical"
    -                    android:paddingBottom="@dimen/spacing_normal"
    -                    android:paddingEnd="@dimen/spacing_xs_large"
    -                    android:paddingStart="@dimen/spacing_xs_large"
    -                    android:paddingTop="@dimen/spacing_normal">
    -
    -                    <android.support.design.widget.TextInputLayout
    -                        android:id="@+id/username"
    -                        android:layout_width="match_parent"
    -                        android:layout_height="wrap_content"
    -                        android:hint="@string/username">
    -
    -                        <android.support.design.widget.TextInputEditText
    -                            android:id="@+id/usernameEditText"
    -                            android:layout_width="match_parent"
    -                            android:layout_height="wrap_content"
    -                            android:inputType="text"
    -                            android:maxLines="1"/>
    -                    </android.support.design.widget.TextInputLayout>
    -
    -                    <android.support.design.widget.TextInputLayout
    -                        android:id="@+id/password"
    -                        android:layout_width="match_parent"
    -                        android:layout_height="wrap_content"
    -                        android:layout_marginTop="@dimen/spacing_xs_large"
    -                        android:hint="@string/password"
    -                        app:passwordToggleEnabled="true"
    -                        app:passwordToggleTint="?colorAccent">
    -
    -                        <android.support.design.widget.TextInputEditText
    -                            android:id="@+id/passwordEditText"
    -                            android:layout_width="match_parent"
    -                            android:layout_height="wrap_content"
    -                            android:imeOptions="actionSend"
    -                            android:inputType="textPassword"
    -                            android:maxLines="1"/>
    -                    </android.support.design.widget.TextInputLayout>
    -
    -                    <android.support.design.widget.TextInputLayout
    -                        android:id="@+id/twoFactor"
    -                        android:layout_width="match_parent"
    -                        android:layout_height="wrap_content"
    -                        android:layout_marginTop="@dimen/spacing_xs_large"
    -                        android:hint="@string/twoFactor"
    -                        android:visibility="gone"
    -                        tools:visibility="visible">
    -
    -                        <android.support.design.widget.TextInputEditText
    -                            android:id="@+id/twoFactorEditText"
    -                            android:layout_width="match_parent"
    -                            android:layout_height="wrap_content"
    -                            android:imeOptions="actionSend"
    -                            android:inputType="text"
    -                            android:maxLines="1"/>
    -                    </android.support.design.widget.TextInputLayout>
    -
    -                    <FrameLayout
    -                        android:layout_width="wrap_content"
    -                        android:layout_height="wrap_content">
    -
    -                        <android.support.design.widget.FloatingActionButton
    -                            android:id="@+id/login"
    -                            android:layout_width="wrap_content"
    -                            android:layout_height="wrap_content"
    -                            android:layout_gravity="center"
    -                            android:layout_margin="@dimen/fab_margin"
    -                            android:src="@drawable/ic_send"
    -                            android:tint="@color/white"
    -                            app:fabSize="normal"/>
    -
    -                        <ProgressBar
    -                            android:id="@+id/progress"
    -                            android:layout_width="wrap_content"
    -                            android:layout_height="wrap_content"
    -                            android:layout_gravity="center"
    -                            android:layout_margin="@dimen/fab_margin"
    -                            android:visibility="gone"/>
    -                    </FrameLayout>
    -
    -                    <com.fastaccess.ui.widgets.FontTextView
    -                        style="@style/TextAppearance.AppCompat.Small"
    -                        android:layout_width="match_parent"
    -                        android:layout_height="wrap_content"
    -                        android:background="@drawable/bottom_border"
    -                        android:gravity="center"
    -                        android:paddingBottom="@dimen/spacing_normal"
    -                        android:text="@string/or_character"/>
    -
    -                    <com.fastaccess.ui.widgets.FontTextView
    -                        style="@style/TextAppearance.AppCompat.Small"
    -                        android:layout_width="match_parent"
    -                        android:layout_height="wrap_content"
    -                        android:layout_marginTop="@dimen/spacing_normal"
    -                        android:gravity="center"
    -                        android:text="@string/login_using_your_default_browser"/>
    -
    -                    <com.fastaccess.ui.widgets.FontButton
    -                        android:id="@+id/browserLogin"
    -                        style="@style/Widget.AppCompat.Button.Borderless.Colored"
    -                        android:layout_width="wrap_content"
    -                        android:layout_height="wrap_content"
    -                        android:text="@string/open_in_browser"/>
    -
    -                </LinearLayout>
    -            </LinearLayout>
    -
    -        </android.support.v7.widget.CardView>
    -
    -
    -    </android.support.v4.widget.NestedScrollView>
    -
    -
    -</android.support.design.widget.CoordinatorLayout>
    \ No newline at end of file
    diff --git a/app/src/main/res/layouts/main_layouts/layout/activity_settings.xml b/app/src/main/res/layouts/main_layouts/layout/activity_settings.xml
    index c31f1e66..92bf4d94 100644
    --- a/app/src/main/res/layouts/main_layouts/layout/activity_settings.xml
    +++ b/app/src/main/res/layouts/main_layouts/layout/activity_settings.xml
    @@ -1,7 +1,6 @@
     <?xml version="1.0" encoding="utf-8"?>
     <LinearLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
    -    xmlns:app="http://schemas.android.com/apk/res-auto"
         xmlns:tools="http://schemas.android.com/tools"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
    diff --git a/app/src/main/res/layouts/main_layouts/layout/gists_pager_layout.xml b/app/src/main/res/layouts/main_layouts/layout/gists_pager_layout.xml
    index 957a9ddf..4d69d563 100644
    --- a/app/src/main/res/layouts/main_layouts/layout/gists_pager_layout.xml
    +++ b/app/src/main/res/layouts/main_layouts/layout/gists_pager_layout.xml
    @@ -34,6 +34,17 @@
                         android:layout_height="?actionBarSize"
                         android:background="?colorPrimary">
     
    +                    <com.fastaccess.ui.widgets.ForegroundImageView
    +                        android:id="@+id/browser"
    +                        android:layout_width="wrap_content"
    +                        android:layout_height="wrap_content"
    +                        android:layout_gravity="center|end"
    +                        android:background="?selectableItemBackgroundBorderless"
    +                        android:contentDescription="@string/open_in_browser"
    +                        android:padding="@dimen/spacing_normal"
    +                        android:scaleType="centerCrop"
    +                        android:src="@drawable/ic_brower"/>
    +
                         <com.fastaccess.ui.widgets.ForegroundImageView
                             android:id="@+id/startGist"
                             android:layout_width="wrap_content"
    diff --git a/app/src/main/res/layouts/main_layouts/layout/trending_activity_layout.xml b/app/src/main/res/layouts/main_layouts/layout/trending_activity_layout.xml
    index 785d2a57..a6c5515c 100644
    --- a/app/src/main/res/layouts/main_layouts/layout/trending_activity_layout.xml
    +++ b/app/src/main/res/layouts/main_layouts/layout/trending_activity_layout.xml
    @@ -55,6 +55,7 @@
                         android:clickable="true"
                         android:focusable="true"
                         android:gravity="center"
    +                    android:maxLines="1"
                         android:padding="@dimen/spacing_normal"
                         android:text="@string/daily"
                         android:textColor="@color/search_tab_highlighter"/>
    @@ -69,6 +70,7 @@
                         android:clickable="true"
                         android:focusable="true"
                         android:gravity="center"
    +                    android:maxLines="1"
                         android:padding="@dimen/spacing_normal"
                         android:text="@string/weekly"
                         android:textColor="@color/search_tab_highlighter"/>
    @@ -83,6 +85,7 @@
                         android:clickable="true"
                         android:focusable="true"
                         android:gravity="center"
    +                    android:maxLines="1"
                         android:padding="@dimen/spacing_normal"
                         android:text="@string/monthly"
                         android:textColor="@color/search_tab_highlighter"/>
    @@ -105,4 +108,7 @@
             </LinearLayout>
     
         </android.support.design.widget.NavigationView>
    +
    +    <include layout="@layout/nav_menu_layout"/>
    +
     </android.support.v4.widget.DrawerLayout>
    \ No newline at end of file
    diff --git a/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml b/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml
    index 5160f615..446d9f85 100644
    --- a/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml
    +++ b/app/src/main/res/layouts/other_layouts/layout/simple_footer_list_dialog.xml
    @@ -80,12 +80,19 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content">
     
    -        <com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView
    -            android:id="@+id/recycler"
    +        <android.support.v4.widget.SwipeRefreshLayout
    +            android:id="@+id/refresh"
                 android:layout_width="match_parent"
    -            android:layout_height="wrap_content"
    -            android:scrollbars="vertical"
    -            app:layoutManager="@string/linear_layout_manager"/>
    +            android:layout_height="wrap_content">
    +
    +            <com.fastaccess.ui.widgets.recyclerview.DynamicRecyclerView
    +                android:id="@+id/recycler"
    +                android:layout_width="match_parent"
    +                android:layout_height="wrap_content"
    +                android:scrollbars="vertical"
    +                app:layoutManager="@string/linear_layout_manager"/>
    +
    +        </android.support.v4.widget.SwipeRefreshLayout>
     
             <include layout="@layout/state_layout"/>
         </FrameLayout>
    diff --git a/app/src/main/res/layouts/row_layouts/layout/comments_row_item.xml b/app/src/main/res/layouts/row_layouts/layout/comments_row_item.xml
    index 932e4888..69b187a3 100644
    --- a/app/src/main/res/layouts/row_layouts/layout/comments_row_item.xml
    +++ b/app/src/main/res/layouts/row_layouts/layout/comments_row_item.xml
    @@ -82,10 +82,10 @@
                 android:id="@+id/comment"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
    -            android:layout_marginBottom="@dimen/spacing_normal"
    +            android:layout_marginBottom="@dimen/spacing_micro"
                 android:layout_marginEnd="@dimen/spacing_xs_large"
    -            android:layout_marginStart="@dimen/avatar_margin"
    -            android:layout_marginTop="@dimen/spacing_normal"
    +            android:layout_marginStart="@dimen/spacing_xs_large"
    +            android:layout_marginTop="@dimen/spacing_micro"
                 android:textIsSelectable="true"/>
     
             <com.fastaccess.ui.widgets.FontTextView
    diff --git a/app/src/main/res/layouts/row_layouts/layout/feeds_row_no_image_item.xml b/app/src/main/res/layouts/row_layouts/layout/feeds_row_no_image_item.xml
    index 82eb04bb..3c0234d0 100644
    --- a/app/src/main/res/layouts/row_layouts/layout/feeds_row_no_image_item.xml
    +++ b/app/src/main/res/layouts/row_layouts/layout/feeds_row_no_image_item.xml
    @@ -28,13 +28,27 @@
                 android:transitionName="@string/title_transition"
                 tools:text="When one acquires music and afterlife, one is able to capture heaven."/>
     
    +        <com.fastaccess.ui.widgets.FontTextView
    +            android:id="@+id/description"
    +            style="@style/TextAppearance.AppCompat.Small"
    +            android:layout_width="match_parent"
    +            android:layout_height="wrap_content"
    +            android:maxLines="2"
    +            android:textColor="?android:attr/textColorSecondary"
    +            android:visibility="gone"
    +            tools:text="Hello World"
    +            tools:visibility="visible"/>
    +
             <com.fastaccess.ui.widgets.FontTextView
                 android:id="@+id/date"
                 style="@style/TextAppearance.AppCompat.Small"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
    -            android:textColor="?android:attr/textColorSecondary"
    +            android:drawablePadding="@dimen/spacing_normal"
    +            android:textColor="?android:attr/textColorTertiary"
    +            tools:drawableStart="@drawable/ic_notification"
                 tools:text="50 minutes ago"/>
    +
         </LinearLayout>
     
     </com.fastaccess.ui.widgets.ForegroundRelativeLayout>
    \ No newline at end of file
    diff --git a/app/src/main/res/layouts/row_layouts/layout/issue_detail_header_row_item.xml b/app/src/main/res/layouts/row_layouts/layout/issue_detail_header_row_item.xml
    index 06b4c2ad..7bd06ec8 100644
    --- a/app/src/main/res/layouts/row_layouts/layout/issue_detail_header_row_item.xml
    +++ b/app/src/main/res/layouts/row_layouts/layout/issue_detail_header_row_item.xml
    @@ -84,10 +84,10 @@
                 android:id="@+id/comment"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
    -            android:layout_marginBottom="@dimen/spacing_normal"
    +            android:layout_marginBottom="@dimen/spacing_micro"
                 android:layout_marginEnd="@dimen/spacing_xs_large"
    -            android:layout_marginStart="@dimen/avatar_margin"
    -            android:layout_marginTop="@dimen/spacing_normal"
    +            android:layout_marginStart="@dimen/spacing_xs_large"
    +            android:layout_marginTop="@dimen/spacing_micro"
                 android:textIsSelectable="true"/>
     
             <com.fastaccess.ui.widgets.FontTextView
    diff --git a/app/src/main/res/layouts/row_layouts/layout/no_emojies_comments_row_item.xml b/app/src/main/res/layouts/row_layouts/layout/no_emojies_comments_row_item.xml
    index f2b7050e..53cf36fd 100644
    --- a/app/src/main/res/layouts/row_layouts/layout/no_emojies_comments_row_item.xml
    +++ b/app/src/main/res/layouts/row_layouts/layout/no_emojies_comments_row_item.xml
    @@ -69,10 +69,10 @@
                 android:id="@+id/comment"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
    -            android:layout_marginBottom="@dimen/spacing_normal"
    +            android:layout_marginBottom="@dimen/spacing_micro"
                 android:layout_marginEnd="@dimen/spacing_xs_large"
    -            android:layout_marginStart="@dimen/avatar_margin"
    -            android:layout_marginTop="@dimen/spacing_normal"
    +            android:layout_marginStart="@dimen/spacing_xs_large"
    +            android:layout_marginTop="@dimen/spacing_micro"
                 android:textIsSelectable="true"/>
     
         </LinearLayout>
    diff --git a/app/src/main/res/layouts/row_layouts/layout/review_comments_row_item.xml b/app/src/main/res/layouts/row_layouts/layout/review_comments_row_item.xml
    index f46318e2..1bb0da7a 100644
    --- a/app/src/main/res/layouts/row_layouts/layout/review_comments_row_item.xml
    +++ b/app/src/main/res/layouts/row_layouts/layout/review_comments_row_item.xml
    @@ -80,10 +80,10 @@
                 android:id="@+id/comment"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
    -            android:layout_marginBottom="@dimen/spacing_normal"
    +            android:layout_marginBottom="@dimen/spacing_micro"
                 android:layout_marginEnd="@dimen/spacing_xs_large"
    -            android:layout_marginStart="@dimen/avatar_margin"
    -            android:layout_marginTop="@dimen/spacing_normal"
    +            android:layout_marginStart="@dimen/spacing_xs_large"
    +            android:layout_marginTop="@dimen/spacing_micro"
                 android:textIsSelectable="true"
                 tools:text="Hello World"/>
     
    diff --git a/app/src/main/res/layouts/row_layouts/layout/trending_row_item.xml b/app/src/main/res/layouts/row_layouts/layout/trending_row_item.xml
    index c0dbf2d0..e3bb8b99 100644
    --- a/app/src/main/res/layouts/row_layouts/layout/trending_row_item.xml
    +++ b/app/src/main/res/layouts/row_layouts/layout/trending_row_item.xml
    @@ -46,10 +46,10 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/spacing_micro"
    +            android:orientation="horizontal"
                 app:auto_gravity="start"
                 app:auto_orientation="horizontal">
     
    -
                 <com.fastaccess.ui.widgets.FontTextView
                     android:id="@+id/stars"
                     style="@style/TextAppearance.AppCompat.Small"
    @@ -91,6 +91,20 @@
                     app:drawableColor="?android:attr/textColorSecondary"
                     tools:text="50 minutes ago"/>
     
    +            <com.fastaccess.ui.widgets.FontTextView
    +                android:id="@+id/language"
    +                style="@style/TextAppearance.AppCompat.Caption"
    +                android:layout_width="wrap_content"
    +                android:layout_height="wrap_content"
    +                android:layout_gravity="center"
    +                android:layout_marginStart="@dimen/spacing_normal"
    +                android:drawablePadding="@dimen/spacing_micro"
    +                android:drawableStart="@drawable/ic_language_small"
    +                android:gravity="start|center"
    +                android:textColor="?android:attr/textColorSecondary"
    +                android:visibility="gone"
    +                app:drawableColor="?android:attr/textColorSecondary"
    +                tools:text="10000"/>
     
             </com.fastaccess.ui.widgets.AutoLinearLayout>
         </LinearLayout>
    diff --git a/app/src/main/res/raw/changelog.html b/app/src/main/res/raw/changelog.html
    index 752760d2..ebdcc6d0 100644
    --- a/app/src/main/res/raw/changelog.html
    +++ b/app/src/main/res/raw/changelog.html
    @@ -1,76 +1,75 @@
     <!DOCTYPE html>
     <html>
    -<body id="preview">
    -<h2><a id="FastHub_changelog_0"></a>FastHub changelog</h2>
    -<h3><a id="Version__250_2"></a>Version 2.5.0</h3>
    -<blockquote>
    -    <p><strong>P.S: I’m not asking for to much, if you are facing a problem in FastHub please report it at the issue tracker in GitHub either via
    -        FastHub app or from GitHub website, your reviews are what keeps me motivated to further improve FastHub.<br>
    -        Keep in mind that FastHub is free &amp; open source.</strong></p>
    -</blockquote>
    -<h4><a id="Bugs__Enhancements__new_Features_7"></a>Bugs , Enhancements &amp; new Features</h4>
    -<ul>
    -    <li>(FIX) Oauth login for good!</li>
    -    <li>(FIX) Notifications gets triggered every few seconds</li>
    -    <li>(New) Reply, edit, delete &amp; add PR review comment</li>
    -    <li>(New) Long click on Issue &amp; PR to peak details &amp; add comments faster</li>
    -    <li>(New) Github emoji support in comments &amp; profile bio</li>
    -    <li>(New) Reply, edit, delete &amp; add PR review comment</li>
    -    <li>(New) Reply, edit, delete &amp; add PR review comment</li>
    -    <li>(New) Second click on any top tab will scrollTop.</li>
    -    <li>(New) FastHub Signature</li>
    -    <li>(New) Backup settings option (Pinned Items are coming soon)</li>
    -    <li>(New) Ability to see the Orgs. a person is part of in their profile</li>
    -    <li>(New) Profile contribution Graph</li>
    -    <li>(New) Ability to choose theme accent color</li>
    -    <li>(New) Mentioning ‘@’ in comments.</li>
    -    <li>(New) Repo topics</li>
    -    <li>(New) Reply, now shows the message you’re replying too</li>
    -    <li>(New) Many android “O” items</li>
    -    <li>(New) Language bar on login where default lang is not supported</li>
    -    <li>(New) Created a share option for comments</li>
    -    <li>(New) More notification interval options</li>
    -    <li>(New) Opening repo directories from deep links</li>
    -    <li>(New) Opening releases links</li>
    -    <li>(New) Japanese language</li>
    -    <li>(New) Clicking user details in profile should open image in full</li>
    -    <li>(Enhancement) Redid profile layout</li>
    -    <li>(Enhancement) Redid the layout of the settings</li>
    -    <li>(Enhancement) Truncate PR review files to max 3 lines</li>
    -    <li>(Enhancement) Moved FastHub Repo from <code>DrawerLayout</code> to Pinned Items</li>
    -    <li>(Enhancement) Lowered the white color tone</li>
    -    <li>(Enhancement) More Efficient Markdown</li>
    -    <li>(Enhancement) Merged Gists into one tab</li>
    -    <li>(Enhancement) Issues and Pull Requests now display the repo they’re in</li>
    -    <li>(Enhancement) Reconfigured the Notification Options</li>
    -    <li>(Enhancement) Added the Issue Number to the feed and personal Issues</li>
    -    <li>(Enhancement) Removed the scrollbar for Reactions</li>
    -    <li>(Enhancement) Notifications on a comment now show the profile picture</li>
    -    <li>(Enhancement) You can now dismiss all hints at once</li>
    -    <li>(Enhancement) Removed color accent from <code>DrawerLayout</code></li>
    -    <li>(Enhancement) Code snippets now show in monospace font</li>
    -    <li>(Enhancement) Comments layout</li>
    -    <li>(Enhancement) Lists &amp; tasks lists in comments.</li>
    -    <li>(Fix) Showing more than 100 comments.</li>
    -    <li>(Fix) Fixed creating new issue link</li>
    -    <li>(Fix) Assignee in issues</li>
    -    <li>(Fix) Ability to react on the first comment</li>
    -    <li>(Fix) Tablet pictures not inline with text</li>
    -    <li>(Fix) Profile icon not updating</li>
    -    <li>(Fix) Changed the color of “Private” label to gray</li>
    -    <li>(Fix) Double progress bar.</li>
    -    <li>(Fix) Fix bolding and italic in the feed</li>
    -    <li>(Fix) Some spelling mistakes</li>
    -    <li>(Fix) Attempt to fix where FastHub would not re-load when muti-tasking</li>
    -    <li>(Fix) Reply editor would not initially focus</li>
    -    <li>(Fix) Hide Mark all as read if there are no unread items</li>
    -    <li>There are more stuff are not mentioned, find them out :p</li>
    -    <li>Lots of bug fixes</li>
    -</ul>
    -<blockquote>
    -    <p>Thanks to @JediBurrell, @yakov116 &amp; everyone who contributed either via reporting bugs or via code contribution</p>
    -</blockquote>
    -<p><strong>Thank you very much</strong></p>
    -</body>
    +    <head>
    +        <meta charset="utf-8">
    +        <title>Untitled Document.md</title>
    +        <style></style>
    +    </head>
    +    <body id="preview">
    +        <h2><a id="FastHub_changelog_0"></a>FastHub changelog
    +        </h2>
    +        <h3><a id="Version__301_Trending_Improvement_2"></a>Version 3.0.1 (Trending Improvement!)
    +        </h3>
    +        <blockquote>
    +            <p>
    +                <strong>P.S: I’m not asking for too much, if you are facing a problem in FastHub please report it at the issue tracker in GitHub
    +                    either via FastHub or from GitHub website, your reviews are what keeps me motivated to further improve FastHub.
    +                    <br>
    +                    Keep in mind that FastHub is free &amp; open source.
    +                </strong>
    +            </p>
    +        </blockquote>
    +        <h4><a id="Bugs__Enhancements__new_Features_301_7"></a>Bugs , Enhancements &amp; new Features (3.0.1)
    +        </h4>
    +        <ul>
    +            <li>(New) Showing language to Trending list items.</li>
    +            <li>(Fix) Description in Trending might show in wrong place.</li>
    +            <li>(Fix) Large files in dark theme text color.</li>
    +            <li>(Fix) Notifications after migrating to RxJava2 only one were showing.</li>
    +            <li>(Fix) Scrolling code in Readme causes header to move as well.</li>
    +            <li>(Fix) Personal Gists were opening some random gist.</li>
    +            <li>(Enhancement) Clicking on user avatar from profile will open their image in full screen.</li>
    +            <li>(Enhancement) No new line shows in wrong position.</li>
    +        </ul>
    +        <hr>
    +        <h4><a id="Bugs__Enhancements__new_Features_300_16"></a>Bugs , Enhancements &amp; new Features (3.0.0)
    +        </h4>
    +        <ul>
    +            <li>(New) Explore trending with all the languages out there.</li>
    +            <li>(New) Filter Repos (Thanks to @aadithyabk)</li>
    +            <li>(New) See specific user feed.</li>
    +            <li>(New) Display amount of starred repos.</li>
    +            <li>(New) Copy Repo URL to clipboard</li>
    +            <li>(New) Added participated issue sorting to personal issue list</li>
    +            <li>(New) Showing multiple build statues.</li>
    +            <li>(New) Lithuanian language (Thanks to @mistermantas)</li>
    +            <li>(New) no new line at end of file now shows a picture</li>
    +            <li>(Enhancement/Fix) Sort issues by reaction</li>
    +            <li>(Fix) Issues/PRs editing, was semi-broken in preview release</li>
    +            <li>(Fix) Showing missing repo (broken in previous version)</li>
    +            <li>(Fix) Support development now works,
    +                <em>please use it.</em>
    +            </li>
    +            <li>(Fix) Issue count not updating.</li>
    +            <li>(Fix) Emoji’s were joining :crossed_swords:</li>
    +            <li>(Fix) Back button when opening FastHub from an external link</li>
    +            <li>(Fix) Issue comment were only showing up to 100 comments</li>
    +            <li>(Fix) Dropdown menus not closing</li>
    +            <li>(Fix) Some tablets had text wrapping issues</li>
    +            <li>(Fix) Pictures not loading in PR’s/commits</li>
    +            <li>(Fix) Fixed crash when adding a react</li>
    +            <li>(Fix) Some tooltips were incorrect</li>
    +            <li>(Fix) Stargazers are now updated in pinned repo’s</li>
    +            <li>(Fix) Gist links (edited)</li>
    +            <li>There are more stuff are not mentioned, find them out :p</li>
    +            <li>Lots of bug fixes</li>
    +        </ul>
    +        <blockquote>
    +            <p>Thanks to everyone who contributed either via reporting bugs or via code contribution</p>
    +        </blockquote>
    +        <p>
    +            <strong>Thank you very much</strong>
    +        </p>
     
    -</html>
    +    </body>
    +</html>
    \ No newline at end of file
    diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
    index bfe48633..bf5b25a6 100644
    --- a/app/src/main/res/values-lt/strings.xml
    +++ b/app/src/main/res/values-lt/strings.xml
    @@ -105,12 +105,12 @@
         <string name="users">Naudotojai</string>
         <string name="title">Pavadinimas</string>
         <string name="file">Failas</string>
    -    <string name="milestone">Slenksčiai (etapai)</string>
    +    <string name="milestone">Tikslai (slenksčiai arba etapai)</string>
         <string name="assign_myself">Skirti sau</string>
         <string name="submit_issue">Pateikti taloną</string>
         <string name="error_creating_issue">Nepavyko sukurti taloną</string>
         <string name="create_issue">Kurti taloną</string>
    -    <string name="error_highlighting_editor">Please un-select highlighting to continue editing.</string>
    +    <string name="error_highlighting_editor">Atrinkite pažymėjimą, norint toliau redaguoti tekstą.</string>
         <string name="notifications">Pranešimai</string>
         <string name="unread_notification">Turite neperskaitytų pranešimų</string>
         <string name="open">Atverti</string>
    @@ -130,32 +130,32 @@
         <string name="login">Prisijungti</string>
         <string name="gist_description">Gisto aprašymas</string>
         <string name="avatar_click_hint">Gali peržiūrėti žmonių profilius, jeigu spustelėsi ant jų profilio paveikslėlių.</string>
    -    <string name="feeds_fork_hint">Long click on a fork event to open either the original or the forked repo.</string>
    +    <string name="feeds_fork_hint">Ilgiau spustelėk ant kopijavimo (fork) mygtuko, jei nori atverti orginalią talpyklą arba kopijuotą talpyklą (repo).</string>
         <string name="click_here_to_download_release_hint">Parsiųsti leidimą (-us)</string>
         <string name="options">Pasirinkimai</string>
    -    <string name="click_file_option_hint">Download file or share directory</string>
    -    <string name="comment_hint">Tap a comment to tag its author or to edit your comment.
    -        \nLong press your comment to delete it.</string>
    +    <string name="click_file_option_hint">Parsiųsti failą arba dalintis duomenimis</string>
    +    <string name="comment_hint">Spausk komentarą, jei nori pridėti etiketę arba keisti komentarą.
    +        \nIlgiau spaustelėk savo komentarą, norint jį ištrinti.</string>
         <string name="star_hint">Žvaigždės žymėjimas</string>
         <string name="watch">Stebėti</string>
         <string name="watch_hint">Stebėti talpyklą (repo)</string>
    -    <string name="pin_repo_hint">Pin repos to access them faster from the navigation drawer.</string>
    -    <string name="dismiss_all">Dismiss All</string>
    -    <string name="no_url">No URL found</string>
    -    <string name="last_updated">Last updated</string>
    -    <string name="preview">Preview</string>
    -    <string name="view_code">Syntax highlighter</string>
    -    <string name="click_to_toggle_highlighting">Toggle syntax highlighting.
    -        \nScroll the Markdown editor icons for more options.</string>
    -    <string name="creation_date">Creation date</string>
    -    <string name="creation_date_hint">When the file was created</string>
    -    <string name="last_updated_hint">When the file was last updated</string>
    -    <string name="mark_all_as_read">Mark all as read</string>
    -    <string name="all_notifications">All notifications</string>
    -    <string name="unread">Unread</string>
    -    <string name="all">All</string>
    -    <string name="delete_repo">Delete Repo</string>
    -    <string name="delete_repo_warning">Deleting this repo can\'t be undone</string>
    +    <string name="pin_repo_hint">Prisegtas talpyklas galima lengvai matyti viename sąraše, kuris randamas meniu.</string>
    +    <string name="dismiss_all">Atmesti viską</string>
    +    <string name="no_url">Nuoroda nebuvo rasta</string>
    +    <string name="last_updated">Pask. kart. atnaujinta</string>
    +    <string name="preview">Peržiūrėti</string>
    +    <string name="view_code">Sintaksės pabrėžimas</string>
    +    <string name="click_to_toggle_highlighting">Sintaksės pabrėžimas
    +        \nSlinkite ikonus „Markdown“ rengyklėje, jei norite daugiau pasirinkimų.</string>
    +    <string name="creation_date">Sukūrimo data</string>
    +    <string name="creation_date_hint">Kada failas buvo sukurtas</string>
    +    <string name="last_updated_hint">Kada failas buvo preitą kartą atnaujintas</string>
    +    <string name="mark_all_as_read">Perskaičiau</string>
    +    <string name="all_notifications">Visi pranešimai</string>
    +    <string name="unread">Neperskaityta</string>
    +    <string name="all">Viskas</string>
    +    <string name="delete_repo">Ištrinti talpyklą (repo)</string>
    +    <string name="delete_repo_warning">Jeigu ištrinsite šią talpyklą (repo), jos duomenys dings amžinai</string>
         <string name="thirty_minutes">30 min.</string>
         <string name="twenty_minutes">20 min.</string>
         <string name="ten_minutes">10 min.</string>
    @@ -171,118 +171,117 @@
         <string name="commented_on_issue">Paliko komentarą</string>
         <string name="member">Narys</string>
         <string name="pr_comment_review">PR komentaras</string>
    -    <string name="pushed">Pushed to</string>
    +    <string name="pushed">Nustumti pakeitimai (push; commit)</string>
         <string name="team_event">Komandos narys</string>
         <string name="deleted">Ištrynė</string>
         <string name="unknown">Nežinoma(-s)</string>
    -    <string name="commented_on_commit">Commented on commit</string>
    -    <string name="switch_branch">Switch branch</string>
    -    <string name="assignees">Assignees</string>
    -    <string name="edit">Edit</string>
    -    <string name="edited">\u2022 edited</string>
    -    <string name="update_issue">Update Issue</string>
    -    <string name="update_pull_request">Update Pull Request</string>
    -    <string name="no_milestones">No milestones</string>
    -    <string name="add">Add</string>
    -    <string name="done">Done</string>
    -    <string name="home">Home</string>
    -    <string name="create_milestone">Create Milestone</string>
    -    <string name="error_creating_milestone">Error creating milestone</string>
    -    <string name="due_on">Due on</string>
    -    <string name="no_assignees">No assignees</string>
    -    <string name="this_value">this</string>
    -    <string name="commits_reflected">Commits have been switched to the selected branch</string>
    -    <string name="general_settings">General</string>
    -    <string name="background_job_summary">Change how frequently FastHub checks for new notifications</string>
    -    <string name="background_job_title">Notification Sync Interval</string>
    -    <string name="every">Every</string>
    -    <string name="behavior">Behavior</string>
    -    <string name="customization">Customization</string>
    -    <string name="recycler_view_animation_summary">Enable list animations</string>
    -    <string name="recycler_view_animation_title">List Animation</string>
    -    <string name="back_button_summary">Disable dialog preventing accidental app closure</string>
    -    <string name="back_button_title">Press Back to Exit</string>
    -    <string name="restore">Restore</string>
    -    <string name="backup">Backup</string>
    -    <string name="backed_up">Successfully backed up!</string>
    -    <string name="select_backup">Select Backup to Restore</string>
    -    <string name="permission_failed">Permission Not Granted.</string>
    -    <string name="backup_summary">Last update: %s</string>
    -    <string name="now">Now</string>
    -    <string name="unsaved_data_warning">Any unsaved changes will be discarded</string>
    -    <string name="private_repo">Private</string>
    -    <string name="rect_avatar_summary">Use rounded rectangle avatars instead of circular avatars</string>
    -    <string name="rect_avatar_title">Avatar Appearance</string>
    -    <string name="rate_app">Rate this app</string>
    -    <string name="author">Author</string>
    -    <string name="fork_github">Fork on GitHub</string>
    -    <string name="send_email">Send an email</string>
    -    <string name="question_concerning_fasthub">Question concerning FastHub</string>
    -    <string name="feedback">Feedback</string>
    -    <string name="report_issue">Report an issue</string>
    -    <string name="report_issue_here">Having an issue? Report it here</string>
    -    <string name="about">About</string>
    -    <string name="notification_settings">Notification</string>
    -    <string name="turn_off">Turn off</string>
    -    <string name="unauthorized_user">Unauthorized user</string>
    -    <string name="two_factors_otp_error">Two factors OTP is required</string>
    -    <string name="no_issue">No issue</string>
    -    <string name="copy">Copy</string>
    -    <string name="success_copied">Copied</string>
    -    <string name="commit_message">Commit message</string>
    -    <string name="network_error">Error occurred while communicating to the server</string>
    -    <string name="unexpected_error">Unexpected error while requesting API</string>
    -    <string name="request_error">Error requesting server, please try again later</string>
    -    <string name="marking_as_read">Marking notification as read</string>
    -    <string name="forking_gist">Forking gist</string>
    -    <string name="login_using_your_default_browser">Login using your default browser (OAuth)</string>
    -    <string name="or_character">OR</string>
    -    <string name="mark_notification_title">Disable Notification Read Status</string>
    -    <string name="mark_notification_summary">Disable marking as read upon clicking a notification.</string>
    -    <string name="theme_title">Choose Theme</string>
    -    <string name="theme_summary">Choose your default theme</string>
    -    <string name="theme_color_summary">Choose theme accent color</string>
    -    <string name="theme_color_title">Theme Accent Color</string>
    +    <string name="commented_on_commit">Paliktas komentaras po pokyčių (commito)</string>
    +    <string name="switch_branch">Keisti skyrių (branch)</string>
    +    <string name="assignees">Paskirtieji</string>
    +    <string name="edit">Atnaujinti</string>
    +    <string name="edited">\u2022 pakeitė</string>
    +    <string name="update_issue">Atnajinti taloną</string>
    +    <string name="update_pull_request">Atnaujinti PR</string>
    +    <string name="no_milestones">Nepavyko sukurti tikslo (milestonų)</string>
    +    <string name="add">Pridėti</string>
    +    <string name="done">Baigta</string>
    +    <string name="home">Namai</string>
    +    <string name="create_milestone">Sukurti tikslą</string>
    +    <string name="error_creating_milestone">Nepavyko sukurti tikslą</string>
    +    <string name="due_on">Pabaigti pagal šią datą:</string>
    +    <string name="no_assignees">Nepaskirta</string>
    +    <string name="this_value">tai</string>
    +    <string name="commits_reflected">Pakeitimai (commit) buvo pakeisti į pasirinktą skyrių (branch)</string>
    +    <string name="general_settings">Bendra</string>
    +    <string name="background_job_summary">Kas kiek laiko „FastHub“ turėtų žiūrėti, ar yra naujų pranešimų automatiškai?</string>
    +    <string name="background_job_title">Pranešimų grėbimo intervalas</string>
    +    <string name="every">Kiekvieną/kas</string>
    +    <string name="behavior">Elgesys</string>
    +    <string name="customization">Pritaikymas tau</string>
    +    <string name="recycler_view_animation_summary">Įgalinti sąrašo animacija</string>
    +    <string name="recycler_view_animation_title">Sąrašo animacija</string>
    +    <string name="back_button_summary">Klausti ar noriu užverti „FastHub“</string>
    +    <string name="back_button_title">Dar kart spausk atgal, jei nori užverti programą</string>
    +    <string name="restore">Parsiųsti atsarg. kopijos duomenis</string>
    +    <string name="backup">Įkelti duomenis</string>
    +    <string name="backed_up">Padaryta atsarg. kopija!</string>
    +    <string name="select_backup">Padaryti atsarg. kopiją</string>
    +    <string name="permission_failed">Nėra leidimo</string>
    +    <string name="backup_summary">Atnaujinta: %s</string>
    +    <string name="now">Dabar</string>
    +    <string name="unsaved_data_warning">Jeigu neišsaugosite savo pakeitimų, jie dings</string>
    +    <string name="private_repo">Nėra paviešinta</string>
    +    <string name="rect_avatar_summary">Rodyti stačiakampius arba apskritimo tipo profilio nuotraukas    </string>
    +    <string name="rect_avatar_title">Profilio nuotraukų išvaizda</string>
    +    <string name="rate_app">Įvertink programėlę</string>
    +    <string name="author">Autorius</string>
    +    <string name="fork_github">Kopijuoti (fork) „GitHub“</string>
    +    <string name="send_email">Siųsti el. paštu</string>
    +    <string name="question_concerning_fasthub">Klausimas apie programą</string>
    +    <string name="feedback">Atsiliepimai</string>
    +    <string name="report_issue">Pranešti problemą</string>
    +    <string name="report_issue_here">Pranešk savo problemą (tik angl.)</string>
    +    <string name="about">Apie</string>
    +    <string name="notification_settings">Pranešimas</string>
    +    <string name="turn_off">Išjungti</string>
    +    <string name="unauthorized_user">Neautorizuotas naudotojas</string>
    +    <string name="two_factors_otp_error">Reikia 2FA OTP kodo</string>
    +    <string name="no_issue">Nėra talonų(-o)</string>
    +    <string name="copy">Kopijuoti</string>
    +    <string name="success_copied">Nukopijuota</string>
    +    <string name="commit_message">Pakeitimo (commito) pastabos</string>
    +    <string name="network_error">Nepavyko susisiekti su serveriu</string>
    +    <string name="unexpected_error">Supyko API serveris</string>
    +    <string name="request_error">Serveris supyko, pabandykite užkrauti iš naujo</string>
    +    <string name="marking_as_read">Kategorizuojamas, kaip perskaitytas</string>
    +    <string name="forking_gist">Kopijuojamas (fork) gistą</string>
    +    <string name="login_using_your_default_browser">Prisijungti naudojant naršykle (OAuth)</string>
    +    <string name="or_character">arba</string>
    +    <string name="mark_notification_title">Perskaičius pranešimą, nepažymėti kaip perskaitytą</string>
    +    <string name="mark_notification_summary">Nepažymėti pranešimą, kaip perskaitytą, kai jį noriu perskaityti</string>
    +    <string name="theme_title">Pasirinkti temą</string>
    +    <string name="theme_summary">Pasirinkti numatytą temą</string>
    +    <string name="theme_color_summary">Pasirinkti akcentinę spalvą</string>
    +    <string name="theme_color_title">Akcentinė spalva</string>
         <string name="website">Svetainė</string>
    -    <string name="support_development">Support Development</string>
    -    <string name="success_purchase_message">Thanks for being extremely awesome!</string>
    -    <string name="change_theme_warning">If the theme didn\'t apply properly, please kill and open the app manually.</string>
    -    <string name="pin">Pin</string>
    -    <string name="pinned">Pinned</string>
    -    <string name="unpin">Unpin</string>
    -    <string name="empty_pinned_repos">No pinned repositories yet, pin some to see them here</string>
    -    <string name="yes">Yes</string>
    -    <string name="no">No</string>
    -    <string name="no_feeds">No feeds</string>
    -    <string name="no_gists">No gists</string>
    -    <string name="no_comments">No comments</string>
    -    <string name="no_notifications">No notifications</string>
    -    <string name="no_followers">No followers</string>
    -    <string name="no_followings">No followings</string>
    -    <string name="no_repos">No repositories</string>
    -    <string name="no_starred_repos">No starred repositories</string>
    -    <string name="no_commits">No commits</string>
    -    <string name="no_contributors">No contributors</string>
    -    <string name="no_releases">No releases</string>
    -    <string name="no_closed_issues">No closed issues</string>
    -    <string name="no_opened_issues">No open issues</string>
    -    <string name="no_events">No events</string>
    -    <string name="no_open_pull_requests">No open pull requests</string>
    -    <string name="no_closed_pull_request">No closed pull requests</string>
    -    <string name="no_search_results">No search results</string>
    -    <string name="read_write_permission_explanation">Please accept the permissions in order for FastHub to
    -        store the files on your device to be able to view them</string>
    +    <string name="support_development">Paremkite programos autorių</string>
    +    <string name="success_purchase_message">Ačiū. Tu šaunus vaikinas (arba šauni panelė)!</string>
    +    <string name="change_theme_warning">Jeigu nematote pakeitimų, iš naujo įjunkite programėlę</string>
    +    <string name="pin">Prisegti</string>
    +    <string name="pinned">Prisegta</string>
    +    <string name="unpin">Atsegti</string>
    +    <string name="empty_pinned_repos">Nėra prisegtų talpyklų (repų)</string>
    +    <string name="yes">Taip</string>
    +    <string name="no">Ne</string>
    +    <string name="no_feeds">Nėra sratų</string>
    +    <string name="no_gists">Nėra gistų</string>
    +    <string name="no_comments">Nėra komentarų</string>
    +    <string name="no_notifications">Nėra pranešimų</string>
    +    <string name="no_followers">Niekas neseka</string>
    +    <string name="no_followings">Nieko neseka</string>
    +    <string name="no_repos">Nėra talpyklų (repo)</string>
    +    <string name="no_starred_repos">Nėra žvaigžzde pažymėtų talpyklų (repo)</string>
    +    <string name="no_commits">Nėra pakeitimų</string>
    +    <string name="no_contributors">Nėra bendrų autorių</string>
    +    <string name="no_releases">Nėra leidimų</string>
    +    <string name="no_closed_issues">Nėra užvertų talonų</string>
    +    <string name="no_opened_issues">Nėra atvertų talonų</string>
    +    <string name="no_events">Nėra įvykių</string>
    +    <string name="no_open_pull_requests">Nėra atvirų PR</string>
    +    <string name="no_closed_pull_request">Nėra užvertų PR</string>
    +    <string name="no_search_results">Paieška nieko nerado</string>
    +    <string name="read_write_permission_explanation">Leiskite programėlei talpinti failus, jeigu norite peržiūrėti juos</string>
         <string name="public_gists">Vieši gistai</string>
         <string name="enable_ads">Rodyti reklamas</string>
    -    <string name="no_issues">No issues</string>
    -    <string name="no_unread_notifications">No unread notifications.</string>
    +    <string name="no_issues">Nėra talonų</string>
    +    <string name="no_unread_notifications">Visi pranešimai perskaityti</string>
         <string name="my_gists">Mano gistai</string>
         <string name="changelog">Pakeitimai</string>
    -    <string name="notifications_hint">Click to open notifications list or swipe to dismiss</string>
    -    <string name="home_long_click_hint">Long press to navigate to main screen from anywhere</string>
    -    <string name="created">Created</string>
    -    <string name="assigned">Assigned</string>
    -    <string name="mentioned">Mentioned</string>
    +    <string name="notifications_hint">Spausk čia, jei nori peržiūrėti pranešimus ir slink pranešimo kortelę ant dešinės, jei nori pašalinti iš sąrašo</string>
    +    <string name="home_long_click_hint">Spustelėkite ilgiau, jei norite aplankyti pagr. ekraną bet kur</string>
    +    <string name="created">Sukurta</string>
    +    <string name="assigned">Paskirta</string>
    +    <string name="mentioned">Paminėta</string>
         <string name="name">Pavadinimas</string>
         <string name="color">Spalva</string>
         <string name="create_label">Sukurti etiketę</string>
    @@ -294,40 +293,40 @@
         <string name="no_members">Nėra narių</string>
         <string name="no_teams">Nėra grupelių</string>
         <string name="no_orgs">Nęra organizacijų</string>
    -    <string name="mark_as_read">Pažymėti, kad perskaitei</string>
    +    <string name="mark_as_read">Perskaičiau</string>
         <string name="animations">Animacijos</string>
         <string name="dialog_animation_summary">Įgalinti sarąšo animaciją</string>
         <string name="dialog_animation_title">Animacinis efektas</string>
    -    <string name="milestones">Slenksčiai (etapai)</string>
    -    <string name="assignee">Assignee</string>
    +    <string name="milestones">Tikslai</string>
    +    <string name="assignee">Paskirtasis</string>
         <string name="checks_failed">Patikrinime buvo rasta problemų</string>
         <string name="checks_pending">Vyksta patikrinimas</string>
         <string name="checks_passed">Viskas OK</string>
         <string name="sort">Rūšiuoti</string>
         <string name="newest">Naujausia (-s)</string>
         <string name="oldest">Seniausia (-s)</string>
    -    <string name="most_commented">Most commented</string>
    -    <string name="least_commented">Least commented</string>
    -    <string name="recently_updated">Recently updated</string>
    -    <string name="least_recent_updated">Least recently updated</string>
    -    <string name="up_to_date">You\'re up to date!</string>
    -    <string name="new_version">A new version is available.</string>
    +    <string name="most_commented">Daugiausiai koment.</string>
    +    <string name="least_commented">Mažiausiai koment.</string>
    +    <string name="recently_updated">Neseniai atnauj.</string>
    +    <string name="least_recent_updated">Seniaus. atnauj.</string>
    +    <string name="up_to_date">Viskas atnaujinta!</string>
    +    <string name="new_version">Nauja versija pasiekiama</string>
         <string name="empty_search_error">Kažką parašyk į tuščią laukelį!</string>
    -    <string name="long_press_repo_fab_hint">Long press to create issue ticket on the fly</string>
    -    <string name="commit_can_be_merged">This pull request can be merged</string>
    +    <string name="long_press_repo_fab_hint">Spustelėkite truputį ilgiau, jei norite sukurti taloną iš karto</string>
    +    <string name="commit_can_be_merged">Šie pakeitimai neturi konfliktų (PR)</string>
         <string name="reviewed">peržiūrėjo</string>
    -    <string name="dismissed_review">dismissed their review</string>
    -    <string name="approved_these_changes">approved these changes</string>
    -    <string name="no_reactions">No reactions</string>
    -    <string name="reactions">Reactions</string>
    -    <string name="wrap_content">Wrap content</string>
    -    <string name="wrap_code_summary">Wrap code in code viewer by default</string>
    -    <string name="wrap_code_title">Wrap Code</string>
    -    <string name="open_source_libs">Open source libraries</string>
    -    <string name="enable_notification_sound_summary">Enable notification sound once a notification is received.</string>
    +    <string name="dismissed_review">atmetė jų peržiūra (PR)</string>
    +    <string name="approved_these_changes">priėmė šiuos pakeitimus (PR)</string>
    +    <string name="no_reactions">Nėra reakcijų</string>
    +    <string name="reactions">Reakcijos</string>
    +    <string name="wrap_content">Teksto kėlimas į kitą liniją</string>
    +    <string name="wrap_code_summary">Kelti tekstą į kitą liniją, kai peržiūriamas turinys</string>
    +    <string name="wrap_code_title">Teksto kėlimas į kitą liniją</string>
    +    <string name="open_source_libs">Atviro kodo „bibliotekos“</string>
    +    <string name="enable_notification_sound_summary">Groti garsą, kai gaunu pranešimą.</string>
         <string name="enable_notification_sound_title">Įgalinti pranešimų garsą</string>
         <string name="enable_notification_title">Įgalinti pranešimus</string>
    -    <string name="login_with_personal_token">Prisijungti su „Personal Token“</string>
    +    <string name="login_with_personal_token">Prisijungti su „asmeniniu tokenu“</string>
         <string name="personal_token">Naudoti asmeninį tokeną</string>
         <string name="basic_login">Prisijungti „paprastai“</string>
         <string name="no_orgs_description">Nematai savo organizacijų? Žiūrėk čia:\nhttps://help.github.com/articles/about-third-party-application-restrictions\nArba iš naujo prisijunk naudodama (-s) tokeną, angl. „access token“.</string>
    @@ -341,7 +340,7 @@
         <string name="app_language">Programos kalba</string>
         <string name="language">Kalba</string>
         <string name="choose_language_title">Pasirinkti kalbą</string>
    -    <string name="choose_language_summary">Pasirinkite tokią, kuri jums lengviausia</string>
    +    <string name="choose_language_summary">Pasirinkite tokią, kuri jums lengviausia suprasti</string>
         <string name="un_subscribe">Atšaukti prenumeratą</string>
         <string name="from">nuo</string>
         <string name="in_value">viduje</string>
    @@ -358,7 +357,7 @@
         <string name="successfully_invited">Pavyko pakviesti</string>
         <string name="reply">Atsakyti</string>
         <string name="failed_selecting_image">Nepavyko užkrauti paveikslėlį</string>
    -    <string name="want_to_merge">noriu sujungti kodą</string>
    +    <string name="want_to_merge">noriu sujungti kodą (PR)</string>
         <string name="watchers">Stebėtojai</string>
         <string name="reviewers">Vertintojai</string>
         <string name="no_reviewers">Nėra vertintojų</string>
    @@ -370,14 +369,12 @@
         <string name="tags">Etiketės</string>
         <string name="add_comment">Pridėti komentarą</string>
         <string name="banners">Nauja funkcija: profilio viršeliai</string>
    -    <string name="banners_info">With FastHub 2.5.0, you can now better express yourself with banners
    -        for your profile page.\n\nAnyone using the FastHub app, will see your header, and you\'ll
    -        begin seeing other peoples headers as well! If you\'d like to create a banner for yourself,
    -        make it 1280x384 or divisible, otherwise, it may get cropped.\n\nYou can add or change your
    -        banner at any time, by creating a gist described "header.fst" with a file containing a
    -        direct link to the header image.\n\nOr even simpler, just use the built-in image chooser!
    +    <string name="banners_info">Pastabos: Profilio viršelius mato tik „FastHub“ 2.5+ programėlės vartotojai.
    +        Geriausias dydis viršeliui yra: 1280x384. Jeigu neturite „FastHub“ programėlės, bet vistiek
    +        norite pakeisti viršelį, sukurkite gistą, kuris pavadintas „header.fst“. Jis gali nustatyti
    +        jūsų viršelį. Giste turi būti nuoroda, kurioje yra patalpintas viršelis (pvz. „Imgur direct link“).
         </string>
    -    <string name="edit_banner">PASIRINKTI VIRŠLIO NUOTRAUKĄ</string>
    +    <string name="edit_banner">Pasirinkti viršelio nuotrauką</string>
         <string name="image_error">Nepavyko įkrauti paveikslėlį, dar kartą pabandykite vėliau.</string>
         <string name="trending">Populiaru</string>
         <string name="not_really_working">„GitHub“ neleidžia rūšiuoti pagal jaustukus dėl techninių limitacijų.</string>
    diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
    index 6ff29d37..bab39de9 100644
    --- a/app/src/main/res/values/arrays.xml
    +++ b/app/src/main/res/values/arrays.xml
    @@ -124,7 +124,7 @@
             <item>@string/all</item>
         </string-array>
     
    -    <string-array name="trending_days_array">
    +    <string-array name="trending_days_array" translatable="false">
             <item>Daily</item>
             <item>Weekly</item>
             <item>Monthly</item>
    diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
    index e49e7275..ecc0cada 100644
    --- a/app/src/main/res/values/strings.xml
    +++ b/app/src/main/res/values/strings.xml
    @@ -475,4 +475,8 @@
         <string name="type">Type</string>
         <string name="Sort">Sort</string>
         <string name="sort_direction">Sort direction</string>
    +    <string name="assignee_added">Assignee added successfully</string>
    +    <string name="reviewer_added">Reviewer added successfully</string>
    +    <string name="milestone_added">Milestone added successfully</string>
    +    <string name="feed">Feed</string>
     </resources>
    diff --git a/app/src/main/res/xml/fasthub_settings.xml b/app/src/main/res/xml/fasthub_settings.xml
    index f88d3b88..6a86d3fe 100644
    --- a/app/src/main/res/xml/fasthub_settings.xml
    +++ b/app/src/main/res/xml/fasthub_settings.xml
    @@ -1,7 +1,7 @@
     <?xml version="1.0" encoding="utf-8"?>
     <PreferenceScreen
         xmlns:android="http://schemas.android.com/apk/res/android"
    -    xmlns:app="http://schemas.android.com/apk/res-auto">
    +    >
     
         <PreferenceCategory android:title="@string/notification_settings">
     
    @@ -10,22 +10,22 @@
                 android:dialogTitle="@string/every"
                 android:entries="@array/notification_duration"
                 android:entryValues="@array/notification_duration"
    -            android:key="notificationTime"
                 android:icon="@drawable/ic_time"
    +            android:key="notificationTime"
                 android:summary="@string/background_job_summary"
                 android:title="@string/background_job_title"/>
     
             <SwitchPreference
                 android:defaultValue="false"
    -            android:key="markNotificationAsRead"
                 android:icon="@drawable/ic_check"
    +            android:key="markNotificationAsRead"
                 android:summary="@string/mark_notification_summary"
                 android:title="@string/mark_notification_title"/>
     
             <SwitchPreference
                 android:defaultValue="true"
    -            android:key="notificationSound"
                 android:icon="@drawable/ic_ring"
    +            android:key="notificationSound"
                 android:summary="@string/enable_notification_sound_summary"
                 android:title="@string/enable_notification_sound_title"/>
     
    @@ -43,8 +43,8 @@
                 android:dialogTitle="@string/theme_title"
                 android:entries="@array/theme_modes"
                 android:entryValues="@array/theme_modes"
    -            android:key="appTheme"
                 android:icon="@drawable/ic_brush"
    +            android:key="appTheme"
                 android:summary="@string/theme_summary"
                 android:title="@string/theme_title"/>
     
    @@ -53,8 +53,8 @@
                 android:dialogTitle="@string/theme_color_title"
                 android:entries="@array/theme_colors"
                 android:entryValues="@array/theme_colors"
    -            android:key="appColor"
                 android:icon="@drawable/ic_blank"
    +            android:key="appColor"
                 android:summary="@string/theme_color_summary"
                 android:title="@string/theme_color_title"/>
     
    @@ -107,29 +107,4 @@
     
         </PreferenceCategory>
     
    -    <PreferenceCategory android:title="@string/about">
    -
    -        <Preference
    -            android:key="joinSlack"
    -            android:title="@string/join_slack"/>
    -
    -        <Preference
    -            android:key="showChangelog"
    -            android:title="@string/changelog"/>
    -
    -        <Preference
    -            android:key="about"
    -            android:title="@string/about">
    -            <intent
    -                android:targetClass="com.fastaccess.ui.modules.about.FastHubAboutActivity"
    -                android:targetPackage="com.fastaccess.github"/>
    -        </Preference>
    -
    -        <Preference
    -            android:key="currentVersion"
    -            android:title="@string/app_name"
    -            app:summary="@string/current_version"/>
    -    </PreferenceCategory>
    -
    -
     </PreferenceScreen>
    \ No newline at end of file
    diff --git a/build.gradle b/build.gradle
    index 72846e86..87117820 100644
    --- a/build.gradle
    +++ b/build.gradle
    @@ -15,7 +15,6 @@ buildscript {
             espresseVersion = '2.2.2'
             requery = '1.3.2'
             kotlin_version = '1.1.2-4'
    -        retrojsoupVersion = '1.0.3'
         }
     
         repositories {
    @@ -24,7 +23,7 @@ buildscript {
             maven { url 'https://maven.fabric.io/public' }
         }
         dependencies {
    -        classpath 'com.android.tools.build:gradle:3.0.0-alpha2'
    +        classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
             classpath 'com.google.gms:google-services:3.0.0'
             classpath 'com.novoda:gradle-build-properties-plugin:0.3'
             classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
    diff --git a/debug_gradle.properties b/debug_gradle.properties
    index 95f8cf7a..d0ba5760 100644
    --- a/debug_gradle.properties
    +++ b/debug_gradle.properties
    @@ -5,4 +5,5 @@ android_key_alias=ALIAS
     github_client_id=GITHUB_CLIENT_ID
     github_secret=GITHUB_SECRET
     imgur_client_id=imgur_client_id
    -imgur_secret=imgur_secret
    \ No newline at end of file
    +imgur_secret=imgur_secret
    +redirect_url=fasthub://login
    \ No newline at end of file