// Path: android/Commons/src/triaina/commons/exception/SecurityRuntimeException.java
// public class SecurityRuntimeException extends CommonRuntimeException {
// 
// 	private static final long serialVersionUID = 6244026068714272574L;
// 
// 	private String mUrl;
// 
// 	public SecurityRuntimeException() {
// 		super();
// 	}
// 
// 	public SecurityRuntimeException(String detailMessage, Throwable throwable) {
// 		super(detailMessage, throwable);
// 	}
// 
// 	public SecurityRuntimeException(String detailMessage) {
// 		super(detailMessage);
// 	}
// 
// 	public SecurityRuntimeException(String detailMessage, String url) {
// 		this(detailMessage);
// 		mUrl = url;
// 	}
// 
// 	public SecurityRuntimeException(Throwable throwable) {
// 		super(throwable);
// 	}
// 
// 	public SecurityRuntimeException(Throwable throwable, String url) {
// 		this(throwable);
// 		mUrl = url;
// 	}
// 
// 	public String getUrl(){
// 		return mUrl;
// 	}
// }
// 
// Path: android/Commons/src/triaina/commons/utils/UriUtils.java
// public final class UriUtils {
//     private UriUtils() {
//     }
// 
//     public static boolean compareDomain(Uri uri, String domain) {
//         if (domain == null) {
//             return false;
//         }
// 
//         //in case domain string contains port values we need to make sure we are getting right value
//         //we will need only host, so we only need scheme to parse url
//         Uri domainUri = Uri.parse("http://" + domain);
// 
//         String originialDomain = uri.getHost();
//         String targetDomain = domainUri.getHost();
//         if (originialDomain == null || targetDomain == null) return false;
// 
//         int diff = originialDomain.length() - targetDomain.length();
// 
//         if (diff < 0) {  //hosts do not match or originialDomain and targetDomain subdomains does not match
//             return false;
//         } else if (diff > 0) { // hosts do not match, but this might be because originialDomain might have a subdomain
//             if (hostHasMatchingSubdomain(diff, originialDomain))
//                 return false; // original domain does not have a subdomain or subdomains does not match
//         }
// 
//         return targetDomain.equals(originialDomain.substring(diff));
//     }
// 
// 
//     private static boolean hostHasMatchingSubdomain(int diff, String originalDomain) {
//         return originalDomain.substring(diff - 1).charAt(0) != '.';
//     }
// 
// }


import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import org.json.JSONObject;
import java.net.URLEncoder;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import triaina.commons.exception.SecurityRuntimeException;
import triaina.commons.json.JSONConverter;
import triaina.commons.utils.JSONObjectUtils;
import triaina.commons.utils.UriUtils;
import triaina.webview.config.BridgeObjectConfig;
import triaina.webview.config.DomainConfig;
import triaina.webview.entity.Error;
import triaina.webview.entity.Params;
import triaina.webview.entity.Result;
import triaina.webview.exception.SkipDomainCheckRuntimeException;
    public static class WebViewClientProxy extends WebViewClient {
        private WebViewClient mWebViewClient;
        private DomainConfig mDomainConfig;
        private SecurityRuntimeExceptionResolver mSecurityRuntimeExceptionResolver;

        public WebViewClientProxy(WebViewClient webViewClient, DomainConfig domainConfig) {
            this(webViewClient, domainConfig, null);
        }

        public WebViewClientProxy(WebViewClient webViewClient, DomainConfig domainConfig, SecurityRuntimeExceptionResolver resolver) {
            mWebViewClient = webViewClient;
            mDomainConfig = domainConfig;
            mSecurityRuntimeExceptionResolver = resolver;
        }

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return mWebViewClient.shouldOverrideUrlLoading(view, url);
        }

        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            try {
                // XXX ugly
                mWebViewClient.onPageStarted(view, url, favicon);
            } catch (SkipDomainCheckRuntimeException exp) {
                return;
            }

            Uri uri = Uri.parse(url);
            String[] domains = mDomainConfig.getDomains();
            for (String domain : domains) {
// Path: android/Commons/src/triaina/commons/exception/SecurityRuntimeException.java
// public class SecurityRuntimeException extends CommonRuntimeException {
// 
// 	private static final long serialVersionUID = 6244026068714272574L;
// 
// 	private String mUrl;
// 
// 	public SecurityRuntimeException() {
// 		super();
// 	}
// 
// 	public SecurityRuntimeException(String detailMessage, Throwable throwable) {
// 		super(detailMessage, throwable);
// 	}
// 
// 	public SecurityRuntimeException(String detailMessage) {
// 		super(detailMessage);
// 	}
// 
// 	public SecurityRuntimeException(String detailMessage, String url) {
// 		this(detailMessage);
// 		mUrl = url;
// 	}
// 
// 	public SecurityRuntimeException(Throwable throwable) {
// 		super(throwable);
// 	}
// 
// 	public SecurityRuntimeException(Throwable throwable, String url) {
// 		this(throwable);
// 		mUrl = url;
// 	}
// 
// 	public String getUrl(){
// 		return mUrl;
// 	}
// }
// 
// Path: android/Commons/src/triaina/commons/utils/UriUtils.java
// public final class UriUtils {
//     private UriUtils() {
//     }
// 
//     public static boolean compareDomain(Uri uri, String domain) {
//         if (domain == null) {
//             return false;
//         }
// 
//         //in case domain string contains port values we need to make sure we are getting right value
//         //we will need only host, so we only need scheme to parse url
//         Uri domainUri = Uri.parse("http://" + domain);
// 
//         String originialDomain = uri.getHost();
//         String targetDomain = domainUri.getHost();
//         if (originialDomain == null || targetDomain == null) return false;
// 
//         int diff = originialDomain.length() - targetDomain.length();
// 
//         if (diff < 0) {  //hosts do not match or originialDomain and targetDomain subdomains does not match
//             return false;
//         } else if (diff > 0) { // hosts do not match, but this might be because originialDomain might have a subdomain
//             if (hostHasMatchingSubdomain(diff, originialDomain))
//                 return false; // original domain does not have a subdomain or subdomains does not match
//         }
// 
//         return targetDomain.equals(originialDomain.substring(diff));
//     }
// 
// 
//     private static boolean hostHasMatchingSubdomain(int diff, String originalDomain) {
//         return originalDomain.substring(diff - 1).charAt(0) != '.';
//     }
// 
// }


// Path: android/WebViewBridge/src/triaina/webview/WebViewBridge.java
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.webkit.HttpAuthHandler;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import org.json.JSONObject;
import java.net.URLEncoder;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import triaina.commons.exception.SecurityRuntimeException;
import triaina.commons.json.JSONConverter;
import triaina.commons.utils.JSONObjectUtils;
import triaina.commons.utils.UriUtils;
import triaina.webview.config.BridgeObjectConfig;
import triaina.webview.config.DomainConfig;
import triaina.webview.entity.Error;
import triaina.webview.entity.Params;
import triaina.webview.entity.Result;
import triaina.webview.exception.SkipDomainCheckRuntimeException;

    public static class WebViewClientProxy extends WebViewClient {
        private WebViewClient mWebViewClient;
        private DomainConfig mDomainConfig;
        private SecurityRuntimeExceptionResolver mSecurityRuntimeExceptionResolver;

        public WebViewClientProxy(WebViewClient webViewClient, DomainConfig domainConfig) {
            this(webViewClient, domainConfig, null);
        }

        public WebViewClientProxy(WebViewClient webViewClient, DomainConfig domainConfig, SecurityRuntimeExceptionResolver resolver) {
            mWebViewClient = webViewClient;
            mDomainConfig = domainConfig;
            mSecurityRuntimeExceptionResolver = resolver;
        }

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return mWebViewClient.shouldOverrideUrlLoading(view, url);
        }

        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            try {
                // XXX ugly
                mWebViewClient.onPageStarted(view, url, favicon);
            } catch (SkipDomainCheckRuntimeException exp) {
                return;
            }

            Uri uri = Uri.parse(url);
            String[] domains = mDomainConfig.getDomains();
            for (String domain : domains) {
                if (UriUtils.compareDomain(uri, domain))