}
// Within the encapsulated expressions
else {
// Create a collection representation of the encapsulated expression(s)
CollectionExpression collectionExpression = helper.buildCollectionExpression(expression);
boolean hasComma = false;
boolean previousHasComma = false;
// Determine the maximum children count, it is possible the query contains more children
// than the expession's grammar would actually allow. The content assist will only
// provide assistance from the first child to the last allowed child
int childrenCount = collectionExpression.childrenSize();
int count = Math.min(childrenCount, helper.maxCollectionSize(expression));
// Iterate through each child of the collection
for (int index = 0; index < count; index++) {
Expression child = collectionExpression.getChild(index);
int childLength = 0;
// At the beginning of the child
if (position == length) {
helper.addTheBeginningOfChild(expression, collectionExpression, index, hasComma);
break;
}
// Each expression within the collection has to be separated by a comma, the previous
// expression and the expression at the current index are not separated by a comma
// Example: "SELECT e FROM Employee e GROUP" <- [ "Employee e", "GROUP" ]
else if ((index > 0) && !hasComma) {
length += child.getLength();
// At the end of the child
if (position == length) {
helper.addAtTheEndOfChild(expression, collectionExpression, index, hasComma, false);
break;
}
// To be valid, each child has to be separated by a comma,
// ask the helper if it should continue with the next child
if (!helper.canContinue(expression, collectionExpression, index)) {
break;
}
// Special case when reaching the end of the collection
else if (index + 1 == count) {
helper.addAtTheEndOfChild(expression, collectionExpression, index, hasComma, false);
}
}
else {
childLength = child.getLength();
// At the end of the child
if ((position == length + childLength) ||
(virtualSpace && (position == length + childLength + SPACE_LENGTH))) {
helper.addAtTheEndOfChild(expression, collectionExpression, index, hasComma, virtualSpace);
break;
}
}
// Now add the child's length and length used by the comma and space
length += childLength;
// Move after the comma
previousHasComma = hasComma;
hasComma = collectionExpression.hasComma(index);
if (hasComma) {
// Two items were not separated by a comma and the next one is, this is invalid
if ((index > 0) && !previousHasComma) {
return;
}
length++;
// After the comma, add the proposals
if (position == length) {
helper.addTheBeginningOfChild(expression, collectionExpression, index + 1, hasComma);
break;
}
}
// Move after the space that follows the comma
if (collectionExpression.hasSpace(index)) {
length++;
// At the end of the child
if (!hasComma && (position == length)) {
helper.addAtTheEndOfChild(expression, collectionExpression, index, hasComma, true);