Skip to main content

Other Expressions

Definition Properties

PropertyDescription
idThe unique technical identifier of the definition.
categoryThe category of the definition, if set in the related model.
deploymentIdA reference to the deployment related to this definition. See the documentation on deployments to learn more what this means.
descriptionThe description of the definition, if configured in the model.
keyThe key of the definition, which must be unique for all similar model types. For a given key, multiple versions are typically deployed in a runtime system.
nameThe name of the definition, which matches the name of the BPMN or CMMN model.
tenantIdThe identifier of the tenant in which this definition was deployed.
versionThe version of the definition. Each time a model is published, a new definition for the same key is created with version equal to the last version + 1.

Variable Functions

Variable manipulation is an important use case of expressions.

Setting variables can be done through the runtimeService:

  • ${runtimeService.setVariable(processInstanceId, variableName, variableValue)}
  • ${cmmnRuntimeService.setVariable(caseInstanceId, variableName, variableValue)}

Or on a keyword object (depending on the context):

  • ${execution.setVariable(varName, varValue)} sets the value varValue to variable varName of the current process instance.
  • ${caseInstance.setVariable(varName, varValue)} sets the value varValue to variable varName of the current case instance.
  • ${planItemInstance.setVariable(varName, varValue)} sets the value varValue to variable varName of the current case instance.
  • ${task.setVariable(varName, varValue)} sets the value varValue to variable varName of the current process/case instance.

Following functions are available for handling variables, both applicable to BPMN and CMMN context:

FunctionDescription
${var:get(varName)}Retrieves the value of a variable. The main difference with writing the variable name directly in the expression is that using this function won’t throw an exception when the variable doesn’t exist. For example ${myVariable == "hello"} would throw an exception if myVariable doesn’t exist, but ${var:get(myVariable) == 'hello'} won't.
${var:getOrDefault(varName, defaultValue)}variables:getOrDefault(varName, defaultValue).
${var:exists(varName)}variables:exists(varName).
${var:isEmpty(varName)}Checks if the variable value is not empty. Depending on the variable type, the behavior is the following. For String variables, the variable is deemed empty if it’s the empty string. For java.util.Collection variables, true is returned if the collection has no elements. For ArrayNode variables, true is returned if there are no elements. In case the variable is null, true is always returned.
${var:isNotEmpty(varName)}The reverse operation of isEmpty.
${var:equals(varName, value)}Checks if a variable is equal to a given value. This is a shorthand function for an expression that would otherwise be written as ${execution.getVariable("varName") != null && execution.getVariable("varName") == value}. If the variable value is null, false is returned (unless compared to null).
${var:notEquals(varName, value)}The reverse operation of equals.
${var:contains(varName, value1, value2, …​)}Checks if all values provided are contained within a variable. Depending on the variable type, the behavior is the following. For String variables, the passed values are used as substrings that need to be part of the variable. For java.util.Collection variables, all the passed values need to be an element of the collection (regular contains semantics). For ArrayNode variables: supports checking if the arraynode contains a JsonNode for the types that are supported as variable type. When the variable value is null, false is returned in all cases. When the variable value is not null, and the instance type is not one of the types above, false will be returned.
${var:containsAny(varName, value1, value2, …​)}Similar to the contains function, but true will be returned if any (and not all) the passed values is contained in the variable.
${var:base64(varName}Converts a Binary or String variable to a Base64 String.
${var:lowerThan(varName, value)}shorthand for ${execution.getVariable("varName") != null && execution.getVariable("varName") < value}. Alias = lt
${var:lowerThanOrEquals(varName, value)}Similar, but now for < =. Alias = lte
${variables:greaterThan(varName, value)}Similar, but now for >. Alias = gr
${variables:greaterThanOrEquals(varName, value)}Similar, but now for > =. Alias = gte

String Utilities

String manipulation methods are a classic use case for expressions. The following methods are available:

ExpressionDescription
${flw.string.carriageReturn()}Returns the carriage return character.
${flw.string.capitalize(text)}Capitalizes a text, i.e. sets the first letter to uppercase. Supported values are String, a Json TextNode or null.
${flw.string.contains(text, otherText)}Checks if a strings contains another string. Supported values are String, a Json TextNode or null.
${flw.string.containsIgnoreCase(text, otherText)}Checks if a strings contains another string ignoring the case. Supported values are String, a Json TextNode or null.
${flw.string.equals(text, otherText)}Checks if two strings are the equal. Supported values are String, a Json TextNode or null.
${flw.string.equalsIgnoreCase(text, otherText)}Checks if two strings are the equal, ignoring the case. Supported values are String, a Json TextNode or null.
${flw.string.escapeHtml(text)}Escapes the characters in an object using HTML entities. Supported values are String, a Json TextNode or null.
${flw.string.hasText(text)}Checks whether a string contains text (is not null or empty). Supported values are String, a Json TextNode or null.
${flw.string.join(collection, String delimiter)}Concatenates all entries of a list or collection to a single string using a given delimiter. Supported values are String, a Json TextNode or null.
${flw.string.matches(text, regularExpression)}Checks whether a text matches a regular expression. Supported values are String, a Json TextNode or null.
${flw.string.newline()}Returns a new line linefeed character.
${flw.string.substring(text, from, to)}Returns a substring within a provided character range. Index is 0 based, from is inclusive, to is exclusive. Supported values are String, a Json TextNode or null.
${flw.string.substringFrom(text, from)}Returns the text starting at a given position (index is 0 based). Supported values are String, a Json TextNode or null.
${flw.string.split(text, delimiter)}Splits a text into a collection with a given delimiter. The delimiter can be a single character, e.g. a semicolon or a regular expression. Supported values are String, a Json TextNode or null.
${flw.string.toLowerCase(text)}Turns all characters of the string to lowercase.
${flw.string.toUpperCase(text)}Turns all characters of the string to uppercase.
${flw.string.trimWhitespace(text)}Removes all leading and trailing whitespaces from a text. Supported values are String, a Json TextNode or null.
${flw.string.unescapeHtml(text)}Unescapes a string containing entity escapes to a string containing the actual Unicode characters corresponding to the escapes. Supported values are String, a Json TextNode or null.

Date and Time Utilities

ExpressionDescription
${flw.time.now()}Returns the current date and time in UTC.
${flw.time.currentDate()}Returns the current date at 00:00 AM UTC as an Instant.
${flw.time.currentLocalDate()}Returns the current date in the system time zone (which is UTC) as a LocalDate instance.
${flw.time.currentLocalDateTime()}Returns the current date and time in the system time zone (which is UTC) as a LocalDateTime instance.
${flw.time.instantFromTimestamp(long timestamp)}Returns an Instant from the number of seconds that have passed since the first of January 1970 (Unix Timestamp).
${flw.time.dateFromTimestamp(long timestamp)}Returns an Date from the number of seconds that have passed since the first of January 1970 (Unix Timestamp).
${flw.time.parseInstant(Date date)}Returns an Instant out of a Date }
${flw.time.parseInstant(String instantIsoString)}Parses an ISO8601 formatted string into an Instant.
${flw.time.parseInstant(Object value, String pattern)}Parses an object into an Instant using the provided pattern. Supported inputs are String, Json TextNode or null.
${flw.time.parseLocalDate(Object value, String pattern)}Parses an object into a LocalDate using the provided pattern. Supported inputs are String, Json TextNode or null.
${flw.time.parseLocalDateTime(Object value, String pattern)}Parses an object into a LocalDateTime using the provided pattern. Supported inputs are String, Json TextNode or null.
${flw.time.asInstant(Object value)}Converts a value to an Instant with UTC time zone. Supported values are: Date, Instant (which will be returned directly), LocalDate, LocalDateTime, an ISO8601 formatted String or null.
${flw.time.asInstant(Object value, String timeZoneId)}Converts a value to an Instant in the given time zone. Supported values are: Date, Instant (which will be returned directly), LocalDate, LocalDateTime, an ISO8601 formatted String or null.
${flw.time.asLocalDate(Object value)}Converts a value to a LocalDate with UTC time zone. Supported values are: Date, Instant, LocalDate (which will be returned directly), LocalDateTime, an ISO8601 formatted String or null.
${flw.time.asLocalDate(Object value, String timeZoneId)}Converts a value to an LocalDate in the given time zone. Supported values are: Date, Instant, LocalDate (which will be returned directly), LocalDateTime, an ISO8601 formatted String or null.
${flw.time.asLocalDateTime(Object value)}Converts a value to a LocalDateTime with UTC time zone. Supported values are: Date, Instant, LocalDate, LocalDateTime (which will be returned directly), an ISO8601 formatted String or null.
${flw.time.asLocalDateTime(Object value, String timeZoneId)}Converts a value to an LocalDateTime in the given time zone. Supported values are: Date, Instant, LocalDate, LocalDateTime (which will be returned directly), an ISO8601 formatted String or null.
${flw.time.asDate(Object value)}Converts a value to a Date in the UTC time zone. Supported values are Instant, LocalDate, LocalDateTime, an ISO8601 formatted String or null.
${flw.time.atTime(Object value, int hours, int minutes, int seconds)}Sets the time of the value to the specified hours, minutes and seconds in the UTC time zone. Supported values are Date, Instant, LocalDateTime or an ISO8601 formatted String. The returned value will be the same type as the input type, for a string, it will either be an Instant or a LocalDateTime depending on the provided format of the string.
${flw.time.atTimeWithTimeZone(Object value, int hours, int minutes, int seconds, String timeZoneId)}Sets the time of the value to the specified hours, minutes and seconds in the given time zone. Supported values are Date, Instant, LocalDateTime or an ISO8601 formatted String. The returned value will be the same type as the input type, for a string, it will either be an Instant or a LocalDateTime depending on the provided format of the string.
${flw.time.atTimeZone(Object value, String timeZoneId)}Returns an Instant at a specified time zone. Supported values are Date or Instant. Only use this one for display purposes, never store a date in something else than UTC.
${flw.time.getAvailableTimeZoneIds()}Returns a list of available time zone ids. A more or less complete list can also be found here
${flw.time.getField(Object value, String chronoFieldString)}Obtains a 'slice of time' by specifying a ChronoField as a String. The chrono field can be specified either as the display name or the enum name. Supported values are Date, Instant, LocalDate, LocalDateTimeor an ISO8601 formatted String. A list of all chrono fields can be found here. Example: flw.time.getField(flw.time.now(), 'DAY_OF_WEEK'), or flw.time.getField(flw.time.now(), 'AlignedWeekOfYear')}
${flw.time.isWeekend(Object value)}Determines whether the given value represents a weekend. Supported values are Date, Instant, LocalDate, LocalDateTime or a ISO8601 formatted String.
${flw.time.fullDateTimeInstant(int year, int month, int day, int hour, int minute, int second)}Creates an Instant with the given values in UTC time zone.
${flw.time.fullDateTimeDate(int year, int month, int day, int hour, int minute, int second)}Creates a Date with the given values.
${flw.time.plusSeconds(Object value, long seconds)}Adds seconds to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.plusMinutes(Object value, long minutes)}Adds minutes to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.plusHours(Object value, long hours)}Adds hours to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.plusDays(Object value, long days)}Adds days to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.plusWeeks(Object value, long weeks)}Adds weeks to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.plusMonths(Object value, long months)}Adds months to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.plusYears(Object value, long years)}Adds years to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.plusDuration(Object value, String iso8601Duration)}Adds an ISO8601 encoded duration to a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. Examples: flw.time.plusDuration(flw.time.now(), 'P1Y') (adds one year to now), flw.time.plusDuration(flw.time.now(), 'P14D') (adds 14 days to now), flw.time.plusDuration(flw.time..now(), 'PT30M10S') (adds 30 minutes and 10 seconds to now).
${flw.time.minusSeconds(Object value, long seconds)}Subtracts seconds from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minusMinutes(Object value, long minutes)}Subtracts minutes from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minusHours(Object value, long hours)}Subtracts hours from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minusDays(Object value, long days)}Subtracts days from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minusWeeks(Object value, long weeks)}Subtracts weeks from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minusMonths(Object value, long months)}Subtracts months from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minusYears(Object value, long years)}Subtracts years from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minusDuration(Object value, String iso8601Duration)}Subtracts an ISO8601 encoded duration from a given value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. Examples: flw.time.minusDuration(flw.time.now(), 'P1Y') (subtracts one year from now), flw.time.minusDuration(flw.time.now(), 'P14D') (subtracts 14 days from now), flw.time.minusDuration(flw.time..now(), 'PT30M10S') (subtracts 30 minutes and 10 seconds from now).
${flw.time.secondsOfDuration(String iso8601Duration)}Returns the number of seconds in a ISO duration string, e.g. PT60M returns 3600.
${flw.time.isBefore(Object firstValue, Object secondValue)}Checks if the first value is before the second value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. The values don't need to be the same type, they will be converted automatically, if needed.
${flw.time.isBeforeOrEqual(Object firstValue, Object secondValue)}Checks if the first value is before or equals to the second value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. The values don't need to be the same type, they will be converted automatically, if needed.
${flw.time.isAfter(Object firstValue, Object secondValue)}Checks if the first value is after the second value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. The values don't need to be the same type, they will be converted automatically, if needed.
${flw.time.isAfterOrEqual(Object firstValue, Object secondValue)}Checks if the first value is after or equal to the second value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. The values don't need to be the same type, they will be converted automatically, if needed.
${flw.time.areEqual(Object firstValue, Object secondValue)}Checks if the first value is equal to the second value. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. The values don't need to be the same type, they will be converted automatically, if needed.
${flw.time.isBeforeTime(Object value, String timeZoneId, int hours, int minutes, int seconds)}Checks if the given value is before a certain time in a given time zone. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.isAfterTime(Object value, String timeZoneId, int hours, int minutes, int seconds)}Checks if the given value is after a certain time in a given time zone. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.getFieldFromDurationBetweenDates(Object firstValue, Object secondValue, String chronoUnitString)}Returns the duration between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String. The following units are supported: Nanos, Micros, Millis, Seconds, Hours, HalfDays, Days, Weeks, Months, Years, Decades, Centuries, Millenia. Please note that the number will always be a long, i.e. the number will always be rounded.
${flw.time.secondsBetween(Object firstValue, Object secondValue)}Return the number of seconds between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.minutesBetween(Object firstValue, Object secondValue)}Return the number of minutes between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.hoursBetween(Object firstValue, Object secondValue)}Return the number of hours between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.daysBetween(Object firstValue, Object secondValue)}Return the number of days between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.weeksBetween(Object firstValue, Object secondValue)}Return the number of weeks between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.monthsBetween(Object firstValue, Object secondValue)}Return the number of month between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.yearsBetween(Object firstValue, Object secondValue)}Return the number of years between two values. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.
${flw.time.getTimeZoneOffset(Object value, String timeZoneId)}Calculates the number of seconds a specific point in time at a specified time zone is set off from UTC. Supported values are Date, Instant, LocalDate, LocalDateTime or an ISO8601 formatted String.

JSON Utilities

The following functions are available when working with JSON objects in expressions. They work in BPMN and CMMN context.

ExpressionDescription
${json:object()} returns an empty json object.
${json:array()} returns an empty json array.
${json:arrayWithSize(size)} returns a json array with a given size.
${json:addToArray(arrayNode, object)} adds a given object to a given array node.

Formatting Utilities

The following methods are available when needing to format values:

ExpressionDescription
${flw.format.formatString(text, substitutes)}Formats a string according to the Java formatter specification, see here or here.
${flw.format.formatDate(value, dateFormat)}Formats the value to a string with the given format. Supported values are Date, Instant, LocalDate, LocaDateTime or an ISO8601 formatted string.
${flw.format.formatDecimal(pattern, decimal)}Formats a string according to the Java formatter specification with a decimal formatter in the default locale. See
${flw.format.formatStringWithLocale(languageTag, text, substitutes)}Formats a string according to the Java formatter specification. The string is formatted according to the format specified in the locale of the provided language tag. See See here or here
${flw.format.formatCurrencyWithLocale(currencyCode, amount, languageTag)}Formats a currency amount according to the format specified in the locale of the provided language tag.

Example: ${flw.format.formatDate(flw.time.now(), 'dd.MM.yyyy')} formats today's date as dd.MM.yyyy

Locale Utilities

ExpressionDescription
${flw.locale.getLocaleForLanguageTag(languageTag)}Returns the locale with the given language tag, e.g. 'ch-DE'.
${flw.locale.getAvailableLocales()}Returns a list of available locales.
${flw.locale.getDefaultLocale()}Returns the system default locale.
${flw.locale.getAllCountryCodes()}Returns a list of all 2-letter ISO country codes.
${flw.locale.getAllLanguageCodes()}Returns a list of all ISO language codes, e.g. "de" (NOT "de-CH").
${flw.locale.getLanguageDisplayName(languageIsoCode, displayLanguageTag)}Returns a single language name in a certain language, e.g. "German" or "Spanish".
${flw.locale.getCountryDisplayName(languageTag, displayLanguageTag)}Returns a single country name in a certain language, e.g. "Switzerland" or "Germany".
${flw.locale.getAllLanguageDisplayNames(displayLanguageTag)}Returns a list of all language names in a certain language.
${flw.locale.getAllCountryDisplayNames(displayLanguageTag)}Returns a list of all country names in a certain language.

Mathematical Utilities

The following methods are available when needing to do mathematical operations:

ExpressionDescription
${flw.math.abs(number)}Returns the absolute value of a number.
${flw.math.average(numbers}Calculates the average of a list of numbers.
${flw.math.ceil(number)}Returns the next higher integer of a provided number.
${flw.math.floor(number)}Returns the next lower integer of a provided number.
${flw.math.median(numbers)}Returns the median of a list of numbers.
${flw.math.min(numbers)}Returns the lowest number from a list of numbers.
${flw.math.max(numbers)}Returns the highest number from a list of numbers.
${flw.math.parseDouble(string)}Converts a string into a double value.
${flw.math.parseInt(string)}Converts a string into an integer value.
${flw.math.round(number)}Rounds a number to an integer value.
${flw.math.round(number, scale)}Round a number to a maximum of decimal places using RoundingMode#HALF_UP.
${flw.math.sum(numbers)}Calculates the sum of a list of numbers.

User functions

The following methods can be used for retrieving user information:

ExpressionDescription
${findUser(userId)}Returns the user representation corresponding to passed id.
${findGroupMemberUserIds('GROUP_A, GROUP_B')} v3.14.0+Returns a string Collection of userIds of the members of the given groups. Note: string Collection String should only be stored transiently, if you want to persist it as a variable, you'll have to convert it to JSON.
${findGroupMemberEmails('GROUP_A, GROUP_B')} v3.14.0+Returns a string Collection of emails of the members of the given groups. Users without emails are ignored.
${isUserInAllGroups(userId, groupKeys)}Returns true if the given userId is in the provided groups with the given keys.
${isUserInAnyGroup(userId, groupKeys)}Returns true if the given userId is in the provided groups with the given keys.
${isUserInNoGroup(userId, groupKeys)}Returns true if the given userId is in none of the provided groups with the given keys.
${userInfo:findUserInfo(property, findUser(authenticatedUserId))}Returns a given user infoproperty of the current user.
${userInfo:findBooleanUserInfo(property, findUser(authenticatedUserId))}Returns a given boolean user info property of the current user.

Sequence Models

When working with sequence models, there is often a need to generate these numbers in e.g. names of activities of BPMN or CMMN instances. The following functions are available to do that:

ExpressionDescription
${seq:nextNumber(<parameter>, sequenceDefinitionKey)Returns the next number of the sequence. The parameter should be a runtime object that has access to the current variables, such as a process instance, a case instance, an execution, a task, a plan item instance, etc.. The sequenceDefinitionKey should match the key set in the sequence model.
${seq:next(<parameter>, sequenceDefinitionKey)Similar as the previous one, but also takes into account the configuration settings for formatting that have been set in the model.

Configuration Service

The configuration service allows to access configuration properties (for example those which are set in application.properties file or similar.) In expressions, this service is useful as it allows changing behavior based on environment specific properties (e.g. DEV, TEST, PROD env).

ExpressionDescription
${propertyConfigurationService.getProperty(key, defaultValue)}returns the string value of a configuration property.
${propertyConfigurationService.getBooleanProperty(key, defaultValue)}returns the boolean value of a configuration property.
${propertyConfigurationService.getIntegerProperty(key, defaultValue)}returns the integer value of a configuration property.

Auth Tokens

This advanced expression is useful when working with external services and OAuth. Obviously storing the credentials hard-coded in expressions is a no-go. This expression will help with that:

  • ${flwAuthTokenUtils.getAccessToken('externalServiceId')} (note: resolves an access token for the given external service id, when a Spring Security OAuth2 Client configuration is available for the given externalServiceId)

Collection Utils

The following options are for working with collections or list of ContentItem.

ExpressionDescription
${flwCollectionUtils.emptyNode()}Create an empty JSON object node.
${flwCollectionUtils.emptyList()}Create an empty Java List. The result should not be directly stored as a none transient variable.
${flwCollectionUtils.emptyMap()}Create an empty Java Map. The result should not be directly stored as a none transient variable.
${flwCollectionUtils.distinct(list)}Remove duplicate elements from a Java list. The result should only be stored as a none transient variable for ContentItems.
${flwCollectionUtils.listWithElements(itemOne, itemTwo, ...)}Creates a Java list with multiple elements. The result should only be stored as a none transient variable for ContentItem's.
${flwCollectionUtils.mergeCollections(collection1, collection2, ...)}Merges multiple Java collections to a single list. The result should only be stored as a none transient variable for ContentItem's.
caution

When using List or Map from Java, they will be stored as a serializable in the Flowable databases. This means, that they will be stored in the byte array table, and it might get inefficient for large amount of data. The only exception from this is for List of ContentItem.