class BaseMappedQuery extends BaseMappedStatement<T, ID> implements GenericRowMapper<T> {

	@Override
	public T mapRow(DatabaseResults results) throws SQLException {
		Map<String, Integer> colPosMap;
		if (columnPositions == null) {
			colPosMap = new HashMap<String, Integer>();
		} else {
			colPosMap = columnPositions;
		}

		ObjectCache objectCache = results.getObjectCacheForRetrieve();
		if (objectCache != null) {
			Object id = idField.resultToJava(results, colPosMap);
			T cachedInstance = objectCache.get(clazz, id);
			if (cachedInstance != null) {
				// if we have a cached instance for this id then return it
				return cachedInstance;
			}
		}

		// create our instance
		T instance = tableInfo.createObject();
		// populate its fields
		Object id = null;
		boolean foreignCollections = false;
		for (FieldType fieldType : resultsFieldTypes) {
			if (fieldType.isForeignCollection()) {
				foreignCollections = true;
			} else {
				Object val = fieldType.resultToJava(results, colPosMap);
				/*
				 * This is pretty subtle. We introduced multiple foreign fields to the same type which use the {@link
				 * ForeignCollectionField} foreignColumnName field. The bug that was created was that all the fields
				 * were then set with the parent class. Only the fields that have a matching id value should be set to
				 * the parent. We had to add the val.equals logic.
				 */
				if (val != null && parent != null && fieldType.getField().getType() == parent.getClass()
						&& val.equals(parentId)) {
					fieldType.assignField(instance, parent, true, objectCache);
				} else {
					fieldType.assignField(instance, val, false, objectCache);
				}
				if (fieldType.isId()) {
					id = val;
				}
			}
		}
		if (foreignCollections) {
			// go back and initialize any foreign collections
			for (FieldType fieldType : resultsFieldTypes) {
				if (fieldType.isForeignCollection()) {
					BaseForeignCollection<?, ?> collection = fieldType.buildForeignCollection(instance, id);
					if (collection != null) {
						fieldType.assignField(instance, collection, false, objectCache);
					}
				}
			}
		}
		// if we have a cache and we have an id then add it to the cache
		objectCache = results.getObjectCacheForStore();
		if (objectCache != null && id != null) {
			objectCache.put(clazz, id, instance);
		}
		if (columnPositions == null) {
			columnPositions = colPosMap;
		}
		return instance;
	}

	protected  BaseMappedQuery(TableInfo<T, ID> tableInfo, String statement, FieldType[] argFieldTypes,
			FieldType[] resultsFieldTypes);

}