/**
   * Set computation class
   *
   * @param computationClass computation class
   */
  public void setComputationClass(Class<? extends Computation> computationClass) {
    this.computationClass = computationClass;

    if (computationClass != null) {
      Class[] computationTypes =
          ReflectionUtils.getTypeArguments(TypesHolder.class, computationClass);
      if (computationTypes[4] != null && outgoingMessageClasses instanceof DefaultMessageClasses) {
        ((DefaultMessageClasses) outgoingMessageClasses)
            .setIfNotModifiedMessageClass(computationTypes[4]);
      }
    }
  }
  /**
   * Verify that types of current Computation and MessageCombiner are valid. If types don't match an
   * {@link IllegalStateException} will be thrown.
   *
   * @param checkMatchingMesssageTypes Check that the incoming/outgoing message types match
   */
  public void verifyTypesMatch(boolean checkMatchingMesssageTypes) {
    // In some cases, for example when using Jython, the Computation class may
    // not be set. This is because it is created by a ComputationFactory
    // dynamically and not known ahead of time. In this case there is nothing to
    // verify here so we bail.
    if (COMPUTATION_LANGUAGE.get(conf) == Language.JYTHON) {
      return;
    }

    Class<?>[] computationTypes =
        ReflectionUtils.getTypeArguments(TypesHolder.class, computationClass);
    ReflectionUtils.verifyTypes(
        conf.getVertexIdClass(), computationTypes[0], "Vertex id", computationClass);
    ReflectionUtils.verifyTypes(
        conf.getVertexValueClass(), computationTypes[1], "Vertex value", computationClass);
    ReflectionUtils.verifyTypes(
        conf.getEdgeValueClass(), computationTypes[2], "Edge value", computationClass);

    if (checkMatchingMesssageTypes) {
      ReflectionUtils.verifyTypes(
          incomingMessageClasses.getMessageClass(),
          computationTypes[3],
          "Incoming message type",
          computationClass);
    }

    ReflectionUtils.verifyTypes(
        outgoingMessageClasses.getMessageClass(),
        computationTypes[4],
        "Outgoing message type",
        computationClass);

    outgoingMessageClasses.verifyConsistent(conf);
  }