private void OnDocumentFileChanged(DocumentFileChanged data) { var pathParts = data.Path.Substring(_documentRoot.Path.Length) .Split(PathSeparators, StringSplitOptions.RemoveEmptyEntries); var current = _documentRoot; for (var index = 0; index < pathParts.Length; index++) { if (!current.IsChildrenInitialized) { break; } var part = pathParts[index]; var isLast = index == pathParts.Length - 1; var parent = current; current = current.InternalChildren[part]; // the current part is not in the tree if (current == null) { if (data.Type != DocumentFileChangeType.Deleted) { var currentPath = isLast && data.Type == DocumentFileChangeType.Renamed ? data.NewPath : Path.Combine(_documentRoot.Path, Path.Combine(pathParts.Take(index + 1).ToArray())); var newDocument = DocumentViewModel.FromPath(currentPath); if (!newDocument.IsAutoSave && IsRelevantDocument(newDocument)) { parent.AddChild(newDocument); } } break; } // it's the last part - the actual file if (isLast) { switch (data.Type) { case DocumentFileChangeType.Renamed: current.ChangePath(data.NewPath); // move it to the correct place parent.InternalChildren.Remove(current); if (IsRelevantDocument(current)) { parent.AddChild(current); } break; case DocumentFileChangeType.Deleted: parent.InternalChildren.Remove(current); break; } } } }