// Path: measures/src/main/java/org/xbill/DNS/DNSClient.java
// public interface DNSClient {
//   void bind(SocketAddress addr) throws IOException;
// 
//   void connect(SocketAddress addr) throws IOException;
// 
//   void send(byte[] data) throws IOException;
// 
//   byte[] recv(int max) throws IOException;
// 
//   void cleanup() throws IOException;
// }
// 
// Path: measures/src/main/java/org/xbill/DNS/PublicTCPClient.java
// public final class PublicTCPClient implements DNSClient {
//   private final TCPClient client;
// 
//   public PublicTCPClient(long endTime) throws IOException {
//     client = new TCPClient(endTime);
//   }
// 
//   @Override
//   public void bind(SocketAddress addr) throws IOException {
//     client.bind(addr);
//   }
// 
//   @Override
//   public void connect(SocketAddress addr) throws IOException {
//     client.connect(addr);
//   }
// 
//   @Override
//   public void send(byte[] data) throws IOException {
//     client.send(data);
//   }
// 
//   /**
//    * Receive DNS data.
//    *
//    * @param max Not used in tcp implementation
//    * @return The received content.
//    * @throws IOException {@inheritDoc}
//    */
//   @Override
//   public byte[] recv(int max) throws IOException {
//     return client.recv();
//   }
// 
//   @Override
//   public void cleanup() throws IOException {
//     client.cleanup();
//   }
// }
// 
// Path: measures/src/main/java/org/xbill/DNS/PublicUDPClient.java
// public final class PublicUDPClient implements DNSClient {
//   private final UDPClient client;
// 
//   public PublicUDPClient(long endTime) throws IOException {
//     client = new UDPClient(endTime);
//   }
// 
//   @Override
//   public void bind(SocketAddress addr) throws IOException {
//     client.bind(addr);
//   }
// 
//   @Override
//   public void connect(SocketAddress addr) throws IOException {
//     client.connect(addr);
//   }
// 
//   @Override
//   public void send(byte[] data) throws IOException {
//     client.send(data);
//   }
// 
//   @Override
//   public byte[] recv(int max) throws IOException {
//     return client.recv(max);
//   }
// 
//   @Override
//   public void cleanup() throws IOException {
//     client.cleanup();
//   }
// }
// 
// Path: measures/src/main/java/io/apisense/network/Measurement.java
// public abstract class Measurement {
//   public final String taskName;
// 
//   protected Measurement(String taskName) {
//     this.taskName = taskName;
//   }
// 
//   /**
//    * Ensure that the measurement is asynchronously called in an {@link ExecutorService}.
//    *
//    * @param callback The {@link MeasurementCallback} used
//    *                 for reporting success or failure of this measurement.
//    */
//   public final void call(MeasurementCallback callback) {
//     AsyncTask.execute(new MeasurementExecutor(this, callback));
//   }
// 
//   /**
//    * Actual, synchronous, process of a measurement.
//    * This method has to be called from another thread than the UI one.
//    *
//    * @return The results of this measurement.
//    * @throws MeasurementError If anything goes wrong during measurement.
//    */
//   public abstract MeasurementResult execute() throws MeasurementError;
// }
// 
// Path: measures/src/main/java/io/apisense/network/MeasurementError.java
// public class MeasurementError extends Exception {
//   public final String taskName;
// 
//   public MeasurementError(String taskName, String reason) {
//     super(reason);
//     this.taskName = taskName;
//   }
// 
//   public MeasurementError(String taskName, String reason, Throwable e) {
//     super(reason, e);
//     this.taskName = taskName;
//   }
// 
//   public MeasurementError(String taskName, Exception e) {
//     this(taskName, e.getMessage(), e);
//   }
// }


import android.support.annotation.NonNull;
import android.util.Log;
import org.xbill.DNS.DClass;
import org.xbill.DNS.DNSClient;
import org.xbill.DNS.Flags;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.OPTRecord;
import org.xbill.DNS.PublicTCPClient;
import org.xbill.DNS.PublicUDPClient;
import org.xbill.DNS.Record;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import io.apisense.network.Measurement;
import io.apisense.network.MeasurementError;
    }
    return in;
  }

  @Override
  public DNSLookupResult execute() throws MeasurementError {
    Log.d(TAG, "Running DNS lookup with configuration: " + config);
    Record question;
    try {
      question = Record.newRecord(Name.fromString(config.getTarget()),
          Type.value(config.getQtype()), DClass.value(config.getQclass()));
    } catch (TextParseException e) {
      throw new MeasurementError("Error constructing packet", e);
    }
    Message query = Message.newQuery(question);
    Log.v(TAG, "Constructed question: " + question);
    Log.v(TAG, "Constructed query: " + query);
    return sendMeasurement(query, config.isForceTCP());
  }

  /**
   * Put the query on the wire and wait for responses.
   *
   * @param query    The DNS query to send to the server.
   * @param forceTCP Tells whether we should force request to use TCP or not.
   * @return The lookup result.
   * @throws MeasurementError If anything goes wrong during DNS lookup.
   */
  @NonNull
  private DNSLookupResult sendMeasurement(Message query, boolean forceTCP) throws MeasurementError {
// Path: measures/src/main/java/org/xbill/DNS/DNSClient.java
// public interface DNSClient {
//   void bind(SocketAddress addr) throws IOException;
// 
//   void connect(SocketAddress addr) throws IOException;
// 
//   void send(byte[] data) throws IOException;
// 
//   byte[] recv(int max) throws IOException;
// 
//   void cleanup() throws IOException;
// }
// 
// Path: measures/src/main/java/org/xbill/DNS/PublicTCPClient.java
// public final class PublicTCPClient implements DNSClient {
//   private final TCPClient client;
// 
//   public PublicTCPClient(long endTime) throws IOException {
//     client = new TCPClient(endTime);
//   }
// 
//   @Override
//   public void bind(SocketAddress addr) throws IOException {
//     client.bind(addr);
//   }
// 
//   @Override
//   public void connect(SocketAddress addr) throws IOException {
//     client.connect(addr);
//   }
// 
//   @Override
//   public void send(byte[] data) throws IOException {
//     client.send(data);
//   }
// 
//   /**
//    * Receive DNS data.
//    *
//    * @param max Not used in tcp implementation
//    * @return The received content.
//    * @throws IOException {@inheritDoc}
//    */
//   @Override
//   public byte[] recv(int max) throws IOException {
//     return client.recv();
//   }
// 
//   @Override
//   public void cleanup() throws IOException {
//     client.cleanup();
//   }
// }
// 
// Path: measures/src/main/java/org/xbill/DNS/PublicUDPClient.java
// public final class PublicUDPClient implements DNSClient {
//   private final UDPClient client;
// 
//   public PublicUDPClient(long endTime) throws IOException {
//     client = new UDPClient(endTime);
//   }
// 
//   @Override
//   public void bind(SocketAddress addr) throws IOException {
//     client.bind(addr);
//   }
// 
//   @Override
//   public void connect(SocketAddress addr) throws IOException {
//     client.connect(addr);
//   }
// 
//   @Override
//   public void send(byte[] data) throws IOException {
//     client.send(data);
//   }
// 
//   @Override
//   public byte[] recv(int max) throws IOException {
//     return client.recv(max);
//   }
// 
//   @Override
//   public void cleanup() throws IOException {
//     client.cleanup();
//   }
// }
// 
// Path: measures/src/main/java/io/apisense/network/Measurement.java
// public abstract class Measurement {
//   public final String taskName;
// 
//   protected Measurement(String taskName) {
//     this.taskName = taskName;
//   }
// 
//   /**
//    * Ensure that the measurement is asynchronously called in an {@link ExecutorService}.
//    *
//    * @param callback The {@link MeasurementCallback} used
//    *                 for reporting success or failure of this measurement.
//    */
//   public final void call(MeasurementCallback callback) {
//     AsyncTask.execute(new MeasurementExecutor(this, callback));
//   }
// 
//   /**
//    * Actual, synchronous, process of a measurement.
//    * This method has to be called from another thread than the UI one.
//    *
//    * @return The results of this measurement.
//    * @throws MeasurementError If anything goes wrong during measurement.
//    */
//   public abstract MeasurementResult execute() throws MeasurementError;
// }
// 
// Path: measures/src/main/java/io/apisense/network/MeasurementError.java
// public class MeasurementError extends Exception {
//   public final String taskName;
// 
//   public MeasurementError(String taskName, String reason) {
//     super(reason);
//     this.taskName = taskName;
//   }
// 
//   public MeasurementError(String taskName, String reason, Throwable e) {
//     super(reason, e);
//     this.taskName = taskName;
//   }
// 
//   public MeasurementError(String taskName, Exception e) {
//     this(taskName, e.getMessage(), e);
//   }
// }


// Path: measures/src/main/java/io/apisense/network/dns/DNSLookupTask.java
import android.support.annotation.NonNull;
import android.util.Log;
import org.xbill.DNS.DClass;
import org.xbill.DNS.DNSClient;
import org.xbill.DNS.Flags;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.OPTRecord;
import org.xbill.DNS.PublicTCPClient;
import org.xbill.DNS.PublicUDPClient;
import org.xbill.DNS.Record;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import io.apisense.network.Measurement;
import io.apisense.network.MeasurementError;

    }
    return in;
  }

  @Override
  public DNSLookupResult execute() throws MeasurementError {
    Log.d(TAG, "Running DNS lookup with configuration: " + config);
    Record question;
    try {
      question = Record.newRecord(Name.fromString(config.getTarget()),
          Type.value(config.getQtype()), DClass.value(config.getQclass()));
    } catch (TextParseException e) {
      throw new MeasurementError("Error constructing packet", e);
    }
    Message query = Message.newQuery(question);
    Log.v(TAG, "Constructed question: " + question);
    Log.v(TAG, "Constructed query: " + query);
    return sendMeasurement(query, config.isForceTCP());
  }

  /**
   * Put the query on the wire and wait for responses.
   *
   * @param query    The DNS query to send to the server.
   * @param forceTCP Tells whether we should force request to use TCP or not.
   * @return The lookup result.
   * @throws MeasurementError If anything goes wrong during DNS lookup.
   */
  @NonNull
  private DNSLookupResult sendMeasurement(Message query, boolean forceTCP) throws MeasurementError {
    byte[] output = query.toWire();