abstract public long getTopContentCount(String hostId, Date fromDate, Date toDate) throws DotDataException, DotHibernateException;

package com.dotmarketing.portlets.dashboard.business;

import java.util.Date;
import java.util.List;
import java.util.Map;
import com.dotmarketing.beans.Host;
import com.dotmarketing.beans.Inode;
import com.dotmarketing.db.DbConnectionFactory;
import com.dotmarketing.exception.DotDataException;
import com.dotmarketing.exception.DotHibernateException;
import com.dotmarketing.exception.DotSecurityException;
import com.dotmarketing.portlets.dashboard.model.DashboardSummary;
import com.dotmarketing.portlets.dashboard.model.DashboardSummary404;
import com.dotmarketing.portlets.dashboard.model.DashboardSummaryContent;
import com.dotmarketing.portlets.dashboard.model.DashboardSummaryPage;
import com.dotmarketing.portlets.dashboard.model.DashboardSummaryReferer;
import com.dotmarketing.portlets.dashboard.model.DashboardSummaryVisits;
import com.dotmarketing.portlets.dashboard.model.DashboardWorkStream;
import com.dotmarketing.portlets.dashboard.model.TopAsset;
import com.dotmarketing.portlets.dashboard.model.ViewType;
import com.dotmarketing.portlets.structure.model.Structure;
import com.dotmarketing.util.UtilMethods;
import com.liferay.portal.model.User;

public abstract class DashboardFactory {

    protected String getSummaryPagesQuery() {
        StringBuilder queryBuilder = new StringBuilder("");
        if (DbConnectionFactory.isPostgres() || DbConnectionFactory.isOracle()) {
            // Find contentlets type 'html page'
            queryBuilder.append("SELECT COUNT(*) AS hits, contentlet_version_info.live_inode AS inode, ").append("(identifier.parent_path || identifier.asset_name) AS uri ").append("FROM clickstream_request cr ").append("JOIN contentlet ON (contentlet.identifier = cr.associated_identifier) ").append("JOIN structure ON (structure.inode = contentlet.structure_inode) ").append("JOIN identifier ON (identifier.id = contentlet.identifier) ").append("JOIN contentlet_version_info ON (contentlet_version_info.identifier = identifier.id) ").append("WHERE EXTRACT(DAY FROM cr.timestampper) = ? AND EXTRACT(MONTH FROM cr.timestampper) = ? AND EXTRACT(YEAR FROM cr.timestampper) = ? ").append("AND cr.host_id = ? AND structure.structuretype = ").append(Structure.STRUCTURE_TYPE_HTMLPAGE).append(" ").append("GROUP BY associated_identifier, (identifier.parent_path || identifier.asset_name), contentlet_version_info.live_inode");
        } else if (DbConnectionFactory.isMySql()) {
            // MySQL Query Builder
            // Find contentlets type 'html page'
            queryBuilder.append("SELECT COUNT(*) AS hits, contentlet_version_info.live_inode AS inode, ").append("CONCAT(identifier.parent_path, identifier.asset_name) AS uri ").append("FROM clickstream_request cr ").append("JOIN contentlet ON (contentlet.identifier = cr.associated_identifier) ").append("JOIN structure ON (structure.inode = contentlet.structure_inode) ").append("JOIN identifier ON (identifier.id = contentlet.identifier) ").append("JOIN contentlet_version_info ON (contentlet_version_info.identifier = identifier.id) ").append("WHERE DAY(cr.timestampper) = ? AND MONTH(cr.timestampper) = ? AND YEAR(cr.timestampper) = ? ").append("AND cr.host_id = ? AND structure.structuretype = ").append(Structure.STRUCTURE_TYPE_HTMLPAGE).append(" ").append("GROUP BY associated_identifier, CONCAT(identifier.parent_path, identifier.asset_name), contentlet_version_info.live_inode");
        } else if (DbConnectionFactory.isMsSql()) {
            // MsSQL Query Builder
            // Find contentlets type 'html page'
            queryBuilder.append("SELECT COUNT(*) AS hits, contentlet_version_info.live_inode AS inode, ").append("(identifier.parent_path + identifier.asset_name) AS uri ").append("FROM clickstream_request cr ").append("JOIN contentlet ON (contentlet.identifier = cr.associated_identifier) ").append("JOIN structure ON (structure.inode = contentlet.structure_inode) ").append("JOIN identifier ON (identifier.id = contentlet.identifier) ").append("JOIN contentlet_version_info ON (contentlet_version_info.identifier = identifier.id) ").append("WHERE DATEPART(DAY, cr.timestampper) = ? AND DATEPART(MONTH, cr.timestampper) = ? AND DATEPART(YEAR, cr.timestampper) = ? ").append("AND cr.host_id = ? AND structure.structuretype = ").append(Structure.STRUCTURE_TYPE_HTMLPAGE).append(" ").append("GROUP BY associated_identifier, (identifier.parent_path + identifier.asset_name), contentlet_version_info.live_inode");
        }
        return queryBuilder.toString();
    }

    protected String getSummaryContentQuery() {
        return (DbConnectionFactory.isPostgres() || DbConnectionFactory.isOracle()) ? " select count(*) as hits, identifier.parent_path as uri ,contentlet.identifier as inode, contentlet.title as title  from clickstream_request " + " join identifier on identifier.id = associated_identifier join multi_tree on associated_identifier = parent1 join contentlet on contentlet.identifier = multi_tree.child  " + " where extract(day from timestampper) = ? and extract(month from timestampper) = ? and " + " extract(year from timestampper) = ? and host_id = ?" + " group by associated_identifier, identifier.parent_path,contentlet.identifier,contentlet.title " : DbConnectionFactory.isMySql() ? " select count(*) as hits, identifier.parent_path as uri ,contentlet.identifier as inode, contentlet.title as title  from clickstream_request " + " join identifier on identifier.id = associated_identifier join multi_tree on associated_identifier = parent1 join contentlet on contentlet.identifier = multi_tree.child  " + " where DAY(timestampper) = ? and MONTH(timestampper) = ? and YEAR(timestampper) = ? " + " and host_id = ? group by associated_identifier, identifier.parent_path,contentlet.identifier,contentlet.title " : DbConnectionFactory.isMsSql() ? " select count(*) as hits, identifier.parent_path as uri ,contentlet.identifier as inode, contentlet.title as title  from clickstream_request " + " join identifier on identifier.id = associated_identifier join multi_tree on associated_identifier = parent1 join contentlet on contentlet.identifier = multi_tree.child  " + " where DATEPART(day, timestampper) = ? and DATEPART(month, timestampper) = ? and DATEPART(year, timestampper) = ? " + " and host_id = ? group by associated_identifier, identifier.parent_path,contentlet.identifier,contentlet.title " : "";
    }

    protected String getWorkstreamQuery(String hostId) {
        return " inode, asset_type, mod_user_id, host_id, mod_date,case when deleted = 1 then 'Deleted' else case when live_inode IS NOT NULL then 'Published' else 'Saved' end end as action, name from( " + " select contentlet.inode as inode, case when st.structuretype=" + Structure.STRUCTURE_TYPE_FILEASSET + " then 'contentlet' else 'file_asset' end as asset_type, " + " mod_user as mod_user_id, identifier.host_inode as host_id, contentlet.mod_date,lang_info.live_inode,lang_info.working_inode,lang_info.deleted, coalesce(contentlet.title,contentlet.identifier) as name " + " from contentlet_version_info lang_info join contentlet on (contentlet.identifier = lang_info.identifier) join identifier identifier on (identifier.id = contentlet.identifier) " + " join structure st on (contentlet.structure_inode=st.inode) " + " UNION ALL " + " select template.inode as inode, 'template' as asset_type, mod_user as mod_user_id, identifier.host_inode as host_id, mod_date, temp_info.live_inode,temp_info.working_inode,temp_info.deleted, coalesce(template.title,template.identifier) as name " + " from template_version_info temp_info join template on(template.identifier = temp_info.identifier) join identifier identifier on identifier.id = template.identifier " + " UNION ALL " + " select " + Inode.Type.CONTAINERS.getTableName() + ".inode as inode, 'container' as asset_type, mod_user as mod_user_id, identifier.host_inode as host_id, mod_date, con_info.live_inode,con_info.working_inode,con_info.deleted, coalesce(" + Inode.Type.CONTAINERS.getTableName() + ".title," + Inode.Type.CONTAINERS.getTableName() + ".identifier) as name " + " from container_version_info con_info join " + Inode.Type.CONTAINERS.getTableName() + " on(" + Inode.Type.CONTAINERS.getTableName() + ".identifier = con_info.identifier) join identifier identifier on (identifier.id = " + Inode.Type.CONTAINERS.getTableName() + ".identifier) " + " UNION ALL " + " select links.inode as inode, 'link' as asset_type, mod_user as mod_user_id, identifier.host_inode as host_id, mod_date, links_info.live_inode,links_info.working_inode,links_info.deleted, coalesce(links.title,links.identifier) as name " + " from link_version_info links_info join links on(links_info.identifier= links.identifier) join identifier identifier on (identifier.id = links.identifier) " + " )assets where mod_date>(select coalesce(max(mod_date)," + (DbConnectionFactory.isPostgres() ? "'1970-01-01 00:00:00')" : (DbConnectionFactory.isOracle()) ? "TO_TIMESTAMP('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'))" : (DbConnectionFactory.isMySql()) ? "STR_TO_DATE('1970-01-01','%Y-%m-%d'))" : (DbConnectionFactory.isMsSql()) ? "CAST('1970-01-01' AS DATETIME))" : "") + " from analytic_summary_workstream) and host_id = '" + hostId + "' order by assets.mod_date,assets.name asc ";
    }

    protected String getTopAssetsQuery() {
        // This query counts contentlets
        StringBuilder sbCountContentlets = new StringBuilder("SELECT identifier.host_inode as host_inode, ").append("COUNT(contentlet.inode) AS count, 'contentlet' AS asset_type ").append("FROM contentlet_version_info contentinfo JOIN identifier ON (identifier.id = contentinfo.identifier) ").append("JOIN contentlet ON (contentlet.identifier = identifier.id) JOIN structure ON (contentlet.structure_inode = structure.inode) ").append("WHERE identifier.host_inode = ? ").append(" AND contentinfo.live_inode IS NOT NULL ").append("GROUP BY identifier.host_inode");
        return sbCountContentlets.toString();
    }

    protected String getIdentifierColumn() {
        return "contentlet.identifier";
    }

    protected String getWorkstreamListQuery() {
        return new StringBuilder("select distinct {analytic_summary_workstream.*}, user_.firstname as username, contentlet.title as hostname ").append(" from analytic_summary_workstream, user_ , contentlet,contentlet_version_info contentinfo ").append(" where user_.userid = analytic_summary_workstream.mod_user_id and contentlet.identifier = analytic_summary_workstream.host_id ").append(" and contentlet.identifier = contentinfo.identifier and contentinfo.live_inode is not null and analytic_summary_workstream.name is not null ").append(" and user_.delete_in_progress = ").append(DbConnectionFactory.getDBFalse()).toString();
    }

    protected String getWorkstreamCountQuery() {
        return new StringBuilder("select count(distinct analytic_summary_workstream.id) as summaryCount from analytic_summary_workstream, user_, contentlet,contentlet_version_info info where").append(" user_.userid = analytic_summary_workstream.mod_user_id and contentlet.identifier = analytic_summary_workstream.host_id ").append(" and contentlet.identifier = info.identifier and info.live_inode is not null and analytic_summary_workstream.name is not null ").append(" and user_.delete_in_progress = ").append(DbConnectionFactory.getDBFalse()).toString();
    }

    protected StringBuffer getHostListQuery(boolean hasCategory, String selectedCategories, String runDashboardFieldContentlet) {
        StringBuffer query = new StringBuffer();
        query.append("select " + (DbConnectionFactory.isOracle() || DbConnectionFactory.isMsSql() ? "" : " distinct ") + (" {contentlet.*}, ") + "coalesce(d.page_views,0) as totalpageviews,  " + "CASE WHEN contentinfo.live_inode is not null THEN 'Live' " + " ELSE 'Stopped' " + "END AS status " + "from contentlet_version_info contentinfo,inode contentlet_1_ , contentlet " + "left join " + "(" + "select sum(page_views) as page_views, host_id from analytic_summary join " + "analytic_summary_period on analytic_summary.summary_period_id = analytic_summary_period.id " + "and analytic_summary_period.full_date > ? and analytic_summary_period.full_date < ? " + "group by host_id" + ") " + (DbConnectionFactory.isMsSql() ? " as d" : DbConnectionFactory.isOracle() ? " d " : " as d") + " on d.host_id = contentlet.identifier " + (hasCategory ? " join tree on tree.child = contentlet.inode and tree.parent in(" + selectedCategories + ") " : "") + "join structure s on contentlet.structure_inode = s.inode " + "where contentlet_1_.type = 'contentlet' and contentlet.inode = contentlet_1_.inode and s.name ='Host' and contentlet.identifier = contentinfo.identifier " + "and contentlet.title <> 'System Host' and contentinfo.working_inode = contentlet.inode " + (UtilMethods.isSet(runDashboardFieldContentlet) ? " and contentlet." + runDashboardFieldContentlet + "= " + DbConnectionFactory.getDBTrue() + "" : "") + " ");
        return query;
    }

    protected StringBuffer getHostListCountQuery(boolean hasCategory, String selectedCategories, String runDashboardFieldContentlet) {
        StringBuffer query = new StringBuffer();
        query.append("select count(distinct contentlet.inode) as total " + "from contentlet_version_info contentinfo,inode contentlet_1_ , contentlet " + (hasCategory ? " join tree on tree.child = contentlet.inode and tree.parent in(" + selectedCategories + ") " : "") + "join structure s on contentlet.structure_inode = s.inode " + "where contentlet_1_.type = 'contentlet' and contentlet.inode = contentlet_1_.inode and s.name ='Host' " + "and contentlet.title <> 'System Host' and contentlet.identifier = contentinfo.identifier and contentinfo.working_inode = contentlet.inode " + (UtilMethods.isSet(runDashboardFieldContentlet) ? " and contentlet." + runDashboardFieldContentlet + "= " + DbConnectionFactory.getDBTrue() + "" : "") + " ");
        return query;
    }

    protected String getHostQueryForClickstream(String runDashboardFieldContentlet) {
        String query = " select contentlet.identifier as host_id from contentlet, structure s,contentlet_version_info info " + " where contentlet.structure_inode = s.inode and s.name ='Host' and contentlet.identifier = info.identifier " + " and contentlet.title <> 'System Host' and info.working_inode = contentlet.inode " + (UtilMethods.isSet(runDashboardFieldContentlet) ? " and contentlet." + runDashboardFieldContentlet + "= " + DbConnectionFactory.getDBTrue() + "" : "") + " group by contentlet.identifier ";
        return query;
    }

    /**
     * @param user
     * @param includeArchived
     * @param params
     * @param limit
     * @param offset
     * @param sortBy
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public List<Host> getHostList(User user, boolean includeArchived, Map<String, Object> params, int limit, int offset, String sortBy) throws DotDataException, DotHibernateException;

    /**
     * @param user
     * @param includeArchived
     * @param params
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public long getHostListCount(User user, boolean includeArchived, Map<String, Object> params) throws DotDataException, DotHibernateException;

    /**
     * @param user
     * @param hostId
     * @param userId
     * @param fromDate
     * @param toDate
     * @param limit
     * @param offset
     * @param sortBy
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public List<DashboardWorkStream> getWorkStreamList(User user, String hostId, String userId, Date fromDate, Date toDate, int limit, int offset, String sortBy) throws DotDataException, DotHibernateException;

    /**
     * @param user
     * @param hostId
     * @param userId
     * @param fromDate
     * @param toDate
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public long getWorkStreamListCount(User user, String hostId, String userId, Date fromDate, Date toDate) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param fromDate
     * @param toDate
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public DashboardSummary getDashboardSummary(String hostId, Date fromDate, Date toDate) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param viewType
     * @param fromDate
     * @param toDate
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public List<DashboardSummaryVisits> getDashboardSummaryVisits(String hostId, ViewType viewType, Date fromDate, Date toDate) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param fromDate
     * @param toDate
     * @param limit
     * @param offset
     * @param sortBy
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public List<DashboardSummaryReferer> getTopReferers(String hostId, Date fromDate, Date toDate, int limit, int offset, String sortBy) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param fromDate
     * @param toDate
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public long getTopReferersCount(String hostId, Date fromDate, Date toDate) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param fromDate
     * @param toDate
     * @param limit
     * @param offset
     * @param sortBy
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public List<DashboardSummaryPage> getTopPages(String hostId, Date fromDate, Date toDate, int limit, int offset, String sortBy) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param fromDate
     * @param toDate
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public long getTopPagesCount(String hostId, Date fromDate, Date toDate) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param fromDate
     * @param toDate
     * @param limit
     * @param offset
     * @param sortBy
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public List<DashboardSummaryContent> getTopContent(String hostId, Date fromDate, Date toDate, int limit, int offset, String sortBy) throws DotDataException, DotHibernateException;

    /**
     * @param hostId
     * @param fromDate
     * @param toDate
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */

    /**
     * @param user
     * @param hostId
     * @param showIgnored
     * @param fromDate
     * @param toDate
     * @param limit
     * @param offset
     * @param sortBy
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public List<DashboardSummary404> get404s(String userId, String hostId, boolean showIgnored, Date fromDate, Date toDate, int limit, int offset, String sortBy) throws DotDataException, DotHibernateException;

    /**
     * @param user
     * @param hostId
     * @param showIgnored
     * @param fromDate
     * @param toDate
     * @return
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public long get404Count(String userId, String hostId, boolean showIgnored, Date fromDate, Date toDate) throws DotDataException, DotHibernateException;

    /**
     * @param user
     * @param id
     * @param ignored
     * @throws DotDataException
     * @throws DotHibernateException
     */
    abstract public void setIgnored(User user, long id, boolean ignored) throws DotDataException, DotHibernateException;

    /**
     * @param user
     * @param hostId
     * @return
     * @throws DotDataException
     * @throws DotSecurityException
     */
    abstract public List<TopAsset> getTopAssets(User user, String hostId) throws DotDataException;

    abstract public void populateAnalyticSummaryTables();

    /**
     * @param month
     * @param year
     * @return
     */
    abstract public int checkPeriodData(int month, int year);
}


public FillContext createFromParcel(Parcel parcel)

package android.service.autofill;

import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
import android.util.ArrayMap;
import android.util.SparseIntArray;
import android.view.autofill.AutofillId;
import android.view.autofill.Helper;
import java.util.LinkedList;

public final class FillContext implements Parcelable {

    public static final Creator<FillContext> CREATOR = new Creator<FillContext>() {

{
            return new FillContext(parcel, null);
        }

        public FillContext[] newArray(int size) {
            return new FillContext[size];
        }
    };

    private final int mRequestId;

    private final AssistStructure mStructure;

    private ArrayMap<AutofillId, ViewNode> mViewNodeLookupTable;

    public FillContext(int requestId, AssistStructure structure) {
        this.mRequestId = requestId;
        this.mStructure = structure;
    }

    private FillContext(Parcel parcel) {
        this(parcel.readInt(), (AssistStructure) parcel.readParcelable(null));
    }

    public int getRequestId() {
        return this.mRequestId;
    }

    public AssistStructure getStructure() {
        return this.mStructure;
    }

    public String toString() {
        if (!Helper.sDebug) {
            return super.toString();
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("FillContext [reqId=");
        stringBuilder.append(this.mRequestId);
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(this.mRequestId);
        parcel.writeParcelable(this.mStructure, flags);
    }

    /* JADX WARNING: Removed duplicated region for block: B:31:0x0099 A:{LOOP_END, LOOP:4: B:29:0x0093->B:31:0x0099} */
    /* Code decompiled incorrectly, please refer to instructions dump. */
    public ViewNode[] findViewNodesByAutofillIds(AutofillId[] ids) {
        int i;
        int lookupTableIndex;
        LinkedList<ViewNode> nodesToProcess = new LinkedList();
        ViewNode[] foundNodes = new ViewNode[ids.length];
        SparseIntArray missingNodeIndexes = new SparseIntArray(ids.length);
        int i2 = 0;
        for (i = 0; i < ids.length; i++) {
            if (this.mViewNodeLookupTable != null) {
                lookupTableIndex = this.mViewNodeLookupTable.indexOfKey(ids[i]);
                if (lookupTableIndex >= 0) {
                    foundNodes[i] = (ViewNode) this.mViewNodeLookupTable.valueAt(lookupTableIndex);
                } else {
                    missingNodeIndexes.put(i, 0);
                }
            } else {
                missingNodeIndexes.put(i, 0);
            }
        }
        i = this.mStructure.getWindowNodeCount();
        for (lookupTableIndex = 0; lookupTableIndex < i; lookupTableIndex++) {
            nodesToProcess.add(this.mStructure.getWindowNodeAt(lookupTableIndex).getRootViewNode());
        }
        while (missingNodeIndexes.size() > 0 && !nodesToProcess.isEmpty()) {
            ViewNode node = (ViewNode) nodesToProcess.removeFirst();
            int i3 = 0;
            while (i3 < missingNodeIndexes.size()) {
                int index = missingNodeIndexes.keyAt(i3);
                AutofillId id = ids[index];
                if (id.equals(node.getAutofillId())) {
                    foundNodes[index] = node;
                    if (this.mViewNodeLookupTable == null) {
                        this.mViewNodeLookupTable = new ArrayMap(ids.length);
                    }
                    this.mViewNodeLookupTable.put(id, node);
                    missingNodeIndexes.removeAt(i3);
                    for (i3 = 0; i3 < node.getChildCount(); i3++) {
                        nodesToProcess.addLast(node.getChildAt(i3));
                    }
                } else {
                    i3++;
                }
            }
            while (i3 < node.getChildCount()) {
            }
        }
        while (i2 < missingNodeIndexes.size()) {
            if (this.mViewNodeLookupTable == null) {
                this.mViewNodeLookupTable = new ArrayMap(missingNodeIndexes.size());
            }
            this.mViewNodeLookupTable.put(ids[missingNodeIndexes.keyAt(i2)], null);
            i2++;
        }
        return foundNodes;
    }
}


{
            return new FillContext(parcel, null);
        }

package android.service.autofill;

import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
import android.util.ArrayMap;
import android.util.SparseIntArray;
import android.view.autofill.AutofillId;
import android.view.autofill.Helper;
import java.util.LinkedList;

public final class FillContext implements Parcelable {

    public static final Creator<FillContext> CREATOR = new Creator<FillContext>() {

        public FillContext createFromParcel(Parcel parcel)

        public FillContext[] newArray(int size) {
            return new FillContext[size];
        }
    };

    private final int mRequestId;

    private final AssistStructure mStructure;

    private ArrayMap<AutofillId, ViewNode> mViewNodeLookupTable;

    public FillContext(int requestId, AssistStructure structure) {
        this.mRequestId = requestId;
        this.mStructure = structure;
    }

    private FillContext(Parcel parcel) {
        this(parcel.readInt(), (AssistStructure) parcel.readParcelable(null));
    }

    public int getRequestId() {
        return this.mRequestId;
    }

    public AssistStructure getStructure() {
        return this.mStructure;
    }

    public String toString() {
        if (!Helper.sDebug) {
            return super.toString();
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("FillContext [reqId=");
        stringBuilder.append(this.mRequestId);
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(this.mRequestId);
        parcel.writeParcelable(this.mStructure, flags);
    }

    /* JADX WARNING: Removed duplicated region for block: B:31:0x0099 A:{LOOP_END, LOOP:4: B:29:0x0093->B:31:0x0099} */
    /* Code decompiled incorrectly, please refer to instructions dump. */
    public ViewNode[] findViewNodesByAutofillIds(AutofillId[] ids) {
        int i;
        int lookupTableIndex;
        LinkedList<ViewNode> nodesToProcess = new LinkedList();
        ViewNode[] foundNodes = new ViewNode[ids.length];
        SparseIntArray missingNodeIndexes = new SparseIntArray(ids.length);
        int i2 = 0;
        for (i = 0; i < ids.length; i++) {
            if (this.mViewNodeLookupTable != null) {
                lookupTableIndex = this.mViewNodeLookupTable.indexOfKey(ids[i]);
                if (lookupTableIndex >= 0) {
                    foundNodes[i] = (ViewNode) this.mViewNodeLookupTable.valueAt(lookupTableIndex);
                } else {
                    missingNodeIndexes.put(i, 0);
                }
            } else {
                missingNodeIndexes.put(i, 0);
            }
        }
        i = this.mStructure.getWindowNodeCount();
        for (lookupTableIndex = 0; lookupTableIndex < i; lookupTableIndex++) {
            nodesToProcess.add(this.mStructure.getWindowNodeAt(lookupTableIndex).getRootViewNode());
        }
        while (missingNodeIndexes.size() > 0 && !nodesToProcess.isEmpty()) {
            ViewNode node = (ViewNode) nodesToProcess.removeFirst();
            int i3 = 0;
            while (i3 < missingNodeIndexes.size()) {
                int index = missingNodeIndexes.keyAt(i3);
                AutofillId id = ids[index];
                if (id.equals(node.getAutofillId())) {
                    foundNodes[index] = node;
                    if (this.mViewNodeLookupTable == null) {
                        this.mViewNodeLookupTable = new ArrayMap(ids.length);
                    }
                    this.mViewNodeLookupTable.put(id, node);
                    missingNodeIndexes.removeAt(i3);
                    for (i3 = 0; i3 < node.getChildCount(); i3++) {
                        nodesToProcess.addLast(node.getChildAt(i3));
                    }
                } else {
                    i3++;
                }
            }
            while (i3 < node.getChildCount()) {
            }
        }
        while (i2 < missingNodeIndexes.size()) {
            if (this.mViewNodeLookupTable == null) {
                this.mViewNodeLookupTable = new ArrayMap(missingNodeIndexes.size());
            }
            this.mViewNodeLookupTable.put(ids[missingNodeIndexes.keyAt(i2)], null);
            i2++;
        }
        return foundNodes;
    }
}


package android.service.autofill;

import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
import android.util.ArrayMap;
import android.util.SparseIntArray;
import android.view.autofill.AutofillId;
import android.view.autofill.Helper;
import java.util.LinkedList;

public final class FillContext implements Parcelable {

    public static final Creator<FillContext> CREATOR = new Creator<FillContext>() {

        public FillContext createFromParcel(Parcel parcel) {
            return new FillContext(parcel, null);
        }

        public FillContext[] newArray(int size) {
            return new FillContext[size];
        }
    };

    private final int mRequestId;

    private final AssistStructure mStructure;

    private ArrayMap<AutofillId, ViewNode> mViewNodeLookupTable;

    public FillContext(int requestId, AssistStructure structure) {
        this.mRequestId = requestId;
        this.mStructure = structure;
    }

    private FillContext(Parcel parcel) {
        this(parcel.readInt(), (AssistStructure) parcel.readParcelable(null));
    }

    public int getRequestId() {
        return this.mRequestId;
    }

    public AssistStructure getStructure() {
        return this.mStructure;
    }

    public String toString() {
        if (!Helper.sDebug) {
            return super.toString();
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("FillContext [reqId=");
        stringBuilder.append(this.mRequestId);
        stringBuilder.append("]");
        return st

    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(this.mRequestId);
        parcel.writeParcelable(this.mStructure, flags);
    }

    /* JADX WARNING: Removed duplicated region for block: B:31:0x0099 A:{LOOP_END, LOOP:4: B:29:0x0093->B:31:0x0099} */
    /* Code decompiled incorrectly, please refer to instructions dump. */
    public ViewNode[] findViewNodesByAutofillIds(AutofillId[] ids) {
        int i;
        int lookupTableIndex;
        LinkedList<ViewNode> nodesToProcess = new LinkedList();
        ViewNode[] foundNodes = new ViewNode[ids.length];
        SparseIntArray missingNodeIndexes = new SparseIntArray(ids.length);
        int i2 = 0;
        for (i = 0; i < ids.length; i++) {
            if (this.mViewNodeLookupTable != null) {
                lookupTableIndex = this.mViewNodeLookupTable.indexOfKey(ids[i]);
                if (lookupTableIndex >= 0) {
                    foundNodes[i] = (ViewNode) this.mViewNodeLookupTable.valueAt(lookupTableIndex);
                } else {
                    missingNodeIndexes.put(i, 0);
                }
            } else {
                missingNodeIndexes.put(i, 0);
            }
        }
        i = this.mStructure.getWindowNodeCount();
        for (lookupTableIndex = 0; lookupTableIndex < i; lookupTableIndex++) {
            nodesToProcess.add(this.mStructure.getWindowNodeAt(lookupTableIndex).getRootViewNode());
        }
        while (missingNodeIndexes.size() > 0 && !nodesToProcess.isEmpty()) {
            ViewNode node = (ViewNode) nodesToProcess.removeFirst();
            int i3 = 0;
            while (i3 < missingNodeIndexes.size()) {
                int index = missingNodeIndexes.keyAt(i3);
                AutofillId id = ids[index];
                if (id.equals(node.getAutofillId())) {
                    foundNodes[index] = node;
                    if (this.mViewNodeLookupTable == null) {
                        this.mViewNodeLookupTable = new ArrayMap(ids.length);
                    }
                    this.mViewNodeLookupTable.put(id, node);
                    missingNodeIndexes.removeAt(i3);
                    for (i3 = 0; i3 < node.getChildCount(); i3++) {
                        nodesToProcess.addLast(node.getChildAt(i3));
                    }
                } else {
                    i3++;
                }
            }
            while (i3 < node.getChildCount()) {
            }
        }
        while (i2 < missingNodeIndexes.size()) {
            if (this.mViewNodeLookupTable == null) {
                this.mViewNodeLookupTable = new ArrayMap(missingNodeIndexes.size());
            }
            this.mViewNodeLookupTable.put(ids[missingNodeIndexes.keyAt(i2)], null);
            i2++;
        }
        return foundNodes;
    }
}


for (lookupTableIndex = 0; lookupTableIndex < i; lookupTableIndex++) {
            nodesToProcess.add(this.mStructure.getWindowNodeAt(lookupTableIndex).getRootViewNode());
        }

package android.service.autofill;

import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
import android.util.ArrayMap;
import android.util.SparseIntArray;
import android.view.autofill.AutofillId;
import android.view.autofill.Helper;
import java.util.LinkedList;

public final class FillContext implements Parcelable {

    public static final Creator<FillContext> CREATOR = new Creator<FillContext>() {

        public FillContext createFromParcel(Parcel parcel) {
            return new FillContext(parcel, null);
        }

        public FillContext[] newArray(int size) {
            return new FillContext[size];
        }
    };

    private final int mRequestId;

    private final AssistStructure mStructure;

    private ArrayMap<AutofillId, ViewNode> mViewNodeLookupTable;

    public FillContext(int requestId, AssistStructure structure) {
        this.mRequestId = requestId;
        this.mStructure = structure;
    }

    private FillContext(Parcel parcel) {
        this(parcel.readInt(), (AssistStructure) parcel.readParcelable(null));
    }

    public int getRequestId() {
        return this.mRequestId;
    }

    public AssistStructure getStructure() {
        return this.mStructure;
    }

    public String toString() {
        if (!Helper.sDebug) {
            return super.toString();
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("FillContext [reqId=");
        stringBuilder.append(this.mRequestId);
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(this.mRequestId);
        parcel.writeParcelable(this.mStructure, flags);
    }

    /* JADX WARNING: Removed duplicated region for block: B:31:0x0099 A:{LOOP_END, LOOP:4: B:29:0x0093->B:31:0x0099} */
    /* Code decompiled incorrectly, please refer to instructions dump. */
    public ViewNode[] findViewNodesByAutofillIds(AutofillId[] ids) {
        int i;
        int lookupTableIndex;
        LinkedList<ViewNode> nodesToProcess = new LinkedList();
        ViewNode[] foundNodes = new ViewNode[ids.length];
        SparseIntArray missingNodeIndexes = new SparseIntArray(ids.length);
        int i2 = 0;
        for (i = 0; i < ids.length; i++) {
            if (this.mViewNodeLookupTable != null) {
                lookupTableIndex = this.mViewNodeLookupTable.indexOfKey(ids[i]);
                if (lookupTableIndex >= 0) {
                    foundNodes[i] = (ViewNode) this.mViewNodeLookupTable.valueAt(lookupTableIndex);
                } else {
                    missingNodeIndexes.put(i, 0);
                }
            } else {
                missingNodeIndexes.put(i, 0);
            }
        }
        i = this.mStructure.getWindowNodeCount();

        while (missingNodeIndexes.size() > 0 && !nodesToProcess.isEmpty()) {
            ViewNode node = (ViewNode) nodesToProcess.removeFirst();
            int i3 = 0;
            while (i3 < missingNodeIndexes.size()) {
                int index = missingNodeIndexes.keyAt(i3);
                AutofillId id = ids[index];
                if (id.equals(node.getAutofillId())) {
                    foundNodes[index] = node;
                    if (this.mViewNodeLookupTable == null) {
                        this.mViewNodeLookupTable = new ArrayMap(ids.length);
                    }
                    this.mViewNodeLookupTable.put(id, node);
                    missingNodeIndexes.removeAt(i3);
                    for (i3 = 0; i3 < node.getChildCount(); i3++) {
                        nodesToProcess.addLast(node.getChildAt(i3));
                    }
                } else {
                    i3++;
                }
            }
            while (i3 < node.getChildCount()) {
            }
        }
        while (i2 < missingNodeIndexes.size()) {
            if (this.mViewNodeLookupTable == null) {
                this.mViewNodeLookupTable = new ArrayMap(missingNodeIndexes.size());
            }
            this.mViewNodeLookupTable.put(ids[missingNodeIndexes.keyAt(i2)], null);
            i2++;
        }
        return foundNodes;
    }
}


while (i3 < node.getChildCount()) {
            }

package android.service.autofill;

import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
import android.util.ArrayMap;
import android.util.SparseIntArray;
import android.view.autofill.AutofillId;
import android.view.autofill.Helper;
import java.util.LinkedList;

public final class FillContext implements Parcelable {

    public static final Creator<FillContext> CREATOR = new Creator<FillContext>() {

        public FillContext createFromParcel(Parcel parcel) {
            return new FillContext(parcel, null);
        }

        public FillContext[] newArray(int size) {
            return new FillContext[size];
        }
    };

    private final int mRequestId;

    private final AssistStructure mStructure;

    private ArrayMap<AutofillId, ViewNode> mViewNodeLookupTable;

    public FillContext(int requestId, AssistStructure structure) {
        this.mRequestId = requestId;
        this.mStructure = structure;
    }

    private FillContext(Parcel parcel) {
        this(parcel.readInt(), (AssistStructure) parcel.readParcelable(null));
    }

    public int getRequestId() {
        return this.mRequestId;
    }

    public AssistStructure getStructure() {
        return this.mStructure;
    }

    public String toString() {
        if (!Helper.sDebug) {
            return super.toString();
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("FillContext [reqId=");
        stringBuilder.append(this.mRequestId);
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(this.mRequestId);
        parcel.writeParcelable(this.mStructure, flags);
    }

    /* JADX WARNING: Removed duplicated region for block: B:31:0x0099 A:{LOOP_END, LOOP:4: B:29:0x0093->B:31:0x0099} */
    /* Code decompiled incorrectly, please refer to instructions dump. */
    public ViewNode[] findViewNodesByAutofillIds(AutofillId[] ids) {
        int i;
        int lookupTableIndex;
        LinkedList<ViewNode> nodesToProcess = new LinkedList();
        ViewNode[] foundNodes = new ViewNode[ids.length];
        SparseIntArray missingNodeIndexes = new SparseIntArray(ids.length);
        int i2 = 0;
        for (i = 0; i < ids.length; i++) {
            if (this.mViewNodeLookupTable != null) {
                lookupTableIndex = this.mViewNodeLookupTable.indexOfKey(ids[i]);
                if (lookupTableIndex >= 0) {
                    foundNodes[i] = (ViewNode) this.mViewNodeLookupTable.valueAt(lookupTableIndex);
                } else {
                    missingNodeIndexes.put(i, 0);
                }
            } else {
                missingNodeIndexes.put(i, 0);
            }
        }
        i = this.mStructure.getWindowNodeCount();
        for (lookupTableIndex = 0; lookupTableIndex < i; lookupTableIndex++) {
            nodesToProcess.add(this.mStructure.getWindowNodeAt(lookupTableIndex).getRootViewNode());
        }
        while (missingNodeIndexes.size() > 0 && !nodesToProcess.isEmpty()) {
            ViewNode node = (ViewNode) nodesToProcess.removeFirst();
            int i3 = 0;
            while (i3 < missingNodeIndexes.size()) {
                int index = missingNodeIndexes.keyAt(i3);
                AutofillId id = ids[index];
                if (id.equals(node.getAutofillId())) {
                    foundNodes[index] = node;
                    if (this.mViewNodeLookupTable == null) {
                        this.mViewNodeLookupTable = new ArrayMap(ids.length);
                    }
                    this.mViewNodeLookupTable.put(id, node);
                    missingNodeIndexes.removeAt(i3);
                    for (i3 = 0; i3 < node.getChildCount(); i3++) {
                        nodesToProcess.addLast(node.getChildAt(i3));
                    }
                } else {
                    i3++;
                }
            }

        }
        while (i2 < missingNodeIndexes.size()) {
            if (this.mViewNodeLookupTable == null) {
                this.mViewNodeLookupTable = new ArrayMap(missingNodeIndexes.size());
            }
            this.mViewNodeLookupTable.put(ids[missingNodeIndexes.keyAt(i2)], null);
            i2++;
        }
        return foundNodes;
    }
}


private static CloudHealthcare createClient() throws IOException

package snippets.healthcare.datasets;

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.Dataset;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class DatasetCreate {

    private static final String DATASET_NAME = "projects/%s/locations/%s/datasets/%s";

    private static final JsonFactory JSON_FACTORY = new JacksonFactory();

    private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

    public static void datasetCreate(String projectId, String regionId, String datasetId) throws IOException {
        // Initialize the client, which will be used to interact with the service.
        CloudHealthcare client = createClient();
        // Configure the dataset to be created.
        Dataset dataset = new Dataset();
        dataset.setTimeZone("America/Chicago");
        // Create request and configure any parameters.
        String parentName = String.format("projects/%s/locations/%s", projectId, regionId);
        Datasets.Create request = client.projects().locations().datasets().create(parentName, dataset);
        request.setDatasetId(datasetId);
        // Execute the request, wait for the operation to complete, and process the results.
        try {
            Operation operation = request.execute();
            System.out.println(operation.toPrettyString());
            while (operation.getDone() == null || !operation.getDone()) {
                // Update the status of the operation with another request.
                // Pause for 500ms between requests.
                Thread.sleep(500);
                operation = client.projects().locations().datasets().operations().get(operation.getName()).execute();
            }
            System.out.println("Dataset created. Response content: " + operation.getResponse());
        } catch (Exception ex) {
            System.out.printf("Error during request execution: %s\n", ex.toString());
            ex.printStackTrace(System.out);
        }
    }

{
        // Use Application Default Credentials (ADC) to authenticate the requests
        // For more information see http://example.com
        GoogleCredentials credential = GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));
        // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
        HttpRequestInitializer requestInitializer = request -> {
            new HttpCredentialsAdapter(credential).initialize(request);
            // 1 minute connect timeout
            request.setConnectTimeout(60000);
            // 1 minute read timeout
            request.setReadTimeout(60000);
        };
        // Build the client for interacting with the service.
        return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).setApplicationName("your-application-name").build();
    }
}


package snippets.healthcare.datasets;

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.Dataset;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class DatasetCreate {

    private static final String DATASET_NAME = "projects/%s/locations/%s/datasets/%s";

    private static final JsonFactory JSON_FACTORY = new JacksonFactory();

    private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

    public static void datasetCreate(String projectId, String regionId, String datasetId) throws IOException {
        // Initialize the client, which will be used to interact with the service.
        CloudHealthcare client = createClient();
        // Configure the dataset to be created.
        Dataset dataset = new Dataset();
        dataset.setTimeZone("America/Chicago");
        // Create request and configure any parameters.
        String parentName = String.format("projects/%s/locations/%s", projectId, regionId);
        Datasets.Create request = client.projects().locations().datasets().create(p

        request.setDatasetId(datasetId);
        // Execute the request, wait for the operation to complete, and process the results.
        try {
            Operation operation = request.execute();
            System.out.println(operation.toPrettyString());
            while (operation.getDone() == null || !operation.getDone()) {
                // Update the status of the operation with another request.
                // Pause for 500ms between requests.
                Thread.sleep(500);
                operation = client.projects().locations().datasets().operations().get(operation.getName()).execute();
            }
            System.out.println("Dataset created. Response content: " + operation.getResponse());
        } catch (Exception ex) {
            System.out.printf("Error during request execution: %s\n", ex.toString());
            ex.printStackTrace(System.out);
        }
    }

    private static CloudHealthcare createClient() throws IOException {
        // Use Application Default Credentials (ADC) to authenticate the requests
        // For more information see http://example.com
        GoogleCredentials credential = GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));
        // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
        HttpRequestInitializer requestInitializer = request -> {
            new HttpCredentialsAdapter(credential).initialize(request);
            // 1 minute connect timeout
            request.setConnectTimeout(60000);
            // 1 minute read timeout
            request.setReadTimeout(60000);
        };
        // Build the client for interacting with the service.
        return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).setApplicationName("your-application-name").build();
    }
}


while (operation.getDone() == null || !operation.getDone()) {
                // Update the status of the operation with another request.
                // Pause for 500ms between requests.
                Thread.sleep(500);
                operation = client.projects().locations().datasets().operations().get(operation.getName()).execute();
            }

package snippets.healthcare.datasets;

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.Dataset;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class DatasetCreate {

    private static final String DATASET_NAME = "projects/%s/locations/%s/datasets/%s";

    private static final JsonFactory JSON_FACTORY = new JacksonFactory();

    private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

    public static void datasetCreate(String projectId, String regionId, String datasetId) throws IOException {
        // Initialize the client, which will be used to interact with the service.
        CloudHealthcare client = createClient();
        // Configure the dataset to be created.
        Dataset dataset = new Dataset();
        dataset.setTimeZone("America/Chicago");
        // Create request and configure any parameters.
        String parentName = String.format("projects/%s/locations/%s", projectId, regionId);
        Datasets.Create request = client.projects().locations().datasets().create(parentName, dataset);
        request.setDatasetId(datasetId);
        // Execute the request, wait for the operation to complete, and process the results.
        try {
            Operation operation = request.execute();
            System.out.println(operation.toPrettyString());

            System.out.println("Dataset created. Response content: " + operation.getResponse());
        } catch (Exception ex) {
            System.out.printf("Error during request execution: %s\n", ex.toString());
            ex.printStackTrace(System.out);
        }
    }

    private static CloudHealthcare createClient() throws IOException {
        // Use Application Default Credentials (ADC) to authenticate the requests
        // For more information see http://example.com
        GoogleCredentials credential = GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));
        // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
        HttpRequestInitializer requestInitializer = request -> {
            new HttpCredentialsAdapter(credential).initialize(request);
            // 1 minute connect timeout
            request.setConnectTimeout(60000);
            // 1 minute read timeout
            request.setReadTimeout(60000);
        };
        // Build the client for interacting with the service.
        return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).setApplicationName("your-application-name").build();
    }
}


private void updateSettingsState(ScanSettings scanSettings)

package com.mirasense.scanditsdk.plugin;

import com.scandit.barcodepicker.ScanSession;
import com.scandit.barcodepicker.ScanSettings;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.Map;

/**
 * @brief Simple state machine for managing the different states of the barcode picker
 */
class PickerStateMachine {

    // must match values of JS wrapper
    public final static int STOPPED = 2;

    public final static int PAUSED = 1;

    public final static int ACTIVE = 3;

    private final BarcodePickerWithSearchBar mPicker;

    private int mCurrentState = STOPPED;

    private WeakReference<Callback> mCallback;

    private boolean mMatrixScanEnabled = false;

    /**
     * Create a new picker state machine.
     * @param picker The picker for which to control the states. Must not be null.
     * @param scanSettings The initial scan settings, used to set parts of the initial state.
     * @param callback The state change callback gets invoked whenever the state of the picker
     *                 changes. The callback is stored as a weak reference, so make sure to keep a
     *                 reference to the object around.
     */
    PickerStateMachine(BarcodePickerWithSearchBar picker, ScanSettings scanSettings, Callback callback) {
        mPicker = picker;
        mCallback = new WeakReference<Callback>(callback);
        updateSettingsState(scanSettings);
    }

    public void applyScanSettings(ScanSettings scanSettings) {
        mPicker.applyScanSettings(scanSettings);
        updateSettingsState(scanSettings);
    }

{
        if (mMatrixScanEnabled != scanSettings.isMatrixScanEnabled()) {
            mMatrixScanEnabled = scanSettings.isMatrixScanEnabled();
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerSwitchedMatrixScanState(mPicker, mMatrixScanEnabled);
            }
        }
    }

    public int getState() {
        return mCurrentState;
    }

    public int setState(int state) {
        if (mCurrentState == state) {
            return state;
        }
        switch(state) {
            case ACTIVE:
                transitionToActiveState(false);
                break;
            case PAUSED:
                transitionToPausedState();
                break;
            case STOPPED:
                transitionToStoppedState();
                break;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, state);
        }
        mCurrentState = state;
        return state;
    }

    public boolean isMatrixScanEnabled() {
        return mMatrixScanEnabled;
    }

    protected void setTrackedCodeStates(Map<Long, JSONObject> trackedCodeStates) {
        mPicker.setTrackedCodeStates(trackedCodeStates);
    }

    public void startScanning(boolean paused) {
        if (mCurrentState == ACTIVE) {
            return;
        }
        if (!paused) {
            transitionToActiveState(true);
            mCurrentState = ACTIVE;
        } else {
            transitionToPausedState();
            mCurrentState = PAUSED;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, mCurrentState);
        }
    }

    private void transitionToStoppedState() {
        if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
            mPicker.stopScanning();
        }
    }

    private void transitionToPausedState() {
        if (mCurrentState == ACTIVE) {
            mPicker.pauseScanning();
            return;
        }
        if (mCurrentState == STOPPED) {
            mPicker.startScanning(true);
        }
    }

    private void transitionToActiveState(boolean useStartInsteadOfResume) {
        if (mCurrentState == STOPPED) {
            mPicker.startScanning();
        }
        if (mCurrentState == PAUSED) {
            if (useStartInsteadOfResume) {
                mPicker.startScanning();
            } else {
                mPicker.resumeScanning();
            }
        }
    }

    public BarcodePickerWithSearchBar getPicker() {
        return mPicker;
    }

    /**
     * Implements the logic of handling picker state changes sent from the didScan callback.
     * @param nextState The next state.
     * @param session The implementation calls stopScanning/pauseScanning if the provided session
     *                is non-null.
     */
    public void switchToNextScanState(int nextState, ScanSession session) {
        if (nextState == STOPPED) {
            if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
                if (session != null) {
                    session.stopScanning();
                } else {
                    mPicker.stopScanning();
                }
            }
            mCurrentState = STOPPED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, STOPPED);
            }
            return;
        }
        if (nextState == PAUSED) {
            if (mCurrentState == ACTIVE) {
                if (session != null) {
                    session.pauseScanning();
                } else {
                    mPicker.pauseScanning();
                }
            }
            mCurrentState = PAUSED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, PAUSED);
            }
        }
    }

    interface Callback {

        /**
         * Invoked whenever the state of the barcode picker changes to a new state.
         *
         * @param picker The picker
         * @param newState the new state of the picker
         */
        void pickerEnteredState(BarcodePickerWithSearchBar picker, int newState);

        /**
         * Invoked whenever the picker starts or stops using matrix scan.
         *
         * @param picker The picker
         * @param matrixScan Whether matrix scan is enabled.
         */
        void pickerSwitchedMatrixScanState(BarcodePickerWithSearchBar picker, boolean matrixScan);
    }
}


{
        if (mCurrentState == ACTIVE) {
            return;
        }
        if (!paused) {
            transitionToActiveState(true);
            mCurrentState = ACTIVE;
        } else {
            transitionToPausedState();
            mCurrentState = PAUSED;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, mCurrentState);
        }
    }

package com.mirasense.scanditsdk.plugin;

import com.scandit.barcodepicker.ScanSession;
import com.scandit.barcodepicker.ScanSettings;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.Map;

/**
 * @brief Simple state machine for managing the different states of the barcode picker
 */
class PickerStateMachine {

    // must match values of JS wrapper
    public final static int STOPPED = 2;

    public final static int PAUSED = 1;

    public final static int ACTIVE = 3;

    private final BarcodePickerWithSearchBar mPicker;

    private int mCurrentState = STOPPED;

    private WeakReference<Callback> mCallback;

    private boolean mMatrixScanEnabled = false;

    /**
     * Create a new picker state machine.
     * @param picker The picker for which to control the states. Must not be null.
     * @param scanSettings The initial scan settings, used to set parts of the initial state.
     * @param callback The state change callback gets invoked whenever the state of the picker
     *                 changes. The callback is stored as a weak reference, so make sure to keep a
     *                 reference to the object around.
     */
    PickerStateMachine(BarcodePickerWithSearchBar picker, ScanSettings scanSettings, Callback callback) {
        mPicker = picker;
        mCallback = new WeakReference<Callback>(callback);
        updateSettingsState(scanSettings);
    }

    public void applyScanSettings(ScanSettings scanSettings) {
        mPicker.applyScanSettings(scanSettings);
        updateSettingsState(scanSettings);
    }

    private void updateSettingsState(ScanSettings scanSettings) {
        if (mMatrixScanEnabled != scanSettings.isMatrixScanEnabled()) {
            mMatrixScanEnabled = scanSettings.isMatrixScanEnabled();
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerSwitchedMatrixScanState(mPicker, mMatrixScanEnabled);
            }
        }
    }

    public int getState() {
        return mCurrentState;
    }

    public int setState(int state) {
        if (mCurrentState == state) {
            return state;
        }
        switch(state) {
            case ACTIVE:
                transitionToActiveState(false);
                break;
            case PAUSED:
                transitionToPausedState();
                break;
            case STOPPED:
                transitionToStoppedState();
                break;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, state);
        }
        mCurrentState = state;
        return state;
    }

    public boolean isMatrixScanEnabled() {
        return mMatrixScanEnabled;
    }

    protected void setTrackedCodeStates(Map<Long, JSONObject> trackedCodeStates) {
        mPicker.setTrackedCodeStates(trackedCodeStates);
    }

    public void startScanning(boolean paused)

    private void transitionToStoppedState() {
        if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
            mPicker.stopScanning();
        }
    }

    private void transitionToPausedState() {
        if (mCurrentState == ACTIVE) {
            mPicker.pauseScanning();
            return;
        }
        if (mCurrentState == STOPPED) {
            mPicker.startScanning(true);
        }
    }

    private void transitionToActiveState(boolean useStartInsteadOfResume) {
        if (mCurrentState == STOPPED) {
            mPicker.startScanning();
        }
        if (mCurrentState == PAUSED) {
            if (useStartInsteadOfResume) {
                mPicker.startScanning();
            } else {
                mPicker.resumeScanning();
            }
        }
    }

    public BarcodePickerWithSearchBar getPicker() {
        return mPicker;
    }

    /**
     * Implements the logic of handling picker state changes sent from the didScan callback.
     * @param nextState The next state.
     * @param session The implementation calls stopScanning/pauseScanning if the provided session
     *                is non-null.
     */
    public void switchToNextScanState(int nextState, ScanSession session) {
        if (nextState == STOPPED) {
            if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
                if (session != null) {
                    session.stopScanning();
                } else {
                    mPicker.stopScanning();
                }
            }
            mCurrentState = STOPPED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, STOPPED);
            }
            return;
        }
        if (nextState == PAUSED) {
            if (mCurrentState == ACTIVE) {
                if (session != null) {
                    session.pauseScanning();
                } else {
                    mPicker.pauseScanning();
                }
            }
            mCurrentState = PAUSED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, PAUSED);
            }
        }
    }

    interface Callback {

        /**
         * Invoked whenever the state of the barcode picker changes to a new state.
         *
         * @param picker The picker
         * @param newState the new state of the picker
         */
        void pickerEnteredState(BarcodePickerWithSearchBar picker, int newState);

        /**
         * Invoked whenever the picker starts or stops using matrix scan.
         *
         * @param picker The picker
         * @param matrixScan Whether matrix scan is enabled.
         */
        void pickerSwitchedMatrixScanState(BarcodePickerWithSearchBar picker, boolean matrixScan);
    }
}


package com.mirasense.scanditsdk.plugin;

import com.scandit.barcodepicker.ScanSession;
import com.scandit.barcodepicker.ScanSettings;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.Map;

/**
 * @brief Simple state machine for managing the different states of the barcode picker
 */
class PickerStateMachine {

    // must match values of JS wrapper
    public final static int STOPPED = 2;

    public final static int PAUSED = 1;

    public final static int ACTIVE = 3;

    private final BarcodePickerWithSearchBar mPicker;

    private int mCurrentState = STOPPED;

    private WeakReference<Callback> mCallback;

    private boolean mMatrixScanEnabled = false;

    /**
     * Create a new picker state machine.
     * @param picker The picker for which to control the states. Must not be null.
     * @param scanSettings The initial scan settings, used to set parts of the initial state.
     * @param callback The state change callback gets invoked whenever the state of the picker
     *                 changes. The callback is stored as a weak reference, so make sure to keep a
     *                 reference to the object around.
     */
    PickerStateMachine(BarcodePickerWithSearchBar picker, ScanSettings scanSettings, Callback callback) {
        mPicker = picker;
        mCallback = new WeakReference<Callback>(callback);
        updateSettingsState(scanSettings);
    }

    public void applyScanSettings(ScanSettings scanSettings) {
        mPicker.applyScanSettings(scanSettings);
        updateSettingsState(scanSettings);
    }

    private void updateSettingsState(ScanSettings scanSettings) {
        if (mMatrixScanEnabled != scanSettings.isMatrixScanEnabled()) {
            mMatrixScanEnabled = scanSettings.isMatrixScanEnabled();
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerSwitchedMatrixScanState(mPicker, mMatrixScanEnabled);
            }
        }
    }

    public int getState() {
        return mCurrentState;
    }

    public int setState(int state) {
        if (mCurrentState == state) {
            return state;
        }
        switch(state) {
            case ACTIVE:
                transitionToActiveState(false);
                break;
            case PAUSED:
                transitionToPausedState();
                break;
            case STOPPED:
                transitionToStoppedState();
                break;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, state);
        }
        mCurrentState = state;
        return state;
    }

    public boolean isMatrixScanEnabled() {
        return mMatrixScanEnabled;
    }

    protected void setTrackedCodeStates(Map<Long, JSONObject> trackedCodeStates) {
        mPicker.setTrackedCodeStates(trackedCodeStates);
    }

    public void startScanning(boolean paused) {
        if (mCurrentState == ACTIVE) {
            return;
        }
        if (!paused) {
            transitionToActiveState(true);
            mCurrentState = ACTIVE;
        } else {
            transitionToPausedState();
            mCurrentState = PAUSED;
        }
        Callback cb = mCallback.get()

        if (cb != null) {
            cb.pickerEnteredState(mPicker, mCurrentState);
        }
    }

    private void transitionToStoppedState() {
        if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
            mPicker.stopScanning();
        }
    }

    private void transitionToPausedState() {
        if (mCurrentState == ACTIVE) {
            mPicker.pauseScanning();
            return;
        }
        if (mCurrentState == STOPPED) {
            mPicker.startScanning(true);
        }
    }

    private void transitionToActiveState(boolean useStartInsteadOfResume) {
        if (mCurrentState == STOPPED) {
            mPicker.startScanning();
        }
        if (mCurrentState == PAUSED) {
            if (useStartInsteadOfResume) {
                mPicker.startScanning();
            } else {
                mPicker.resumeScanning();
            }
        }
    }

    public BarcodePickerWithSearchBar getPicker() {
        return mPicker;
    }

    /**
     * Implements the logic of handling picker state changes sent from the didScan callback.
     * @param nextState The next state.
     * @param session The implementation calls stopScanning/pauseScanning if the provided session
     *                is non-null.
     */
    public void switchToNextScanState(int nextState, ScanSession session) {
        if (nextState == STOPPED) {
            if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
                if (session != null) {
                    session.stopScanning();
                } else {
                    mPicker.stopScanning();
                }
            }
            mCurrentState = STOPPED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, STOPPED);
            }
            return;
        }
        if (nextState == PAUSED) {
            if (mCurrentState == ACTIVE) {
                if (session != null) {
                    session.pauseScanning();
                } else {
                    mPicker.pauseScanning();
                }
            }
            mCurrentState = PAUSED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, PAUSED);
            }
        }
    }

    interface Callback {

        /**
         * Invoked whenever the state of the barcode picker changes to a new state.
         *
         * @param picker The picker
         * @param newState the new state of the picker
         */
        void pickerEnteredState(BarcodePickerWithSearchBar picker, int newState);

        /**
         * Invoked whenever the picker starts or stops using matrix scan.
         *
         * @param picker The picker
         * @param matrixScan Whether matrix scan is enabled.
         */
        void pickerSwitchedMatrixScanState(BarcodePickerWithSearchBar picker, boolean matrixScan);
    }
}


void pickerEnteredState(BarcodePickerWithSearchBar picker, int newState);

package com.mirasense.scanditsdk.plugin;

import com.scandit.barcodepicker.ScanSession;
import com.scandit.barcodepicker.ScanSettings;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.Map;

/**
 * @brief Simple state machine for managing the different states of the barcode picker
 */
class PickerStateMachine {

    // must match values of JS wrapper
    public final static int STOPPED = 2;

    public final static int PAUSED = 1;

    public final static int ACTIVE = 3;

    private final BarcodePickerWithSearchBar mPicker;

    private int mCurrentState = STOPPED;

    private WeakReference<Callback> mCallback;

    private boolean mMatrixScanEnabled = false;

    /**
     * Create a new picker state machine.
     * @param picker The picker for which to control the states. Must not be null.
     * @param scanSettings The initial scan settings, used to set parts of the initial state.
     * @param callback The state change callback gets invoked whenever the state of the picker
     *                 changes. The callback is stored as a weak reference, so make sure to keep a
     *                 reference to the object around.
     */
    PickerStateMachine(BarcodePickerWithSearchBar picker, ScanSettings scanSettings, Callback callback) {
        mPicker = picker;
        mCallback = new WeakReference<Callback>(callback);
        updateSettingsState(scanSettings);
    }

    public void applyScanSettings(ScanSettings scanSettings) {
        mPicker.applyScanSettings(scanSettings);
        updateSettingsState(scanSettings);
    }

    private void updateSettingsState(ScanSettings scanSettings) {
        if (mMatrixScanEnabled != scanSettings.isMatrixScanEnabled()) {
            mMatrixScanEnabled = scanSettings.isMatrixScanEnabled();
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerSwitchedMatrixScanState(mPicker, mMatrixScanEnabled);
            }
        }
    }

    public int getState() {
        return mCurrentState;
    }

    public int setState(int state) {
        if (mCurrentState == state) {
            return state;
        }
        switch(state) {
            case ACTIVE:
                transitionToActiveState(false);
                break;
            case PAUSED:
                transitionToPausedState();
                break;
            case STOPPED:
                transitionToStoppedState();
                break;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, state);
        }
        mCurrentState = state;
        return state;
    }

    public boolean isMatrixScanEnabled() {
        return mMatrixScanEnabled;
    }

    protected void setTrackedCodeStates(Map<Long, JSONObject> trackedCodeStates) {
        mPicker.setTrackedCodeStates(trackedCodeStates);
    }

    public void startScanning(boolean paused) {
        if (mCurrentState == ACTIVE) {
            return;
        }
        if (!paused) {
            transitionToActiveState(true);
            mCurrentState = ACTIVE;
        } else {
            transitionToPausedState();
            mCurrentState = PAUSED;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, mCurrentState);
        }
    }

    private void transitionToStoppedState() {
        if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
            mPicker.stopScanning();
        }
    }

    private void transitionToPausedState() {
        if (mCurrentState == ACTIVE) {
            mPicker.pauseScanning();
            return;
        }
        if (mCurrentState == STOPPED) {
            mPicker.startScanning(true);
        }
    }

    private void transitionToActiveState(boolean useStartInsteadOfResume) {
        if (mCurrentState == STOPPED) {
            mPicker.startScanning();
        }
        if (mCurrentState == PAUSED) {
            if (useStartInsteadOfResume) {
                mPicker.startScanning();
            } else {
                mPicker.resumeScanning();
            }
        }
    }

    public BarcodePickerWithSearchBar getPicker() {
        return mPicker;
    }

    /**
     * Implements the logic of handling picker state changes sent from the didScan callback.
     * @param nextState The next state.
     * @param session The implementation calls stopScanning/pauseScanning if the provided session
     *                is non-null.
     */
    public void switchToNextScanState(int nextState, ScanSession session) {
        if (nextState == STOPPED) {
            if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
                if (session != null) {
                    session.stopScanning();
                } else {
                    mPicker.stopScanning();
                }
            }
            mCurrentState = STOPPED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, STOPPED);
            }
            return;
        }
        if (nextState == PAUSED) {
            if (mCurrentState == ACTIVE) {
                if (session != null) {
                    session.pauseScanning();
                } else {
                    mPicker.pauseScanning();
                }
            }
            mCurrentState = PAUSED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, PAUSED);
            }
        }
    }

    interface Callback {

        /**
         * Invoked whenever the state of the barcode picker changes to a new state.
         *
         * @param picker The picker
         * @param newState the new state of the picker
         */

        /**
         * Invoked whenever the picker starts or stops using matrix scan.
         *
         * @param picker The picker
         * @param matrixScan Whether matrix scan is enabled.
         */
        void pickerSwitchedMatrixScanState(BarcodePickerWithSearchBar picker, boolean matrixScan);
    }
}


switch(state) {
            case ACTIVE:
                transitionToActiveState(false);
                break;
            case PAUSED:
                transitionToPausedState();
                break;
            case STOPPED:
                transitionToStoppedState();
                break;
        }

package com.mirasense.scanditsdk.plugin;

import com.scandit.barcodepicker.ScanSession;
import com.scandit.barcodepicker.ScanSettings;
import org.json.JSONObject;
import java.lang.ref.WeakReference;
import java.util.Map;

/**
 * @brief Simple state machine for managing the different states of the barcode picker
 */
class PickerStateMachine {

    // must match values of JS wrapper
    public final static int STOPPED = 2;

    public final static int PAUSED = 1;

    public final static int ACTIVE = 3;

    private final BarcodePickerWithSearchBar mPicker;

    private int mCurrentState = STOPPED;

    private WeakReference<Callback> mCallback;

    private boolean mMatrixScanEnabled = false;

    /**
     * Create a new picker state machine.
     * @param picker The picker for which to control the states. Must not be null.
     * @param scanSettings The initial scan settings, used to set parts of the initial state.
     * @param callback The state change callback gets invoked whenever the state of the picker
     *                 changes. The callback is stored as a weak reference, so make sure to keep a
     *                 reference to the object around.
     */
    PickerStateMachine(BarcodePickerWithSearchBar picker, ScanSettings scanSettings, Callback callback) {
        mPicker = picker;
        mCallback = new WeakReference<Callback>(callback);
        updateSettingsState(scanSettings);
    }

    public void applyScanSettings(ScanSettings scanSettings) {
        mPicker.applyScanSettings(scanSettings);
        updateSettingsState(scanSettings);
    }

    private void updateSettingsState(ScanSettings scanSettings) {
        if (mMatrixScanEnabled != scanSettings.isMatrixScanEnabled()) {
            mMatrixScanEnabled = scanSettings.isMatrixScanEnabled();
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerSwitchedMatrixScanState(mPicker, mMatrixScanEnabled);
            }
        }
    }

    public int getState() {
        return mCurrentState;
    }

    public int setState(int state) {
        if (mCurrentState == state) {
            return state;
        }

        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, state);
        }
        mCurrentState = state;
        return state;
    }

    public boolean isMatrixScanEnabled() {
        return mMatrixScanEnabled;
    }

    protected void setTrackedCodeStates(Map<Long, JSONObject> trackedCodeStates) {
        mPicker.setTrackedCodeStates(trackedCodeStates);
    }

    public void startScanning(boolean paused) {
        if (mCurrentState == ACTIVE) {
            return;
        }
        if (!paused) {
            transitionToActiveState(true);
            mCurrentState = ACTIVE;
        } else {
            transitionToPausedState();
            mCurrentState = PAUSED;
        }
        Callback cb = mCallback.get();
        if (cb != null) {
            cb.pickerEnteredState(mPicker, mCurrentState);
        }
    }

    private void transitionToStoppedState() {
        if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
            mPicker.stopScanning();
        }
    }

    private void transitionToPausedState() {
        if (mCurrentState == ACTIVE) {
            mPicker.pauseScanning();
            return;
        }
        if (mCurrentState == STOPPED) {
            mPicker.startScanning(true);
        }
    }

    private void transitionToActiveState(boolean useStartInsteadOfResume) {
        if (mCurrentState == STOPPED) {
            mPicker.startScanning();
        }
        if (mCurrentState == PAUSED) {
            if (useStartInsteadOfResume) {
                mPicker.startScanning();
            } else {
                mPicker.resumeScanning();
            }
        }
    }

    public BarcodePickerWithSearchBar getPicker() {
        return mPicker;
    }

    /**
     * Implements the logic of handling picker state changes sent from the didScan callback.
     * @param nextState The next state.
     * @param session The implementation calls stopScanning/pauseScanning if the provided session
     *                is non-null.
     */
    public void switchToNextScanState(int nextState, ScanSession session) {
        if (nextState == STOPPED) {
            if (mCurrentState == ACTIVE || mCurrentState == PAUSED) {
                if (session != null) {
                    session.stopScanning();
                } else {
                    mPicker.stopScanning();
                }
            }
            mCurrentState = STOPPED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, STOPPED);
            }
            return;
        }
        if (nextState == PAUSED) {
            if (mCurrentState == ACTIVE) {
                if (session != null) {
                    session.pauseScanning();
                } else {
                    mPicker.pauseScanning();
                }
            }
            mCurrentState = PAUSED;
            Callback cb = mCallback.get();
            if (cb != null) {
                cb.pickerEnteredState(mPicker, PAUSED);
            }
        }
    }

    interface Callback {

        /**
         * Invoked whenever the state of the barcode picker changes to a new state.
         *
         * @param picker The picker
         * @param newState the new state of the picker
         */
        void pickerEnteredState(BarcodePickerWithSearchBar picker, int newState);

        /**
         * Invoked whenever the picker starts or stops using matrix scan.
         *
         * @param picker The picker
         * @param matrixScan Whether matrix scan is enabled.
         */
        void pickerSwitchedMatrixScanState(BarcodePickerWithSearchBar picker, boolean matrixScan);
    }
}


@Provides
    @Singleton
    @NetworkVariancePercent
    Preference<Integer> provideNetworkVariancePercent(RxSharedPreferences preferences)

package com.jakewharton.u2020.data;

import android.app.Application;
import android.content.SharedPreferences;
import com.f2prateek.rx.preferences.Preference;
import com.f2prateek.rx.preferences.RxSharedPreferences;
import com.jakewharton.picasso.OkHttp3Downloader;
import com.jakewharton.u2020.IsInstrumentationTest;
import com.jakewharton.u2020.data.api.DebugApiModule;
import com.jakewharton.u2020.data.api.oauth.AccessToken;
import com.jakewharton.u2020.data.prefs.InetSocketAddressPreferenceAdapter;
import com.jakewharton.u2020.intentfactory.CapturingIntentFactory;
import com.jakewharton.u2020.intentfactory.IntentFactory;
import com.squareup.picasso.Picasso;
import dagger.Module;
import dagger.Provides;
import java.net.InetSocketAddress;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.inject.Singleton;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import retrofit2.mock.NetworkBehavior;
import timber.log.Timber;

@Module(includes = DebugApiModule.class, complete = false, library = true, overrides = true)
public final class DebugDataModule {

    private static final int DEFAULT_ANIMATION_SPEED = 1;

    // Debug indicators displayed
    private static final boolean DEFAULT_PICASSO_DEBUGGING = false;

    // No pixel grid overlay.
    private static final boolean DEFAULT_PIXEL_GRID_ENABLED = false;

    // No pixel ratio overlay.
    private static final boolean DEFAULT_PIXEL_RATIO_ENABLED = false;

    // No crazy 3D view tree.
    private static final boolean DEFAULT_SCALPEL_ENABLED = false;

    // Draw views by default.
    private static final boolean DEFAULT_SCALPEL_WIREFRAME_ENABLED = false;

    // Show debug drawer first time.
    private static final boolean DEFAULT_SEEN_DEBUG_DRAWER = false;

    // Capture external intents.
    private static final boolean DEFAULT_CAPTURE_INTENTS = true;

    @Provides
    @Singleton
    RxSharedPreferences provideRxSharedPreferences(SharedPreferences prefs) {
        return RxSharedPreferences.create(prefs);
    }

    @Provides
    @Singleton
    IntentFactory provideIntentFactory(@IsMockMode boolean isMockMode, @CaptureIntents Preference<Boolean> captureIntents) {
        return new CapturingIntentFactory(IntentFactory.REAL, () -> isMockMode && captureIntents.get());
    }

    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(Application app, Preference<InetSocketAddress> networkProxyAddress) {
        return DataModule.createOkHttpClient(app).sslSocketFactory(createBadSslSocketFactory()).proxy(InetSocketAddressPreferenceAdapter.createProxy(networkProxyAddress.get())).build();
    }

    @Provides
    @Singleton
    @AccessToken
    Preference<String> provideAccessToken(RxSharedPreferences prefs, @ApiEndpoint Preference<String> endpoint) {
        // Return an endpoint-specific preference.
        return prefs.getString("access-token-" + endpoint.get());
    }

    @Provides
    @Singleton
    @ApiEndpoint
    Preference<String> provideEndpointPreference(RxSharedPreferences preferences) {
        return preferences.getString("debug_endpoint", ApiEndpoints.MOCK_MODE.url);
    }

    @Provides
    @Singleton
    @IsMockMode
    boolean provideIsMockMode(@ApiEndpoint Preference<String> endpoint, @IsInstrumentationTest boolean isInstrumentationTest) {
        // Running in an instrumentation forces mock mode.
        return isInstrumentationTest || ApiEndpoints.isMockMode(endpoint.get());
    }

    @Provides
    @Singleton
    @NetworkDelay
    Preference<Long> provideNetworkDelay(RxSharedPreferences preferences) {
        return preferences.getLong("debug_network_delay", 2000l);
    }

    @Provides
    @Singleton
    @NetworkFailurePercent
    Preference<Integer> provideNetworkFailurePercent(RxSharedPreferences preferences) {
        return preferences.getInteger("debug_network_failure_percent", 3);
    }

    @Provides
    @Singleton
    @NetworkErrorPercent
    Preference<Integer> provideNetworkErrorPercent(RxSharedPreferences preferences) {
        return preferences.getInteger("debug_network_error_percent", 0);
    }

    @Provides
    @Singleton
    Preference<NetworkErrorCode> provideNetworkErrorCode(RxSharedPreferences preferences) {
        return preferences.getEnum("debug_network_error_code", NetworkErrorCode.HTTP_500, NetworkErrorCode.class);
    }

{
        return preferences.getInteger("debug_network_variance_percent", 40);
    }

    @Provides
    @Singleton
    Preference<InetSocketAddress> provideNetworkProxyAddress(RxSharedPreferences preferences) {
        return preferences.getObject("debug_network_proxy", InetSocketAddressPreferenceAdapter.INSTANCE);
    }

    @Provides
    @Singleton
    @CaptureIntents
    Preference<Boolean> provideCaptureIntentsPreference(RxSharedPreferences preferences) {
        return preferences.getBoolean("debug_capture_intents", DEFAULT_CAPTURE_INTENTS);
    }

    @Provides
    @Singleton
    @AnimationSpeed
    Preference<Integer> provideAnimationSpeed(RxSharedPreferences preferences) {
        return preferences.getInteger("debug_animation_speed", DEFAULT_ANIMATION_SPEED);
    }

    @Provides
    @Singleton
    @PicassoDebugging
    Preference<Boolean> providePicassoDebugging(RxSharedPreferences preferences) {
        return preferences.getBoolean("debug_picasso_debugging", DEFAULT_PICASSO_DEBUGGING);
    }

    @Provides
    @Singleton
    @PixelGridEnabled
    Preference<Boolean> providePixelGridEnabled(RxSharedPreferences preferences) {
        return preferences.getBoolean("debug_pixel_grid_enabled", DEFAULT_PIXEL_GRID_ENABLED);
    }

    @Provides
    @Singleton
    @PixelRatioEnabled
    Preference<Boolean> providePixelRatioEnabled(RxSharedPreferences preferences) {
        return preferences.getBoolean("debug_pixel_ratio_enabled", DEFAULT_PIXEL_RATIO_ENABLED);
    }

    @Provides
    @Singleton
    @SeenDebugDrawer
    Preference<Boolean> provideSeenDebugDrawer(RxSharedPreferences preferences) {
        return preferences.getBoolean("debug_seen_debug_drawer", DEFAULT_SEEN_DEBUG_DRAWER);
    }

    @Provides
    @Singleton
    @ScalpelEnabled
    Preference<Boolean> provideScalpelEnabled(RxSharedPreferences preferences) {
        return preferences.getBoolean("debug_scalpel_enabled", DEFAULT_SCALPEL_ENABLED);
    }

    @Provides
    @Singleton
    @ScalpelWireframeEnabled
    Preference<Boolean> provideScalpelWireframeEnabled(RxSharedPreferences preferences) {
        return preferences.getBoolean("debug_scalpel_wireframe_drawer", DEFAULT_SCALPEL_WIREFRAME_ENABLED);
    }

    @Provides
    @Singleton
    Picasso providePicasso(OkHttpClient client, NetworkBehavior behavior, @IsMockMode boolean isMockMode, Application app) {
        Picasso.Builder builder = new Picasso.Builder(app).downloader(new OkHttp3Downloader(client));
        if (isMockMode) {
            builder.addRequestHandler(new MockRequestHandler(behavior, app.getAssets()));
        }
        builder.listener((picasso, uri, exception) -> {
            Timber.e(exception, "Error while loading image %s", uri);
        });
        return builder.build();
    }

    private static SSLSocketFactory createBadSslSocketFactory() {
        try {
            // Construct SSLSocketFactory that accepts any cert.
            SSLContext context = SSLContext.getInstance("TLS");
            TrustManager permissive = new X509TrustManager() {

                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            };
            context.init(null, new TrustManager[] { permissive }, null);
            return context.getSocketFactory();
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}