             messageFlags = message.flags
             do parser.end
      
-    fetch.on 'error', (error) ->
-        server.logout () ->
-            console.log 'Error emitted on fetch object'
-            console.log error
-            server.emit 'error', error
-
 
 Mailbox::getNewMail = (job, callback, limit=250) ->
     
-    ## dependences
-    imap = require "imap"
-    mailparser = require "mailparser"
-
     # global vars
     debug = true
     
     # reload
-    @reload (error, mailbox) ->
-        
-        if error
-            callback error
-        else
-            id = Number(mailbox.IMAP_last_fetched_id) + 1
-            console.log "Fetching mail " + mailbox + " | UID " + id + ':' + (id + limit) if debug
-    
-            # let's create a connection
-            server = new imap.ImapConnection
-                username: mailbox.login
-                password: mailbox.pass
-                host: mailbox.IMAP_server
-                port: mailbox.IMAP_port
-                secure: mailbox.IMAP_secure
-
-            # set up listeners, handle errors and callback
-            server.on "alert", (alert) ->
-                console.log "[SERVER ALERT]" + alert
-
-            server.on "error", (error) ->
-                console.error "[ERROR]: " + error.toString()
-                mailbox.updateAttributes {status: error.toString()}, (err) ->
-                    console.error "Mailbox update with error status"
-                    callback error
-
-            server.on "close", (error) ->
-                console.log "Connection closed: " + error.toString() if debug
-                
-            emitOnErr = (err) ->
+    id = Number(@IMAP_last_fetched_id) + 1
+    console.log "Fetching mail #{@} | UID #{id}:#{id + limit})"
+
+    @connectImapServer (err, server) =>
+        return emitOnErr(server, err) if err
+        @loadInbox server, (err) =>
+            return emitOnErr server, err if err
+            loadNewMails(server, id)
+                            
+    emitOnErr = (server, error) ->
+        if error
+            console.log error
+            server.emit "error", error if server?
+
+    loadNewMails = (server, id) =>
+        range = "#{id}:#{id + limit}"
+        server.search [['UID', range]], (err, results) =>
+            return emitOnErr(server, err) if err
+
+            unless results.length
+                console.log "Nothing to download"
+                server.logout ->
+                    callback()
+            else
+                console.log "#{results.length} mails to download"
+                LogMessage.createImportInfo results, @, ->
+                    fetchOne server, 0, results
+
+    fetchOne = (server, i, results, mailsDone) =>
+        console.log "#{@} fetch new mail: #{i}/#{results.length}"
+        mailsDone = 0
+
+        if i < results.length
+            remoteId = results[i]
+
+            @fetchMessage server, remoteId, (err, mail) =>
                 if err
-                    server.emit "error", err
-
-            # LET THE GAMES BEGIN
-            server.connect (err) =>
-
-                emitOnErr err
-                unless err
-        
-                    console.log "Connection established successfuly" if debug
-
-                    server.openBox 'INBOX', false, (err, box) ->
-
-                        emitOnErr err
-                        unless err
-                
-                            console.log "INBOX opened successfuly" if debug
-                            
-                            # search mails on server satisfying constraints
-                            server.search [['UID', id + ':' + (id + limit)]], (err, results) =>
-
-                                emitOnErr err
-                                unless err
-
-                                    console.log "Search query successful" if debug
-                            
-                                    # nothing to download
-                                    unless results.length
-                                        console.log "Nothing to download" if debug
-                                        server.logout () ->
-                                            callback()
-                                    else
-                                        console.log "[" + results.length + "] mails to download" if debug
-                                        LogMessage.createImportInfo results, mailbox
-
-                                        mailsToGo = results.length
-                                        mailsDone = 0
-                                
-                                        # for every ID, fetch the message
-                                        # closure, to avoid sharing variables
-                                        fetchOne = (i) ->
-                                    
-                                            console.log "fetching one: " + i + "/" + results.length if debug
-                                    
-                                            if i < results.length
-                                        
-                                                remoteId = results[i]
-                                    
-                                                messageFlags = []
-                        
-                                                fetch = server.fetch remoteId,
-                                                    request:
-                                                        body: "full"
-                                                        headers: false
-
-                                                console.log "let's go fetching"
-                                                
-                                                fetch.on "message", (message) ->
-                                                    parser = new mailparser.MailParser()
-                                                    
-                                                    parser.on "end", (mailParsedObject) ->
-                                                
-                                                        # choose the right date
-                                                        if mailParsedObject.headers.date
-                                                            if mailParsedObject.headers.date.toString() == '[object Array]'
-                                                                # if an array pick the first date
-                                                                dateSent = new Date mailParsedObject.headers.date[0]
-                                                            else
-                                                                dateSent = new Date mailParsedObject.headers.date
-                                                        else
-                                                            dateSent = new Date()
-                                                
-                                                        # compile the mail data
-                                                        mail =
-                                                            mailbox:            mailbox.id
-                                                            date:                 dateSent.toJSON()
-                                                            dateValueOf:    dateSent.valueOf()
-                                                            createdAt:        new Date().valueOf()
-                                                            from:                 JSON.stringify mailParsedObject.from
-                                                            to:                     JSON.stringify mailParsedObject.to
-                                                            cc:                     JSON.stringify mailParsedObject.cc
-                                                            subject:            mailParsedObject.subject
-                                                            priority:         mailParsedObject.priority
-                                                            text:                 mailParsedObject.text
-                                                            html:                 mailParsedObject.html
-                                                            id_remote_mailbox: remoteId
-                                                            headers_raw:    JSON.stringify mailParsedObject.headers
-                                                    
-                                                            # optional parameters
-                                                            references:     mailParsedObject.references or ""
-                                                            inReplyTo:        mailParsedObject.inReplyTo or ""
-                    
-                                                            # flags
-                                                            flags:                JSON.stringify messageFlags
-                                                            read:                 "\\Seen" in messageFlags
-                                                            flagged:            "\\Flagged" in messageFlags
-                                                            hasAttachments: if mailParsedObject.attachments then true else false
-                                                    
-                                                        attachments = mailParsedObject.attachments
-
-                                                        # and now we can create a new mail on database, as a child of this mailbox
-                                                        Mail.create mail, (err, mail) ->
-        
-                                                            # for now we will just skip messages which are being rejected by parser
-                                                            # emitOnErr err
-                                                            unless err
-                                                            
-                                                                # attachements
-                                                                mail.saveAttachments attachments, ->
-
-                                                                        mailbox.reload (error, mailbox) ->
-                                                                    
-                                                                            if error
-                                                                                server.logout () ->
-                                                                                    console.log "Error emitted on mailbox.reload: " + error.toString() if debug
-                                                                                    server.emit "error", error
-                                                                            else
-                                                                        
-                                                                                # check if we need to update the last_fetch_id index in the mailbox
-                                                                                if mailbox.IMAP_last_fetched_id < mail.id_remote_mailbox
-                                                                            
-                                                                                    mailbox.updateAttributes {IMAP_last_fetched_id: mail.id_remote_mailbox}, (error) ->
-                                                                                
-                                                                                        if error
-                                                                                            server.logout () ->
-                                                                                                console.log "Error emitted on mailbox.update: " + error.toString() if debug
-                                                                                                server.emit "error", error
-                                                                                        else
-                                                                                            console.log "New highest id saved to mailbox: " + mail.id_remote_mailbox if debug
-                                                                                            mailsDone++
-                                                                                            job.progress mailsDone, mailsToGo
-                                                                                            # next iteration of our asynchronous for loop
-                                                                                            fetchOne(i + 1)
-                                                                                            # when finished
-                                                                                            if mailsToGo == mailsDone
-                                                                                                callback()
-                                                                                else
-                                                                                    mailsDone++
-                                                                                    job.progress mailsDone, mailsToGo
-                                                                                    # next iteration of our asynchronous for loop
-                                                                                    fetchOne(i + 1)
-                                                                                    # when finished
-                                                                                    if mailsToGo == mailsDone
-                                                                                        callback()
-                                                            else
-                                                                console.error "Parser error - skipping this message for now: " + err.toString()
-                                                                fetchOne(i + 1)
-
-                                                    message.on "data", (data) ->
-                                                        # on data, we feed the parser
-                                                        parser.write data.toString()
-
-                                                    message.on "end", ->
-                                                        # additional data to store, which is "forgotten" byt the parser
-                                                        # well, for now, we will store it on the parser itself
-                                                        messageFlags = message.flags
-                                                        do parser.end
-                                                                    
-                                                fetch.on "error", (error) ->
-                                                    # undocumented error emitted on fetch() object
-                                                    server.logout () ->
-                                                        console.log "Error emitted on fetch object: " + error.toString() if debug
-                                                        server.emit "error", error
-
-                                            else
-                                                # my job here is done
-                                                server.logout () ->
-                                                    if mailsToGo != mailsDone
-                                                        server.emit "error", new Error("Could not import all the mail. Retry")
-                                        # start the loop
-                                        fetchOne(0)
+                    emitOnErr server, err
+                else
+                    if @IMAP_last_fetched_id < mail.id_remote_mailbox
+                        data = IMAP_last_fetched_id: mail.id_remote_mailbox
+                        @updateAttributes data, (err) ->
+                            if err
+                                emitOnErr server, err
+                            else
+                                mailsDone++
+                                job.progress mailsDone, results.length
+
+                                if mailsToGo is mailsDone
+                                    callback()
+                                else
+                                    fetchOne(server, i + 1, results, mailsDone)
+
+        else
+            server.logout ->
+                if mailsToGo isnt mailsDone
+                    msg = "Could not import all the mail. Retry"
+                    server.emit "error", new Error(msg)
+
 
 ###
     ## Specialised function to prepare a new mailbox for import and fetching new mail


Mailbox::setupImport = (callback) ->
    
    ## dependences
    imap = require "imap"

    # global vars
    mailbox = @
    debug = true
               
    emitOnErr = (server, error) ->
        if error
            console.log error
            server.emit "error", error

    loadInboxMails = (server) ->
        console.log "INBOX opened successfuly" if debug
        server.search ['ALL'], (err, results) =>
            if err
                emitOnErr err
            else
                console.log "Search query succeeded" if debug

                unless results.length
                    console.log "Nothing to download" if debug
                    server.logout()
                    callback()
                else
                    if debug
                        console.log "[" + results.length + "] mails to download"
                    
                    mailsToGo = results.length
                    mailsDone = 0
                    maxId = 0
                    fetchOne server, results, 0, mailsDone, mailsToGo, maxId

            
    # for every ID, fetch the message
    fetchOne = (server, results, i, mailsDone, mailsToGo, maxId) ->
        
        if i < results.length
            

            idInt = parseInt id
            maxId = idInt if idInt > maxId
    
            mailbox.mailsToBe.create remoteId: idInt, (error, mailToBe) =>
                if error
                    server.logout -> server.emit "error", error
                else
                    console.log "#{mailToBe.remoteId} id saved successfully"
                    mailsDone++
        
                    if mailsDone is mailsToGo
                        console.log "Finished saving ids to database"
                        console.log "max id = #{maxId}"
