// Path: IOIO/iOIOLibAccessory/src/main/java/ioio/lib/android/accessory/Adapter.java
// static interface UsbAccessoryInterface {
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/api/IOIOConnection.java
// public interface IOIOConnection {
//     void waitForConnect() throws ConnectionLostException;
// 
//     void disconnect();
// 
//     InputStream getInputStream() throws ConnectionLostException;
// 
//     OutputStream getOutputStream() throws ConnectionLostException;
// 
//     /**
//      * Can this connection be closed. Normally the answer would be "true", but
//      * some weird connections cannot be closed and need the higher layer to do
//      * a "soft close" instead.
//      *
//      * @return true This connection can be closed.
//      */
//     boolean canClose();
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/impl/FixedReadBufferedInputStream.java
// public class FixedReadBufferedInputStream extends InputStream {
//     private int bufferIndex_ = 0;
//     private int validData_ = 0;
//     private final byte[] buffer_;
//     private final InputStream source_;
// 
//     public FixedReadBufferedInputStream(InputStream source, int size) {
//         buffer_ = new byte[size];
//         source_ = source;
//     }
// 
//     @Override
//     public int available() throws IOException {
//         return validData_ - bufferIndex_;
//     }
// 
//     @Override
//     public void close() throws IOException {
//         source_.close();
//     }
// 
//     @Override
//     public int read(byte[] buffer, int offset, int length) throws IOException {
//         fillIfEmpty();
//         if (validData_ == -1) {
//             return -1;
//         }
//         length = Math.min(length, validData_ - bufferIndex_);
//         System.arraycopy(buffer_, bufferIndex_, buffer, offset, length);
//         bufferIndex_ += length;
//         return length;
//     }
// 
//     @Override
//     public int read(byte[] buffer) throws IOException {
//         return read(buffer, 0, buffer.length);
//     }
// 
//     @Override
//     public int read() throws IOException {
//         fillIfEmpty();
//         if (validData_ == -1) {
//             return -1;
//         }
//         return buffer_[bufferIndex_++] & 0xFF;
//     }
// 
//     @Override
//     public long skip(long byteCount) throws IOException {
//         long skipped = 0;
//         while (byteCount > 0) {
//             fillIfEmpty();
//             if (validData_ == -1) {
//                 return skipped;
//             }
//             int count = (int) Math.min(available(), byteCount);
//             byteCount -= count;
//             bufferIndex_ += count;
//             skipped += count;
//         }
//         return skipped;
//     }
// 
//     private void fillIfEmpty() throws IOException {
//         while (available() == 0 && validData_ != -1) {
//             fill();
//         }
//     }
// 
//     private void fill() throws IOException {
//         bufferIndex_ = 0;
//         validData_ = source_.read(buffer_);
//     }
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/spi/IOIOConnectionBootstrap.java
// public interface IOIOConnectionBootstrap {
//     public void getFactories(Collection<IOIOConnectionFactory> result);
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/spi/IOIOConnectionFactory.java
// public interface IOIOConnectionFactory {
//     /**
//      * A unique name of the connection type. Typically a fully-qualified
//      * name of the connection class.
//      */
//     public String getType();
// 
//     /**
//      * Extra information on the connection. This is specific to the
//      * connection type. For example, for a Bluetooth connection, this is an
//      * array containing the name and the Bluetooth address of the remote
//      * IOIO.
//      */
//     public Object getExtra();
// 
//     public IOIOConnection createConnection();
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/util/android/ContextWrapperDependent.java
// public interface ContextWrapperDependent {
//     public void onCreate(ContextWrapper wrapper);
// 
//     public void onDestroy();
// 
//     public void open();
// 
//     public void reopen();
// 
//     public void close();
// }


import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import ioio.lib.android.accessory.Adapter.UsbAccessoryInterface;
import ioio.lib.api.IOIOConnection;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.impl.FixedReadBufferedInputStream;
import ioio.lib.spi.IOIOConnectionBootstrap;
import ioio.lib.spi.IOIOConnectionFactory;
import ioio.lib.spi.NoRuntimeSupportException;
import ioio.lib.util.android.ContextWrapperDependent;

    private ContextWrapper activity_;
    private Adapter adapter_;
    private Adapter.AbstractUsbManager usbManager_;
    private Adapter.UsbAccessoryInterface accessory_;
    private State state_ = State.CLOSED;
    private PendingIntent pendingIntent_;
    private ParcelFileDescriptor fileDescriptor_;
    private InputStream inputStream_;
    private OutputStream outputStream_;

    public AccessoryConnectionBootstrap() throws NoRuntimeSupportException {
        adapter_ = new Adapter();
    }

    @Override
    public void onCreate(ContextWrapper wrapper) {
        activity_ = wrapper;
        usbManager_ = adapter_.getManager(wrapper);
        registerReceiver();
    }

    @Override
    public void onDestroy() {
        unregisterReceiver();
    }

    @Override
    public synchronized void open() {
        if (state_ != State.CLOSED) {
// Path: IOIO/iOIOLibAccessory/src/main/java/ioio/lib/android/accessory/Adapter.java
// static interface UsbAccessoryInterface {
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/api/IOIOConnection.java
// public interface IOIOConnection {
//     void waitForConnect() throws ConnectionLostException;
// 
//     void disconnect();
// 
//     InputStream getInputStream() throws ConnectionLostException;
// 
//     OutputStream getOutputStream() throws ConnectionLostException;
// 
//     /**
//      * Can this connection be closed. Normally the answer would be "true", but
//      * some weird connections cannot be closed and need the higher layer to do
//      * a "soft close" instead.
//      *
//      * @return true This connection can be closed.
//      */
//     boolean canClose();
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/impl/FixedReadBufferedInputStream.java
// public class FixedReadBufferedInputStream extends InputStream {
//     private int bufferIndex_ = 0;
//     private int validData_ = 0;
//     private final byte[] buffer_;
//     private final InputStream source_;
// 
//     public FixedReadBufferedInputStream(InputStream source, int size) {
//         buffer_ = new byte[size];
//         source_ = source;
//     }
// 
//     @Override
//     public int available() throws IOException {
//         return validData_ - bufferIndex_;
//     }
// 
//     @Override
//     public void close() throws IOException {
//         source_.close();
//     }
// 
//     @Override
//     public int read(byte[] buffer, int offset, int length) throws IOException {
//         fillIfEmpty();
//         if (validData_ == -1) {
//             return -1;
//         }
//         length = Math.min(length, validData_ - bufferIndex_);
//         System.arraycopy(buffer_, bufferIndex_, buffer, offset, length);
//         bufferIndex_ += length;
//         return length;
//     }
// 
//     @Override
//     public int read(byte[] buffer) throws IOException {
//         return read(buffer, 0, buffer.length);
//     }
// 
//     @Override
//     public int read() throws IOException {
//         fillIfEmpty();
//         if (validData_ == -1) {
//             return -1;
//         }
//         return buffer_[bufferIndex_++] & 0xFF;
//     }
// 
//     @Override
//     public long skip(long byteCount) throws IOException {
//         long skipped = 0;
//         while (byteCount > 0) {
//             fillIfEmpty();
//             if (validData_ == -1) {
//                 return skipped;
//             }
//             int count = (int) Math.min(available(), byteCount);
//             byteCount -= count;
//             bufferIndex_ += count;
//             skipped += count;
//         }
//         return skipped;
//     }
// 
//     private void fillIfEmpty() throws IOException {
//         while (available() == 0 && validData_ != -1) {
//             fill();
//         }
//     }
// 
//     private void fill() throws IOException {
//         bufferIndex_ = 0;
//         validData_ = source_.read(buffer_);
//     }
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/spi/IOIOConnectionBootstrap.java
// public interface IOIOConnectionBootstrap {
//     public void getFactories(Collection<IOIOConnectionFactory> result);
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/spi/IOIOConnectionFactory.java
// public interface IOIOConnectionFactory {
//     /**
//      * A unique name of the connection type. Typically a fully-qualified
//      * name of the connection class.
//      */
//     public String getType();
// 
//     /**
//      * Extra information on the connection. This is specific to the
//      * connection type. For example, for a Bluetooth connection, this is an
//      * array containing the name and the Bluetooth address of the remote
//      * IOIO.
//      */
//     public Object getExtra();
// 
//     public IOIOConnection createConnection();
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/util/android/ContextWrapperDependent.java
// public interface ContextWrapperDependent {
//     public void onCreate(ContextWrapper wrapper);
// 
//     public void onDestroy();
// 
//     public void open();
// 
//     public void reopen();
// 
//     public void close();
// }


// Path: IOIO/iOIOLibAccessory/src/main/java/ioio/lib/android/accessory/AccessoryConnectionBootstrap.java
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
import ioio.lib.android.accessory.Adapter.UsbAccessoryInterface;
import ioio.lib.api.IOIOConnection;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.impl.FixedReadBufferedInputStream;
import ioio.lib.spi.IOIOConnectionBootstrap;
import ioio.lib.spi.IOIOConnectionFactory;
import ioio.lib.spi.NoRuntimeSupportException;
import ioio.lib.util.android.ContextWrapperDependent;


    private ContextWrapper activity_;
    private Adapter adapter_;
    private Adapter.AbstractUsbManager usbManager_;
    private Adapter.UsbAccessoryInterface accessory_;
    private State state_ = State.CLOSED;
    private PendingIntent pendingIntent_;
    private ParcelFileDescriptor fileDescriptor_;
    private InputStream inputStream_;
    private OutputStream outputStream_;

    public AccessoryConnectionBootstrap() throws NoRuntimeSupportException {
        adapter_ = new Adapter();
    }

    @Override
    public void onCreate(ContextWrapper wrapper) {
        activity_ = wrapper;
        usbManager_ = adapter_.getManager(wrapper);
        registerReceiver();
    }

    @Override
    public void onDestroy() {
        unregisterReceiver();
    }

    @Override
    public synchronized void open() {
        if (state_ != State.CLOSED) {
            return;