         title = note_meta['title']
         console.log('Merging note [' + guid + ']')
 
-        @find_note_by_guid(guid).then (note) =>
+        find_p = @find_note_by_guid(guid).then (note) =>
+          _find_p_must_finish_promise_list = []
           if note == null
             console.log('About to add note ' + guid)
-            @add_note_meta({
+            p = @add_note_meta({
               guid: guid
               title: title
-            })
+            }).then () => console.log('note ' + guid + ' metadata added!')
+            _find_p_must_finish_promise_list.push(p)
+            console.log('pushed to _find_p_must_finish_promise_list. TAG: A')
+
           else
             console.log('local note ' + guid + ' exists, updating from remote.')
-            switch local_note.status
+            switch note.status
               when @NOTE_STATUS.NEW
                 console.log('[IMPOSSIBLE] remote note\'s local cache is in status NEW')
+
               when @NOTE_STATUS.SYNCED_META
                 # update note title
-                @update_note({
+                p = @update_note({
                   guid: guid
                   title: title
                 })
+                _find_p_must_finish_promise_list.push(p)
+                console.log('pushed to _find_p_must_finish_promise_list. TAG: B')
+
               when @NOTE_STATUS.SYNCED_ALL
                 # fetch the whole note from server and update local
+                console.log('local note ' + guid + ' is SYNCED_ALL, about to fetch from remote for updating')
                 @fetch_remote_note(guid).then(
                   (data) =>
                     note =
                       guid: data.note.guid
                       title: data.note.title
                       md: data.note.md
-                    @update_note(note)
-                    # TODO @update_image_manager
+                    p = @update_note(note)
+                    # maybe FIXME did not add to promise waiting list
+                    #_find_p_must_finish_promise_list.push(p)
+                    #console.log('pushed to _find_p_must_finish_promise_list. TAG: C')
                   (error) =>
-                    alert('fetch note ' + guid + ' failed during _merge_remote_notess():' + JSON.stringify(error))
+                    alert('fetch note ' + guid + ' failed during _merge_remote_notes():' + JSON.stringify(error))
                 )
+
               when @NOTE_STATUS.MODIFIED
                 # do nothing
                 console.log('do nothing')
+
+              else
+                alert('IMPOSSIBLE: no correct note status')
+          return Promise.all(_find_p_must_finish_promise_list)
+        must_finish_promise_list.push(find_p)
+        console.log('pushed to must_finish_promise_list. TAG: D')
+
     # Phase two: deleted local notes not needed
     # Notes that should be deleted:
     # not in remote and status is not new/modified
-    @get_all_notes().then (notes) =>
+    p = @get_all_notes().then (notes) =>
       for n in notes
         if (n.guid not in remote_note_guid_list) && n.status != @NOTE_STATUS.NEW && n.status != @NOTE_STATUS.MODIFIED
-          @delete_note(n.guid)
+          _p = @delete_note(n.guid)
+          must_finish_promise_list.push(_p)
+          console.log('pushed to must_finish_promise_list. TAG: E')
+    must_finish_promise_list.push(p)
+    console.log('pushed to must_finish_promise_list. TAG: F')
+
+    console.log('about to return from _merge_remote_notes(). promise list: ' + JSON.stringify(must_finish_promise_list))
+    console.log('check if promises in promise list is actually Promises:')
+    for p in must_finish_promise_list
+      if p instanceof Promise
+        console.log('is Promise!')
+      else
+        console.log('is NOT Promise!!')
+    return Promise.all(must_finish_promise_list)
 
   # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| DB Operations >
 
   get_all_notes: () =>
+    console.log('get_all_notes() invoked')
     return new Promise (resolve, reject) =>
       resolve(@db_server.notes.query().all().execute())
 
   delete_note: (guid) =>
     console.log('delete_note(' + guid + ') invoked')
-    @find_note_by_guid(guid).then(
+    return @find_note_by_guid(guid).then(
       (note) =>
         alert('!!')
         if note is null

  # Possible situations: TODO
  # ------------------------------------------------------------
  _merge_remote_notes: (notes) =>
    # Phase one: patch remote notes to local
    remote_note_guid_list = []
    for note_meta in notes
      remote_note_guid_list.push(note_meta['guid'])
      do (note_meta) =>

  # return: promise
  # ------------------------------------------------------------
  load_remote_notes: =>
    # TODO handle failure
    return apiClient.notes.all().$promise.then (data) =>
      @_merge_remote_notes(data['notes']).then(
        () =>
          console.log('finish merging remote notes')
          return @get_all_notes()
        (error) =>
          # TODO pass error on
          alert('_merge_remote_notes() failed!')
      )

  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Merge/Sync Operations >

