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;

/**
 * TestLineParsedNodeList
 *
 */
public class TestLineParsedNodeList {

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

		final Map<String, Object> map = new HashMap<>();
		map.put("DateTime", "20100118");
		final 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 buildTest2() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"OFFSET ((/*?Page*/1 - 1) * /*?Line*/20 ) LIMIT /*?Line*/20 \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("Page", "1");
		map.put("Line", "30");
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

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

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

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

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

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

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", Integer.valueOf(1));
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", "A");
		map.put("Shubetsu3", "B");
		map.put("Shubetsu4", "C");
		final 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.assertNull(list.get(1));
		Assert.assertEquals("B", list.get(2));
		Assert.assertEquals("C", list.get(3));
	}

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"X", "Y", "Z"});
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new ArrayList<>(Arrays.asList("X", "Y", "Z")));
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", "A");
		map.put("Shubetsu2", "C");
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"A", "B", "C"});
		map.put("Shubetsu2", new String[]{"D", "E", "F"});
		final 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));
	}

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

		final 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")));
		final 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));
	}

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"A", "B", "C"});
		map.put("Shubetsu2", new String[]{"D", "E", "F"});
		final 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));
	}

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu1", new String[]{"A", "B"});
		map.put("Shubetsu2", new String[]{"C", "D"});
		final 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));
	}


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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", "A");
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", new String[]{"A", "B"});
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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));
	}

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", Integer.valueOf(10));
		final 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));
	}

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("Shubetsu", Integer.valueOf(10));
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		final 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 buildTest36() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"COALESCE(/*:dtShuryo*/'0000', '0000') AS DT_TOROKU_YM, \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtShuryo", "9876");
		final 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 buildTest37() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"DECODE (DT_KOJO_YM, /*:dtKojo*/'200901', '1', '0') AS FG_TOU, \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "201001");
		final 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 buildTest38() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"DECODE (DT_KOJO_YM, /*$dtKojo*/'200901', '1', '0') AS FG_TOU, \n");

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "201001");
		final 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 buildTest40() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"OR DT_KOJO_YM <= /*$dtKojo*/'200901' \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "201001");
		final 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 buildTest41() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"OR DT_KOJO_YM <= /*$dtKojo*/'200901' \n");

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", new String[]{"", "asdf"});
		final 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 buildTest43() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZZ DESC, YYYY, XXXX; \n");
		final 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 buildTest44() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZZ DESC, 'YYYY', XXXX \n");
		final 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 buildTest45() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		final Map<String, Object> map = new HashMap<>();
		final 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 buildTest46() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"ORDER BY /*@dtKojo*/AAA, BBB DESC, CCCC \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", new String[]{"ZZZ DESC", "'YYYY'", "XXXX"});
		final 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 buildTest47() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"FROM /*@YmTable/YYYYMM*/TR_MEISAI_YYYYMM WHERE AAA = 'ABC' \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("YmTable", "201202");
		final 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 buildTest48() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"FROM /*@YmTable1/YYYYMM*/TR_MEISAI_YYYYMM \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("YmTable1", new String[]{"201202", "'YYYY'", "XXXX"});
		final 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 buildTest49() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"FROM /*@YmTable/YYYYMM*/TR_MEISAI_YYYYMM \n");

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

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

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

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("YmTable", "201202");
		final 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 buildTest52() {
		final LineParsedNodeList sut = new LineParsedNodeList("OR NO_KOJO <= /*$dtKojo*/200901 \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "123,456,789");
		final 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 buildTest53() {
		final LineParsedNodeList sut = new LineParsedNodeList("OR NO_KOJO <= /*$dtKojo*/200901 \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "123,456,789.001");
		final 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 buildTest54() {
		final LineParsedNodeList sut = new LineParsedNodeList("OR NO_KOJO <= /*$dtKojo*/200901 \n");

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("dtGyomu", "300, 400");
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZZZ");
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("dtKojo", "ZZ%%ZZ");
		final 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 buildTest58() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"AND date_trunc('day', TRN.TS_TORIKOMI) = "
				+ "/*$DateTime*/TO_DATE('20100805','YYYYMMDD') \n");

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("DateTime", new Timestamp(new Date().getTime()));
		final 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 buildTest60() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"AND TS_TORIKOMI = /*?DateTime*/TO_DATE('20100805','YYYYMMDD') \n");

		final Map<String, Object> map = new HashMap<>();
		final 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 buildTest61() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"AND TS_TOROKU <= "
				+ "/*$DtHenko*/TO_TIMESTAMP('99991231235959999','YYYYMMDDHH24MISSMS') \n");

		final Map<String, Object> map = new HashMap<>();
		map.put("DtHenko", "20100805");
		final 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());
	}

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

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

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

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

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

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

	/**
	 * WHERE句内可変で一部パラメータあり
	 */
	@Test
	public void buildTest64() {
		final 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' )");

		final Map<String, Object> map = new HashMap<>();
		map.put("mnPay", Integer.valueOf(3));
		final 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));
	}

	/**
	 * WHERE句内中間パラメータあり
	 */
	@Test
	public void buildTest65() {
		final 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' )");

		final Map<String, Object> map = new HashMap<>();
		map.put("DtDattaiYm", "aaaaa");
		final 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));
	}

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

		final Map<String, Object> map = new HashMap<>();
		map.put("StShoninSearch", "0");
		final 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());
	}

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

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

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

	/**
	 * AND_OR句文字列可変でパラメータありOR後除去
	 */
	@Test
	public void buildTest68() {
		final 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'))");

		final Map<String, Object> map = new HashMap<>();
		map.put("KbUriageSearch", "123");
		final 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));
	}

	/**
	 * AND_OR句文字列可変でパラメータありOR前除去
	 */
	@Test
	public void buildTest69() {
		final 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'))");

		final Map<String, Object> map = new HashMap<>();
		map.put("KbKeihiSearch", "456");
		final 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));
	}

	/**
	 * AND_OR句複数文字列可変でパラメータなし
	 */
	@Test
	public void buildTest70() {
		final 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'))");

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

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

	/**
	 * AND_OR句複数文字列可変でパラメータありOR内AND後除去
	 */
	@Test
	public void buildTest71() {
		final 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'))");

		final Map<String, Object> map = new HashMap<>();
		map.put("CdKamokuSearch", "123");
		final 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));
	}

	/**
	 * AND_OR句複数文字列可変でパラメータありOR内AND前除去
	 */
	@Test
	public void buildTest72() {
		final 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'))");

		final Map<String, Object> map = new HashMap<>();
		map.put("CdHojoSearch", "333");
		final 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));
	}

	/**
	 * AND_OR句複数文字列可変でパラメータあり
	 */
	@Test
	public void buildTest73() {
		final 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'))");

		final Map<String, Object> map = new HashMap<>();
		map.put("CdKamokuSearch", "123");
		map.put("CdHojoSearch", "333");
		final 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 buildTest74() {
		final LineParsedNodeList sut = new LineParsedNodeList(
			"AND (SELECT MIN(CD) FROM MS_CODE WHERE 'SHOHIZEI' = CD_SBT "
			+ "AND /*:DdShimebi*/'' <= CD AND 0 < VERSION) = CM.CODE");

		final Map<String, Object> map = new HashMap<>();
		map.put("DdShimebi", "20101010");
		final 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 buildTest75() {
		final LineParsedNodeList sut = new LineParsedNodeList(
			"AND CM.CODE =(SELECT MIN(CD) FROM MS_CODE "
			+ "WHERE 'SHOHIZEI' = CD_SBT AND /*:DdShimebi*/'' <= CD AND 0 < VERSION)");

		final Map<String, Object> map = new HashMap<>();
		map.put("DdShimebi", "20101010");
		final 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 buildTest76() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"AND TS_TOROKU = /*?DtHenko*/TO_DATE('昨日','YYYYMMDD') \n");

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

		final 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 buildTest77() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"--<KbHenko\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

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

		final 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 buildTest78() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"--<KbHenko\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

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

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

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

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

		final 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 buildTest80() {
		final LineParsedNodeList sut = new LineParsedNodeList(
				"--<KbHenko 10\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

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

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

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

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

		final 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 buildTest82() {
		final LineParsedNodeList sut = new LineParsedNodeList(
			"--<!KbKomoku 1 2\n AND TS_TOROKU = /*?DtHenko*/TO_DATE('20110404','YYYYMMDD') \n-->");

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

		final 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());
	}

	/**
	 * AND_OR句内LIKE句複数文字列可変でパラメータなし
	 */
	@Test
	public void buildTest83() {
		final 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%'))");

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

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

	/**
	 * AND_OR句内LIKE句複数文字列可変で１パラメータあり１
	 */
	@Test
	public void buildTest84() {
		final 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%'))");

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

		final 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));
	}

	/**
	 * AND_OR句内LIKE句複数文字列可変で１パラメータあり２
	 */
	@Test
	public void buildTest85() {
		final 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%'))");

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

		final 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));
	}

	/**
	 * AND_OR句内LIKE句複数文字列可変で１パラメータあり３
	 */
	@Test
	public void buildTest86() {
		final 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%'))");

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

		final 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));
	}

	/**
	 * AND_OR句内LIKE句複数文字列可変で２パラメータあり１
	 */
	@Test
	public void buildTest87() {
		final 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%'))");

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

		final 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));
	}

	/**
	 * AND_OR句内LIKE句複数文字列可変で２パラメータあり２
	 */
	@Test
	public void buildTest88() {
		final 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%'))");

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

		final 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));
	}

	/**
	 * AND_OR句内LIKE句複数文字列可変で２パラメータあり３
	 */
	@Test
	public void buildTest89() {
		final 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%'))");

		final Map<String, Object> map = new HashMap<>();
		map.put("KbKomoku1", "KBUNKB");
		map.put("KbKomoku3", "KBUNKBKBUNKB");
		final 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 buildTest90() {
		final LineParsedNodeList sut = new LineParsedNodeList(" 'XX''X:' || /*?NoPage*/1 \n");

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

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

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

		final Map<String, Object> map = new HashMap<>();
		map.put("NoPage", Integer.valueOf(3));
		final 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 buildTest92() {
		final LineParsedNodeList sut = new LineParsedNodeList(" 'XXX:' || /*?NoPage*/1 \n");

		final Map<String, Object> map = new HashMap<>();
		final 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 buildTest93() {
		final LineParsedNodeList sut = new LineParsedNodeList("-- 'XXX:' || /*?NoPage*/1 \n");

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

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

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

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

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

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

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

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

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

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

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

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

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

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