final char[] chars = value.toCharArray();
StringBuffer result = new StringBuffer(chars.length);
boolean haveEscape = false;
int state = PropertyLookupParser.EXPECT_DOLLAR;
final FastStack stack = new FastStack();
for (int i = 0; i < chars.length; i++)
{
final char c = chars[i];
if (haveEscape)
{
haveEscape = false;
if (state == PropertyLookupParser.EXPECT_CLOSE_BRACE ||
escapeMode == ESCAPE_MODE_ALL)
{
result.append(c);
}
else
{
if (c == openingBraceChar || c == closingBraceChar || c == escapeChar || c == markerChar)
{
result.append(c);
}
else
{
result.append(escapeChar);
result.append(c);
}
}
continue;
}
if ((state == PropertyLookupParser.EXPECT_DOLLAR || state == PropertyLookupParser.EXPECT_CLOSE_BRACE)
&& c == markerChar)
{
state = PropertyLookupParser.EXPECT_OPEN_BRACE;
continue;
}
if (state == PropertyLookupParser.EXPECT_CLOSE_BRACE && c == closingBraceChar)
{
final String columnName = result.toString();
result = (StringBuffer) stack.pop();
handleVariableLookup(result, parameters, columnName);
if (stack.isEmpty())
{
state = PropertyLookupParser.EXPECT_DOLLAR;
}
else
{
state = PropertyLookupParser.EXPECT_CLOSE_BRACE;
}
continue;
}
if (state == PropertyLookupParser.EXPECT_OPEN_BRACE)
{
if (c == openingBraceChar)
{
state = PropertyLookupParser.EXPECT_CLOSE_BRACE;
stack.push(result);
result = new StringBuffer(100);
continue;
}
result.append(markerChar);
if (stack.isEmpty())
{
state = PropertyLookupParser.EXPECT_DOLLAR;
}
else
{
state = PropertyLookupParser.EXPECT_CLOSE_BRACE;
}
// continue with adding the current char ..
}
if (c == escapeChar && escapeMode != ESCAPE_MODE_NONE)
{
haveEscape = true;
continue;
}
result.append(c);
}
if (state != PropertyLookupParser.EXPECT_DOLLAR)
{
while (stack.isEmpty() == false)
{
final String columnName = result.toString();
result = (StringBuffer) stack.pop();
result.append(markerChar);
if (state != PropertyLookupParser.EXPECT_OPEN_BRACE)
{
result.append(openingBraceChar);
result.append(columnName);