@Override
    public String getName() {
        return "asyncLuaOuyaInitInput";
    }

package tv.ouya.sdk.corona;

import com.ansca.corona.input.ViewInputHandler;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

/**
 * Implements the asyncCallLuaFunction() function in Lua.
 *

 * Demonstrates how to fetch a "Lua function argument" and then call that Lua function from another thread.
 *

 * You must never manipulate the Lua state from another thread or else race conditions and exceptions that
 * can crash the application can occur. This example demonstrates how to do this in a thread safe manner.
 */
public class AsyncLuaOuyaInitInput implements com.naef.jnlua.NamedJavaFunction {

    public static final String TAG = "AsyncLuaOuyaInitInput";

    // Custom input view detects input to send axis and button events to Lua
    private CoronaOuyaInputView mInputView = null;

    /**
     * Gets the name of the Lua function as it would appear in the Lua script.
     * @return Returns the name of the custom Lua function.
     */

    /**
     * This method is called when the Lua function is called.
     * <p>
     * Warning! This method is not called on the main UI thread.
     * @param luaState Reference to the Lua state.
     *                 Needed to retrieve the Lua function's parameters and to return values back to Lua.
     * @return Returns the number of values to be returned by the Lua function.
     */
    @Override
    public int invoke(com.naef.jnlua.LuaState luaState) {
        CallbacksOuyaInput callbacks = new CallbacksOuyaInput(luaState);
        // store for access
        IOuyaActivity.SetCallbacksOuyaInput(callbacks);
        // disable built-in input
        disableBuiltInCoronaInput();
        // add Corona OUYA Input View to layout
        addCoronaOuyaInputView();
        // Return 0 since this Lua function does not return any values.
        return 0;
    }

    private void disableBuiltInCoronaInput() {
        Activity activity = com.ansca.corona.CoronaEnvironment.getCoronaActivity();
        // disable standard Corona input
        Field[] fs = com.ansca.corona.CoronaActivity.class.getDeclaredFields();
        for (Field field : fs) {
            if (null != field) {
                field.setAccessible(true);
                try {
                    if (field.getType().getName().equals("com.ansca.corona.input.ViewInputHandler")) {
                        field.setAccessible(true);
                        ViewInputHandler view = (ViewInputHandler) field.get(activity);
                        if (null != view) {
                            // Log.i(TAG, "Got the view handler");
                            unsubscribeViewInputHandler(view);
                        } else {
                            Log.w(TAG, "Didn't get the view handler");
                        }
                    }
                } catch (java.lang.Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    private void unsubscribeEventHandler(Object eventHandler) {
        if (null == eventHandler) {
            return;
        }
        try {
            Method unsubscribe = eventHandler.getClass().getMethod("unsubscribe");
            if (null != unsubscribe) {
                unsubscribe.invoke(eventHandler, new Object[0]);
            } else {
                Log.w(TAG, "Failed to find unsubscribe method");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void unsubscribeViewInputHandler(ViewInputHandler inputHandler) {
        if (null == inputHandler) {
            return;
        }
        Field[] fs = ViewInputHandler.class.getDeclaredFields();
        for (Field field : fs) {
            if (null != field) {
                field.setAccessible(true);
                try {
                    if (field.getType().getName().equals("com.ansca.corona.input.ViewInputHandler$EventHandler")) {
                        Object handler = field.get(inputHandler);
                        if (null != handler) {
                            // Log.i(TAG, "Found event handler");
                            unsubscribeEventHandler(handler);
                        } else {
                            Log.w(TAG, "Failed to get event handler");
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    // find the main frame layout from the layout content
    private FrameLayout getFrameLayout(final Activity activity) {
        if (null != activity.getWindow() && null != activity.getWindow().getDecorView()) {
            View view = activity.getWindow().getDecorView().findViewById(android.R.id.content);
            if (null != view) {
                if (view instanceof android.widget.FrameLayout) {
                    return (FrameLayout) view;
                }
            }
        }
        return null;
    }

    private void addCoronaOuyaInputView() {
        final Activity activity = com.ansca.corona.CoronaEnvironment.getCoronaActivity();
        activity.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                // *** We are now running in the main UI thread. ***
                try {
                    if (null == mInputView) {
                        mInputView = new CoronaOuyaInputView(activity.getApplicationContext());
                        mInputView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
                        // Log.i(TAG, "Find frame layout");
                        FrameLayout fm = getFrameLayout(activity);
                        if (null != fm) {
                            // Log.i(TAG, "Add OuyaInputView to frame layout");
                            fm.addView(mInputView);
                            mInputView.requestFocus();
                        } else {
                            Log.w(TAG, "Filed to find frame layout");
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    }
}


try {
            Method unsubscribe = eventHandler.getClass().getMethod("unsubscribe");
            if (null != unsubscribe) {
                unsubscribe.invoke(eventHandler, new Object[0]);
            } else {
                Log.w(TAG, "Failed to find unsubscribe method");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

package tv.ouya.sdk.corona;

import com.ansca.corona.input.ViewInputHandler;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

/**
 * Implements the asyncCallLuaFunction() function in Lua.
 *

 * Demonstrates how to fetch a "Lua function argument" and then call that Lua function from another thread.
 *

 * You must never manipulate the Lua state from another thread or else race conditions and exceptions that
 * can crash the application can occur. This example demonstrates how to do this in a thread safe manner.
 */
public class AsyncLuaOuyaInitInput implements com.naef.jnlua.NamedJavaFunction {

    public static final String TAG = "AsyncLuaOuyaInitInput";

    // Custom input view detects input to send axis and button events to Lua
    private CoronaOuyaInputView mInputView = null;

    /**
     * Gets the name of the Lua function as it would appear in the Lua script.
     * @return Returns the name of the custom Lua function.
     */
    @Override
    public String getName() {
        return "asyncLuaOuyaInitInput";
    }

    /**
     * This method is called when the Lua function is called.
     *

     * Warning! This method is not called on the main UI thread.
     * @param luaState Reference to the Lua state.
     *                 Needed to retrieve the Lua function's parameters and to return values back to Lua.
     * @return Returns the number of values to be returned by the Lua function.
     */
    @Override
    public int invoke(com.naef.jnlua.LuaState luaState) {
        CallbacksOuyaInput callbacks = new CallbacksOuyaInput(luaState);
        // store for access
        IOuyaActivity.SetCallbacksOuyaInput(callbacks);
        // disable built-in input
        disableBuiltInCoronaInput();
        // add Corona OUYA Input View to layout
        addCoronaOuyaInputView();
        // Return 0 since this Lua function does not return any values.
        return 0;
    }

    private void disableBuiltInCoronaInput() {
        Activity activity = com.ansca.corona.CoronaEnvironment.getCoronaActivity();
        // disable standard Corona input
        Field[] fs = com.ansca.corona.CoronaActivity.class.getDeclaredFields();
        for (Field field : fs) {
            if (null != field) {
                field.setAccessible(true);
                try {
                    if (field.getType().getName().equals("com.ansca.corona.input.ViewInputHandler")) {
                        field.setAccessible(true);
                        ViewInputHandler view = (ViewInputHandler) field.get(activity);
                        if (null != view) {
                            // Log.i(TAG, "Got the view handler");
                            unsubscribeViewInputHandler(view);
                        } else {
                            Log.w(TAG, "Didn't get the view handler");
                        }
                    }
                } catch (java.lang.Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    private void unsubscribeEventHandler(Object eventHandler) {
        if (null == eventHandler) {
            return;
        }

    }

    private void unsubscribeViewInputHandler(ViewInputHandler inputHandler) {
        if (null == inputHandler) {
            return;
        }
        Field[] fs = ViewInputHandler.class.getDeclaredFields();
        for (Field field : fs) {
            if (null != field) {
                field.setAccessible(true);
                try {
                    if (field.getType().getName().equals("com.ansca.corona.input.ViewInputHandler$EventHandler")) {
                        Object handler = field.get(inputHandler);
                        if (null != handler) {
                            // Log.i(TAG, "Found event handler");
                            unsubscribeEventHandler(handler);
                        } else {
                            Log.w(TAG, "Failed to get event handler");
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    // find the main frame layout from the layout content
    private FrameLayout getFrameLayout(final Activity activity) {
        if (null != activity.getWindow() && null != activity.getWindow().getDecorView()) {
            View view = activity.getWindow().getDecorView().findViewById(android.R.id.content);
            if (null != view) {
                if (view instanceof android.widget.FrameLayout) {
                    return (FrameLayout) view;
                }
            }
        }
        return null;
    }

    private void addCoronaOuyaInputView() {
        final Activity activity = com.ansca.corona.CoronaEnvironment.getCoronaActivity();
        activity.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                // *** We are now running in the main UI thread. ***
                try {
                    if (null == mInputView) {
                        mInputView = new CoronaOuyaInputView(activity.getApplicationContext());
                        mInputView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
                        // Log.i(TAG, "Find frame layout");
                        FrameLayout fm = getFrameLayout(activity);
                        if (null != fm) {
                            // Log.i(TAG, "Add OuyaInputView to frame layout");
                            fm.addView(mInputView);
                            mInputView.requestFocus();
                        } else {
                            Log.w(TAG, "Filed to find frame layout");
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
    }
}


for (int i = 0; i < split.length; i++) {
            out[i] = fromText(split[i]);
        }

package stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import shared.Shared;

/**
 * @author Brian Bushnell
 * @date Jul 16, 2012
 */
public final class SiteScoreR implements Comparable<SiteScoreR> {

    public SiteScoreR(SiteScore ss, int readlen_, long numericID_, byte pairnum_) {
        this(ss.chrom, ss.strand, ss.start, ss.stop, readlen_, numericID_, pairnum_, ss.score, ss.pairedScore, ss.perfect, ss.semiperfect);
    }

    public SiteScoreR(int chrom_, byte strand_, int start_, int stop_, int readlen_, long numericID_, byte pairnum_, int score_, int pscore_, boolean perfect_, boolean semiperfect_) {
        chrom = chrom_;
        strand = strand_;
        start = start_;
        stop = stop_;
        readlen = readlen_;
        numericID = numericID_;
        pairnum = pairnum_;
        score = score_;
        pairedScore = pscore_;
        perfect = perfect_;
        semiperfect = semiperfect_ | perfect_;
        assert (start_ <= stop_) : this.toText();
    }

    @Override
    public int compareTo(SiteScoreR other) {
        int x = other.score - score;
        if (x != 0) {
            return x;
        }
        x = other.pairedScore - pairedScore;
        if (x != 0) {
            return x;
        }
        x = chrom - other.chrom;
        if (x != 0) {
            return x;
        }
        x = strand - other.strand;
        if (x != 0) {
            return x;
        }
        x = start - other.start;
        return x;
    }

    @Override
    public boolean equals(Object other) {
        return compareTo((SiteScoreR) other) == 0;
    }

    @Override
    public int hashCode() {
        assert (false) : "This class should not be hashed.";
        return super.hashCode();
    }

    public boolean equals(SiteScore other) {
        if (other.start != start) {
            return false;
        }
        if (other.stop != stop) {
            return false;
        }
        if (other.chrom != chrom) {
            return false;
        }
        if (other.strand != strand) {
            return false;
        }
        return true;
    }

    public boolean equals(SiteScoreR other) {
        return compareTo(other) == 0;
    }

    @Override
    public String toString() {
        return toText().toString();
    }

    public StringBuilder toText() {
        StringBuilder sb = new StringBuilder(50);
        if (correct) {
            sb.append('*');
        }
        sb.append(chrom);
        sb.append(',');
        sb.append(strand);
        sb.append(',');
        sb.append(start);
        sb.append(',');
        sb.append(stop);
        sb.append(',');
        sb.append(readlen);
        sb.append(',');
        sb.append(numericID);
        sb.append(',');
        sb.append(pairnum);
        sb.append(',');
        sb.append((semiperfect ? 1 : 0));
        sb.append((perfect ? 1 : 0));
        sb.append(',');
        sb.append(pairedScore);
        sb.append(',');
        sb.append(score);
        return sb;
    }

    public final boolean overlaps(SiteScoreR ss) {
        return chrom == ss.chrom && strand == ss.strand && overlap(start, stop, ss.start, ss.stop);
    }

    private static boolean overlap(int a1, int b1, int a2, int b2) {
        assert (a1 <= b1 && a2 <= b2) : a1 + ", " + b1 + ", " + a2 + ", " + b2;
        return a2 <= b1 && b2 >= a1;
    }

    public static String header() {
        return "chrom,strand,start,stop,readlen,numericID,pairnum,semiperfect+perfect,quickScore,slowScore,pairedScore,score";
    }

    public static SiteScoreR fromText(String s) {
        // System.err.println("Trying to make a SS from "+s);
        String[] line = s.split(",");
        SiteScoreR ss;
        assert (line.length == 10 || line.length == 11) : "\n" + line.length + "\n" + s + "\n" + Arrays.toString(line) + "\n";
        boolean correct = false;
        if (line[0].charAt(0) == '*') {
            correct = true;
            line[0] = line[0].substring(1);
        }
        int chrom = Byte.parseByte(line[0]);
        byte strand = Byte.parseByte(line[1]);
        int start = Integer.parseInt(line[2]);
        int stop = Integer.parseInt(line[3]);
        int readlen = Integer.parseInt(line[4]);
        long numericID = Long.parseLong(line[5]);
        byte pairnum = Byte.parseByte(line[6]);
        int p = Integer.parseInt(line[7], 2);
        boolean perfect = (p & 1) == 1;
        boolean semiperfect = (p & 2) == 2;
        int pairedScore = Integer.parseInt(line[8]);
        int score = Integer.parseInt(line[9]);
        ss = new SiteScoreR(chrom, strand, start, stop, readlen, numericID, pairnum, score, pairedScore, perfect, semiperfect);
        ss.correct = correct;
        return ss;
    }

    public static SiteScoreR[] fromTextArray(String s) {
        String[] split = s.split("\t");
        SiteScoreR[] out = new SiteScoreR[split.length];

        return out;
    }

    public boolean positionalMatch(SiteScoreR b) {
        if (chrom != b.chrom || strand != b.strand || start != b.start || stop != b.stop) {
            return false;
        }
        return true;
    }

    public static class PositionComparator implements Comparator<SiteScoreR> {

        private PositionComparator() {
        }

        @Override
        public int compare(SiteScoreR a, SiteScoreR b) {
            if (a.chrom != b.chrom) {
                return a.chrom - b.chrom;
            }
            if (a.start != b.start) {
                return a.start - b.start;
            }
            if (a.stop != b.stop) {
                return a.stop - b.stop;
            }
            if (a.strand != b.strand) {
                return a.strand - b.strand;
            }
            if (a.score != b.score) {
                return b.score - a.score;
            }
            if (a.perfect != b.perfect) {
                return a.perfect ? -1 : 1;
            }
            return 0;
        }

        public void sort(List<SiteScoreR> list) {
            if (list == null || list.size() < 2) {
                return;
            }
            Collections.sort(list, this);
        }

        public void sort(SiteScoreR[] list) {
            if (list == null || list.length < 2) {
                return;
            }
            Arrays.sort(list, this);
        }
    }

    public static class NormalizedComparator implements Comparator<SiteScoreR> {

        private NormalizedComparator() {
        }

        @Override
        public int compare(SiteScoreR a, SiteScoreR b) {
            if ((int) a.normalizedScore != (int) b.normalizedScore) {
                return (int) b.normalizedScore - (int) a.normalizedScore;
            }
            if (a.score != b.score) {
                return b.score - a.score;
            }
            if (a.pairedScore != b.pairedScore) {
                return b.pairedScore - a.pairedScore;
            }
            if (a.retainVotes != b.retainVotes) {
                return b.retainVotes - a.retainVotes;
            }
            if (a.perfect != b.perfect) {
                return a.perfect ? -1 : 1;
            }
            if (a.chrom != b.chrom) {
                return a.chrom - b.chrom;
            }
            if (a.start != b.start) {
                return a.start - b.start;
            }
            if (a.stop != b.stop) {
                return a.stop - b.stop;
            }
            if (a.strand != b.strand) {
                return a.strand - b.strand;
            }
            return 0;
        }

        public void sort(List<SiteScoreR> list) {
            if (list == null || list.size() < 2) {
                return;
            }
            Collections.sort(list, this);
        }

        public void sort(SiteScoreR[] list) {
            if (list == null || list.length < 2) {
                return;
            }
            Arrays.sort(list, this);
        }
    }

    public static class IDComparator implements Comparator<SiteScoreR> {

        private IDComparator() {
        }

        @Override
        public int compare(SiteScoreR a, SiteScoreR b) {
            if (a.numericID != b.numericID) {
                return a.numericID > b.numericID ? 1 : -1;
            }
            if (a.pairnum != b.pairnum) {
                return a.pairnum - b.pairnum;
            }
            if (a.chrom != b.chrom) {
                return a.chrom - b.chrom;
            }
            if (a.start != b.start) {
                return a.start - b.start;
            }
            if (a.stop != b.stop) {
                return a.stop - b.stop;
            }
            if (a.strand != b.strand) {
                return a.strand - b.strand;
            }
            if (a.score != b.score) {
                return b.score - a.score;
            }
            if (a.perfect != b.perfect) {
                return a.perfect ? -1 : 1;
            }
            return 0;
        }

        public void sort(ArrayList<SiteScoreR> list) {
            if (list == null || list.size() < 2) {
                return;
            }
            Shared.sort(list, this);
        }

        public void sort(SiteScoreR[] list) {
            if (list == null || list.length < 2) {
                return;
            }
            Arrays.sort(list, this);
        }
    }

    public static final PositionComparator PCOMP = new PositionComparator();

    public static final NormalizedComparator NCOMP = new NormalizedComparator();

    public static final IDComparator IDCOMP = new IDComparator();

    public int reflen() {
        return stop - start + 1;
    }

    public int start;

    public int stop;

    public int readlen;

    public int score;

    public int pairedScore;

    public final int chrom;

    public final byte strand;

    public boolean perfect;

    public boolean semiperfect;

    public final long numericID;

    public final byte pairnum;

    public float normalizedScore;

    // public int weight=0; //Temp variable, for calculating normalized score
    public boolean correct = false;

    public int retainVotes = 0;
}


try {
            mVersion.setText("v" + mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName);
        } catch (Exception e) {
            mVersion.setText("v???");
        }

/*
 *
 * This file is part of Spydroid (http://example.com/)
 *
 */
package net.majorkernelpanic.spydroid.ui;

import java.util.Locale;
import net.majorkernelpanic.http.TinyHttpServer;
import net.majorkernelpanic.spydroid.R;
import net.majorkernelpanic.spydroid.SpydroidApplication;
import net.majorkernelpanic.spydroid.Utilities;
import net.majorkernelpanic.spydroid.api.CustomHttpServer;
import net.majorkernelpanic.spydroid.api.CustomRtspServer;
import net.majorkernelpanic.streaming.rtsp.RtspServer;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.TextView;

public class HandsetFragment extends Fragment {

    public final static String TAG = "HandsetFragment";

    private TextView mDescription1, mDescription2, mLine1, mLine2, mVersion, mSignWifi, mTextBitrate;

    private LinearLayout mSignInformation, mSignStreaming;

    private Animation mPulseAnimation;

    private SpydroidApplication mApplication;

    private CustomHttpServer mHttpServer;

    private RtspServer mRtspServer;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mApplication = (SpydroidApplication) getActivity().getApplication();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.main, container, false);
        mLine1 = (TextView) rootView.findViewById(R.id.line1);
        mLine2 = (TextView) rootView.findViewById(R.id.line2);
        mDescription1 = (TextView) rootView.findViewById(R.id.line1_description);
        mDescription2 = (TextView) rootView.findViewById(R.id.line2_description);
        mVersion = (TextView) rootView.findViewById(R.id.version);
        mSignWifi = (TextView) rootView.findViewById(R.id.advice);
        mSignStreaming = (LinearLayout) rootView.findViewById(R.id.streaming);
        mSignInformation = (LinearLayout) rootView.findViewById(R.id.information);
        mPulseAnimation = AnimationUtils.loadAnimation(mApplication.getApplicationContext(), R.anim.pulse);
        mTextBitrate = (TextView) rootView.findViewById(R.id.bitrate);
        return rootView;
    }

    @Override
    public void onStart() {
        super.onStart();
        // Print version number
        Context mContext = mApplication.getApplicationContext();

    }

    @Override
    public void onPause() {
        super.onPause();
        update();
        getActivity().unregisterReceiver(mWifiStateReceiver);
        getActivity().unbindService(mHttpServiceConnection);
        getActivity().unbindService(mRtspServiceConnection);
    }

    @Override
    public void onResume() {
        super.onResume();
        getActivity().bindService(new Intent(getActivity(), CustomHttpServer.class), mHttpServiceConnection, Context.BIND_AUTO_CREATE);
        getActivity().bindService(new Intent(getActivity(), CustomRtspServer.class), mRtspServiceConnection, Context.BIND_AUTO_CREATE);
        getActivity().registerReceiver(mWifiStateReceiver, new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION));
    }

    public void update() {
        getActivity().runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if (mDescription1 != null) {
                    if (mHttpServer != null && mRtspServer != null) {
                        if (!mHttpServer.isHttpEnabled() && !mHttpServer.isHttpsEnabled()) {
                            mDescription1.setVisibility(View.INVISIBLE);
                            mLine1.setVisibility(View.INVISIBLE);
                        } else {
                            mDescription1.setVisibility(View.VISIBLE);
                            mLine1.setVisibility(View.VISIBLE);
                        }
                        if (!mRtspServer.isEnabled()) {
                            mDescription2.setVisibility(View.INVISIBLE);
                            mLine2.setVisibility(View.INVISIBLE);
                        } else {
                            mDescription2.setVisibility(View.VISIBLE);
                            mLine2.setVisibility(View.VISIBLE);
                        }
                        if (!mHttpServer.isStreaming() && !mRtspServer.isStreaming())
                            displayIpAddress();
                        else
                            streamingState(1);
                    }
                }
            }
        });
    }

    private void streamingState(int state) {
        if (state == 0) {
            // Not streaming
            mSignStreaming.clearAnimation();
            mSignWifi.clearAnimation();
            mSignStreaming.setVisibility(View.GONE);
            mSignInformation.setVisibility(View.VISIBLE);
            mSignWifi.setVisibility(View.GONE);
        } else if (state == 1) {
            // Streaming
            mSignWifi.clearAnimation();
            mSignStreaming.setVisibility(View.VISIBLE);
            mSignStreaming.startAnimation(mPulseAnimation);
            mHandler.post(mUpdateBitrate);
            mSignInformation.setVisibility(View.INVISIBLE);
            mSignWifi.setVisibility(View.GONE);
        } else if (state == 2) {
            // No wifi !
            mSignStreaming.clearAnimation();
            mSignStreaming.setVisibility(View.GONE);
            mSignInformation.setVisibility(View.INVISIBLE);
            mSignWifi.setVisibility(View.VISIBLE);
            mSignWifi.startAnimation(mPulseAnimation);
        }
    }

    private void displayIpAddress() {
        WifiManager wifiManager = (WifiManager) mApplication.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        WifiInfo info = wifiManager.getConnectionInfo();
        String ipaddress = null;
        if (info != null && info.getNetworkId() > -1) {
            int i = info.getIpAddress();
            String ip = String.format(Locale.ENGLISH, "%d.%d.%d.%d", i & 0xff, i >> 8 & 0xff, i >> 16 & 0xff, i >> 24 & 0xff);
            mLine1.setText(mHttpServer.isHttpsEnabled() ? "https://" : "http://");
            mLine1.append(ip);
            mLine1.append(":" + mHttpServer.getHttpPort());
            mLine2.setText("rtsp://");
            mLine2.append(ip);
            mLine2.append(":" + mRtspServer.getPort());
            streamingState(0);
        } else if ((ipaddress = Utilities.getLocalIpAddress(true)) != null) {
            mLine1.setText(mHttpServer.isHttpsEnabled() ? "https://" : "http://");
            mLine1.append(ipaddress);
            mLine1.append(":" + mHttpServer.getHttpPort());
            mLine2.setText("rtsp://");
            mLine2.append(ipaddress);
            mLine2.append(":" + mRtspServer.getPort());
            streamingState(0);
        } else {
            streamingState(2);
        }
    }

    private final ServiceConnection mRtspServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mRtspServer = (RtspServer) ((RtspServer.LocalBinder) service).getService();
            update();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    private final ServiceConnection mHttpServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mHttpServer = (CustomHttpServer) ((TinyHttpServer.LocalBinder) service).getService();
            update();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    // BroadcastReceiver that detects wifi state changements
    private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // This intent is also received when app resumes even if wifi state hasn't changed :/
            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                update();
            }
        }
    };

    private final Handler mHandler = new Handler();

    private Runnable mUpdateBitrate = new Runnable() {

        @Override
        public void run() {
            if ((mRtspServer != null && mRtspServer.isStreaming()) || (mHttpServer != null && mHttpServer.isStreaming())) {
                long bitrate = 0;
                bitrate += mRtspServer != null ? mRtspServer.getBitrate() : 0;
                bitrate += mHttpServer != null ? mHttpServer.getBitrate() : 0;
                mTextBitrate.setText("" + bitrate / 1000 + " kbps");
                mHandler.postDelayed(mUpdateBitrate, 1000);
            } else {
                mTextBitrate.setText("0 kbps");
            }
        }
    };
}


for (int i = 0; i < undoer.length; i++) if (this.undoer[i] != null)
                undoer[i].dispose();

/*

Disclaimer:  The Mesquite source code is lengthy and we are few.  There are no doubt inefficiencies and goofs in this code.
The commenting leaves much to be desired. Please approach this source code with the spirit of helping out.
Perhaps with your help we can be more than a few, and make Mesquite better.

Mesquite's web site is http://mesquiteproject.org

This source code and its compiled class files are free and modifiable under the terms of
 */
package mesquite.lib;

import mesquite.lib.characters.*;
import mesquite.lib.characters.CharacterData;
import mesquite.lib.table.*;

public class UndoReference {

    Undoer[] undoer;

    MesquiteModule responsibleModule;

    public UndoReference() {
    }

    public UndoReference(CharacterData data, MesquiteModule responsibleModule, int[] changesThatMightHappen) {
        UndoInstructions undoInstructions = data.getUndoInstructionsAllMatrixCells(changesThatMightHappen);
        if (undoInstructions != null)
            undoInstructions.setNewData(data);
        setUndoer(new Undoer[] { undoInstructions });
        setResponsibleModule(responsibleModule);
    }

    public UndoReference(CharacterData data, MesquiteModule responsibleModule, int icStart, int icEnd, int itStart, int itEnd) {
        UndoInstructions undoInstructions = new UndoInstructions(UndoInstructions.DATABLOCK, data, data, icStart, icEnd, itStart, itEnd, icStart, icEnd, itStart, itEnd, true);
        setUndoer(new Undoer[] { undoInstructions });
        setResponsibleModule(responsibleModule);
    }

    public static final int ALLCHARACTERNAMES = 7;

    /**
     * a constructor for an Undoreference that preserves both data and the taxon names
     */
    public UndoReference(CharacterData data, MesquiteModule responsibleModule, int icStart, int icEnd, int itStart, int itEnd, int[] undoableObjects) {
        if (undoableObjects == null)
            return;
        UndoInstructions[] undoInstructions = new UndoInstructions[undoableObjects.length];
        for (int i = 0; i < undoableObjects.length; i++) {
            switch(undoableObjects[i]) {
                case UndoInstructions.ALLDATACELLS:
                    // TODO:  pass into this something more refined!
                    undoInstructions[i] = data.getUndoInstructionsAllMatrixCells(null);
                    if (undoInstructions != null)
                        undoInstructions[i].setNewData(data);
                    break;
                case UndoInstructions.DATABLOCK:
                    undoInstructions[i] = new UndoInstructions(UndoInstructions.DATABLOCK, data, data, icStart, icEnd, itStart, itEnd, icStart, icEnd, itStart, itEnd, true);
                    break;
                case UndoInstructions.ALLTAXONNAMES:
                    if (data != null)
                        undoInstructions[i] = new UndoInstructions(UndoInstructions.ALLTAXONNAMES, data.getTaxa(), data.getTaxa());
                    break;
                case UndoInstructions.ALLCHARACTERNAMES:
                    undoInstructions[i] = new UndoInstructions(UndoInstructions.ALLCHARACTERNAMES, data, data);
                    break;
            }
        }
        setUndoer(undoInstructions);
        setResponsibleModule(responsibleModule);
    }

    public UndoReference(Undoer[] undoer, MesquiteModule responsibleModule) {
        this.undoer = undoer;
        this.responsibleModule = responsibleModule;
    }

    public UndoReference(Undoer undoer, MesquiteModule responsibleModule) {
        this.undoer = new Undoer[] { undoer };
        this.responsibleModule = responsibleModule;
    }

    public MesquiteModule getResponsibleModule() {
        return responsibleModule;
    }

    public void setResponsibleModule(MesquiteModule responsibleModule) {
        this.responsibleModule = responsibleModule;
    }

    public Undoer[] getUndoer() {
        return undoer;
    }

    public void setUndoer(Undoer[] undoer) {
        this.undoer = undoer;
    }

    public void setUndoer(Undoer undoer) {
        if (this.undoer != null) {
            for (int i = 0; i < this.undoer.length; i++) if (this.undoer[i] != null && undoer != this.undoer[i])
                this.undoer[i].dispose();
        }
        this.undoer = new Undoer[] { undoer };
    }

    public void dispose() {
        if (undoer != null) {

        }
    }

    public static UndoReference getUndoReferenceForMatrixSelection(CharacterData data, MesquiteTable table, MesquiteModule responsibleModule, int[] changesThatMightHappen) {
        if (data != null)
            if (table != null) {
                MesquiteInteger firstRow = new MesquiteInteger();
                MesquiteInteger lastRow = new MesquiteInteger();
                MesquiteInteger firstColumn = new MesquiteInteger();
                MesquiteInteger lastColumn = new MesquiteInteger();
                if (table.singleCellBlockSelected(firstRow, lastRow, firstColumn, lastColumn)) {
                    if (table.numRowNamesSelected() > 0)
                        return new UndoReference(data, responsibleModule, firstColumn.getValue(), lastColumn.getValue(), firstRow.getValue(), lastRow.getValue(), new int[] { UndoInstructions.DATABLOCK, UndoInstructions.ALLTAXONNAMES });
                    else
                        return new UndoReference(data, responsibleModule, firstColumn.getValue(), lastColumn.getValue(), firstRow.getValue(), lastRow.getValue(), new int[] { UndoInstructions.DATABLOCK });
                }
            } else
                return new UndoReference(data, responsibleModule, changesThatMightHappen);
        return null;
    }
}


for (int i = 0; i < len; i++) {
            Srch_crt_tkn tkn = ary[i];
            rv[i] = tkn.Tid;
        }

/*
XOWA: the XOWA Offline Wiki Application

The terms of each license can be found in the source code repository:

*/
package gplx.xowa.addons.wikis.searchs.searchers.crts;

import gplx.*;
import gplx.xowa.*;
import gplx.xowa.addons.*;
import gplx.xowa.addons.wikis.*;
import gplx.xowa.addons.wikis.searchs.*;
import gplx.xowa.addons.wikis.searchs.searchers.*;
import org.junit.*;
import gplx.xowa.addons.wikis.searchs.parsers.*;

public class Srch_crt_scanner_tst {

    private final Srch_crt_scanner_fxt fxt = new Srch_crt_scanner_fxt();

    @Test
    public void Word() {
        fxt.Test__scan("abc", "abc");
    }

    @Test
    public void Word__many() {
        fxt.Test__scan("abc d ef", "abc", "d", "ef");
    }

    @Test
    public void Word__symbol() {
        fxt.Test__scan("a; b", "a;", "b");
    }

    @Test
    public void And() {
        fxt.Test__scan("a + b", "a", "+", "b");
    }

    // check that ( causes and to be treated as separate word
    @Test
    public void And__parens() {
        fxt.Test__scan("a +(b)", "a", "+", "(", "b", ")");
    }

    @Test
    public void Or() {
        fxt.Test__scan("a , b", "a", ",", "b");
    }

    @Test
    public void Or__no_space() {
        fxt.Test__scan("a, b", "a", ",", "b");
    }

    @Test
    public void Not() {
        fxt.Test__scan("-abc", "-", "abc");
    }

    @Test
    public void Not__mid__1() {
        fxt.Test__scan("a-b", "a-b");
    }

    // ignore - if in middle of word
    @Test
    public void Not__mid__2() {
        fxt.Test__scan("a b-c", "a", "b-c");
    }

    @Test
    public void Not__and() {
        fxt.Test__scan("a -bc", "a", "-", "bc");
    }

    @Test
    public void Not__dangling() {
        fxt.Test__scan("a -", "a", "-");
    }

    // spaces should not generate tkns
    @Test
    public void Space() {
        fxt.Test__scan(" a   b ", "a", "b");
    }

    @Test
    public void Quote() {
        fxt.Test__scan("\"a b\"", "a b");
    }

    @Test
    public void Quote__mid() {
        fxt.Test__scan("a\"b", "a", "b");
    }

    @Test
    public void Quote__double() {
        fxt.Test__scan("\"a\"\"b\"", "a\"b");
    }

    @Test
    public void Quote__missing__one() {
        fxt.Test__scan("\"abc", "abc");
    }

    @Test
    public void Quote__missing__many() {
        fxt.Test__scan("\"abc a", "abc", "a");
    }

    @Test
    public void Escape__bgn() {
        fxt.Test__scan("\\-a", "-a");
    }

    @Test
    public void Escape__and__bgn() {
        fxt.Test__scan("\\+", "+");
    }

    @Test
    public void Escape__and__mid() {
        fxt.Test__scan("a\\+b", "a+b");
    }

    @Test
    public void Escape__eos__1() {
        fxt.Test__scan("\\", String_.Ary_empty);
    }

    @Test
    public void Escape__eos__2() {
        fxt.Test__scan("a \\", "a");
    }

    @Test
    public void Escape__eos__3() {
        fxt.Test__scan("a\\", "a");
    }

    @Test
    public void Escape__many() {
        fxt.Test__scan("c\\+\\+", "c++");
    }

    @Test
    public void Escape__end() {
        fxt.Test__scan("a\\\\", "a\\");
    }

    @Test
    public void Complicated() {
        fxt.Test__scan("(a + \"b\") , -c", "(", "a", "+", "b", ")", ",", "-", "c");
    }
}

class Srch_crt_scanner_fxt {

    private final Srch_crt_scanner scanner;

    public Srch_crt_scanner_fxt() {
        this.scanner = new Srch_crt_scanner(Srch_crt_scanner_syms.Dflt);
        Srch_text_parser text_parser = new Srch_text_parser();
        text_parser.Init_for_ttl(gplx.xowa.langs.cases.Xol_case_mgr_.A7());
    }

    public void Test__scan(String src_str, String... expd) {
        byte[] src_bry = Bry_.new_a7(src_str);
        Srch_crt_tkn[] actl_itms = scanner.Scan(src_bry);
        Tfds.Eq_ary(expd, To_vals(src_bry, actl_itms));
    }

    public void Test__scan_tids(String src_str, byte... expd) {
        byte[] src_bry = Bry_.new_a7(src_str);
        Srch_crt_tkn[] actl_itms = scanner.Scan(src_bry);
        Tfds.Eq_ary(expd, To_tids(actl_itms));
    }

    private String[] To_vals(byte[] src, Srch_crt_tkn[] ary) {
        int len = ary.length;
        String[] rv = new String[len];
        for (int i = 0; i < len; i++) {
            Srch_crt_tkn tkn = ary[i];
            rv[i] = String_.new_a7(tkn.Val);
        }
        return rv;
    }

    private byte[] To_tids(Srch_crt_tkn[] ary) {
        int len = ary.length;
        byte[] rv = new byte[len];


package net.minecraftforge.client.model.pipeline;

import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.EnumFacing;

/**
 * Assumes that the data length is not less than e.getElementCount().
 * Also assumes that element index passed will increment from 0 to format.getElementCount() - 1.
 * Normal, Color and UV are assumed to be in 0-1 range.
 */
public interface IVertexConsumer {

    /**
     * @return the format that should be used for passed data.
     */

    void setQuadTint(int tint);

    void setQuadOrientation(EnumFacing orientation);

    void setApplyDiffuseLighting(boolean diffuse);

    void setTexture(TextureAtlasSprite texture);

    void put(int element, float... data);
}


@NotNull
    public static ComponentUI createUI(@NotNull final JComponent c) {
        return new WebButtonUI();
    }

/*
 * This file is part of WebLookAndFeel library.
 *
 */
package com.alee.laf.button;

import com.alee.api.annotations.NotNull;
import com.alee.api.annotations.Nullable;
import com.alee.managers.style.StyleManager;
import com.alee.painter.PainterSupport;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import java.awt.*;

/**
 * Custom UI for {@link JButton} component.
 *
 * @param <C> component type
 * @author Mikle Garin
 */
public class WebButtonUI<C extends JButton> extends WButtonUI<C> implements SwingConstants {

    /**
     * Returns an instance of the {@link WebButtonUI} for the specified component.
     * This tricky method is used by {@link UIManager} to create component UIs when needed.
     *
     * @param c component that will use UI instance
     * @return instance of the {@link WebButtonUI}
     */

    @Override
    public void installUI(@NotNull final JComponent c) {
        super.installUI(c);
        // Applying skin
        StyleManager.installSkin(button);
    }

    @Override
    public void uninstallUI(@NotNull final JComponent c) {
        // Uninstalling applied skin
        StyleManager.uninstallSkin(button);
        super.uninstallUI(c);
    }

    @Override
    public boolean contains(@NotNull final JComponent c, final int x, final int y) {
        return PainterSupport.contains(c, this, x, y);
    }

    @Override
    public int getBaseline(@NotNull final JComponent c, final int width, final int height) {
        return PainterSupport.getBaseline(c, this, width, height);
    }

    @NotNull
    @Override
    public Component.BaselineResizeBehavior getBaselineResizeBehavior(@NotNull final JComponent c) {
        return PainterSupport.getBaselineResizeBehavior(c, this);
    }

    @Override
    public void paint(@NotNull final Graphics g, @NotNull final JComponent c) {
        PainterSupport.paint(g, c, this);
    }

    @Nullable
    @Override
    public Dimension getPreferredSize(@NotNull final JComponent c) {
        return PainterSupport.getPreferredSize(c);
    }
}


while (buffer.remaining() >= 16) {
            k1 = getLong(buffer);
            k2 = getLong(buffer);
            h1 ^= mixK1(k1);
            h1 = Long.rotateLeft(h1, 27);
            h1 += h2;
            h1 = h1 * 5 + 0x52dce729;
            h2 ^= mixK2(k2);
            h2 = Long.rotateLeft(h2, 31);
            h2 += h1;
            h2 = h2 * 5 + 0x38495ab5;
        }

package org.caffinitas.ohc.chunked;

import java.nio.ByteBuffer;
import static org.caffinitas.ohc.util.ByteBufferCompat.byteBufferPosition;

final class Murmur3Hash extends Hasher {

    long hash(ByteBuffer buffer) {
        long h1 = 0L;
        long h2 = 0L;
        long k1, k2;
        long length = buffer.remaining();

        int r = buffer.remaining();
        if (r > 0) {
            k1 = 0;
            k2 = 0;
            int p = buffer.position();
            switch(r) {
                case 15:
                    // fall through
                    k2 ^= toLong(buffer.get(p + 14)) << 48;
                case 14:
                    // fall through
                    k2 ^= toLong(buffer.get(p + 13)) << 40;
                case 13:
                    // fall through
                    k2 ^= toLong(buffer.get(p + 12)) << 32;
                case 12:
                    // fall through
                    k2 ^= toLong(buffer.get(p + 11)) << 24;
                case 11:
                    // fall through
                    k2 ^= toLong(buffer.get(p + 10)) << 16;
                case 10:
                    // fall through
                    k2 ^= toLong(buffer.get(p + 9)) << 8;
                case 9:
                    // fall through
                    k2 ^= toLong(buffer.get(p + 8));
                case 8:
                    k1 ^= getLong(buffer);
                    break;
                case 7:
                    // fall through
                    k1 ^= toLong(buffer.get(p + 6)) << 48;
                case 6:
                    // fall through
                    k1 ^= toLong(buffer.get(p + 5)) << 40;
                case 5:
                    // fall through
                    k1 ^= toLong(buffer.get(p + 4)) << 32;
                case 4:
                    // fall through
                    k1 ^= toLong(buffer.get(p + 3)) << 24;
                case 3:
                    // fall through
                    k1 ^= toLong(buffer.get(p + 2)) << 16;
                case 2:
                    // fall through
                    k1 ^= toLong(buffer.get(p + 1)) << 8;
                case 1:
                    k1 ^= toLong(buffer.get(p));
                    break;
                default:
                    throw new AssertionError("Should never get here.");
            }
            byteBufferPosition(buffer, p + r);
            h1 ^= mixK1(k1);
            h2 ^= mixK2(k2);
        }
        h1 ^= length;
        h2 ^= length;
        h1 += h2;
        h2 += h1;
        h1 = fmix64(h1);
        h2 = fmix64(h2);
        h1 += h2;
        return h1;
    }

    private static long getLong(ByteBuffer buffer) {
        int o = buffer.position();
        long l = toLong(buffer.get(o + 7)) << 56;
        l |= toLong(buffer.get(o + 6)) << 48;
        l |= toLong(buffer.get(o + 5)) << 40;
        l |= toLong(buffer.get(o + 4)) << 32;
        l |= toLong(buffer.get(o + 3)) << 24;
        l |= toLong(buffer.get(o + 2)) << 16;
        l |= toLong(buffer.get(o + 1)) << 8;
        l |= toLong(buffer.get(o));
        byteBufferPosition(buffer, o + 8);
        return l;
    }

    static final long C1 = 0x87c37b91114253d5L;

    static final long C2 = 0x4cf5ad432745937fL;

    static long fmix64(long k) {
        k ^= k >>> 33;
        k *= 0xff51afd7ed558ccdL;
        k ^= k >>> 33;
        k *= 0xc4ceb9fe1a85ec53L;
        k ^= k >>> 33;
        return k;
    }

    static long mixK1(long k1) {
        k1 *= C1;
        k1 = Long.rotateLeft(k1, 31);
        k1 *= C2;
        return k1;
    }

    static long mixK2(long k2) {
        k2 *= C2;
        k2 = Long.rotateLeft(k2, 33);
        k2 *= C1;
        return k2;
    }

    static long toLong(byte value) {
        return value & 0xff;
    }
}


for (int i = 0; i < csvWidth; i++) {
            csvRow[i].set(row);
        }

package com.nhl.dflib.csv;

import com.nhl.dflib.Index;
import com.nhl.dflib.csv.loader.ColumnBuilder;
import com.nhl.dflib.csv.loader.CsvCell;
import org.apache.commons.csv.CSVRecord;
import java.util.function.Predicate;

class FilteringCsvLoaderWorker extends BaseCsvLoaderWorker {

    private CsvCell<?>[] csvRow;

    private Predicate<CsvCell<?>[]> csvRowFilter;

    public FilteringCsvLoaderWorker(Index columnIndex, ColumnBuilder<?>[] columns, CsvCell<?>[] csvRow, Predicate<CsvCell<?>[]> csvRowFilter) {
        super(columnIndex, columns);
        this.csvRow = csvRow;
        this.csvRowFilter = csvRowFilter;
    }

    @Override
    protected void addRow(int width, CSVRecord row) {
        // 1. fill the buffer for condition evaluation. All values will be converted to the right data types
        int csvWidth = csvRow.length;

        if (csvRowFilter.test(csvRow)) {
            // 3. add row since the condition is satisfied
            for (int i = 0; i < width; i++) {
                columnAccumulators[i].add(csvRow);
            }
        }
    }
}


protected final void initDstBuffer(int sizeBytes) {
        initDstBuffer(sizeBytes, null);
    }

package com.hazelcast.internal.networking;

import com.hazelcast.internal.nio.IOUtil;
import java.nio.ByteBuffer;
import static com.hazelcast.internal.networking.ChannelOption.DIRECT_BUF;
import static com.hazelcast.internal.networking.ChannelOption.SO_SNDBUF;
import static com.hazelcast.internal.nio.IOUtil.newByteBuffer;

/**
 * The {@link OutboundHandler} is a {@link ChannelHandler} for outbound
 * traffic.
 *
 * An example is the PacketEncoder that takes packets from the src (Provider) and
 * encodes them to the dst (ByteBuffer).
 *
 * An {@link OutboundHandler} instances are not expected to be thread-safe;
 * each channel will get its own instance(s).
 *
 * An {@link OutboundHandler} is constructed through a {@link ChannelInitializer}.
 *
 *
Buffer

 * The OutboundHandler is responsible for its own destination buffer
 * if it has one. So if the buffer needs to be compacted/flipped etc., it should
 * take care of that.
 *
 * If OutboundHandler has a destination buffer and the {@link #onWrite()}
 * is called, the first thing it should do is to call
 * {@link IOUtil#compactOrClear(ByteBuffer)} so it flips to
 * writing mode. And at the end of the onWrite method, the destination buffer
 * should be flipped into reading mode.
 *
 * If the OutboundHandler has a source buffer, it is expected to be
 * in reading mode, and it is the responsibility of the OutboundHandler
 * in front to put that buffer in reading mode.
 *
 * @param <S> the type of the source. E.g. a ByteBuffer or a
 *            {@link java.util.function.Supplier}.
 * @param <D> the type of the destination. E.g. a ByteBuffer or a
 *            {@link java.util.function.Consumer}.
 * @see Networking
 * @see InboundHandler
 * @see ChannelInitializer
 * @see ChannelErrorHandler
 * @see Channel
 */
public abstract class OutboundHandler<S, D> extends ChannelHandler<OutboundHandler, S, D> {

    /**
     * A callback to indicate that this OutboundHandler should be
     * processed.
     *
     * A OutboundHandler should be able to deal with a spurious wakeup.
     * So it could be for example there is no frame for it to write to.
     *
     * @return {@link HandlerStatus} the status of the handler after processing the src.
     * @throws Exception if something fails while executing the onWrite. When
     *                   an exception is thrown, the {@link ChannelErrorHandler}
     *                   is called.
     */
    public abstract HandlerStatus onWrite() throws Exception;

    /**
     * Initializes the dst ByteBuffer with the value for {@link ChannelOption#SO_SNDBUF}.
     *
     * The buffer created is reading mode.
     */
    protected final void initDstBuffer() {
        initDstBuffer(channel.options().getOption(SO_SNDBUF));
    }

    /**
     * Initializes the dst ByteBuffer with the configured size.
     *
     * The buffer created is reading mode.
     *
     * @param sizeBytes the size of the dst ByteBuffer.
     */

    /**
     * Initializes the dst ByteBuffer with the configured size.
     *
     * The buffer created is reading mode.
     *
     * @param sizeBytes the size of the dst ByteBuffer.
     * @param bytes     the bytes added to the buffer. Can be null if nothing
     *                  should be added.
     * @throws IllegalArgumentException if the size of the buffer is too small.
     */
    protected final void initDstBuffer(int sizeBytes, byte[] bytes) {
        if (bytes != null && bytes.length > sizeBytes) {
            throw new IllegalArgumentException("Buffer overflow. Can't initialize dstBuffer for " + this + " and channel" + channel + " because too many bytes, sizeBytes " + sizeBytes + ". bytes.length " + bytes.length);
        }
        ChannelOptions config = channel.options();
        ByteBuffer buffer = newByteBuffer(sizeBytes, config.getOption(DIRECT_BUF));
        if (bytes != null) {
            buffer.put(bytes);
        }
        buffer.flip();
        dst = (D) buffer;
    }
}


while (!flushRequest) {
                    long waitTimeMs = lastFlushTime + flushIntervalMs - EnvironmentEdgeManager.currentTime();
                    if (waitTimeMs <= 0) {
                        flushRequest = true;
                        break;
                    }
                    flushCond.await(waitTimeMs, TimeUnit.MILLISECONDS);
                    if (closed) {
                        return;
                    }
                }

package org.apache.hadoop.hbase.master.region;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Abortable;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.log.HBaseMarkers;
import org.apache.hadoop.hbase.procedure2.store.region.RegionProcedureStore;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.HStore;
import org.apache.hadoop.hbase.regionserver.Store;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.HFileArchiveUtil;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;

/**
 * As long as there is no RegionServerServices for a master local region, we need implement the
 * flush and compaction logic by our own.
 *

 * The flush logic is very simple, every time after calling a modification method in
 * {@link RegionProcedureStore}, we will call the {@link #onUpdate()} method below, and in this
 * method, we will check the memstore size and if it is above the flush size, we will call
 * {@link HRegion#flush(boolean)} to force flush all stores.
 *

 * And for compaction, the logic is also very simple. After flush, we will check the store file
 * count, if it is above the compactMin, we will do a major compaction.
 */
@InterfaceAudience.Private
class MasterRegionFlusherAndCompactor implements Closeable {

    private static final Logger LOG = LoggerFactory.getLogger(MasterRegionFlusherAndCompactor.class);

    private final Configuration conf;

    private final Abortable abortable;

    private final HRegion region;

    // as we can only count this outside the region's write/flush process so it is not accurate, but
    // it is enough.
    private final AtomicLong changesAfterLastFlush = new AtomicLong(0);

    private final long flushSize;

    private final long flushPerChanges;

    private final long flushIntervalMs;

    private final int compactMin;

    private final Path globalArchivePath;

    private final String archivedHFileSuffix;

    private final Thread flushThread;

    private final Lock flushLock = new ReentrantLock();

    private final Condition flushCond = flushLock.newCondition();

    private boolean flushRequest = false;

    private long lastFlushTime;

    private final ExecutorService compactExecutor;

    private final Lock compactLock = new ReentrantLock();

    private boolean compactRequest = false;

    private volatile boolean closed = false;

    MasterRegionFlusherAndCompactor(Configuration conf, Abortable abortable, HRegion region, long flushSize, long flushPerChanges, long flushIntervalMs, int compactMin, Path globalArchivePath, String archivedHFileSuffix) {
        this.conf = conf;
        this.abortable = abortable;
        this.region = region;
        this.flushSize = flushSize;
        this.flushPerChanges = flushPerChanges;
        this.flushIntervalMs = flushIntervalMs;
        this.compactMin = compactMin;
        this.globalArchivePath = globalArchivePath;
        this.archivedHFileSuffix = archivedHFileSuffix;
        flushThread = new Thread(this::flushLoop, region.getRegionInfo().getTable() + "-Flusher");
        flushThread.setDaemon(true);
        flushThread.start();
        compactExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(region.getRegionInfo().getTable() + "-Store-Compactor").setDaemon(true).build());
        LOG.info("Constructor flushSize={}, flushPerChanges={}, flushIntervalMs={}, compactMin={}", flushSize, flushPerChanges, flushIntervalMs, compactMin);
    }

    // inject our flush related configurations
    static void setupConf(Configuration conf, long flushSize, long flushPerChanges, long flushIntervalMs) {
        conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, flushSize);
        conf.setLong(HRegion.MEMSTORE_FLUSH_PER_CHANGES, flushPerChanges);
        conf.setLong(HRegion.MEMSTORE_PERIODIC_FLUSH_INTERVAL, flushIntervalMs);
        LOG.info("Injected flushSize={}, flushPerChanges={}, flushIntervalMs={}", flushSize, flushPerChanges, flushIntervalMs);
    }

    private void moveHFileToGlobalArchiveDir() throws IOException {
        FileSystem fs = region.getRegionFileSystem().getFileSystem();
        for (HStore store : region.getStores()) {
            store.closeAndArchiveCompactedFiles();
            Path storeArchiveDir = HFileArchiveUtil.getStoreArchivePath(conf, region.getRegionInfo(), store.getColumnFamilyDescriptor().getName());
            Path globalStoreArchiveDir = HFileArchiveUtil.getStoreArchivePathForArchivePath(globalArchivePath, region.getRegionInfo(), store.getColumnFamilyDescriptor().getName());
            try {
                MasterRegionUtils.moveFilesUnderDir(fs, storeArchiveDir, globalStoreArchiveDir, archivedHFileSuffix);
            } catch (IOException e) {
                LOG.warn("Failed to move archived hfiles from {} to global dir {}", storeArchiveDir, globalStoreArchiveDir, e);
            }
        }
    }

    private void compact() {
        try {
            region.compact(true);
            moveHFileToGlobalArchiveDir();
        } catch (IOException e) {
            LOG.error("Failed to compact master local region", e);
        }
        compactLock.lock();
        try {
            if (needCompaction()) {
                compactExecutor.execute(this::compact);
            } else {
                compactRequest = false;
            }
        } finally {
            compactLock.unlock();
        }
    }

    private boolean needCompaction() {
        for (Store store : region.getStores()) {
            if (store.getStorefilesCount() >= compactMin) {
                return true;
            }
        }
        return false;
    }

    private void flushLoop() {
        lastFlushTime = EnvironmentEdgeManager.currentTime();
        while (!closed) {
            flushLock.lock();
            try {

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                continue;
            } finally {
                flushLock.unlock();
            }
            assert flushRequest;
            changesAfterLastFlush.set(0);
            try {
                region.flush(true);
                lastFlushTime = EnvironmentEdgeManager.currentTime();
            } catch (IOException e) {
                LOG.error(HBaseMarkers.FATAL, "Failed to flush master local region, aborting...", e);
                abortable.abort("Failed to flush master local region", e);
                return;
            }
            compactLock.lock();
            try {
                if (!compactRequest && needCompaction()) {
                    compactRequest = true;
                    compactExecutor.execute(this::compact);
                }
            } finally {
                compactLock.unlock();
            }
            flushLock.lock();
            try {
                // reset the flushRequest flag
                if (!shouldFlush(changesAfterLastFlush.get())) {
                    flushRequest = false;
                }
            } finally {
                flushLock.unlock();
            }
        }
    }

    private boolean shouldFlush(long changes) {
        long heapSize = region.getMemStoreHeapSize();
        long offHeapSize = region.getMemStoreOffHeapSize();
        boolean flush = heapSize + offHeapSize >= flushSize || changes > flushPerChanges;
        if (flush && LOG.isTraceEnabled()) {
            LOG.trace("shouldFlush totalMemStoreSize={}, flushSize={}, changes={}, flushPerChanges={}", heapSize + offHeapSize, flushSize, changes, flushPerChanges);
        }
        return flush;
    }

    void onUpdate() {
        long changes = changesAfterLastFlush.incrementAndGet();
        if (shouldFlush(changes)) {
            requestFlush();
        }
    }

    void requestFlush() {
        flushLock.lock();
        try {
            if (flushRequest) {
                return;
            }
            flushRequest = true;
            flushCond.signalAll();
        } finally {
            flushLock.unlock();
        }
    }

    @Override
    public void close() {
        closed = true;
        flushThread.interrupt();
        compactExecutor.shutdown();
    }
}


try {
            if (needCompaction()) {
                compactExecutor.execute(this::compact);
            } else {
                compactRequest = false;
            }
        } finally {
            compactLock.unlock();
        }

package org.apache.hadoop.hbase.master.region;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Abortable;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.log.HBaseMarkers;
import org.apache.hadoop.hbase.procedure2.store.region.RegionProcedureStore;
import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.HStore;
import org.apache.hadoop.hbase.regionserver.Store;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.HFileArchiveUtil;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;

/**
 * As long as there is no RegionServerServices for a master local region, we need implement the
 * flush and compaction logic by our own.
 *

 * The flush logic is very simple, every time after calling a modification method in
 * {@link RegionProcedureStore}, we will call the {@link #onUpdate()} method below, and in this
 * method, we will check the memstore size and if it is above the flush size, we will call
 * {@link HRegion#flush(boolean)} to force flush all stores.
 *

 * And for compaction, the logic is also very simple. After flush, we will check the store file
 * count, if it is above the compactMin, we will do a major compaction.
 */
@InterfaceAudience.Private
class MasterRegionFlusherAndCompactor implements Closeable {

    private static final Logger LOG = LoggerFactory.getLogger(MasterRegionFlusherAndCompactor.class);

    private final Configuration conf;

    private final Abortable abortable;

    private final HRegion region;

    // as we can only count this outside the region's write/flush process so it is not accurate, but
    // it is enough.
    private final AtomicLong changesAfterLastFlush = new AtomicLong(0);

    private final long flushSize;

    private final long flushPerChanges;

    private final long flushIntervalMs;

    private final int compactMin;

    private final Path globalArchivePath;

    private final String archivedHFileSuffix;

    private final Thread flushThread;

    private final Lock flushLock = new ReentrantLock();

    private final Condition flushCond = flushLock.newCondition();

    private boolean flushRequest = false;

    private long lastFlushTime;

    private final ExecutorService compactExecutor;

    private final Lock compactLock = new ReentrantLock();

    private boolean compactRequest = false;

    private volatile boolean closed = false;

    MasterRegionFlusherAndCompactor(Configuration conf, Abortable abortable, HRegion region, long flushSize, long flushPerChanges, long flushIntervalMs, int compactMin, Path globalArchivePath, String archivedHFileSuffix) {
        this.conf = conf;
        this.abortable = abortable;
        this.region = region;
        this.flushSize = flushSize;
        this.flushPerChanges = flushPerChanges;
        this.flushIntervalMs = flushIntervalMs;
        this.compactMin = compactMin;
        this.globalArchivePath = globalArchivePath;
        this.archivedHFileSuffix = archivedHFileSuffix;
        flushThread = new Thread(this::flushLoop, region.getRegionInfo().getTable() + "-Flusher");
        flushThread.setDaemon(true);
        flushThread.start();
        compactExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(region.getRegionInfo().getTable() + "-Store-Compactor").setDaemon(true).build());
        LOG.info("Constructor flushSize={}, flushPerChanges={}, flushIntervalMs={}, compactMin={}", flushSize, flushPerChanges, flushIntervalMs, compactMin);
    }

    // inject our flush related configurations
    static void setupConf(Configuration conf, long flushSize, long flushPerChanges, long flushIntervalMs) {
        conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, flushSize);
        conf.setLong(HRegion.MEMSTORE_FLUSH_PER_CHANGES, flushPerChanges);
        conf.setLong(HRegion.MEMSTORE_PERIODIC_FLUSH_INTERVAL, flushIntervalMs);
        LOG.info("Injected flushSize={}, flushPerChanges={}, flushIntervalMs={}", flushSize, flushPerChanges, flushIntervalMs);
    }

    private void moveHFileToGlobalArchiveDir() throws IOException {
        FileSystem fs = region.getRegionFileSystem().getFileSystem();
        for (HStore store : region.getStores()) {
            store.closeAndArchiveCompactedFiles();
            Path storeArchiveDir = HFileArchiveUtil.getStoreArchivePath(conf, region.getRegionInfo(), store.getColumnFamilyDescriptor().getName());
            Path globalStoreArchiveDir = HFileArchiveUtil.getStoreArchivePathForArchivePath(globalArchivePath, region.getRegionInfo(), store.getColumnFamilyDescriptor().getName());
            try {
                MasterRegionUtils.moveFilesUnderDir(fs, storeArchiveDir, globalStoreArchiveDir, archivedHFileSuffix);
            } catch (IOException e) {
                LOG.warn("Failed to move archived hfiles from {} to global dir {}", storeArchiveDir, globalStoreArchiveDir, e);
            }
        }
    }

    private void compact() {
        try {
            region.compact(true);
            moveHFileToGlobalArchiveDir();
        } catch (IOException e) {
            LOG.error("Failed to compact master local region", e);
        }
        compactLock.lock();

    }

    private boolean needCompaction() {
        for (Store store : region.getStores()) {
            if (store.getStorefilesCount() >= compactMin) {
                return true;
            }
        }
        return false;
    }

    private void flushLoop() {
        lastFlushTime = EnvironmentEdgeManager.currentTime();
        while (!closed) {
            flushLock.lock();
            try {
                while (!flushRequest) {
                    long waitTimeMs = lastFlushTime + flushIntervalMs - EnvironmentEdgeManager.currentTime();
                    if (waitTimeMs <= 0) {
                        flushRequest = true;
                        break;
                    }
                    flushCond.await(waitTimeMs, TimeUnit.MILLISECONDS);
                    if (closed) {
                        return;
                    }
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                continue;
            } finally {
                flushLock.unlock();
            }
            assert flushRequest;
            changesAfterLastFlush.set(0);
            try {
                region.flush(true);
                lastFlushTime = EnvironmentEdgeManager.currentTime();
            } catch (IOException e) {
                LOG.error(HBaseMarkers.FATAL, "Failed to flush master local region, aborting...", e);
                abortable.abort("Failed to flush master local region", e);
                return;
            }
            compactLock.lock();
            try {
                if (!compactRequest && needCompaction()) {
                    compactRequest = true;
                    compactExecutor.execute(this::compact);
                }
            } finally {
                compactLock.unlock();
            }
            flushLock.lock();
            try {
                // reset the flushRequest flag
                if (!shouldFlush(changesAfterLastFlush.get())) {
                    flushRequest = false;
                }
            } finally {
                flushLock.unlock();
            }
        }
    }

    private boolean shouldFlush(long changes) {
        long heapSize = region.getMemStoreHeapSize();
        long offHeapSize = region.getMemStoreOffHeapSize();
        boolean flush = heapSize + offHeapSize >= flushSize || changes > flushPerChanges;
        if (flush && LOG.isTraceEnabled()) {
            LOG.trace("shouldFlush totalMemStoreSize={}, flushSize={}, changes={}, flushPerChanges={}", heapSize + offHeapSize, flushSize, changes, flushPerChanges);
        }
        return flush;
    }

    void onUpdate() {
        long changes = changesAfterLastFlush.incrementAndGet();
        if (shouldFlush(changes)) {
            requestFlush();
        }
    }

    void requestFlush() {
        flushLock.lock();
        try {
            if (flushRequest) {
                return;
            }
            flushRequest = true;
            flushCond.signalAll();
        } finally {
            flushLock.unlock();
        }
    }

    @Override
    public void close() {
        closed = true;
        flushThread.interrupt();
        compactExecutor.shutdown();
    }
}


try {
            pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            return pInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, null, e);
            return null;
        }

package com.zegoggles.smssync;

import android.Manifest;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.StrictMode;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import android.util.Log;
import com.fsck.k9.mail.K9MailLib;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import com.zegoggles.smssync.activity.events.AutoBackupSettingsChangedEvent;
import com.zegoggles.smssync.compat.GooglePlayServices;
import com.zegoggles.smssync.preferences.Preferences;
import com.zegoggles.smssync.receiver.BootReceiver;
import com.zegoggles.smssync.receiver.SmsBroadcastReceiver;
import com.zegoggles.smssync.service.BackupJobs;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.DONT_KILL_APP;

public class App extends Application {

    private static final boolean DEBUG = BuildConfig.DEBUG;

    public static final boolean LOCAL_LOGV = DEBUG;

    public static final String TAG = "SMSBackup+";

    public static final String LOG = "sms_backup_plus.log";

    public static final String CHANNEL_ID = "sms_backup_plus";

    private static final Bus bus = new Bus();

    /**
     * Google Play Services present on this device?
     */
    public static boolean gcmAvailable;

    private Preferences preferences;

    private BackupJobs backupJobs;

    @Override
    public void onCreate() {
        super.onCreate();
        setupStrictMode();
        gcmAvailable = GooglePlayServices.isAvailable(this);
        preferences = new Preferences(this);
        preferences.migrate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel();
        }
        backupJobs = new BackupJobs(this);
        if (gcmAvailable) {
            setBroadcastReceiversEnabled(false);
        } else {
            Log.v(TAG, "Google Play Services not available, forcing use of old scheduler");
            preferences.setUseOldScheduler(true);
        }
        K9MailLib.setDebugStatus(new K9MailLib.DebugStatus() {

            @Override
            public boolean enabled() {
                return preferences.isAppLogDebug();
            }

            @Override
            public boolean debugSensitive() {
                return false;
            }
        });
        if (gcmAvailable && DEBUG) {
            getContentResolver().registerContentObserver(Consts.SMS_PROVIDER, true, new LoggingContentObserver());
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED) {
                getContentResolver().registerContentObserver(Consts.CALLLOG_PROVIDER, true, new LoggingContentObserver());
            }
        }
        register(this);
    }

    @Subscribe
    public void autoBackupSettingsChanged(final AutoBackupSettingsChangedEvent event) {
        if (LOCAL_LOGV) {
            Log.v(TAG, "autoBackupSettingsChanged(" + event + ")");
        }
        setBroadcastReceiversEnabled(preferences.isUseOldScheduler() && preferences.isAutoBackupEnabled());
        rescheduleJobs();
    }

    public static void register(Object listener) {
        try {
            bus.register(listener);
        } catch (IllegalArgumentException ignored) {
            Log.w(TAG, ignored);
        }
    }

    public static void unregister(Object listener) {
        try {
            bus.unregister(listener);
        } catch (IllegalArgumentException ignored) {
            Log.w(TAG, ignored);
        }
    }

    public static void post(Object event) {
        bus.post(event);
    }

    @Nullable
    public static String getVersionName(Context context) {
        PackageInfo pInfo;

    }

    @SuppressWarnings("deprecation")
    public static int getVersionCode(Context context) {
        PackageInfo pInfo;
        try {
            pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            return pInfo.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, null, e);
            return -1;
        }
    }

    public static boolean isInstalledOnSDCard(Context context) {
        PackageInfo pInfo;
        try {
            pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            return (pInfo.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "error", e);
            return false;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void createNotificationChannel() {
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "default", NotificationManager.IMPORTANCE_DEFAULT);
        NotificationManagerCompat.from(this).createNotificationChannel(channel);
    }

    private void setBroadcastReceiversEnabled(boolean enabled) {
        enableOrDisableComponent(enabled, SmsBroadcastReceiver.class);
        enableOrDisableComponent(enabled, BootReceiver.class);
    }

    private void enableOrDisableComponent(boolean enabled, Class<?> component) {
        if (LOCAL_LOGV) {
            Log.v(TAG, "enableOrDisableComponent(" + enabled + ", " + component.getSimpleName() + ")");
        }
        // NB: changes made via setComponentEnabledSetting are persisted across reboots
        getPackageManager().setComponentEnabledSetting(new ComponentName(this, component), enabled ? COMPONENT_ENABLED_STATE_ENABLED : COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
    }

    private void rescheduleJobs() {
        backupJobs.cancelAll();
        if (preferences.isAutoBackupEnabled()) {
            backupJobs.scheduleRegular();
            if (preferences.getIncomingTimeoutSecs() > 0 && !preferences.isUseOldScheduler()) {
                backupJobs.scheduleContentTriggerJob();
            }
        }
    }

    private void setupStrictMode() {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskWrites().detectNetwork().penaltyFlashScreen().build());
    }

    private static class LoggingContentObserver extends ContentObserver {

        LoggingContentObserver() {
            super(new Handler());
        }

        @Override
        public void onChange(boolean selfChange) {
            onChange(selfChange, null);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            Log.v(TAG, "onChange(" + selfChange + ", " + uri + ")");
        }
    }
}