const Value* listParser(AttributeParser start, AttributeParser parser, AttributeParser end, StringTokenizer& st, bool possiblyEmpty)
listParser(AttributeParser start, AttributeParser parser, AttributeParser end, StringTokenizer& st, bool possiblyEmpty)
const Value* listParser(AttributeParser start,			AttributeParser parser,			AttributeParser end,			StringTokenizer& st,			bool possiblyEmpty){  assert(parser != NULL);  ValueSequence* seq = new ValueSequence;  assert(seq != NULL);  unsigned mark = st.GetMark();  st.SkipSpaces();  if (!st.MoreTokens()) return NULL;  if (start != NULL) {    const Value* startValue = start(st);    if (startValue == NULL) {      st.SetMark(mark);      return NULL;    }    delete startValue;  }  const Value* p = parser(st);  while (p != NULL) {    seq->AddValue(p);    p = parser(st);  }  if (end != NULL) {    const Value* endValue = end(st);    if (endValue == NULL) {      st.SetMark(mark);      delete p;      return NULL;    }    delete endValue;  }  if (!possiblyEmpty && seq->IsEmpty()) return NULL;  const Value* res = new Value(seq);  return res;}