public void exec(ILineConsumer out, ILineConsumer err) throws IOException{
        logger.info("Command to execute :" + iCmd);
        
        iSession = iConnection.getSession();
        iSession.execCommand(iCmd);
        
        // conditions for processing the streams. Such processing will not exit the call execution.
        int conditions = ChannelCondition.EXIT_STATUS|ChannelCondition.STDOUT_DATA|ChannelCondition.STDERR_DATA;
        
        // condition for exiting the call processing
        int conditionsExit = ChannelCondition.EXIT_STATUS;
        
        int status;
        BufferedReader stdbr = null;
        BufferedReader errbr = null;
        
        Timer timer = new Timer();
        iStatus = new StatusWrapper();
        iStatus.isRunning = true;
            

        // if iTo is specified, then we will create timer task to terminate the call by closing session.
            if( iTo != 0 ){
                timer.schedule((new TimerTask() {
                @Override
                public void run() {
                    if(null!=iSession ){
                        iSession.close();
                        iStatus.isRunning = false;
                        }
                    }
                }), iTo);
            }
            
            // start the stream processing
            do{
                status = iSession.waitForCondition(conditions, iTo*2);
                if( (status&ChannelCondition.STDOUT_DATA) != 0 ){
                    stdbr = reopenBR(stdbr, iSession.getStdout());
                    readStream(out, stdbr);
                }
    
                if( (status&ChannelCondition.STDERR_DATA) != 0 ){
                    errbr = reopenBR(errbr, iSession.getStderr());
                    readStream(err, errbr);
                }
            }
            while((((conditionsExit)&status)==0)&&iStatus.isRunning);
            
        // processing has ended, we try to clean up the streams, that are stil open.
        try{
            stdbr.close();
        }catch(Exception ex){
            // consume exception
        }
        try{
            errbr.close();
        }catch(Exception ex){
            // consume exception
        }
        out.eos();
        err.eos();
        
        // at this point we check if the execution has exited due to timeout or normaly.
        if( !iStatus.isRunning ){
            throw new IOException("Command timed out at "+ iTo);
        }
        // calling interrupt to close the session
        interrupt();
    }