inline void backward_statements(P& problem, O& OUT, I& IN, OS& OUT_S, IS& IN_S, Statements& statements, mtac::basic_block_p& B, bool& changes){
    if(statements.size() > 0){
        log::emit<Dev>("Data-Flow") << "OUT_S[" << (statements.size() - 1) << "] before transfer " << OUT_S[statements[statements.size() - 1]] << log::endl;
        assign(OUT_S[statements.back()], OUT[B], changes);
        log::emit<Dev>("Data-Flow") << "OUT_S[" << (statements.size() - 1) << "] after  transfer " << OUT_S[statements[statements.size() - 1]] << log::endl;

        for(unsigned i = statements.size() - 1; i > 0; --i){
            auto& statement = statements[i];

            log::emit<Dev>("Data-Flow") << "IN_S[" << i << "] before transfer " << IN_S[statement] << log::endl;
            assign(IN_S[statement], problem.transfer(B, statement, OUT_S[statement]), changes);
            log::emit<Dev>("Data-Flow") << "IN_S[" << i << "] after  transfer " << IN_S[statement] << log::endl;

            log::emit<Dev>("Data-Flow") << "OUT_S[" << (i - 1) << "] before transfer " << OUT_S[statements[i - 1]] << log::endl;
            OUT_S[statements[i-1]] = IN_S[statement];
            log::emit<Dev>("Data-Flow") << "OUT_S[" << (i - 1) << "] after  transfer " << OUT_S[statements[i - 1]] << log::endl;
        }

        log::emit<Dev>("Data-Flow") << "IN_S[" << 0 << "] before transfer " << IN_S[statements[0]] << log::endl;
        assign(IN_S[statements[0]], problem.transfer(B, statements[0], OUT_S[statements[0]]), changes);
        log::emit<Dev>("Data-Flow") << "IN_S[" << 0 << "] after  transfer " << IN_S[statements[0]] << log::endl;

        assign(IN[B], IN_S[statements.front()], changes);
    } else {
        //If the basic block is empty, the IN values are the OUT values
        assign(IN[B], OUT[B], changes);
    }
}
inline void forward_statements(P& problem, O& OUT, I& IN, OS& OUT_S, IS& IN_S, Statements& statements, mtac::basic_block_p& B, bool& changes){
    if(statements.size() > 0){
        IN_S[statements.front()] = IN[B];

        for(unsigned i = 0; i < statements.size(); ++i){
            auto& statement = statements[i];

            assign(OUT_S[statement], problem.transfer(B, statement, IN_S[statement]), changes);

            //The entry value of the next statement are the exit values of the current statement
            if(i != statements.size() - 1){
                IN_S[statements[i+1]] = OUT_S[statement];
            }
        }

        assign(OUT[B], OUT_S[statements.back()], changes);
    } else {
        //If the basic block is empty, the OUT values are the IN values
        assign(OUT[B], IN[B], changes);
    }
}
 clang::Stmt* getStmt() {
   assert(isSingleStmt() && "Cannot get multiple stmts.");
   return m_Stmts.front();
 }