diff --git a/alib2cli/src/lexer/Lexer.cpp b/alib2cli/src/lexer/Lexer.cpp
index 7cb42321e02db1a2fc46306058abad373e94f6a3..3654066d9aa86f2b0c775f391c8ff532e2a49e1a 100644
--- a/alib2cli/src/lexer/Lexer.cpp
+++ b/alib2cli/src/lexer/Lexer.cpp
@@ -4,17 +4,21 @@
 
 namespace cli {
 
-Lexer::Token Lexer::nextToken () {
+Lexer::Token Lexer::nextToken ( bool readNextLine ) {
 	Token res { "", TokenType::ERROR };
+	std::string newLine;
 
 q0:	if ( m_index >= m_line.size ( ) ) {
-		res.m_type = TokenType::END;
-		return res;
+		goto qReadLine;
 	}
 	if ( isspace ( m_line [ m_index ] ) ) {
 		m_index ++;
 		goto q0;
 	}
+	if ( m_line [ m_index ] == '\\' ) {
+		m_index ++;
+		goto qReadLineForce;
+	}
 	if ( m_line [ m_index ] == '<' ) {
 		m_index ++;
 		res.m_type = TokenType::IN_REDIRECT;
@@ -125,6 +129,23 @@ q0:	if ( m_index >= m_line.size ( ) ) {
 	res.m_type = TokenType::ERROR;
 	return res;
 
+qReadLine:
+	if ( ! readNextLine ) {
+		res.m_type = TokenType::EOL;
+		return res;
+	}
+	goto qReadLineForce;
+
+qReadLineForce:
+	newLine = m_lineCallback ( );
+	if ( newLine.size ( ) == 0 ) {
+		res.m_type = TokenType::END;
+		return res;
+	}
+
+	m_line += std::move ( newLine );
+	goto q0;
+
 q1:	if ( m_index >= m_line.size ( ) ) {
 		res.m_type = TokenType::INTEGER;
 		return res;
diff --git a/alib2cli/src/lexer/Lexer.h b/alib2cli/src/lexer/Lexer.h
index cf57b93c42ba4c5fa32eec7a0a6d5229d85e366b..74d556df210b2d11200ede5730e048727f804407 100644
--- a/alib2cli/src/lexer/Lexer.h
+++ b/alib2cli/src/lexer/Lexer.h
@@ -11,6 +11,7 @@ namespace cli {
 class Lexer {
 	unsigned m_index;
 	std::string m_line;
+	std::function < std::string ( ) > m_lineCallback;
 
 public:
 	enum class TokenType {
@@ -35,7 +36,8 @@ public:
 		EQUAL_SIGN,
 		HASH_SIGN,
 		ERROR,
-		END
+		END,
+		EOL
 	};
 
 	static std::string tokenTypeToString ( TokenType type ) {
@@ -84,8 +86,10 @@ public:
 			return "error";
 		case TokenType::END :
 			return "end";
+		case TokenType::EOL :
+			return "eol";
 		default:
-			throw exception::CommonException ( "Unhandler case in Lexer::tokenTypeToString" );
+			throw exception::CommonException ( "Unhandled case in Lexer::tokenTypeToString" );
 		}
 	}
 
@@ -117,10 +121,17 @@ public:
 
 	};
 
-	Lexer ( std::string line ) : m_index ( 0 ), m_line ( std::move ( line ) ) {
+	Lexer ( std::function < std::string ( ) > lineCallback ) : m_index ( 0 ), m_line ( "" ), m_lineCallback ( lineCallback ) {
 	}
 
-	Token nextToken ( );
+	Lexer ( std::string line ) : Lexer ( [ line { std::move ( line ) } ] ( ) mutable {
+				std::string res = std::move ( line );
+				line = "";
+				return res;
+			} ) {
+	}
+
+	Token nextToken ( bool readNextLine = false );
 
 	const std::string & getLine ( ) const {
 		return m_line;
diff --git a/alib2cli/src/parser/Parser.cpp b/alib2cli/src/parser/Parser.cpp
index 6a3c512f77b694c19e2169a3e309d6c3e1275138..e8ebe68b254778cace7ddd1d5d9ad3ecf2d2223a 100644
--- a/alib2cli/src/parser/Parser.cpp
+++ b/alib2cli/src/parser/Parser.cpp
@@ -185,7 +185,7 @@ std::shared_ptr < Statement > Parser::statement ( ) {
 		std::unique_ptr < CategoryOption > category = category_option ( );
 		ext::vector < std::shared_ptr < Statement > > params;
 		ext::vector < bool > moves;
-		while ( ! check ( cli::Lexer::TokenType::OUT_REDIRECT ) && ! check ( cli::Lexer::TokenType::PIPE_SIGN ) && ! check ( cli::Lexer::TokenType::END ) && ! check ( cli::Lexer::TokenType::RIGHT_PAREN ) ) {
+		while ( ! check ( cli::Lexer::TokenType::OUT_REDIRECT ) && ! check ( cli::Lexer::TokenType::PIPE_SIGN ) && ! check ( cli::Lexer::TokenType::EOL ) && ! check ( cli::Lexer::TokenType::RIGHT_PAREN ) ) {
 			moves.push_back ( move_arg ( ) );
 			params.emplace_back ( param ( ) );
 		}
@@ -232,7 +232,7 @@ void Parser::out_redirect ( std::shared_ptr < StatementList > & list ) {
 		match ( cli::Lexer::TokenType::DOLAR_SIGN );
 		std::unique_ptr < Arg > name = arg ( );
 		list->append ( std::make_unique < ResultVariableStatement > ( std::move ( name ) ) );
-	} else if ( check ( cli::Lexer::TokenType::END ) ) {
+	} else if ( check ( cli::Lexer::TokenType::EOL ) ) {
 		return;
 	} else {
 		out_redirect_file ( list );
@@ -243,7 +243,7 @@ void Parser::result ( std::shared_ptr < StatementList > & list ) {
 	if ( check ( cli::Lexer::TokenType::OUT_REDIRECT ) ) {
 		match ( cli::Lexer::TokenType::OUT_REDIRECT );
 		out_redirect ( list );
-	} else if ( check ( cli::Lexer::TokenType::END ) ) {
+	} else if ( check ( cli::Lexer::TokenType::EOL ) ) {
 		list->append ( std::make_unique < ResultPrintStatement > ( ) );
 	} else {
 		return;
@@ -302,21 +302,21 @@ std::unique_ptr < Command > Parser::parse ( ) {
 		match_nonreserved_kw ( "execute" );
 		std::shared_ptr < StatementList > res = statement_list ( );
 		result ( res );
-		match ( cli::Lexer::TokenType::END );
+		match ( cli::Lexer::TokenType::EOL );
 		return std::make_unique < ExecuteCommand > ( res );
 	} else if ( check_nonreserved_kw ( "quit" ) ) {
 		match_nonreserved_kw ( "quit" );
-		match ( cli::Lexer::TokenType::END );
+		match ( cli::Lexer::TokenType::EOL );
 		return std::make_unique < QuitCommand > ( );
 	} else if ( check_nonreserved_kw ( "help" ) ) {
 		match_nonreserved_kw ( "help" );
 		std::unique_ptr < cli::Arg > command = optional_arg ( );
-		match ( cli::Lexer::TokenType::END );
+		match ( cli::Lexer::TokenType::EOL );
 		return std::make_unique < HelpCommand > ( std::move ( command ) );
 	} else if ( check_nonreserved_kw ( "introspect" ) ) {
 		match_nonreserved_kw ( "introspect" );
 		std::unique_ptr < Command > command = introspect_command ( );
-		match ( cli::Lexer::TokenType::END );
+		match ( cli::Lexer::TokenType::EOL );
 		return command;
 	} else if ( check_nonreserved_kw ( "set" ) ) {
 		match_nonreserved_kw ( "set" );
@@ -324,14 +324,16 @@ std::unique_ptr < Command > Parser::parse ( ) {
 		match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER );
 		std::string value = getTokenValue ( );
 		match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING );
-		match ( cli::Lexer::TokenType::END );
+		match ( cli::Lexer::TokenType::EOL );
 		return std::make_unique < SetCommand > ( std::move ( param ), std::move ( value ) );
 	} else if ( check_nonreserved_kw ( "load" ) ) {
 		match_nonreserved_kw ( "load" );
 		std::string libraryName = getTokenValue ( );
 		match ( cli::Lexer::TokenType::INTEGER, cli::Lexer::TokenType::IDENTIFIER, cli::Lexer::TokenType::STRING );
-		match ( cli::Lexer::TokenType::END );
+		match ( cli::Lexer::TokenType::EOL );
 		return std::make_unique < LoadCommand > ( std::move ( libraryName ) );
+	} else if ( check ( cli::Lexer::TokenType::END ) ) {
+		return std::make_unique < QuitCommand > ( );
 	} else {
 		throw exception::CommonException ( "Mismatched set while expanding parse rule." );
 	}
diff --git a/alib2cli/src/parser/Parser.h b/alib2cli/src/parser/Parser.h
index 4d769dad9f5b43c0265b7fd5068832e195dc6a98..151f1d1cc201ae04636bdaabef1008f8a213ddf5 100644
--- a/alib2cli/src/parser/Parser.h
+++ b/alib2cli/src/parser/Parser.h
@@ -25,7 +25,11 @@ class Parser {
 	cli::Lexer::Token m_current;
 
 public:
-	Parser ( cli::Lexer lexer ) : m_lexer ( std::move ( lexer ) ), m_current ( m_lexer.nextToken ( ) ) {
+	Parser ( cli::Lexer lexer ) : m_lexer ( lexer ), m_current ( m_lexer.nextToken ( true ) ) {
+	}
+
+	const cli::Lexer & getLexer ( ) const {
+		return m_lexer;
 	}
 
 	template < class ... Tokens >
@@ -43,14 +47,14 @@ public:
 	bool match ( Token token, Tokens ... tokens ) {
 		if ( ! check ( token, tokens ... ) )
 			throw exception::CommonException ( std::string ( "Mismatched token while matching a token " ) + Lexer::tokenTypeToString ( token ) + "." );
-		m_current = m_lexer.nextToken ( );
+		m_current = m_lexer.nextToken ( false );
 		return true;
 	}
 
 	bool match_nonreserved_kw ( const std::string & kw ) {
 		if ( ! check_nonreserved_kw ( kw ) )
 			throw exception::CommonException ( "Mismatched token while matching a token." );
-		m_current = m_lexer.nextToken ( );
+		m_current = m_lexer.nextToken ( false );
 		return true;
 	}
 
@@ -58,7 +62,7 @@ public:
 		if ( ! check ( Lexer::TokenType::IDENTIFIER ) )
 			throw exception::CommonException ( "Mismatched token while matching a token." );
 		std::string res = m_current.m_value;
-		m_current = m_lexer.nextToken ( );
+		m_current = m_lexer.nextToken ( false );
 		return res;
 	}
 
@@ -66,7 +70,7 @@ public:
 		if ( ! check ( Lexer::TokenType::STRING ) )
 			throw exception::CommonException ( "Mismatched token while matching a token." );
 		std::string res = m_current.m_value;
-		m_current = m_lexer.nextToken ( );
+		m_current = m_lexer.nextToken ( false );
 		return res;
 	}
 
@@ -74,7 +78,7 @@ public:
 		if ( ! check ( Lexer::TokenType::INTEGER ) )
 			throw exception::CommonException ( "Mismatched token while matching a token."  );
 		int res = ext::from_string < int > ( m_current.m_value );
-		m_current = m_lexer.nextToken ( );
+		m_current = m_lexer.nextToken ( false );
 		return res;
 	}
 
diff --git a/aql2/src/prompt/Prompt.cpp b/aql2/src/prompt/Prompt.cpp
index 31bcdb496fb9234af772eda1b3363e17fa1997bd..35c2c7c0a9fd615024304299bb8b0504d4ac4a6a 100644
--- a/aql2/src/prompt/Prompt.cpp
+++ b/aql2/src/prompt/Prompt.cpp
@@ -20,20 +20,6 @@
 #include <factory/XmlDataFactory.hpp>
 #include <global/GlobalData.h>
 
-char * Prompt::stripwhite ( char * begin ) {
-	while ( isspace ( * begin ) )
-		++ begin;
-
-	char * end = begin + strlen ( begin ) - 1;
-	while ( end >= begin && isspace ( * end ) )
-		-- end;
-
-	if ( end >= begin )
-		* ++ end = '\0';
-
-	return begin;
-}
-
 Prompt::Prompt ( cli::Environment environment ) : m_prefix ( "> " ), m_history_file ( std::string ( std::getenv ( "HOME" ) ) + "/.aql_history" ), m_environment ( std::move ( environment ) ) {
 	read_history ( m_history_file.c_str ( ) );
 }
@@ -46,28 +32,32 @@ cli::Command::Result Prompt::run ( ) {
 	cli::Command::Result state = cli::Command::Result::OK;
 
 	while ( state != cli::Command::Result::QUIT && state != cli::Command::Result::ERROR ) {
-		char * line = readline ( m_prefix.c_str ( ) );
+		auto callback = [ first { true } ] ( ) mutable -> std::string {
+			char * line = readline ( first ? "> ": "+ " );
 
-		if ( ! line )
-			break;
+			if ( ! line )
+				return "";
 
-		char * s = stripwhite ( line );
+			std::string res ( line );
+			res += "\n";
+			free ( line );
 
-		if ( * s ) {
-			state = execute_line ( std::string ( s ) );
-		}
+			if ( ! std::all_of ( res.begin ( ), res.end ( ), isspace ) )
+				first = false;
 
-		free ( line );
+			return res;
+		};
+		state = execute_line ( callback );
 	}
 
 	return state;
 }
 
 class HistoryRegister {
-	cli::Lexer & m_lexer;
+	const cli::Lexer & m_lexer;
 
 public:
-	HistoryRegister ( cli::Lexer & lexer ) : m_lexer ( lexer ) {
+	HistoryRegister ( const cli::Lexer & lexer ) : m_lexer ( lexer ) {
 	}
 
 	~HistoryRegister ( ) {
@@ -77,9 +67,22 @@ public:
 
 cli::Command::Result Prompt::execute_line ( std::string line ) {
 	try {
-		cli::Lexer lexer ( line );
-		HistoryRegister historyRegister ( lexer );
-		cli::Parser parser = cli::Parser ( lexer );
+		cli::Parser parser = cli::Parser ( cli::Lexer ( line ) );
+		HistoryRegister historyRegister ( parser.getLexer ( ) );
+		return parser.parse ( )->run ( m_environment );
+	} catch ( const exception::CommonException & exception ) {
+		factory::XmlDataFactory::toStdout ( exception );
+		return cli::Command::Result::EXCEPTION;
+	} catch ( const std::exception & exception ) {
+		common::Streams::err << "Exception caught: " << exception.what ( ) << std::endl;
+		return cli::Command::Result::EXCEPTION;
+	}
+}
+
+cli::Command::Result Prompt::execute_line ( std::function < std::string ( ) > callback ) {
+	try {
+		cli::Parser parser = cli::Parser ( cli::Lexer ( callback ) );
+		HistoryRegister historyRegister ( parser.getLexer ( ) );
 		return parser.parse ( )->run ( m_environment );
 	} catch ( const exception::CommonException & exception ) {
 		factory::XmlDataFactory::toStdout ( exception );
diff --git a/aql2/src/prompt/Prompt.h b/aql2/src/prompt/Prompt.h
index 9304076ab8bd4c6918d969d3206a1be0f48bb417..505406f6fd24c6d0fcfbea8113a7550971075b6e 100644
--- a/aql2/src/prompt/Prompt.h
+++ b/aql2/src/prompt/Prompt.h
@@ -30,6 +30,7 @@ public:
 
 	cli::Command::Result run ( );
 	cli::Command::Result execute_line ( std::string line );
+	cli::Command::Result execute_line ( std::function < std::string ( ) > callback );
 };
 
 #endif /* _AQL_PROMPT_H_ */