private void processExpressionCommand(
      Commands.ValueObject valueObject, InvokableValueSender valueSender)
      throws IOException, CommandException {
    Integer expressionID = new Integer(in.readInt());
    byte cmdType = in.readByte();
    ExpressionProcesserController exp = null;
    switch (cmdType) {
      case ExpressionCommands.START_EXPRESSION_TREE_PROCESSING:
        byte trace = in.readByte();
        if (trace == ExpressionCommands.TRACE_DEFAULT)
          exp = new ExpressionProcesserController(server, this);
        else
          exp =
              new ExpressionProcesserController(server, this, trace == ExpressionCommands.TRACE_ON);
        expressionProcessors.put(expressionID, exp);
        break;
      case ExpressionCommands.TRANSFER_EXPRESSION_REQUEST:
        exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID);
        sendObject(exp, NOT_A_PRIMITIVE, valueObject, out, true);
        break;
      case ExpressionCommands.RESUME_EXPRESSION_REQUEST:
        Commands.readValue(in, valueObject);
        exp = (ExpressionProcesserController) getInvokableObject(valueObject);
        expressionProcessors.put(expressionID, exp);
        break;
      case ExpressionCommands.PUSH_EXPRESSION:
        exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
        exp.process(in);
        break;
      case ExpressionCommands.SYNC_REQUEST:
        boolean haveProxies =
            in.readBoolean(); // See if we expression proxy ids that need to be resolved
        if (haveProxies) {
          Commands.readValue(in, valueObject);
          valueSender.initialize(valueObject);
          Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
        }

        exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
        if (haveProxies)
          sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
        if (exp.noErrors()) {
          valueObject.set(true); // Mark that all is good.
          Commands.writeValue(out, valueObject, true, true);
        } else {
          processExpressionError(exp, valueObject);
        }
        break;
      case ExpressionCommands.PULL_VALUE_REQUEST:
        haveProxies = in.readBoolean(); // See if we expression proxy ids that need to be resolved
        if (haveProxies) {
          Commands.readValue(in, valueObject);
          valueSender.initialize(valueObject);
          Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
        }

        exp = (ExpressionProcesserController) expressionProcessors.get(expressionID);
        if (haveProxies)
          sendExpressionProxyResolutions(valueObject, (int[]) valueSender.getArray(), exp);
        if (exp.noErrors()) {
          try {
            Object[] pulledValue = exp.pullValue();
            // Send back the command code for pull value. Don't flush. We will flush when all done.
            if (((Class) pulledValue[1]).isPrimitive()) {
              int returnTypeID = server.getIdentityID(pulledValue[1]);
              // Need to tell sendObject the correct primitive type.
              sendObject(pulledValue[0], returnTypeID, valueObject, out, true, true);

            } else {
              sendObject(
                  pulledValue[0],
                  NOT_A_PRIMITIVE,
                  valueObject,
                  out,
                  true,
                  true); // Just send the object back. sendObject knows how to iterpret the type
            }
          } catch (NoExpressionValueException e) {
            sendNoValueErrorCommand(exp, valueObject);
          }
        } else processExpressionError(exp, valueObject);
        break;
      case ExpressionCommands.END_EXPRESSION_TREE_PROCESSING:
        exp = (ExpressionProcesserController) expressionProcessors.remove(expressionID);
        exp.close();
        break;
    }
  }