// Path: src/main/java/com/nextgis/maplib/api/IGISApplication.java
// public interface IGISApplication
// {
//     /**
//      * @return A MapBase or any inherited classes or null if not created in application
//      */
//     MapBase getMap();
// 
//     /**
//      * @return A authority for sync purposes or empty string if not sync anything
//      */
//     String getAuthority();
// 
//     /**
//      * Add account to android account storage
//      * @param name Account name (must be uniq)
//      * @param url NextGIS Web Server URL
//      * @param login User login
//      * @param password User password
//      * @param token A token returned from NextGIS Web Server (may be empty string)
//      * @return true on success or false
//      */
//     boolean addAccount(String name, String url, String login, String password, String token);
// 
//     /**
//      * Update account information
//      * @param name Account name (the account must be exist)
//      * @param key The account key to change (i.e. URL)
//      * @param value The new value for key
//      */
//     void setUserData(String name, String key, String value);
// 
//     /**
//      * Change password for account
//      * @param name Account name (the account must be exist)
//      * @param value New password
//      */
//     void setPassword(String name,String value);
// 
//     /**
//      * @param accountName Account name
//      * @return Account by its name
//      */
//     Account getAccount(String accountName);
// 
//     /**
//      * Remove an account
//      * @param account Account to remove
//      * @return An @see AccountManagerFuture which resolves to a Boolean, true if the account has been successfully removed
//      */
//     AccountManagerFuture<Boolean> removeAccount(Account account);
// 
//     /**
//      * @param account Account object
//      * @return Account URL
//      */
//     String getAccountUrl(Account account);
// 
//     /**
//      * Return some account data
//      * @param account account object
//      * @param key key to return
//      * @return value in user key - value map
//      */
//     String getAccountUserData(Account account, String key);
// 
//     /**
//      * @param account Account object
//      * @return Account login
//      */
//     String getAccountLogin(Account account);
// 
//     /**
//      * @param account Account object
//      * @return Account password
//      */
//     String getAccountPassword(Account account);
// 
//     /**
//      * @return A GpsEventSource or null if not needed or created in application
//      */
//     GpsEventSource getGpsEventSource();
// 
//     /**
//      * Show settings Activity or nothing
//      */
//     void showSettings(String setting);
// 
//     /**
//      * Send target event to analytics
//      */
//     void sendEvent(String category, String action, String label);
// 
//     /**
//      * Send screen hit to analytics
//      */
//     void sendScreen(String name);
// 
//     /**
//      * Get accounts authenticator type
//      */
//     String getAccountsType();
// 
//     /**
//      * Get LayerFactory
//      */
//     LayerFactory getLayerFactory();
// }


import android.accounts.Account;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncInfo;
import android.os.Build;
import android.util.Base64;
import com.nextgis.maplib.api.IGISApplication;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import static com.nextgis.maplib.util.Constants.JSON_END_DATE_KEY;
import static com.nextgis.maplib.util.Constants.JSON_SIGNATURE_KEY;
import static com.nextgis.maplib.util.Constants.JSON_START_DATE_KEY;
import static com.nextgis.maplib.util.Constants.JSON_SUPPORTED_KEY;
import static com.nextgis.maplib.util.Constants.JSON_USER_ID_KEY;
import static com.nextgis.maplib.util.Constants.SUPPORT;
                    "06z5a0sd3NDbS++GMCJstcKxkzk5KLQljAJ85Jciiuy2vv14WU621ves8S9cMISO\n" + "HwIDAQAB";
            byte[] keyBytes = Base64.decode(key.getBytes("UTF-8"), Base64.DEFAULT);
            X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
            PublicKey publicKey = keyFactory.generatePublic(spec);

            // verify signature
            Signature signCheck = Signature.getInstance("SHA256withRSA");
            signCheck.initVerify(publicKey);
            signCheck.update(data.getBytes("UTF-8"));
            byte[] sigBytes = Base64.decode(signature, Base64.DEFAULT);
            return signCheck.verify(sigBytes);
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean isSyncActive(Account account, String authority) {
        return isSyncActiveHoneycomb(account, authority);
    }

    public static boolean isSyncActiveHoneycomb(Account account, String authority) {
        for (SyncInfo syncInfo : ContentResolver.getCurrentSyncs()) {
            if (syncInfo.account.equals(account) && syncInfo.authority.equals(authority)) {
                return true;
            }
        }
        return false;
    }

    public static AccountData getAccountData(Context context, String accountName) throws IllegalStateException {
// Path: src/main/java/com/nextgis/maplib/api/IGISApplication.java
// public interface IGISApplication
// {
//     /**
//      * @return A MapBase or any inherited classes or null if not created in application
//      */
//     MapBase getMap();
// 
//     /**
//      * @return A authority for sync purposes or empty string if not sync anything
//      */
//     String getAuthority();
// 
//     /**
//      * Add account to android account storage
//      * @param name Account name (must be uniq)
//      * @param url NextGIS Web Server URL
//      * @param login User login
//      * @param password User password
//      * @param token A token returned from NextGIS Web Server (may be empty string)
//      * @return true on success or false
//      */
//     boolean addAccount(String name, String url, String login, String password, String token);
// 
//     /**
//      * Update account information
//      * @param name Account name (the account must be exist)
//      * @param key The account key to change (i.e. URL)
//      * @param value The new value for key
//      */
//     void setUserData(String name, String key, String value);
// 
//     /**
//      * Change password for account
//      * @param name Account name (the account must be exist)
//      * @param value New password
//      */
//     void setPassword(String name,String value);
// 
//     /**
//      * @param accountName Account name
//      * @return Account by its name
//      */
//     Account getAccount(String accountName);
// 
//     /**
//      * Remove an account
//      * @param account Account to remove
//      * @return An @see AccountManagerFuture which resolves to a Boolean, true if the account has been successfully removed
//      */
//     AccountManagerFuture<Boolean> removeAccount(Account account);
// 
//     /**
//      * @param account Account object
//      * @return Account URL
//      */
//     String getAccountUrl(Account account);
// 
//     /**
//      * Return some account data
//      * @param account account object
//      * @param key key to return
//      * @return value in user key - value map
//      */
//     String getAccountUserData(Account account, String key);
// 
//     /**
//      * @param account Account object
//      * @return Account login
//      */
//     String getAccountLogin(Account account);
// 
//     /**
//      * @param account Account object
//      * @return Account password
//      */
//     String getAccountPassword(Account account);
// 
//     /**
//      * @return A GpsEventSource or null if not needed or created in application
//      */
//     GpsEventSource getGpsEventSource();
// 
//     /**
//      * Show settings Activity or nothing
//      */
//     void showSettings(String setting);
// 
//     /**
//      * Send target event to analytics
//      */
//     void sendEvent(String category, String action, String label);
// 
//     /**
//      * Send screen hit to analytics
//      */
//     void sendScreen(String name);
// 
//     /**
//      * Get accounts authenticator type
//      */
//     String getAccountsType();
// 
//     /**
//      * Get LayerFactory
//      */
//     LayerFactory getLayerFactory();
// }


// Path: src/main/java/com/nextgis/maplib/util/AccountUtil.java
import android.accounts.Account;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncInfo;
import android.os.Build;
import android.util.Base64;
import com.nextgis.maplib.api.IGISApplication;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import static com.nextgis.maplib.util.Constants.JSON_END_DATE_KEY;
import static com.nextgis.maplib.util.Constants.JSON_SIGNATURE_KEY;
import static com.nextgis.maplib.util.Constants.JSON_START_DATE_KEY;
import static com.nextgis.maplib.util.Constants.JSON_SUPPORTED_KEY;
import static com.nextgis.maplib.util.Constants.JSON_USER_ID_KEY;
import static com.nextgis.maplib.util.Constants.SUPPORT;

                    "06z5a0sd3NDbS++GMCJstcKxkzk5KLQljAJ85Jciiuy2vv14WU621ves8S9cMISO\n" + "HwIDAQAB";
            byte[] keyBytes = Base64.decode(key.getBytes("UTF-8"), Base64.DEFAULT);
            X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
            PublicKey publicKey = keyFactory.generatePublic(spec);

            // verify signature
            Signature signCheck = Signature.getInstance("SHA256withRSA");
            signCheck.initVerify(publicKey);
            signCheck.update(data.getBytes("UTF-8"));
            byte[] sigBytes = Base64.decode(signature, Base64.DEFAULT);
            return signCheck.verify(sigBytes);
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean isSyncActive(Account account, String authority) {
        return isSyncActiveHoneycomb(account, authority);
    }

    public static boolean isSyncActiveHoneycomb(Account account, String authority) {
        for (SyncInfo syncInfo : ContentResolver.getCurrentSyncs()) {
            if (syncInfo.account.equals(account) && syncInfo.authority.equals(authority)) {
                return true;
            }
        }
        return false;
    }

    public static AccountData getAccountData(Context context, String accountName) throws IllegalStateException {
        IGISApplication app = (IGISApplication) context.getApplicationContext();