// Returns the indices for the objects to check contracts over.
  //
  // If an element is primitive, a String, or null, its index is not returned.
  //
  // The indices are returned as a map, from types to the indices of
  // the given type. Binary contracts are only checked for objects
  // of equal types, so themap is handy.
  private static MultiMap<Class<?>, Integer> objectIndicesToCheck(
      ExecutableSequence s, int maxIdx) {

    MultiMap<Class<?>, Integer> map = new MultiMap<Class<?>, Integer>();

    for (int i = 0; i <= maxIdx; i++) {
      ExecutionOutcome result = s.getResult(i);

      assert result instanceof NormalExecution;

      Class<?> outputType = s.sequence.getStatementKind(i).getOutputType();

      if (outputType.equals(void.class)) continue;
      if (outputType.equals(String.class)) continue;
      if (PrimitiveTypes.isPrimitive(outputType)) continue;

      Object runtimeValue = ((NormalExecution) result).getRuntimeValue();
      if (runtimeValue == null) continue;

      map.add(outputType, i);
    }
    return map;
  }
  /**
   * Determines what indices in the given sequence are active. An active index i means that the i-th
   * method call creates an interesting/useful value that can be used as an input to a larger
   * sequence; inactive indices are never used as inputs. The effect of setting active/inactive
   * indices is that the SequenceCollection to which the given sequences is added only considers the
   * active indices when deciding whether the sequence creates values of a given type.
   *
   * <p>In addition to determining active indices, this method determines if any primitive values
   * created during execution of the sequence are new values not encountered before. Such values are
   * added to the component manager so they can be used during subsequent generation attempts.
   */
  public void processSequence(ExecutableSequence seq) {
    Tracer.trace("processSequence");
    if (GenInputsAbstract.offline) {
      Tracer.trace("offline@processSequence");
      if (Log.isLoggingOn()) {
        Log.logLine(
            "Making all indices active (offline generation specified; sequences are not executed).");
      }
      seq.sequence.setAllActiveFlags();
      return;
    }
    Tracer.trace("NOT offline@processSequence");

    if (seq.hasNonExecutedStatements()) {
      if (Log.isLoggingOn()) {
        Log.logLine(
            "Making all indices inactive (sequence has non-executed statements, so judging it inadequate for further extension).");
      }
      seq.sequence.clearAllActiveFlags();
      return;
    }

    if (seq.hasFailure()) {
      if (Log.isLoggingOn()) {
        Log.logLine(
            "Making all indices inactive (sequence reveals a failure, so judging it inadequate for further extension)");
      }
      seq.sequence.clearAllActiveFlags();
      return;
    }

    if (!seq.isNormalExecution()) {
      if (Log.isLoggingOn()) {
        Log.logLine(
            "Making all indices inactive (exception thrown, or failure revealed during execution).");
      }
      seq.sequence.clearAllActiveFlags();
      return;
    }

    // If runtime value is a primitive value, clear active flag, and
    // if the value is new, add a sequence corresponding to that value.
    for (int i = 0; i < seq.sequence.size(); i++) {

      // type ensured by isNormalExecution clause ealier in this method.
      NormalExecution e = (NormalExecution) seq.getResult(i);
      Object runtimeValue = e.getRuntimeValue();
      if (runtimeValue == null) {
        if (Log.isLoggingOn()) {
          Log.logLine("Making index " + i + " inactive (value is null)");
        }
        seq.sequence.clearActiveFlag(i);
        continue;
      }

      Class<?> objectClass = runtimeValue.getClass();

      Tracer.trace("processSequence-useobjcache");
      if (PrimitiveTypes.isBoxedOrPrimitiveOrStringType(objectClass)) {
        if (Log.isLoggingOn()) {
          Log.logLine("Making index " + i + " inactive (value is a primitive)");
        }
        seq.sequence.clearActiveFlag(i);

        boolean looksLikeObjToString =
            (runtimeValue instanceof String)
                && PrimitiveTypes.looksLikeObjectToString((String) runtimeValue);
        boolean tooLongString =
            (runtimeValue instanceof String)
                && !PrimitiveTypes.stringLengthOK((String) runtimeValue);
        if (!looksLikeObjToString && !tooLongString && runtimePrimitivesSeen.add(runtimeValue)) {
          // Have not seen this value before; add it to the component set.
          componentManager.addGeneratedSequence(
              PrimitiveOrStringOrNullDecl.sequenceForPrimitive(runtimeValue));
        }
      } else if (GenInputsAbstract.use_object_cache) {
        Tracer.trace("use_object_cache@processSequence-useobjcache");
        objectCache.setActiveFlags(seq, i);
      } else {
        if (Log.isLoggingOn()) {
          Log.logLine("Making index " + i + " active.");
        }
      }
    }
  }