public static void lazyLoad(final List<Feature> features, final int featureIncludes,
			final LazyLoadCallback callback) {
		List<SearchCriterion> criteria = new ArrayList<SearchCriterion>();
		final boolean incAttr = (featureIncludes & GeomajasConstant.FEATURE_INCLUDE_ATTRIBUTES) != 0;
		final boolean incGeom = (featureIncludes & GeomajasConstant.FEATURE_INCLUDE_GEOMETRY) != 0;
		final boolean incStyle = (featureIncludes & GeomajasConstant.FEATURE_INCLUDE_STYLE) != 0;
		final boolean incLabel = (featureIncludes & GeomajasConstant.FEATURE_INCLUDE_LABEL) != 0;
		if (null != features) {
			for (Feature feature : features) {
				if ((incAttr && !feature.isAttributesLoaded()) || (incGeom && !feature.isGeometryLoaded()) ||
						(incLabel && feature.getLabel() == null) || (incStyle && feature.getStyleId() == null)) {
					criteria.add(new SearchCriterion(SearchFeatureRequest.ID_ATTRIBUTE, "=", feature.getId()));
				}
			}
		}
		if (criteria.size() > 0) {
			Feature first = features.get(0);
			SearchFeatureRequest request = new SearchFeatureRequest();
			request.setBooleanOperator("OR");
			request.setCriteria(criteria.toArray(new SearchCriterion[criteria.size()]));
			request.setCrs(first.getLayer().getMapModel().getCrs());
			request.setLayerId(first.getLayer().getServerLayerId());
			request.setMax(0);
			request.setFilter(first.getLayer().getFilter());
			request.setFeatureIncludes(featureIncludes);

			GwtCommand command = new GwtCommand(SearchFeatureRequest.COMMAND);
			command.setCommandRequest(request);
			GwtCommandDispatcher.getInstance().execute(command, new AbstractCommandCallback<SearchFeatureResponse>() {

				public void execute(SearchFeatureResponse response) {
					if (null != response.getFeatures() && response.getFeatures().length > 0) {
						// build map of features to allow fast update
						Map<String, Integer> map = new HashMap<String, Integer>();
						for (int i = 0 ; i < features.size() ; i++) {
							Feature feature = features.get(i);
							map.put(feature.getId(), i);
						}

						for (org.geomajas.layer.feature.Feature dto : response.getFeatures()) {
							Feature feature = features.get(map.get(dto.getId()));
							if (incAttr) {
								feature.setAttributes(dto.getAttributes());
							}
							if (incGeom) {
								Geometry geometry = GeometryConverter.toGwt(dto.getGeometry());
								feature.setGeometry(geometry);
							}
							if (incStyle) {
								feature.setStyleId(dto.getStyleId());
							}
							if (incLabel) {
								feature.setLabel(dto.getLabel());
							}
						}
					}
					callback.execute(features);
				}
			});
		} else {
			callback.execute(features);
		}
	}
public static void lazyLoad ( final List < Feature > features , final int featureIncludes , final LazyLoadCallback callback ) { List < SearchCriterion > criteria = new ArrayList < SearchCriterion > ( ) ; final boolean incAttr = ( featureIncludes & GeomajasConstant . FEATURE_INCLUDE_ATTRIBUTES ) != 0 ; final boolean incGeom = ( featureIncludes & GeomajasConstant . FEATURE_INCLUDE_GEOMETRY ) != 0 ; final boolean incStyle = ( featureIncludes & GeomajasConstant . FEATURE_INCLUDE_STYLE ) != 0 ; final boolean incLabel = ( featureIncludes & GeomajasConstant . FEATURE_INCLUDE_LABEL ) != 0 ; if ( null != features ) { for ( Feature feature : features ) { if ( ( incAttr && ! feature . isAttributesLoaded ( ) ) || ( incGeom && ! feature . isGeometryLoaded ( ) ) || ( incLabel && feature . getLabel ( ) == null ) || ( incStyle && feature . getStyleId ( ) == null ) ) { criteria . add ( new SearchCriterion ( SearchFeatureRequest . ID_ATTRIBUTE , "=" , feature . getId ( ) ) ) ; } } } if ( criteria . size ( ) > 0 ) { Feature first = features . get ( 0 ) ; SearchFeatureRequest request = new SearchFeatureRequest ( ) ; request . setBooleanOperator ( "OR" ) ; request . setCriteria ( criteria . toArray ( new SearchCriterion [ criteria . size ( ) ] ) ) ; request . setCrs ( first . getLayer ( ) . getMapModel ( ) . getCrs ( ) ) ; request . setLayerId ( first . getLayer ( ) . getServerLayerId ( ) ) ; request . setMax ( 0 ) ; request . setFilter ( first . getLayer ( ) . getFilter ( ) ) ; request . setFeatureIncludes ( featureIncludes ) ; GwtCommand command = new GwtCommand ( SearchFeatureRequest . COMMAND ) ; command . setCommandRequest ( request ) ; GwtCommandDispatcher . getInstance ( ) . execute ( command , new AbstractCommandCallback < SearchFeatureResponse > ( ) { public void execute ( SearchFeatureResponse response ) { if ( null != response . getFeatures ( ) && response . getFeatures ( ) . length > 0 ) { Map < String , Integer > map = new HashMap < String , Integer > ( ) ; for ( int i = 0 ; i < features . size ( ) ; i ++ ) { Feature feature = features . get ( i ) ; map . put ( feature . getId ( ) , i ) ; } for ( org . geomajas . layer . feature . Feature dto : response . getFeatures ( ) ) { Feature feature = features . get ( map . get ( dto . getId ( ) ) ) ; if ( incAttr ) { feature . setAttributes ( dto . getAttributes ( ) ) ; } if ( incGeom ) { Geometry geometry = GeometryConverter . toGwt ( dto . getGeometry ( ) ) ; feature . setGeometry ( geometry ) ; } if ( incStyle ) { feature . setStyleId ( dto . getStyleId ( ) ) ; } if ( incLabel ) { feature . setLabel ( dto . getLabel ( ) ) ; } } } callback . execute ( features ) ; } } ) ; } else { callback . execute ( features ) ; } }
Assure the specified aspects are set in the list of features.
<p/>
This will update attributes and/or geometry.
<p/>
All features which are passed have to be from the same layer.

@param features list of features
@param featureIncludes data to include
@param callback callback to call when lazy loading is complete.