public Anki2Importer(Collection collection, StorageFolder sourceFolder, string relativePathToFile)
     : base(collection, sourceFolder, relativePathToFile)
 {
     needMapper         = false;
     deckPrefix         = null;
     isAllowUpdate      = new DuplicateNoteUpdate();
     dupeOnSchemaChange = false;
     importedNoteId     = new List <long>();
     importedDeckIdMap  = new Dictionary <long, long>();
 }
        private async Task ImportNotes()
        {
            // build guid -> (id,mod,mid) hash & map of existing note ids
            notes = new Dictionary <string, object[]>();
            Dictionary <long, bool> existing = new Dictionary <long, bool>();
            var list = destCol.Database.QueryColumn <NoteTable>("select id, guid, mod, mid from notes");

            foreach (NoteTable n in list)
            {
                long   id   = n.Id;
                string guid = n.GuId;
                long   mod  = n.TimeModified;
                long   mid  = n.Mid;
                notes.Add(guid, new object[] { id, mod, mid });
                existing.Add(id, true);
            }
            // we may need to rewrite the guid if the model schemas don't match,
            // so we need to keep track of the changes for the card import stage
            changedGuids = new Dictionary <string, string>();
            // apart from upgrading from anki1 decks, we ignore updates to changed
            // schemas. we need to note the ignored guids, so we avoid importing
            // invalid cards
            ignoredGuids = new Dictionary <string, bool>();
            // iterate over source collection
            List <object[]> add          = new List <object[]>();
            List <object[]> update       = new List <object[]>();
            List <long>     dirty        = new List <long>();
            int             usn          = destCol.Usn;
            int             dupes        = 0;
            List <string>   dupesIgnored = new List <string>();

            list = sourceCol.Database.QueryColumn <NoteTable>("select * from notes");

            bool largeCollection = total > 200;
            int  i = 0;

            foreach (NoteTable nl in list)
            {
                bool shouldAdd = UniquifyNote(nl);
                // turn the db result into a mutable list
                object[] note = new object[] { nl.Id, nl.GuId, nl.Mid, nl.TimeModified, nl.Usn,
                                               nl.Tags, nl.Fields, nl.Sortfields, nl.CheckSum,
                                               nl.Flags, nl.Data };

                if (shouldAdd)
                {
                    // ensure id is unique
                    while (existing.ContainsKey(nl.Id))
                    {
                        nl.Id = nl.Id + 999;
                    }
                    existing.Add(nl.Id, true);
                    note[0] = nl.Id;
                    // bump usn
                    note[4] = usn;
                    //WARNING: in ankiU media files are store in their
                    //deckId folder so we simply replace exising files
                    //with imported files if they have the same same
                    //// update media references in case of dupes
                    //note[6] = await MungeMedia(nl.Mid, nl.Fields);
                    note[6] = nl.Fields;
                    add.Add(note);
                    dirty.Add(nl.Id);
                    // note we have the added guid
                    notes.Add(nl.GuId, new object[] { note[0], note[3], note[MID] });
                }
                else
                {
                    // a duplicate or changed schema - safe to update?
                    dupes += 1;
                    if (!isAllowUpdate.isNotAskAgain)
                    {
                        if (DuplicateNoteEvent != null)
                        {
                            isAllowUpdate = await DuplicateNoteEvent();
                        }
                    }

                    if (isAllowUpdate.isAllow)
                    {
                        object[] n      = notes[nl.GuId];
                        long     oldNid = Convert.ToInt64(n[0]);
                        long     oldMod = Convert.ToInt64(n[1]);
                        long     oldMid = Convert.ToInt64(n[2]);
                        // will update if incoming note more recent
                        if (oldMod < nl.TimeModified)
                        {
                            // safe if note types identical
                            if (oldMid == nl.Mid)
                            {
                                // incoming note should use existing id
                                note[0] = oldNid;
                                note[4] = usn;
                                //WARNING: in ankiU media files are store in their
                                //deckId folder so we simply replace exising files
                                //with imported files if they have the same same
                                //// update media references in case of dupes
                                //note[6] = await MungeMedia(nl.Mid, nl.Fields);
                                note[6] = nl.Fields;
                                update.Add(note);
                                dirty.Add(oldNid);
                            }
                            else
                            {
                                dupesIgnored.Add(String.Format("{0}: {1}",
                                                               destCol.Models.Get(oldMid).GetNamedString("name"),
                                                               (nl.Fields).Replace("\u001f", ",")));
                                ignoredGuids.Add(nl.GuId, true);
                            }
                        }
                    }
                }
                i++;
            }
            // export info for calling code
            this.dupes = dupes;
            added      = add.Count;
            updated    = update.Count;
            // add to col
            //Don't use excute many here as we've already call RunInTransaction in Import
            foreach (var c in add)
            {
                //Only in AnkU we will need this ID to move media files after importing
                importedNoteId.Add((long)c[0]);

                destCol.Database.Execute("insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)", c);
            }
            foreach (var u in update)
            {
                //Only in AnkU we will need this ID to move media files after importing
                importedNoteId.Add((long)u[0]);

                destCol.Database.Execute("insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)", u);
            }
            long[] das = dirty.ToArray();
            destCol.UpdateFieldCache(das);
            destCol.Tags.RegisterNotes(das);
        }