//--------------------------------------------------------------------------------
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="from">The folder we're syncing from (where the files are copied from)</param>
 /// <param name="to">The folder we're syncing to (where the files wil be copied to)</param>
 public FileInfoList(string from, string to)
 {
     this.SyncParent     = null;
     this.m_syncFromPath = from;
     this.m_syncToPath   = to;
 }
 //--------------------------------------------------------------------------------
 public FileInfoList(SyncItem parent)
 {
     this.SyncParent = parent;
     m_syncFromPath  = this.SyncParent.SyncFromPath;
     m_syncToPath    = this.SyncParent.SyncToPath;
 }
        //--------------------------------------------------------------------------------
        public void Update(string path, bool incSubs)
        {
            // read from Settings.xml file
            string             FullyQualifiedPath = System.IO.Path.Combine(CreateAppDataFolder(APP_DATA_FOLDER), APP_DATA_FILENAME);
            SyncItemCollection SyncItems          = new SyncItemCollection();

            try
            {
                XDocument doc  = XDocument.Load(FullyQualifiedPath);
                XElement  root = doc.Element("ROOT");
                if (root != null)
                {
                    XElement settings = root.Element(SETTINGS_KEYNAME);
                    if (SyncParent != null)
                    {
                        this.SyncParent = null;
                    }
                    SyncItems       = new SyncItemCollection(root.Element("SyncItems"));
                    this.SyncParent = SyncItems[0];
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Select synchronize folders");
            }


            FileInfoList newList = new FileInfoList(SyncParent.SyncFromPath, this.SyncParent.SyncToPath);

            newList.GetFiles(path, incSubs);

            foreach (FileInfoEx item in newList)
            {
                item.IsDeleted = (!this.NewOrChanged(item));
            }
            var newerList = (from item in newList
                             where NewOrChanged(item)
                             select item).ToList();

            newList.Clear();
            this.Updates = newerList.Count;

            // Rui add
            FileInfoList targetList = new FileInfoList(SyncParent.SyncFromPath, this.SyncParent.SyncToPath);

            targetList.GetFiles(SyncParent.SyncToPath, incSubs);
            var targetAllFileList = (from item in targetList
                                     where NewOrChanged(item)
                                     select item).ToList();

            targetList.Clear();
            if (SyncParent.Mirror)
            {
                SynchroSetup.Model.IPath MirrorFlag = pathClass.GetProcessFlag("-m");
                MirrorFlag.RunProcess("-m", SyncParent, null, null, targetAllFileList, newerList);
            }

            List <string> deletedDirList = new List <string>();
            string        tempPath       = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString());
            bool          isFirstStart   = true;
            // parse FileStates
            JObject filestates = null;

            if (!this.SyncParent.FileStates.Equals(""))
            {
                filestates = JObject.Parse(this.SyncParent.FileStates);
            }
            foreach (FileInfoEx item in newerList)
            {
                try
                {
                    item.FileState = (int)FileStates.Release;
                    if (filestates != null && filestates[item.FileName] != null)
                    {
                        item.FileState = (int)Enum.Parse(typeof(FileStates), filestates[item.FileName].ToString());
                    }
                    // build our file names
                    string sourceName   = System.IO.Path.Combine(SyncParent.SyncFromPath, item.FileName);
                    string targetName   = System.IO.Path.Combine(SyncParent.SyncToPath, item.FileName);
                    string tempFileName = System.IO.Path.Combine(tempPath, item.FileName);

                    if (!this.SyncParent.ExcludeDirOrFile.Equals(""))
                    {
                        IPattern excludeFlag = patternsClass.GetProcessFlag("-e");
                        if (excludeFlag.RunProcess(false, SyncParent, null, sourceName, null, null, null, 0))
                        {
                            continue;
                        }
                    }
                    if (!this.SyncParent.Pattern.Equals(""))
                    {
                        IPattern patternFlag = patternsClass.GetProcessFlag("-p");
                        if (patternFlag.RunProcess(true, SyncParent, item.FileName, null, null, item, null, 0))
                        {
                            continue;
                        }
                    }

                    if (!this.SyncParent.State.Equals("") /*&& !this.SyncParent.FileStates.Equals("")*/)
                    {
                        IPattern patternStateFlag = patternsClass.GetProcessFlag("-s");
                        if (!patternStateFlag.RunProcess(false, null, null, null, null, null, SyncParent.State.Split(','), item.FileState))
                        {
                            continue;
                        }
                    }

                    if (!this.SyncParent.IgnoreState.Equals(""))
                    {
                        IPattern ignoreStateFlag = patternsClass.GetProcessFlag("-is");
                        if (ignoreStateFlag.RunProcess(false, null, null, null, null, null, SyncParent.IgnoreState.Split(','), item.FileState))
                        {
                            continue;
                        }
                    }

                    if (!this.SyncParent.FolderMapping.Equals(""))
                    {
                        SynchroSetup.Model.IPath folderMappingFlag = pathClass.GetProcessFlag("-fm");
                        targetName = folderMappingFlag.RunProcess("-fm", SyncParent, sourceName, targetName, null, null);
                    }

                    if (this.SyncParent.ForceDownlaod && isFirstStart)
                    {
                        SynchroSetup.Model.IPath forceDownFlag = pathClass.GetProcessFlag("-fm");
                        forceDownFlag.RunProcess("-f", SyncParent, null, null, null, null);
                        isFirstStart = false;
                    }

                    if (this.SyncParent.Lock)
                    {
                        if (!Directory.Exists(tempPath))
                        {
                            Directory.CreateDirectory(tempPath);
                        }
                        IPattern lockFlag = patternsClass.GetProcessFlag("-lck");
                        lockFlag.RunProcess(true, SyncParent, null, sourceName, tempFileName, item, null, 0);
                        lockFlag.RunProcess(false, SyncParent, null, tempFileName, targetName, item, null, 0);
                    }
                    else
                    {
                        FileDeleteAndCopy(sourceName, targetName, false, item, true);
                    }

                    if (this.SyncParent.Writable && File.Exists(targetName))
                    {
                        ILocal writableFlag = localClass.GetProcessFlag("-w");
                        writableFlag.RunProcess("-w", null, targetName, null, null, null);
                    }

                    if (!this.SyncParent.DeletedDirOrFile.Equals(""))
                    {
                        ILocal deleteFlag = localClass.GetProcessFlag("-d");
                        deleteFlag.RunProcess("-d", SyncParent, targetName, item, deletedDirList, null);
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Exception encountered while update the file {0}", item.FileName), ex);
                }
            }

            if (deletedDirList.Count != 0)
            {
                DeleteDirectory(deletedDirList);
            }

            if (!this.SyncParent.RunFile.Equals(""))
            {
                ILocal runFlag = localClass.GetProcessFlag("-r");
                runFlag.RunProcess("-r", SyncParent, null, null, null, newerList);
            }
        }