The filter or criteria pattern needs to operate on a collection of data. Those that meet the criteria are kept and the remaining objects are returned and used by the next criteria.
That's what enables the chaining aspect.
It's like the filter function (the extension function on Iterable), you can chain multiple filters. but every filter will only operate on the sub list of objects that passed through the predicates.
In my case if the last criteria returns a non-empty list, that means we have some transactions that we cannot handle.
The chain of responsibility pattern is a good candidate. but I don't want to deal with the initial list for each parser. It could work but not efficient enough with a high volume of sms to operate on.
Thanks again Rygel for your suggestions. Why not review this part of the code together?!