private SelectResults prepareIteratorDef(Object obj, ObjectType elementType,
      ExecutionContext context) throws TypeMismatchException {
    if (obj == null) {
      return null;
    }
    if (obj == QueryService.UNDEFINED) {
      return null;
    }
    if (obj instanceof SelectResults) {
      // probably came from nested query or is a QRegion already from region
      // path
      SelectResults sr = (SelectResults) obj;
      // override the elementType if not Object.class (does not apply to
      // StructBags)
      if (!elementType.equals(TypeUtils.OBJECT_TYPE)) {
        sr.setElementType(elementType);
      }
      return sr;
    }
    if (obj instanceof Region) {
      // this can happen if region passed in as parameter
      QRegion qRegion = new QRegion((Region) obj, false, context);
      if (!elementType.equals(TypeUtils.OBJECT_TYPE)) {
        // override the valueConstraint, if any
        qRegion.setElementType(elementType);
      }
      return qRegion;
    }
    // if this is a domain collection, it should be unmodifiable
    // if obj is a Collection but not a SelectResults, it must be from the
    // domain, otherwise it would be a SelectResults.
    if (obj instanceof Collection) {
      // do not lose ordering and duplicate information,
      ResultsCollectionWrapper res = new ResultsCollectionWrapper(elementType, (Collection) obj);
      res.setModifiable(false);
      return res;
    }
    // Object[] is wrapped and considered a domain object so unmodifiable
    if (obj instanceof Object[]) {
      // the element type is specified in the array itself, unless we have
      // something more specific
      if (elementType.equals(TypeUtils.OBJECT_TYPE)) { // if we don't have
        // constraint info
        elementType = TypeUtils.getObjectType(obj.getClass().getComponentType());
      }
      // do not lose ordering and duplicate information,
      ResultsCollectionWrapper res =
          new ResultsCollectionWrapper(elementType, Arrays.asList((Object[]) obj));
      res.setModifiable(false);
      return res;
    }
    // TODO: primitive arrays?
    if (obj instanceof Map) {
      if (elementType.equals(TypeUtils.OBJECT_TYPE)) { // if we don't have more
        // specific type info,
        // use Map.Entry
        elementType = TypeUtils.getObjectType(Map.Entry.class);
      }
      ResultsCollectionWrapper res =
          new ResultsCollectionWrapper(elementType, ((Map) obj).entrySet());
      res.setModifiable(false);
      return res;
    } else {
      obj = new Object[] {obj};
      // the element type is specified in the array itself, unless we have
      // something more specific
      if (elementType.equals(TypeUtils.OBJECT_TYPE)) { // if we don't have
        // constraint info
        elementType = TypeUtils.getObjectType(obj.getClass().getComponentType());
      }
      // do not lose ordering and duplicate information,
      ResultsCollectionWrapper res =
          new ResultsCollectionWrapper(elementType, Arrays.asList((Object[]) obj));
      res.setModifiable(false);
      return res;
    }
  }
Convert the given object to a SelectResults. Must be a collection of some sort. The obj passed
in must be unmodified, but the resulting SelectResults may or may not be modifiable. Return
null if obj is null or UNDEFINED.
geode-core/src/main/java/org/apache/geode/cache/query/internal/CompiledIteratorDef.java