### Question:
BundleFilterConcat implements BundleFilter { @Override public boolean filter(Bundle bundle) { StringBuilder sb = new StringBuilder(); boolean appendJoin = false; for (AutoField field : in) { if (appendJoin && (join != null)) { sb.append(join); } appendJoin = true; ValueObject v = field.getValue(bundle); if ((v != null) && v.getObjectType().equals(ValueObject.TYPE.ARRAY)) { ValueArray vArray = v.asArray(); boolean innerAppendJoin = false; for (ValueObject valueObject : vArray) { if (innerAppendJoin && (join != null)) { sb.append(join); } innerAppendJoin = true; sb.append(ValueUtil.asNativeString(valueObject)); } } else { sb.append(ValueUtil.asNativeString(v)); } } out.setValue(bundle, ValueFactory.create(sb.toString())); return true; }  @Override boolean filter(Bundle bundle);  }### Answer:
@Test public void basicJoin() throws Exception { BundleFilter concat = Configs.decodeObject(BundleFilterConcat.class, "in = [a, b], out = b, join = \", \""); Bundle bundle = new ListBundle(); BundleFilter setup = Configs.decodeObject( BundleFilter.class, "chain: [{from.const: hi, to: a}, {from.const: there, to: b}]"); setup.filter(bundle); concat.filter(bundle); assertEquals("hi, there", bundle.getValue(bundle.getFormat().getField("b")).toString()); }