class DelimitedBuilder<T> {

		private final FlatFileItemWriterBuilder<T> parent;

		private final List<String> names = new ArrayList<>();

		private String delimiter = ",";

		private String quoteCharacter = "";

		private FieldExtractor<T> fieldExtractor;

		private Class<T> sourceType;

		protected DelimitedBuilder(FlatFileItemWriterBuilder<T> parent) {
			this.parent = parent;
		}

		/**
		 * Define the delimiter for the file.
		 * @param delimiter String used as a delimiter between fields.
		 * @return The instance of the builder for chaining.
		 * @see DelimitedLineAggregator#setDelimiter(String)
		 */
		public DelimitedBuilder<T> delimiter(String delimiter) {
			this.delimiter = delimiter;
			return this;
		}

		/**
		 * Specify the type of items from which fields will be extracted. This is used to
		 * configure the right {@link FieldExtractor} based on the given type (ie a record
		 * or a regular class).
		 * @param sourceType type of items from which fields will be extracted
		 * @return The current instance of the builder.
		 * @since 5.0
		 */
		public DelimitedBuilder<T> sourceType(Class<T> sourceType) {
			this.sourceType = sourceType;

			return this;
		}

		/**
		 * Define the quote character for each delimited field. Default is empty string.
		 * @param quoteCharacter String used as a quote for the aggregate.
		 * @return The instance of the builder for chaining.
		 * @see DelimitedLineAggregator#setQuoteCharacter(String)
		 * @since 5.1
		 */
		public DelimitedBuilder<T> quoteCharacter(String quoteCharacter) {
			this.quoteCharacter = quoteCharacter;
			return this;
		}

		/**
		 * Names of each of the fields within the fields that are returned in the order
		 * they occur within the delimited file. These names will be used to create a
		 * {@link BeanWrapperFieldExtractor} only if no explicit field extractor is set
		 * via {@link DelimitedBuilder#fieldExtractor(FieldExtractor)}.
		 * @param names names of each field
		 * @return The parent {@link FlatFileItemWriterBuilder}
		 * @see BeanWrapperFieldExtractor#setNames(String[])
		 */
		public FlatFileItemWriterBuilder<T> names(String... names) {
			this.names.addAll(Arrays.asList(names));
			return this.parent;
		}

		/**
		 * Set the {@link FieldExtractor} to use to extract fields from each item.
		 * @param fieldExtractor to use to extract fields from each item
		 * @return The parent {@link FlatFileItemWriterBuilder}
		 */
		public FlatFileItemWriterBuilder<T> fieldExtractor(FieldExtractor<T> fieldExtractor) {
			this.fieldExtractor = fieldExtractor;
			return this.parent;
		}

		public DelimitedLineAggregator<T> build() {<FILL_FUNCTION_BODY>}

	}

			Assert.isTrue((this.names != null && !this.names.isEmpty()) || this.fieldExtractor != null,
					"A list of field names or a field extractor is required");

			DelimitedLineAggregator<T> delimitedLineAggregator = new DelimitedLineAggregator<>();
			if (this.delimiter != null) {
				delimitedLineAggregator.setDelimiter(this.delimiter);
			}
			if (StringUtils.hasLength(this.quoteCharacter)) {
				delimitedLineAggregator.setQuoteCharacter(this.quoteCharacter);
			}

			if (this.fieldExtractor == null) {
				if (this.sourceType != null && this.sourceType.isRecord()) {
					this.fieldExtractor = new RecordFieldExtractor<>(this.sourceType);
				}
				else {
					BeanWrapperFieldExtractor<T> beanWrapperFieldExtractor = new BeanWrapperFieldExtractor<>();
					beanWrapperFieldExtractor.setNames(this.names.toArray(new String[this.names.size()]));
					try {
						beanWrapperFieldExtractor.afterPropertiesSet();
						this.fieldExtractor = beanWrapperFieldExtractor;
					}
					catch (Exception e) {
						throw new IllegalStateException("Unable to initialize DelimitedLineAggregator", e);
					}
				}
			}

			delimitedLineAggregator.setFieldExtractor(this.fieldExtractor);
			return delimitedLineAggregator;
		
<no_super_class>