package common.sql;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.JUnitCore;

import common.sql.LineParsedNodeList;

public class TestLineParsedNodeList {

	/**
	 * main
	 * @param args arguments
	 */
	public static void main(final String... args) {
		JUnitCore.main(TestLineParsedNodeList.class.getName());
	}

	@Test
	public void 日付必須でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("UPDATE_DATETIME = /*:DateTime*/TO_DATE('20091225','YYYYMMDD'),");

		Map<String, Object> map = new HashMap<>();
		map.put("DateTime", "20100118");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("UPDATE_DATETIME = ? , \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Date.class, list.get(0).getClass());
		Assert.assertEquals("2010-01-18", list.get(0).toString());
	}

	@Test
	public void 数値デフォルトでパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("OFFSET ((/*?Page*/1 - 1) * /*?Line*/20 ) LIMIT /*?Line*/20 \n");

		Map<String, Object> map = new HashMap<>();
		map.put("Page", "1");
		map.put("Line", "30");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("OFFSET ( ( ? - 1 ) * ? ) LIMIT ? \n", sut.build(map, list));
		Assert.assertEquals(3, list.size());
		Assert.assertEquals(new BigDecimal(1), list.get(0));
		Assert.assertEquals(new BigDecimal(30), list.get(1));
		Assert.assertEquals(new BigDecimal(30), list.get(2));
	}

	@Test
	public void IN句内複数中単一文字列デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AAA IN(/*?dtGyomu*/'200901', '20', '30')");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AAA IN( ?, '20', '30' ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("200901", list.get(0));
	}

	@Test
	public void IN句内複数中単一数値デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN (/*?Shubetsu*/1,2,3,4)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ?,2,3,4 ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(BigDecimal.ONE, list.get(0));
	}

	@Test
	public void IN句内複数中単一数値可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN (/*$Shubetsu*/1,2,3,4)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void OR連結IN句内一方数値可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU IN (/*$Shubetsu*/1) OR SHUBETSU IN (2,3,4))");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND (SHUBETSU IN ( 2,3,4 )) \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void IN句内複数中単一数値可変で別行パラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND SHUBETSU IN (2,3,4 \n, /*$Shubetsu*/1\n)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND SHUBETSU IN (2,3,4 \n) \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void IN句内複数中単一数値可変で別行パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND SHUBETSU IN (2,3,4 \n, /*$Shubetsu*/1\n)");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", Integer.valueOf(1));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND SHUBETSU IN (2,3,4 \n, ? \n) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(Integer.valueOf(1), list.get(0));
	}

	@Test
	public void IN句内全て文字列デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN (/*?Shubetsu1*/'', /*?Shubetsu2*/'', /*?Shubetsu3*/'', /*?Shubetsu4*/'')");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ?, ?, ?, ? ) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("", list.get(0));
		Assert.assertEquals("", list.get(1));
		Assert.assertEquals("", list.get(2));
		Assert.assertEquals("", list.get(3));
	}

	@Test
	public void IN句内全て文字列デフォルトでパラメータなしカンマ密着() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN (/*?Shubetsu1*/'',/*?Shubetsu2*/'',/*?Shubetsu3*/'',/*?Shubetsu4*/'')");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ?,?,?,? ) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("", list.get(0));
		Assert.assertEquals("", list.get(1));
		Assert.assertEquals("", list.get(2));
		Assert.assertEquals("", list.get(3));
	}

	@Test
	public void IN句内全て文字列可変でパラメータ一部あり() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN (/*$Shubetsu1*/'',/*$Shubetsu2*/'',/*$Shubetsu3*/'',/*$Shubetsu4*/'')");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", "A");
		map.put("Shubetsu3", "B");
		map.put("Shubetsu4", "C");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void IN句内全て文字列必須でパラメータ一部あり() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN (/*:Shubetsu1*/'',/*:Shubetsu2*/'',/*:Shubetsu3*/'',/*:Shubetsu4*/'')");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", "A");
		map.put("Shubetsu3", "B");
		map.put("Shubetsu4", "C");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ?,?,?,? ) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals(null, list.get(1));
		Assert.assertEquals("B", list.get(2));
		Assert.assertEquals("C", list.get(3));
	}

	@Test
	public void IN句内単一文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND SHUBETSU IN (SELECT A.SB FROM SHUBE A WHERE A.S IN (/*$Shubetsu1*/'') AND A.VERSION > 0)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void IN句内単一文字列必須でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND SHUBETSU IN (SELECT A.SB FROM SHUBE A WHERE A.S IN (/*:Shubetsu1*/'') AND A.VERSION > 0)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND SHUBETSU IN ( SELECT A.SB FROM SHUBE A WHERE A.S IN ( ? ) AND A.VERSION > 0 ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertNull(list.get(0));
	}

	@Test
	public void IN句内単一文字列可変で配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND SHUBETSU IN (SELECT A.SB FROM SHUBE A WHERE A.S IN (/*$Shubetsu1*/'') AND A.VERSION > 0)");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"X", "Y", "Z"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND SHUBETSU IN ( SELECT A.SB FROM SHUBE A WHERE A.S IN ( ?,?,? ) AND A.VERSION > 0 ) \n", sut.build(map, list));
		Assert.assertEquals(3, list.size());
		Assert.assertEquals("X", list.get(0));
		Assert.assertEquals("Y", list.get(1));
		Assert.assertEquals("Z", list.get(2));
	}

	@Test
	public void IN句内単一文字列可変でリストパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND SHUBETSU IN (SELECT A.SB FROM SHUBE A WHERE A.S IN (/*$Shubetsu1*/'') AND A.VERSION > 0)");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new ArrayList<>(Arrays.asList("X", "Y", "Z")));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND SHUBETSU IN ( SELECT A.SB FROM SHUBE A WHERE A.S IN ( ?,?,? ) AND A.VERSION > 0 ) \n", sut.build(map, list));
		Assert.assertEquals(3, list.size());
		Assert.assertEquals("X", list.get(0));
		Assert.assertEquals("Y", list.get(1));
		Assert.assertEquals("Z", list.get(2));
	}

	@Test
	public void 複数項目IN句内全て文字列デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) NOT IN (/*?Shubetsu1*//*?Shubetsu2*/('A', 'B'))");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SHUBETSU1, SHUBETSU2 ) NOT IN ( ( ?,? ) ) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("B", list.get(1));
	}

	@Test
	public void 複数項目IN句内全て文字列デフォルトでパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) IN (/*?Shubetsu1*//*?Shubetsu2*/('',''))");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", "A");
		map.put("Shubetsu2", "C");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SHUBETSU1, SHUBETSU2 ) IN ( ( ?,? ) ) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("C", list.get(1));
	}

	@Test
	public void 複数項目IN句内単一文字列デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) NOT IN (/*?Shubetsu1*//*?Shubetsu2*/('A', 'B'), ('C', 'D'))");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SHUBETSU1, SHUBETSU2 ) NOT IN ( ( ?,? ) , ( 'C', 'D' ) ) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("B", list.get(1));
	}

	@Test
	public void 複数項目IN句内全て文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) IN ( /*$Shubetsu1*//*$Shubetsu2*/('','') )");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 複数項目IN句内全て文字列可変で配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) IN (/*$Shubetsu1*//*$Shubetsu2*/('',''))");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"A", "B", "C"});
		map.put("Shubetsu2", new String[]{"D", "E", "F"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SHUBETSU1, SHUBETSU2 ) IN ( ( ?,? ),( ?,? ),( ?,? ) ) \n", sut.build(map, list));
		Assert.assertEquals(6, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("D", list.get(1));
		Assert.assertEquals("B", list.get(2));
		Assert.assertEquals("E", list.get(3));
		Assert.assertEquals("C", list.get(4));
		Assert.assertEquals("F", list.get(5));
	}

	@Test
	public void 複数項目IN句内全て文字列可変でリストパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) IN (/*$Shubetsu1*//*$Shubetsu2*/('',''))");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new ArrayList<>(Arrays.asList("A", "B", "C")));
		map.put("Shubetsu2", new ArrayList<>(Arrays.asList("D", "E", "F")));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SHUBETSU1, SHUBETSU2 ) IN ( ( ?,? ),( ?,? ),( ?,? ) ) \n", sut.build(map, list));
		Assert.assertEquals(6, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("D", list.get(1));
		Assert.assertEquals("B", list.get(2));
		Assert.assertEquals("E", list.get(3));
		Assert.assertEquals("C", list.get(4));
		Assert.assertEquals("F", list.get(5));
	}

	@Test
	public void 複数項目IN句内複数中単一文字列可変で別行パラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) IN (('1', '2')\n , /*$Shubetsu1*//*$Shubetsu2*/('','') \n)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND (SHUBETSU1, SHUBETSU2) IN (('1', '2') \n) \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 複数項目IN句内複数中単一文字列可変で別行配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) IN (('1', '2')\n , /*$Shubetsu1*//*$Shubetsu2*/('','') \n)");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"A", "B", "C"});
		map.put("Shubetsu2", new String[]{"D", "E", "F"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND (SHUBETSU1, SHUBETSU2) IN (('1', '2') \n, ( ?,? ),( ?,? ),( ?,? ) \n) \n", sut.build(map, list));
		Assert.assertEquals(6, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("D", list.get(1));
		Assert.assertEquals("B", list.get(2));
		Assert.assertEquals("E", list.get(3));
		Assert.assertEquals("C", list.get(4));
		Assert.assertEquals("F", list.get(5));
	}

	@Test
	public void 複数項目IN句内全て文字列必須でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) NOT IN ( /*:Shubetsu1*//*:Shubetsu2*/('A', 'B'))");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SHUBETSU1, SHUBETSU2 ) NOT IN ( ( ?,? ) ) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals(null, list.get(0));
		Assert.assertEquals(null, list.get(1));
	}

	@Test
	public void 複数項目IN句内全て文字列必須で配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND (SHUBETSU1, SHUBETSU2) IN (/*:Shubetsu1*//*:Shubetsu2*/('',''))");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"A", "B"});
		map.put("Shubetsu2", new String[]{"C", "D"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SHUBETSU1, SHUBETSU2 ) IN ( ( ?,? ),( ?,? ) ) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("C", list.get(1));
		Assert.assertEquals("B", list.get(2));
		Assert.assertEquals("D", list.get(3));
	}


	@Test
	public void IN句全体に文字列デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*?Shubetsu*/('1','2','3','4')");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ?,?,?,? ) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("1", list.get(0));
		Assert.assertEquals("2", list.get(1));
		Assert.assertEquals("3", list.get(2));
		Assert.assertEquals("4", list.get(3));
	}

	@Test
	public void IN句全体に文字列デフォルトでパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*?Shubetsu*/('1','2','3','4')");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", "A");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ? ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("A", list.get(0));
	}

	@Test
	public void IN句全体に文字列デフォルトで配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*?Shubetsu*/('1','2','3','4')");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", new String[]{"A", "B"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ?,? ) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("A", list.get(0));
		Assert.assertEquals("B", list.get(1));
	}

	@Test
	public void IN句全体に数値デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*?Shubetsu*/(1,2,3,4)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ?,?,?,? ) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals(BigDecimal.ONE, list.get(0));
		Assert.assertEquals(new BigDecimal(2), list.get(1));
		Assert.assertEquals(new BigDecimal(3), list.get(2));
		Assert.assertEquals(new BigDecimal(4), list.get(3));
	}

	@Test
	public void IN句全体に数値必須でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*:Shubetsu*/(1,2,3,4)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ? ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(null, list.get(0));
	}

	@Test
	public void IN句全体に数値必須でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*:Shubetsu*/(1,2,3,4)");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", Integer.valueOf(10));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ? ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(new BigDecimal(10), list.get(0));
	}

	@Test
	public void IN句全体に数値可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*$Shubetsu*/(1,2,3,4)");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void IN句全体に数値可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("CASE WHEN SHUBETSU NOT IN /*$Shubetsu*/(1,2,3,4)");

		Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", Integer.valueOf(10));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("CASE WHEN SHUBETSU NOT IN ( ? ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(new BigDecimal(10), list.get(0));
	}

	@Test
	public void IN句内文字列デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AAA IN(/*?dtGyomu*/'200901')");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AAA IN( ? ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("200901", list.get(0));
	}

	@Test
	public void 括弧内複数中単一文字列必須でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("COALESCE(/*:dtShuryo*/'0000', '0000') AS DT_TOROKU_YM, \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtShuryo", "9876");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("COALESCE( ?, '0000' ) AS DT_TOROKU_YM, \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("9876", list.get(0));
	}

	@Test
	public void 括弧内複数中途中文字列必須でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("DECODE (DT_KOJO_YM, /*:dtKojo*/'200901', '1', '0') AS FG_TOU, \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "201001");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("DECODE ( DT_KOJO_YM, ?, '1', '0' ) AS FG_TOU, \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("201001", list.get(0));
	}

	@Test
	public void 括弧内複数中途中文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("DECODE (DT_KOJO_YM, /*$dtKojo*/'200901', '1', '0') AS FG_TOU, \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 括弧内複数中途中文字列可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("DECODE (DT_KOJO_YM, /*$dtKojo*/'200901', '1', '0') AS FG_TOU, \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "201001");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("DECODE ( DT_KOJO_YM, ?, '1', '0' ) AS FG_TOU, \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("201001", list.get(0));
	}

	@Test
	public void 文字列可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("OR DT_KOJO_YM <= /*$dtKojo*/'200901' \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "201001");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("OR DT_KOJO_YM <= ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("201001", list.get(0));
	}

	@Test
	public void 文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("OR DT_KOJO_YM <= /*$dtKojo*/'200901' \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void IN句内文字列可変で配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND DT_KOJO_YM IN (/*$dtKojo*/'') \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", new String[]{"", "asdf"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND DT_KOJO_YM IN ( ? ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("asdf", list.get(0));
	}

	@Test
	public void 文字列置換でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZZ DESC, YYYY, XXXX; \n");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("ORDER BY ZZZ DESC, YYYY, XXXX \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 文字列行末置換でシングルクォートパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZZ DESC, 'YYYY', XXXX \n");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("ORDER BY ZZZ DESC, YYYY, XXXX \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 文字列行末置換でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("ORDER BY AAA, BBB DESC, CCCC \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 文字列行末置換で配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", new String[]{"ZZZ DESC", "'YYYY'", "XXXX"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("ORDER BY ZZZ DESC, YYYY, XXXX \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 文字列対象置換でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("FROM /*@YmTable/YYYYMM*/TR_MEISAI_YYYYMM WHERE AAA = 'ABC' \n");

		Map<String, Object> map = new HashMap<>();
		map.put("YmTable", "201202");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("FROM TR_MEISAI_201202 WHERE AAA = 'ABC' \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 文字列対象置換で配列パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("FROM /*@YmTable1/YYYYMM*/TR_MEISAI_YYYYMM \n");

		Map<String, Object> map = new HashMap<>();
		map.put("YmTable1", new String[]{"201202", "'YYYY'", "XXXX"});
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("FROM TR_MEISAI_201202, YYYY, XXXX \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 文字列対象置換でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("FROM /*@YmTable/YYYYMM*/TR_MEISAI_YYYYMM \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("FROM TR_MEISAI_YYYYMM \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 誤文字列対象置換でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("FROM /*@YmTable/YYYYMM*/TR_MEISAI_201201 \n");

		Map<String, Object> map = new HashMap<>();
		map.put("YmTable", "201202");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("FROM TR_MEISAI_201201 \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 文字列対象文字列内置換でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("FROM TR_MEISAI_201201 WHERE ABC LIKE '%' || /*@YmTable/YYYYMM*/'YYYYMM' || '%' \n");

		Map<String, Object> map = new HashMap<>();
		map.put("YmTable", "201202");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("FROM TR_MEISAI_201201 WHERE ABC LIKE '%' || '201202' || '%' \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 数値可変でカンマパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("OR NO_KOJO <= /*$dtKojo*/200901 \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "123,456,789");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("OR NO_KOJO <= ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(new BigDecimal("123456789"), list.get(0));
	}

	@Test
	public void 数値可変でカンマ小数点パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("OR NO_KOJO <= /*$dtKojo*/200901 \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "123,456,789.001");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("OR NO_KOJO <= ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(new BigDecimal("123456789.001"), list.get(0));
	}

	@Test
	public void 数値可変でカンマ英字パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("OR NO_KOJO <= /*$dtKojo*/200901 \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "abcd123,50L");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("OR NO_KOJO <= ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(null, list.get(0));
	}

	@Test
	public void IN句内数値デフォルトでCSVパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AAA IN(/*?dtGyomu*/200)");

		Map<String, Object> map = new HashMap<>();
		map.put("dtGyomu", "300, 400");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AAA IN( ?,? ) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals(new BigDecimal("300"), list.get(0));
		Assert.assertEquals(new BigDecimal("400"), list.get(1));
	}

	@Test
	public void LIKE句文字列可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND DT_KOJO LIKE /*$dtKojo*/'%AAA%' \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZZZ");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND DT_KOJO LIKE ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("%ZZZZ%", list.get(0));
	}

	@Test
	public void LIKE句文字列可変でワイルドカードパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND DT_KOJO LIKE /*$dtKojo*/'%AAA%' \n");

		Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZ%%ZZ");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND DT_KOJO LIKE ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("%ZZ%%ZZ%", list.get(0));
	}

	@Test
	public void 日付可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND date_trunc('day', TRN.TS_TORIKOMI) = /*$DateTime*/TO_DATE('20100805','YYYYMMDD') \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 日付可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND date_trunc('day', TRN.TS_TORIKOMI) = /*$DateTime*/TO_DATE('20100805','YYYYMMDD') \n");

		Map<String, Object> map = new HashMap<>();
		map.put("DateTime", new Timestamp(new Date().getTime()));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND date_trunc( 'day', TRN.TS_TORIKOMI ) = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
	}

	@Test
	public void 日付デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND TS_TORIKOMI = /*?DateTime*/TO_DATE('20100805','YYYYMMDD') \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND TS_TORIKOMI = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Date.class, list.get(0).getClass());
		Assert.assertEquals("2010-08-05", list.get(0).toString());
	}

	@Test
	public void 日時可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("AND TS_TOROKU <= /*$DtHenko*/TO_TIMESTAMP('99991231235959999','YYYYMMDDHH24MISSMS') \n");

		Map<String, Object> map = new HashMap<>();
		map.put("DtHenko", "20100805");
		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND TS_TOROKU <= ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Timestamp.class, list.get(0).getClass());
		Assert.assertEquals("2010-08-05 23:59:59.999", list.get(0).toString());
	}

	@Test
	public void WHERE句内数値可変文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("WHERE\n AAA = /*$dtGyomu*/200\n  AND BBB= /*$dtG*/'100'\nOFFSET 0");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("OFFSET 0 \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void WHERE句内数値可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("WHERE\n AAA = /*$dtGyomu*/200\nLIMIT 0");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("LIMIT 0 \n", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void WHERE句内可変で一部パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"WHERE \n"
			+ "AAA = /*$dtGyomu*/200 \n"
			+ "AND DT_DATTAI_YM = /*$DtDattaiYm*/'aaa' \n"
			+ "AND (MN_PAY > /*$mnPay*/3 OR DT_DATTAI_YM >= /*$dtGyomu*/'200901' )");

		Map<String, Object> map = new HashMap<>();
		map.put("mnPay", Integer.valueOf(3));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("WHERE \n(MN_PAY > ?) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(Integer.valueOf(3), list.get(0));
	}

	@Test
	public void WHERE句内中間パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"WHERE \n"
			+ "AAA = /*$dtGyomu*/200 \n"
			+ "AND DT_DATTAI_YM = /*$DtDattaiYm*/'aaa' \n"
			+ "AND (MN_PAY > /*$mnPay*/3 OR DT_DATTAI_YM >= /*$dtGyomu*/'200901' )");

		Map<String, Object> map = new HashMap<>();
		map.put("DtDattaiYm", "aaaaa");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("WHERE \nDT_DATTAI_YM = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("aaaaa", list.get(0));
	}

	@Test
	public void AND_OR句文字列可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND  ((/*$StShoninSearch*/'0' = '0' AND TS_SHONIN IS NULL) OR (/*$StShoninSearch*/'0' = '1' AND TS_SHONIN IS NOT NULL))");

		Map<String, Object> map = new HashMap<>();
		map.put("StShoninSearch", "0");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ((? = '0' AND TS_SHONIN IS NULL) OR (? = '1' AND TS_SHONIN IS NOT NULL)) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
	}

	@Test
	public void AND_OR句文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND  ((/*$StShoninSearch*/'0' = '0' AND TS_SHONIN IS NULL) OR (/*$StShoninSearch*/'0' = '1' AND TS_SHONIN IS NOT NULL))");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void AND_OR句文字列可変でパラメータありOR後除去() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND ((KB_URIAGE_KEIHI = '1' AND KB_URIAGE_KEIHI = /*$KbUriageSearch*/'111') OR (KB_URIAGE_KEIHI = '2' AND KB_URIAGE_KEIHI = /*$KbKeihiSearch*/'11'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbUriageSearch", "123");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ((KB_URIAGE_KEIHI = '1' AND KB_URIAGE_KEIHI = ?)) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("123", list.get(0));
	}

	@Test
	public void AND_OR句文字列可変でパラメータありOR前除去() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND ((KB_URIAGE_KEIHI = '1' AND KB_URIAGE_KEIHI = /*$KbUriageSearch*/'111') OR (KB_URIAGE_KEIHI = '2' AND KB_URIAGE_KEIHI = /*$KbKeihiSearch*/'11'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKeihiSearch", "456");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ((KB_URIAGE_KEIHI = '2' AND KB_URIAGE_KEIHI = ?)) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("456", list.get(0));
	}

	@Test
	public void AND_OR句複数文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND ((CD_DR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_DR_HOJO = /*$CdHojoSearch*/'DD66') OR (CD_CR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_CR_HOJO = /*$CdHojoSearch*/'DD66'))");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void AND_OR句複数文字列可変でパラメータありOR内AND後除去() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND ((CD_DR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_DR_HOJO = /*$CdHojoSearch*/'DD66') OR (CD_CR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_CR_HOJO = /*$CdHojoSearch*/'DD66'))");

		Map<String, Object> map = new HashMap<>();
		map.put("CdKamokuSearch", "123");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ((CD_DR_KAMOKU = ?) OR (CD_CR_KAMOKU = ?)) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("123", list.get(0));
		Assert.assertEquals("123", list.get(1));
	}

	@Test
	public void AND_OR句複数文字列可変でパラメータありOR内AND前除去() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND ((CD_DR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_DR_HOJO = /*$CdHojoSearch*/'DD66') OR (CD_CR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_CR_HOJO = /*$CdHojoSearch*/'DD66'))");

		Map<String, Object> map = new HashMap<>();
		map.put("CdHojoSearch", "333");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ((CD_DR_HOJO = ?) OR (CD_CR_HOJO = ?)) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("333", list.get(0));
		Assert.assertEquals("333", list.get(1));
	}

	@Test
	public void AND_OR句複数文字列可変でパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND ((CD_DR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_DR_HOJO = /*$CdHojoSearch*/'DD66') OR (CD_CR_KAMOKU = /*$CdKamokuSearch*/'CC77' AND CD_CR_HOJO = /*$CdHojoSearch*/'DD66'))");

		Map<String, Object> map = new HashMap<>();
		map.put("CdKamokuSearch", "123");
		map.put("CdHojoSearch", "333");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ((CD_DR_KAMOKU = ? AND CD_DR_HOJO = ?) OR (CD_CR_KAMOKU = ? AND CD_CR_HOJO = ?)) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("123", list.get(0));
		Assert.assertEquals("333", list.get(1));
		Assert.assertEquals("123", list.get(2));
		Assert.assertEquals("333", list.get(3));
	}

	@Test
	public void 文字列必須でパラメータあり前置() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND (SELECT MIN(CD) FROM MS_CODE WHERE 'SHOHIZEI' = CD_SBT AND /*:DdShimebi*/'' <= CD AND 0 < VERSION) = CM.CODE");

		Map<String, Object> map = new HashMap<>();
		map.put("DdShimebi", "20101010");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ( SELECT MIN( CD ) FROM MS_CODE WHERE 'SHOHIZEI' = CD_SBT AND ? <= CD AND 0 < VERSION ) = CM.CODE \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("20101010", list.get(0));
	}

	@Test
	public void 文字列必須でパラメータあり後置() {
		LineParsedNodeList sut = new LineParsedNodeList(
			"AND CM.CODE =(SELECT MIN(CD) FROM MS_CODE WHERE 'SHOHIZEI' = CD_SBT AND /*:DdShimebi*/'' <= CD AND 0 < VERSION)");

		Map<String, Object> map = new HashMap<>();
		map.put("DdShimebi", "20101010");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND CM.CODE =( SELECT MIN( CD ) FROM MS_CODE WHERE 'SHOHIZEI' = CD_SBT AND ? <= CD AND 0 < VERSION ) \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals("20101010", list.get(0));
	}

	@Test
	public void 相対日付デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND TS_TOROKU = /*?DtHenko*/TO_DATE('昨日','YYYYMMDD') \n");

		Map<String, Object> map = new HashMap<>();
		Calendar cl = Calendar.getInstance();
		cl.add(Calendar.DATE,-1);
		cl.set(Calendar.HOUR, 0);
		cl.set(Calendar.MINUTE, 0);
		cl.set(Calendar.SECOND, 0);

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND TS_TOROKU = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Date.class, list.get(0).getClass());
		Assert.assertEquals(new java.sql.Date(cl.getTimeInMillis()).toString(), list.get(0).toString());
	}

	@Test
	public void 囲み内日付デフォルトでパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("--<KbHenko\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

		Map<String, Object> map = new HashMap<>();
		map.put("KbHenko", "1");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND TS_TOROKU = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Date.class, list.get(0).getClass());
		Assert.assertEquals("2011-04-04", list.get(0).toString());
	}

	@Test
	public void 囲み内日付デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("--<KbHenko\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

		Map<String, Object> map = new HashMap<>();

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 囲み内日付デフォルトで比較正パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("--<KbHenko 10\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

		Map<String, Object> map = new HashMap<>();
		map.put("KbHenko", "10");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND TS_TOROKU = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Date.class, list.get(0).getClass());
		Assert.assertEquals("2011-04-04", list.get(0).toString());
	}

	@Test
	public void 囲み内日付デフォルトで比較誤パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("--<KbHenko 10\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

		Map<String, Object> map = new HashMap<>();
		map.put("KbHenko", "1");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void 否定囲み内日付デフォルトで比較パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("--<!KbKomoku 1\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku", "10");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND TS_TOROKU = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Date.class, list.get(0).getClass());
		Assert.assertEquals("2011-04-04", list.get(0).toString());
	}

	@Test
	public void 否定囲み内日付デフォルトで複数比較パラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList("--<!KbKomoku 1 2\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku", null);

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND TS_TOROKU = ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(java.sql.Date.class, list.get(0).getClass());
		Assert.assertEquals("2011-04-04", list.get(0).toString());
	}

	@Test
	public void AND_OR句内LIKE句複数文字列可変でパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList("AND ((KB.KOMOKU LIKE /*$KbKomoku1*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku2*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku3*/'%A%') "
				+ " OR (KK.KOMOKU LIKE /*$KbKomoku1*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku2*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku3*/'%C%'))");

		Map<String, Object> map = new HashMap<>();

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("", sut.build(map, list));
		Assert.assertEquals(0, list.size());
	}

	@Test
	public void AND_OR句内LIKE句複数文字列可変で１パラメータあり１() {
		LineParsedNodeList sut = new LineParsedNodeList("AND ((KB.KOMOKU LIKE /*$KbKomoku1*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku2*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku3*/'%A%') "
				+ " OR (KK.KOMOKU LIKE /*$KbKomoku1*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku2*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku3*/'%C%'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku1", "KBUNKB");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND ((KB.KOMOKU LIKE ?) OR (KK.KOMOKU LIKE ?)) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("%KBUNKB%", list.get(0));
		Assert.assertEquals("%KBUNKB%", list.get(1));
	}

	@Test
	public void AND_OR句内LIKE句複数文字列可変で１パラメータあり２() {
		LineParsedNodeList sut = new LineParsedNodeList("AND ((KB.KOMOKU LIKE /*$KbKomoku1*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku2*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku3*/'%A%') "
				+ " OR (KK.KOMOKU LIKE /*$KbKomoku1*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku2*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku3*/'%C%'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku2", "KBUNKBKBUNKB");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND ((KB.KOMOKU LIKE ?) OR (KK.KOMOKU LIKE ?)) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(0));
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(1));
	}

	@Test
	public void AND_OR句内LIKE句複数文字列可変で１パラメータあり３() {
		LineParsedNodeList sut = new LineParsedNodeList("AND ((KB.KOMOKU LIKE /*$KbKomoku1*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku2*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku3*/'%A%') "
				+ " OR (KK.KOMOKU LIKE /*$KbKomoku1*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku2*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku3*/'%C%'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku3", "KBUNKBKBUNKBKBUNKBKBUNKB");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND ((KB.KOMOKU LIKE ?) OR (KK.KOMOKU LIKE ?)) \n", sut.build(map, list));
		Assert.assertEquals(2, list.size());
		Assert.assertEquals("%KBUNKBKBUNKBKBUNKBKBUNKB%", list.get(0));
		Assert.assertEquals("%KBUNKBKBUNKBKBUNKBKBUNKB%", list.get(1));
	}

	@Test
	public void AND_OR句内LIKE句複数文字列可変で２パラメータあり１() {
		LineParsedNodeList sut = new LineParsedNodeList("AND ((KB.KOMOKU LIKE /*$KbKomoku1*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku2*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku3*/'%A%') "
				+ " OR (KK.KOMOKU LIKE /*$KbKomoku1*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku2*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku3*/'%C%'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku1", "KBUNKB");
		map.put("KbKomoku2", "KBUNKBKBUNKB");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND ((KB.KOMOKU LIKE ? AND KB.KOMOKU LIKE ?) OR (KK.KOMOKU LIKE ? AND KK.KOMOKU LIKE ?)) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("%KBUNKB%", list.get(0));
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(1));
		Assert.assertEquals("%KBUNKB%", list.get(2));
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(3));
	}

	@Test
	public void AND_OR句内LIKE句複数文字列可変で２パラメータあり２() {
		LineParsedNodeList sut = new LineParsedNodeList("AND ((KB.KOMOKU LIKE /*$KbKomoku1*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku2*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku3*/'%A%') "
				+ " OR (KK.KOMOKU LIKE /*$KbKomoku1*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku2*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku3*/'%C%'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku2", "KBUNKB");
		map.put("KbKomoku3", "KBUNKBKBUNKB");

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("AND ((KB.KOMOKU LIKE ? AND KB.KOMOKU LIKE ?) OR (KK.KOMOKU LIKE ? AND KK.KOMOKU LIKE ?)) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("%KBUNKB%", list.get(0));
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(1));
		Assert.assertEquals("%KBUNKB%", list.get(2));
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(3));
	}

	@Test
	public void AND_OR句内LIKE句複数文字列可変で２パラメータあり３() {
		LineParsedNodeList sut = new LineParsedNodeList("AND ((KB.KOMOKU LIKE /*$KbKomoku1*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku2*/'%A%' AND KB.KOMOKU LIKE /*$KbKomoku3*/'%A%') "
				+ " OR (KK.KOMOKU LIKE /*$KbKomoku1*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku2*/'%B%' AND KK.KOMOKU LIKE /*$KbKomoku3*/'%C%'))");

		Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku1", "KBUNKB");
		map.put("KbKomoku3", "KBUNKBKBUNKB");
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("AND ((KB.KOMOKU LIKE ? AND KB.KOMOKU LIKE ?) OR (KK.KOMOKU LIKE ? AND KK.KOMOKU LIKE ?)) \n", sut.build(map, list));
		Assert.assertEquals(4, list.size());
		Assert.assertEquals("%KBUNKB%", list.get(0));
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(1));
		Assert.assertEquals("%KBUNKB%", list.get(2));
		Assert.assertEquals("%KBUNKBKBUNKB%", list.get(3));
	}

	@Test
	public void 複数文字列結合と数値デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList(" 'XX''X:' || /*?NoPage*/1 \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("'XX''X:' || ? \n", sut.build(map, list));
	}

	@Test
	public void 文字列結合と数値デフォルトでパラメータあり() {
		LineParsedNodeList sut = new LineParsedNodeList(" 'XXX:' || /*?NoPage*/1 -- :?$\n");

		Map<String, Object> map = new HashMap<>();
		map.put("NoPage", Integer.valueOf(3));
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("'XXX:' || ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(Integer.valueOf(3), list.get(0));
	}

	@Test
	public void 文字列結合と数値デフォルトでパラメータなし() {
		LineParsedNodeList sut = new LineParsedNodeList(" 'XXX:' || /*?NoPage*/1 \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("'XXX:' || ? \n", sut.build(map, list));
		Assert.assertEquals(1, list.size());
		Assert.assertEquals(new BigDecimal(1), list.get(0));
	}

	@Test
	public void ラインコメント() {
		LineParsedNodeList sut = new LineParsedNodeList("-- 'XXX:' || /*?NoPage*/1 \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("", sut.build(map, list));
	}

	@Test
	public void 文字列内ラインコメント() {
		LineParsedNodeList sut = new LineParsedNodeList(" '--------------' AS CD_COMPANY \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("'--------------' AS CD_COMPANY \n", sut.build(map, list));
	}

	@Test
	public void 複数文字列内ラインコメント() {
		LineParsedNodeList sut = new LineParsedNodeList(" '-------''-------' AS CD_COMPANY \n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("'-------''-------' AS CD_COMPANY \n", sut.build(map, list));
	}

	@Test
	public void コメント内ラインコメント() {
		LineParsedNodeList sut = new LineParsedNodeList(" ABCD /* '-------''-------' AS CD_COMPANY */ EFG\n");

		Map<String, Object> map = new HashMap<>();
		List<Object> list = new ArrayList<>();

		Assert.assertEquals("ABCD  EFG \n", sut.build(map, list));
	}

	@Test
	public void コメント内ラインコメントと文字列内必須コロン() {
		LineParsedNodeList sut = new LineParsedNodeList(" ABCD /* '-------''-------' AS CD_COMPANY */ 'XXX:' || /*?Code*/'1' \n");

		Map<String, Object> map = new HashMap<>();

		List<Object> list = new ArrayList<>();
		Assert.assertEquals("ABCD 'XXX:' || ? \n", sut.build(map, list));
	}
}
