// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/api/TwiMaster.java
// public interface TwiMaster extends Closeable {
//     enum Rate {
//         RATE_100KHz, RATE_400KHz, RATE_1MHz
//     }
// 
//     /**
//      * An object that can be waited on for asynchronous calls.
//      */
//     public interface Result {
//         /**
//          * Wait until the asynchronous call which returned this instance is
//          * complete.
//          *
//          * @return true if TWI transaction succeeded.
//          * @throws ConnectionLostException Connection with the IOIO has been lost.
//          * @throws InterruptedException    This operation has been interrupted.
//          */
//         public boolean waitReady() throws ConnectionLostException,
//                 InterruptedException;
//     }
// 
//     /**
//      * Perform a single TWI transaction which includes optional transmission and
//      * optional reception of data to a single slave. This is a blocking
//      * operation that can take a few milliseconds to a few tens of milliseconds.
//      * To abort this operation, client can interrupt the blocked thread.
//      *
//      * @param address    The slave address, either 7-bit or 10-bit. Note that in some
//      *                   TWI device documentation the documented addresses are actually
//      *                   2x the address values used here, as they regard the trailing
//      *                   0-bit as part of the address.
//      * @param tenBitAddr Whether this is a 10-bit addressing mode.
//      * @param writeData  The request data.
//      * @param writeSize  The number of bytes to write. Valid value are 0-255.
//      * @param readData   The array where the response should be stored.
//      * @param readSize   The expected number of response bytes. Valid value are 0-255.
//      * @return Whether operation succeeded.
//      * @throws ConnectionLostException Connection to the IOIO has been lost.
//      * @throws InterruptedException    Calling thread has been interrupted.
//      */
//     public boolean writeRead(int address, boolean tenBitAddr, byte[] writeData,
//                              int writeSize, byte[] readData, int readSize)
//             throws ConnectionLostException, InterruptedException;
// 
//     /**
//      * Asynchronous version of
//      * {@link #writeRead(int, boolean, byte[], int, byte[], int)}. Returns
//      * immediately and provides a {@link Result} object on which the client can
//      * wait for the result.
//      *
//      * @see #writeRead(int, boolean, byte[], int, byte[], int)
//      */
//     public Result writeReadAsync(int address, boolean tenBitAddr,
//                                  byte[] writeData, int writeSize, byte[] readData, int readSize)
//             throws ConnectionLostException;
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/impl/IncomingState.java
// interface DataModuleListener {
//     void dataReceived(byte[] data, int size);
// 
//     void reportAdditionalBuffer(int bytesToAdd);
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/spi/Log.java
// public class Log {
//     public static int println(int priority, String tag, String msg) {
//         return android.util.Log.println(priority, tag, msg);
//     }
// 
//     public static void e(String tag, String message) {
//         android.util.Log.e(tag, message);
//     }
// 
//     public static void e(String tag, String message, Throwable tr) {
//         android.util.Log.e(tag, message, tr);
//     }
// 
//     public static void w(String tag, String message) {
//         android.util.Log.w(tag, message);
//     }
// 
//     public static void w(String tag, String message, Throwable tr) {
//         android.util.Log.w(tag, message);
//     }
// 
//     public static void i(String tag, String message) {
//         android.util.Log.i(tag, message);
//     }
// 
//     public static void d(String tag, String message) {
//         android.util.Log.d(tag, message);
//     }
// 
//     public static void v(String tag, String message) {
//         android.util.Log.v(tag, message);
//     }
// }


import java.util.concurrent.ConcurrentLinkedQueue;
import ioio.lib.api.TwiMaster;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.impl.FlowControlledPacketSender.Packet;
import ioio.lib.impl.FlowControlledPacketSender.Sender;
import ioio.lib.impl.IncomingState.DataModuleListener;
import ioio.lib.impl.ResourceManager.Resource;
import ioio.lib.spi.Log;
import java.io.IOException;
import java.util.Queue;
    }

    @Override
    public boolean writeRead(int address, boolean tenBitAddr, byte[] writeData,
                             int writeSize, byte[] readData, int readSize)
            throws ConnectionLostException, InterruptedException {
        Result result = writeReadAsync(address, tenBitAddr, writeData,
                writeSize, readData, readSize);
        return result.waitReady();
    }

    @Override
    public Result writeReadAsync(int address, boolean tenBitAddr,
                                 byte[] writeData, int writeSize, byte[] readData, int readSize)
            throws ConnectionLostException {
        checkState();
        TwiResult result = new TwiResult(readData);

        OutgoingPacket p = new OutgoingPacket();
        p.writeSize_ = writeSize;
        p.writeData_ = writeData;
        p.tenBitAddr_ = tenBitAddr;
        p.readSize_ = readSize;
        p.addr_ = address;

        synchronized (this) {
            pendingRequests_.add(result);
            try {
                outgoing_.write(p);
            } catch (IOException e) {
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/api/TwiMaster.java
// public interface TwiMaster extends Closeable {
//     enum Rate {
//         RATE_100KHz, RATE_400KHz, RATE_1MHz
//     }
// 
//     /**
//      * An object that can be waited on for asynchronous calls.
//      */
//     public interface Result {
//         /**
//          * Wait until the asynchronous call which returned this instance is
//          * complete.
//          *
//          * @return true if TWI transaction succeeded.
//          * @throws ConnectionLostException Connection with the IOIO has been lost.
//          * @throws InterruptedException    This operation has been interrupted.
//          */
//         public boolean waitReady() throws ConnectionLostException,
//                 InterruptedException;
//     }
// 
//     /**
//      * Perform a single TWI transaction which includes optional transmission and
//      * optional reception of data to a single slave. This is a blocking
//      * operation that can take a few milliseconds to a few tens of milliseconds.
//      * To abort this operation, client can interrupt the blocked thread.
//      *
//      * @param address    The slave address, either 7-bit or 10-bit. Note that in some
//      *                   TWI device documentation the documented addresses are actually
//      *                   2x the address values used here, as they regard the trailing
//      *                   0-bit as part of the address.
//      * @param tenBitAddr Whether this is a 10-bit addressing mode.
//      * @param writeData  The request data.
//      * @param writeSize  The number of bytes to write. Valid value are 0-255.
//      * @param readData   The array where the response should be stored.
//      * @param readSize   The expected number of response bytes. Valid value are 0-255.
//      * @return Whether operation succeeded.
//      * @throws ConnectionLostException Connection to the IOIO has been lost.
//      * @throws InterruptedException    Calling thread has been interrupted.
//      */
//     public boolean writeRead(int address, boolean tenBitAddr, byte[] writeData,
//                              int writeSize, byte[] readData, int readSize)
//             throws ConnectionLostException, InterruptedException;
// 
//     /**
//      * Asynchronous version of
//      * {@link #writeRead(int, boolean, byte[], int, byte[], int)}. Returns
//      * immediately and provides a {@link Result} object on which the client can
//      * wait for the result.
//      *
//      * @see #writeRead(int, boolean, byte[], int, byte[], int)
//      */
//     public Result writeReadAsync(int address, boolean tenBitAddr,
//                                  byte[] writeData, int writeSize, byte[] readData, int readSize)
//             throws ConnectionLostException;
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/impl/IncomingState.java
// interface DataModuleListener {
//     void dataReceived(byte[] data, int size);
// 
//     void reportAdditionalBuffer(int bytesToAdd);
// }
// 
// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/spi/Log.java
// public class Log {
//     public static int println(int priority, String tag, String msg) {
//         return android.util.Log.println(priority, tag, msg);
//     }
// 
//     public static void e(String tag, String message) {
//         android.util.Log.e(tag, message);
//     }
// 
//     public static void e(String tag, String message, Throwable tr) {
//         android.util.Log.e(tag, message, tr);
//     }
// 
//     public static void w(String tag, String message) {
//         android.util.Log.w(tag, message);
//     }
// 
//     public static void w(String tag, String message, Throwable tr) {
//         android.util.Log.w(tag, message);
//     }
// 
//     public static void i(String tag, String message) {
//         android.util.Log.i(tag, message);
//     }
// 
//     public static void d(String tag, String message) {
//         android.util.Log.d(tag, message);
//     }
// 
//     public static void v(String tag, String message) {
//         android.util.Log.v(tag, message);
//     }
// }


// Path: IOIO/iOIOLibAndroid/src/main/java/ioio/lib/impl/TwiMasterImpl.java
import java.util.concurrent.ConcurrentLinkedQueue;
import ioio.lib.api.TwiMaster;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.impl.FlowControlledPacketSender.Packet;
import ioio.lib.impl.FlowControlledPacketSender.Sender;
import ioio.lib.impl.IncomingState.DataModuleListener;
import ioio.lib.impl.ResourceManager.Resource;
import ioio.lib.spi.Log;
import java.io.IOException;
import java.util.Queue;

    }

    @Override
    public boolean writeRead(int address, boolean tenBitAddr, byte[] writeData,
                             int writeSize, byte[] readData, int readSize)
            throws ConnectionLostException, InterruptedException {
        Result result = writeReadAsync(address, tenBitAddr, writeData,
                writeSize, readData, readSize);
        return result.waitReady();
    }

    @Override
    public Result writeReadAsync(int address, boolean tenBitAddr,
                                 byte[] writeData, int writeSize, byte[] readData, int readSize)
            throws ConnectionLostException {
        checkState();
        TwiResult result = new TwiResult(readData);

        OutgoingPacket p = new OutgoingPacket();
        p.writeSize_ = writeSize;
        p.writeData_ = writeData;
        p.tenBitAddr_ = tenBitAddr;
        p.readSize_ = readSize;
        p.addr_ = address;

        synchronized (this) {
            pendingRequests_.add(result);
            try {
                outgoing_.write(p);
            } catch (IOException e) {
                Log.e("SpiMasterImpl", "Exception caught", e);