/**
   * Constructs a sample execution graph consisting of two vertices connected by a channel of the
   * given type.
   *
   * @param channelType the channel type to connect the vertices with
   * @param instanceManager the instance manager that shall be used during the creation of the
   *     execution graph
   * @return a sample execution graph
   */
  private ExecutionGraph createExecutionGraph(
      final ChannelType channelType, final InstanceManager instanceManager) {

    final JobGraph jobGraph = new JobGraph("Job Graph");

    final JobInputVertex inputVertex = new JobInputVertex("Input 1", jobGraph);
    inputVertex.setInputClass(InputTask.class);
    inputVertex.setNumberOfSubtasks(1);

    final JobOutputVertex outputVertex = new JobOutputVertex("Output 1", jobGraph);
    outputVertex.setOutputClass(OutputTask.class);
    outputVertex.setNumberOfSubtasks(1);

    try {
      inputVertex.connectTo(outputVertex, channelType);
    } catch (JobGraphDefinitionException e) {
      fail(StringUtils.stringifyException(e));
    }

    try {
      LibraryCacheManager.register(jobGraph.getJobID(), new String[0]);
      return new ExecutionGraph(jobGraph, instanceManager);

    } catch (GraphConversionException e) {
      fail(StringUtils.stringifyException(e));
    } catch (IOException e) {
      fail(StringUtils.stringifyException(e));
    }

    return null;
  }
  /*
   * (non-Javadoc)
   * @see eu.stratosphere.core.io.IOReadableWritable#read(java.io.DataInput)
   */
  @Override
  public void read(final DataInput in) throws IOException {
    this.mode = ExecutionMode.values()[in.readInt()];

    final ArrayList<String> requiredPackages = new ArrayList<String>();
    for (int count = in.readInt(); count > 0; count--) requiredPackages.add(in.readUTF());
    this.query = null;
    final byte[] planBuffer = new byte[in.readInt()];
    in.readFully(planBuffer);

    final JobID dummId = new JobID();
    try {
      LibraryCacheManager.register(
          dummId, requiredPackages.toArray(new String[requiredPackages.size()]));
      SopremoEnvironment.getInstance().setClassLoader(LibraryCacheManager.getClassLoader(dummId));
      this.query = SopremoUtil.deserialize(planBuffer, SopremoPlan.class);
    } catch (final IOException e) {
      e.printStackTrace();
    } finally {
      try {
        LibraryCacheManager.unregister(dummId);
      } catch (final IOException e) {
      }
    }
  }
  /*
   * (non-Javadoc)
   * @see com.esotericsoftware.kryo.KryoSerializable#read(com.esotericsoftware.kryo.Kryo,
   * com.esotericsoftware.kryo.io.Input)
   */
  @SuppressWarnings("unchecked")
  @Override
  public void read(final Kryo kryo, final Input input) {
    this.mode = kryo.readObject(input, ExecutionMode.class);
    final ArrayList<String> requiredPackages = kryo.readObject(input, ArrayList.class);

    final JobID dummId = JobID.generate();
    final ClassLoader oldClassLoader = kryo.getClassLoader();
    try {
      LibraryCacheManager.register(
          dummId, requiredPackages.toArray(new String[requiredPackages.size()]));
      kryo.setClassLoader(LibraryCacheManager.getClassLoader(dummId));
      this.query = kryo.readObject(input, SopremoPlan.class);
    } catch (final Exception e) {
      SopremoUtil.LOG.error(e.getMessage());
      throw new KryoException(e);
    } finally {
      kryo.setClassLoader(oldClassLoader);
      try {
        LibraryCacheManager.unregister(dummId);
      } catch (final Throwable e) {
        SopremoUtil.LOG.error(e.getMessage());
      }
    }
  }
  /**
   * Reads required JAR files from an input stream and adds them to the library cache manager.
   *
   * @param in the data stream to read the JAR files from
   * @throws IOException thrown if an error occurs while reading the stream
   */
  private void readRequiredJarFiles(final DataInput in) throws IOException {

    // Do jar files follow;
    final int numJars = in.readInt();

    if (numJars > 0) {

      for (int i = 0; i < numJars; i++) {

        final Path p = new Path();
        p.read(in);
        this.userJars.add(p);

        // Read the size of the jar file
        final long sizeOfJar = in.readLong();

        // Add the jar to the library manager
        LibraryCacheManager.addLibrary(this.jobID, p, sizeOfJar, in);
      }
    }

    // Register this job with the library cache manager
    LibraryCacheManager.register(this.jobID, this.userJars.toArray(new Path[0]));
  }