public String removeComments( String script ) {
    if ( script == null ) {
      return null;
    }

    StringBuilder result = new StringBuilder();

    MODE mode = MODE.SQL;

    char currentStringChar = 0;

    for ( int i = 0; i < script.length(); i++ ) {
      char ch = script.charAt( i );
      char nextCh = i < script.length() - 1 ? script.charAt( i + 1 ) : 0;
      char nextPlusOneCh = i < script.length() - 2 ? script.charAt( i + 2 ) : 0;
      switch ( mode ) {
        case SQL:
          switch ( ch ) {
            case '/':
              if ( nextCh == '*' && nextPlusOneCh != '+' ) {
                mode = MODE.BLOCK_COMMENT;
                i++;
                ch = 0;
              }
              break;
            case '-':
              if ( nextCh == '-' ) {
                mode = MODE.LINE_COMMENT;
                i++;
                ch = 0;
              }
              break;
            case '\'':
            case '"':
              mode = MODE.STRING;
              currentStringChar = ch;
              break;
          }
          break;
        case BLOCK_COMMENT:
          if ( ch == '*' ) {
            if ( nextCh == '/' ) {
              mode = MODE.SQL;
              i++;
            }
          }
          ch = 0;
          break;
        case LINE_COMMENT:
          if ( ch == '\n' || ch == '\r' ) {
            mode = MODE.SQL;
          } else {
            ch = 0;
          }
          break;
        case STRING:
          if ( ch == '\\' && nextCh == currentStringChar && usingBackslashAsEscapeCharForQuotation ) {
            /*
             * The user is hard-coding a quote character into the string.
             * Pass the hard-coded quote character through, and skip over the quote on next loop
             */

            /*
             * usingBackslashAsEscapeCharForQuotation
             * PDI-16224.
             *
             * ANSI standards specify that using the backslash character (\) to escape single (' ') or double (" ")
             * quotation marks is invalid. For example, the following attempt to find a quotation mark does not conform to ANSI standards:
             * where col1 = '\'';"
             * In any way a construction '\'|| is correct for Oracle but for others DBs (ex. MySQl) isn't correct.
             *
             */

            result.append( ch );
            result.append( nextCh );
            ch = 0;
            i++;
          } else if ( ch == currentStringChar ) {
            mode = MODE.SQL;
          }
          break;
      }
      if ( ch != 0 ) {
        result.append( ch );
      }
    }

    return result.toString();
  }
@Test
  public void testRemoveComments() {
    assertEquals( null, sqlScriptParser.removeComments( null ) );
    assertEquals( "", sqlScriptParser.removeComments( "" ) );
    assertEquals( "SELECT col1 FROM test", sqlScriptParser.removeComments( "SELECT col1 FROM test" ) );
    assertEquals( "SELECT col1 FROM test ", sqlScriptParser.removeComments( "SELECT col1 FROM test --end comment" ) );
    assertEquals( "SELECT \n col1, col2\n FROM \n test", sqlScriptParser.removeComments( "SELECT \n col1, col2\n FROM \n test" ) );
    assertEquals( "SELECT \n \"col1\", col2\n FROM \n test", sqlScriptParser.removeComments( "SELECT \n \"col1\", col2\n FROM --test\n test" ) );
    assertEquals( "SELECT  col1 FROM  account", sqlScriptParser.removeComments( "SELECT /* \"my_column'\" */ col1 FROM /* 'my_table' */ account" ) );
    assertEquals( "SELECT '/' as col1, '*/*' as regex ", sqlScriptParser.removeComments( "SELECT '/' as col1, '*/*' as regex " ) );
    assertEquals( "SELECT INSTR('/loader/*/*.txt', '/') - INSTR('/loader/*/*.txt', '/') ",
            sqlScriptParser.removeComments( "SELECT INSTR('/loader/*/*.txt', '/') - INSTR('/loader/*/*.txt', '/') " ) );
    assertEquals( "SELECT  col1, col2, col3 FROM account WHERE name = 'Pentaho'",
            sqlScriptParser.removeComments( "SELECT /* my data*/ col1, col2, col3 FROM account WHERE name = 'Pentaho'" ) );
    assertEquals( "SELECT /*+ ORACLE hint*/ col1, col2, col3 FROM account WHERE name = 'Pentaho'",
            sqlScriptParser.removeComments( "SELECT /*+ ORACLE hint*/ col1, col2, col3 FROM account WHERE name = 'Pentaho'" ) );
    assertEquals( "SELECT \n/*+ ORACLE hint*/ col1, col2, col3 FROM account WHERE name = 'Pentaho'",
            sqlScriptParser.removeComments( "SELECT \n/*+ ORACLE hint*/ col1, col2, col3 FROM account WHERE name = 'Pentaho'" ) );
    assertEquals( "SELECT \n/*+ ORACLE hint*/\n col1, col2, col3 FROM account WHERE name = 'Pentaho'",
            sqlScriptParser.removeComments( "SELECT \n/*+ ORACLE hint*/\n col1, col2, col3 FROM account WHERE name = 'Pentaho'" ) );
    assertEquals( "SELECT \"hello\\\"world\" FROM dual", sqlScriptParser.removeComments( "SELECT \"hello\\\"world\" FROM dual" ) );
    assertEquals( "CREATE TABLE test1 (col1 STRING) TBLPROPERTIES (\"prop1\" = \"my\\\"value\")",
            sqlScriptParser.removeComments( "CREATE TABLE test1 (col1 STRING) TBLPROPERTIES (\"prop1\" = \"my\\\"value\")" ) );
    assertEquals( "CREATE TABLE test1 (col1 STRING) TBLPROPERTIES ('prop1' = 'my\\\"value')",
            sqlScriptParser.removeComments( "CREATE TABLE test1 (col1 STRING) TBLPROPERTIES ('prop1' = 'my\\\"value')" ) );
    //PDI-16224
    assertEquals( "SELECT 1 from test where t='\\'||t=a", oracleSqlScriptParser.removeComments( "SELECT 1 from test where t='\\'/* comment */||t=a" ) );
  }