Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 } | 434 } |
| 435 | 435 |
| 436 // Callback for GetEntryByResourceIdAsync. | 436 // Callback for GetEntryByResourceIdAsync. |
| 437 // Adds |entry| to |results|. Runs |callback| with |results| when | 437 // Adds |entry| to |results|. Runs |callback| with |results| when |
| 438 // |run_callback| is true. | 438 // |run_callback| is true. |
| 439 void AddEntryToSearchResults( | 439 void AddEntryToSearchResults( |
| 440 std::vector<SearchResultInfo>* results, | 440 std::vector<SearchResultInfo>* results, |
| 441 const SearchCallback& callback, | 441 const SearchCallback& callback, |
| 442 GDataFileError error, | 442 GDataFileError error, |
| 443 bool run_callback, | 443 bool run_callback, |
| 444 const GURL& next_feed, | |
| 444 GDataEntry* entry) { | 445 GDataEntry* entry) { |
| 445 // If a result is not present in our local file system snapshot, ignore it. | 446 // If a result is not present in our local file system snapshot, ignore it. |
| 446 // For example, this may happen if the entry has recently been added to the | 447 // For example, this may happen if the entry has recently been added to the |
| 447 // drive (and we still haven't received its delta feed). | 448 // drive (and we still haven't received its delta feed). |
| 448 if (entry) { | 449 if (entry) { |
| 449 const bool is_directory = entry->AsGDataDirectory() != NULL; | 450 const bool is_directory = entry->AsGDataDirectory() != NULL; |
| 450 results->push_back(SearchResultInfo(entry->GetFilePath(), is_directory)); | 451 results->push_back(SearchResultInfo(entry->GetFilePath(), is_directory)); |
| 451 } | 452 } |
| 452 | 453 |
| 453 if (run_callback) { | 454 if (run_callback) { |
| 454 scoped_ptr<std::vector<SearchResultInfo> > result_vec(results); | 455 scoped_ptr<std::vector<SearchResultInfo> > result_vec(results); |
| 455 if (!callback.is_null()) | 456 if (!callback.is_null()) |
| 456 callback.Run(error, result_vec.Pass()); | 457 callback.Run(error, next_feed, result_vec.Pass()); |
| 457 } | 458 } |
| 458 } | 459 } |
| 459 | 460 |
| 460 // Runs task on UI thread. | 461 // Runs task on UI thread. |
| 461 void RunTaskOnUIThread(const base::Closure& task) { | 462 void RunTaskOnUIThread(const base::Closure& task) { |
| 462 RunTaskOnThread( | 463 RunTaskOnThread( |
| 463 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), task); | 464 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), task); |
| 464 } | 465 } |
| 465 | 466 |
| 466 // RelayCallback relays arguments for callback running on the given thread. | 467 // RelayCallback relays arguments for callback running on the given thread. |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 967 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 968 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 968 | 969 |
| 969 GDataFileError error = GDataToGDataFileError(status); | 970 GDataFileError error = GDataToGDataFileError(status); |
| 970 if (error != GDATA_FILE_OK) { | 971 if (error != GDATA_FILE_OK) { |
| 971 // Get changes starting from the next changestamp from what we have locally. | 972 // Get changes starting from the next changestamp from what we have locally. |
| 972 LoadFeedFromServer(initial_origin, | 973 LoadFeedFromServer(initial_origin, |
| 973 local_changestamp + 1, 0, | 974 local_changestamp + 1, 0, |
| 974 true, /* should_fetch_multiple_feeds */ | 975 true, /* should_fetch_multiple_feeds */ |
| 975 search_file_path, | 976 search_file_path, |
| 976 std::string() /* no search query */, | 977 std::string() /* no search query */, |
| 978 GURL(), | |
|
satorux1
2012/07/20 17:13:04
please add some comment
tbarzic
2012/07/20 17:51:43
Done.
| |
| 977 std::string() /* no directory resource ID */, | 979 std::string() /* no directory resource ID */, |
| 978 callback, | 980 callback, |
| 979 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, | 981 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, |
| 980 ui_weak_ptr_)); | 982 ui_weak_ptr_)); |
| 981 return; | 983 return; |
| 982 } | 984 } |
| 983 | 985 |
| 984 scoped_ptr<AccountMetadataFeed> account_metadata; | 986 scoped_ptr<AccountMetadataFeed> account_metadata; |
| 985 if (feed_data.get()) { | 987 if (feed_data.get()) { |
| 986 account_metadata = AccountMetadataFeed::CreateFrom(*feed_data); | 988 account_metadata = AccountMetadataFeed::CreateFrom(*feed_data); |
| 987 #ifndef NDEBUG | 989 #ifndef NDEBUG |
| 988 // Save account metadata feed for analysis. | 990 // Save account metadata feed for analysis. |
| 989 const FilePath path = | 991 const FilePath path = |
| 990 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( | 992 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_META).Append( |
| 991 kAccountMetadataFile); | 993 kAccountMetadataFile); |
| 992 PostBlockingPoolSequencedTask( | 994 PostBlockingPoolSequencedTask( |
| 993 FROM_HERE, | 995 FROM_HERE, |
| 994 blocking_task_runner_, | 996 blocking_task_runner_, |
| 995 base::Bind(&SaveFeedOnBlockingPoolForDebugging, | 997 base::Bind(&SaveFeedOnBlockingPoolForDebugging, |
| 996 path, base::Passed(&feed_data))); | 998 path, base::Passed(&feed_data))); |
| 997 #endif | 999 #endif |
| 998 } | 1000 } |
| 999 | 1001 |
| 1000 if (!account_metadata.get()) { | 1002 if (!account_metadata.get()) { |
| 1001 LoadFeedFromServer(initial_origin, | 1003 LoadFeedFromServer(initial_origin, |
| 1002 local_changestamp + 1, 0, | 1004 local_changestamp + 1, 0, |
| 1003 true, /* should_fetch_multiple_feeds */ | 1005 true, /* should_fetch_multiple_feeds */ |
| 1004 search_file_path, | 1006 search_file_path, |
| 1005 std::string() /* no search query */, | 1007 std::string() /* no search query */, |
| 1008 GURL(), | |
|
satorux1
2012/07/20 17:13:04
ditto
tbarzic
2012/07/20 17:51:43
Done.
| |
| 1006 std::string() /* no directory resource ID */, | 1009 std::string() /* no directory resource ID */, |
| 1007 callback, | 1010 callback, |
| 1008 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, | 1011 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, |
| 1009 ui_weak_ptr_)); | 1012 ui_weak_ptr_)); |
| 1010 return; | 1013 return; |
| 1011 } | 1014 } |
| 1012 | 1015 |
| 1013 webapps_registry_->UpdateFromFeed(account_metadata.get()); | 1016 webapps_registry_->UpdateFromFeed(account_metadata.get()); |
| 1014 | 1017 |
| 1015 bool changes_detected = true; | 1018 bool changes_detected = true; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1031 return; | 1034 return; |
| 1032 } | 1035 } |
| 1033 | 1036 |
| 1034 // Load changes from the server. | 1037 // Load changes from the server. |
| 1035 LoadFeedFromServer(initial_origin, | 1038 LoadFeedFromServer(initial_origin, |
| 1036 local_changestamp > 0 ? local_changestamp + 1 : 0, | 1039 local_changestamp > 0 ? local_changestamp + 1 : 0, |
| 1037 account_metadata->largest_changestamp(), | 1040 account_metadata->largest_changestamp(), |
| 1038 true, /* should_fetch_multiple_feeds */ | 1041 true, /* should_fetch_multiple_feeds */ |
| 1039 search_file_path, | 1042 search_file_path, |
| 1040 std::string() /* no search query */, | 1043 std::string() /* no search query */, |
| 1044 GURL(), | |
|
satorux1
2012/07/20 17:13:04
ditto
tbarzic
2012/07/20 17:51:43
Done.
| |
| 1041 std::string() /* no directory resource ID */, | 1045 std::string() /* no directory resource ID */, |
| 1042 callback, | 1046 callback, |
| 1043 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, | 1047 base::Bind(&GDataFileSystem::OnFeedFromServerLoaded, |
| 1044 ui_weak_ptr_)); | 1048 ui_weak_ptr_)); |
| 1045 } | 1049 } |
| 1046 | 1050 |
| 1047 void GDataFileSystem::LoadFeedFromServer( | 1051 void GDataFileSystem::LoadFeedFromServer( |
| 1048 ContentOrigin initial_origin, | 1052 ContentOrigin initial_origin, |
| 1049 int start_changestamp, | 1053 int start_changestamp, |
| 1050 int root_feed_changestamp, | 1054 int root_feed_changestamp, |
| 1051 bool should_fetch_multiple_feeds, | 1055 bool should_fetch_multiple_feeds, |
| 1052 const FilePath& search_file_path, | 1056 const FilePath& search_file_path, |
| 1053 const std::string& search_query, | 1057 const std::string& search_query, |
| 1058 const GURL& feed_to_load, | |
| 1054 const std::string& directory_resource_id, | 1059 const std::string& directory_resource_id, |
| 1055 const FindEntryCallback& entry_found_callback, | 1060 const FindEntryCallback& entry_found_callback, |
| 1056 const LoadDocumentFeedCallback& feed_load_callback) { | 1061 const LoadDocumentFeedCallback& feed_load_callback) { |
| 1057 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1062 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1058 | 1063 |
| 1059 // |feed_list| will contain the list of all collected feed updates that | 1064 // |feed_list| will contain the list of all collected feed updates that |
| 1060 // we will receive through calls of DocumentsService::GetDocuments(). | 1065 // we will receive through calls of DocumentsService::GetDocuments(). |
| 1061 scoped_ptr<std::vector<DocumentFeed*> > feed_list( | 1066 scoped_ptr<std::vector<DocumentFeed*> > feed_list( |
| 1062 new std::vector<DocumentFeed*>); | 1067 new std::vector<DocumentFeed*>); |
| 1063 const base::TimeTicks start_time = base::TimeTicks::Now(); | 1068 const base::TimeTicks start_time = base::TimeTicks::Now(); |
| 1064 documents_service_->GetDocuments( | 1069 documents_service_->GetDocuments( |
| 1065 GURL(), // root feed start. | 1070 feed_to_load, |
| 1066 start_changestamp, | 1071 start_changestamp, |
| 1067 search_query, | 1072 search_query, |
| 1068 directory_resource_id, | 1073 directory_resource_id, |
| 1069 base::Bind(&GDataFileSystem::OnGetDocuments, | 1074 base::Bind(&GDataFileSystem::OnGetDocuments, |
| 1070 ui_weak_ptr_, | 1075 ui_weak_ptr_, |
| 1071 initial_origin, | 1076 initial_origin, |
| 1072 feed_load_callback, | 1077 feed_load_callback, |
| 1073 base::Owned(new GetDocumentsParams(start_changestamp, | 1078 base::Owned(new GetDocumentsParams(start_changestamp, |
| 1074 root_feed_changestamp, | 1079 root_feed_changestamp, |
| 1075 feed_list.release(), | 1080 feed_list.release(), |
| (...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2339 LOG(ERROR) << "Directory entry not found: " << file_path.value(); | 2344 LOG(ERROR) << "Directory entry not found: " << file_path.value(); |
| 2340 return; | 2345 return; |
| 2341 } | 2346 } |
| 2342 | 2347 |
| 2343 LoadFeedFromServer(directory_service_->origin(), | 2348 LoadFeedFromServer(directory_service_->origin(), |
| 2344 0, // Not delta feed. | 2349 0, // Not delta feed. |
| 2345 0, // Not used. | 2350 0, // Not used. |
| 2346 true, // multiple feeds | 2351 true, // multiple feeds |
| 2347 file_path, | 2352 file_path, |
| 2348 std::string(), // No search query | 2353 std::string(), // No search query |
| 2354 GURL(), | |
|
satorux1
2012/07/20 17:13:04
ditto.
tbarzic
2012/07/20 17:51:43
Done.
| |
| 2349 entry_proto->resource_id(), | 2355 entry_proto->resource_id(), |
| 2350 FindEntryCallback(), // Not used. | 2356 FindEntryCallback(), // Not used. |
| 2351 base::Bind(&GDataFileSystem::OnRequestDirectoryRefresh, | 2357 base::Bind(&GDataFileSystem::OnRequestDirectoryRefresh, |
| 2352 ui_weak_ptr_)); | 2358 ui_weak_ptr_)); |
| 2353 } | 2359 } |
| 2354 | 2360 |
| 2355 void GDataFileSystem::OnRequestDirectoryRefresh( | 2361 void GDataFileSystem::OnRequestDirectoryRefresh( |
| 2356 GetDocumentsParams* params, | 2362 GetDocumentsParams* params, |
| 2357 GDataFileError error) { | 2363 GDataFileError error) { |
| 2358 DCHECK(params); | 2364 DCHECK(params); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2631 } | 2637 } |
| 2632 } | 2638 } |
| 2633 | 2639 |
| 2634 void GDataFileSystem::OnSearch(const SearchCallback& callback, | 2640 void GDataFileSystem::OnSearch(const SearchCallback& callback, |
| 2635 GetDocumentsParams* params, | 2641 GetDocumentsParams* params, |
| 2636 GDataFileError error) { | 2642 GDataFileError error) { |
| 2637 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2643 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2638 | 2644 |
| 2639 if (error != GDATA_FILE_OK) { | 2645 if (error != GDATA_FILE_OK) { |
| 2640 if (!callback.is_null()) | 2646 if (!callback.is_null()) |
| 2641 callback.Run(error, scoped_ptr<std::vector<SearchResultInfo> >()); | 2647 callback.Run(error, GURL(), scoped_ptr<std::vector<SearchResultInfo> >()); |
| 2642 return; | 2648 return; |
| 2643 } | 2649 } |
| 2644 | 2650 |
| 2645 // The search results will be returned using virtual directory. | 2651 // The search results will be returned using virtual directory. |
| 2646 // The directory is not really part of the file system, so it has no parent or | 2652 // The directory is not really part of the file system, so it has no parent or |
| 2647 // root. | 2653 // root. |
| 2648 std::vector<SearchResultInfo>* results(new std::vector<SearchResultInfo>()); | 2654 std::vector<SearchResultInfo>* results(new std::vector<SearchResultInfo>()); |
| 2649 | 2655 |
| 2650 DCHECK_EQ(1u, params->feed_list->size()); | 2656 DCHECK_EQ(1u, params->feed_list->size()); |
| 2651 DocumentFeed* feed = params->feed_list->at(0); | 2657 DocumentFeed* feed = params->feed_list->at(0); |
| 2652 | 2658 |
| 2659 GURL next_feed; | |
| 2660 feed->GetNextFeedURL(&next_feed); | |
|
satorux1
2012/07/20 17:13:04
are we going to fetch all the search results? What
tbarzic
2012/07/20 17:51:43
Yeah, we should probably stop at certain number, b
satorux1
2012/07/20 17:55:56
I think having a hard limit here would be safer.
tbarzic
2012/07/20 18:32:19
yep, that was the number I had in mind to limit nu
| |
| 2661 | |
| 2653 if (feed->entries().empty()) { | 2662 if (feed->entries().empty()) { |
| 2654 scoped_ptr<std::vector<SearchResultInfo> > result_vec(results); | 2663 scoped_ptr<std::vector<SearchResultInfo> > result_vec(results); |
| 2655 if (!callback.is_null()) | 2664 if (!callback.is_null()) |
| 2656 callback.Run(error, result_vec.Pass()); | 2665 callback.Run(error, next_feed, result_vec.Pass()); |
| 2657 return; | 2666 return; |
| 2658 } | 2667 } |
| 2659 | 2668 |
| 2660 // Go through all entires generated by the feed and add them to the search | 2669 // Go through all entires generated by the feed and add them to the search |
| 2661 // result directory. | 2670 // result directory. |
| 2662 for (size_t i = 0; i < feed->entries().size(); ++i) { | 2671 for (size_t i = 0; i < feed->entries().size(); ++i) { |
| 2663 DocumentEntry* doc = const_cast<DocumentEntry*>(feed->entries()[i]); | 2672 DocumentEntry* doc = const_cast<DocumentEntry*>(feed->entries()[i]); |
| 2664 scoped_ptr<GDataEntry> entry( | 2673 scoped_ptr<GDataEntry> entry( |
| 2665 GDataEntry::FromDocumentEntry(NULL, doc, directory_service_.get())); | 2674 GDataEntry::FromDocumentEntry(NULL, doc, directory_service_.get())); |
| 2666 | 2675 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2682 | 2691 |
| 2683 // We will need information about result entry to create info for callback. | 2692 // We will need information about result entry to create info for callback. |
| 2684 // We can't use |entry| anymore, so we have to refetch entry from file | 2693 // We can't use |entry| anymore, so we have to refetch entry from file |
| 2685 // system. Also, |entry| doesn't have file path set before |RefreshFile| | 2694 // system. Also, |entry| doesn't have file path set before |RefreshFile| |
| 2686 // call, so we can't get file path from there. | 2695 // call, so we can't get file path from there. |
| 2687 directory_service_->GetEntryByResourceIdAsync(entry_resource_id, | 2696 directory_service_->GetEntryByResourceIdAsync(entry_resource_id, |
| 2688 base::Bind(&AddEntryToSearchResults, | 2697 base::Bind(&AddEntryToSearchResults, |
| 2689 results, | 2698 results, |
| 2690 callback, | 2699 callback, |
| 2691 error, | 2700 error, |
| 2692 i+1 == feed->entries().size())); | 2701 i+1 == feed->entries().size(), |
| 2702 next_feed)); | |
| 2693 } | 2703 } |
| 2694 } | 2704 } |
| 2695 | 2705 |
| 2696 void GDataFileSystem::Search(const std::string& search_query, | 2706 void GDataFileSystem::Search(const std::string& search_query, |
| 2707 const GURL& next_feed, | |
| 2697 const SearchCallback& callback) { | 2708 const SearchCallback& callback) { |
| 2698 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 2709 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || |
| 2699 BrowserThread::CurrentlyOn(BrowserThread::IO)); | 2710 BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 2700 RunTaskOnUIThread(base::Bind(&GDataFileSystem::SearchAsyncOnUIThread, | 2711 RunTaskOnUIThread(base::Bind(&GDataFileSystem::SearchAsyncOnUIThread, |
| 2701 ui_weak_ptr_, | 2712 ui_weak_ptr_, |
| 2702 search_query, | 2713 search_query, |
| 2714 next_feed, | |
| 2703 CreateRelayCallback(callback))); | 2715 CreateRelayCallback(callback))); |
| 2704 } | 2716 } |
| 2705 | 2717 |
| 2706 void GDataFileSystem::SearchAsyncOnUIThread( | 2718 void GDataFileSystem::SearchAsyncOnUIThread( |
| 2707 const std::string& search_query, | 2719 const std::string& search_query, |
| 2720 const GURL& next_feed, | |
| 2708 const SearchCallback& callback) { | 2721 const SearchCallback& callback) { |
| 2709 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 2722 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 2710 scoped_ptr<std::vector<DocumentFeed*> > feed_list( | 2723 scoped_ptr<std::vector<DocumentFeed*> > feed_list( |
| 2711 new std::vector<DocumentFeed*>); | 2724 new std::vector<DocumentFeed*>); |
| 2712 | 2725 |
| 2713 ContentOrigin initial_origin = directory_service_->origin(); | 2726 ContentOrigin initial_origin = directory_service_->origin(); |
| 2714 LoadFeedFromServer(initial_origin, | 2727 LoadFeedFromServer(initial_origin, |
| 2715 0, 0, // We don't use change stamps when fetching search | 2728 0, 0, // We don't use change stamps when fetching search |
| 2716 // data; we always fetch the whole result feed. | 2729 // data; we always fetch the whole result feed. |
| 2717 false, // Stop fetching search results after first feed | 2730 false, // Stop fetching search results after first feed |
| 2718 // chunk to avoid displaying huge number of search | 2731 // chunk to avoid displaying huge number of search |
| 2719 // results (especially since we don't cache them). | 2732 // results (especially since we don't cache them). |
| 2720 FilePath(), // Not used. | 2733 FilePath(), // Not used. |
| 2721 search_query, | 2734 search_query, |
| 2735 next_feed, | |
| 2722 std::string(), // No directory resource ID. | 2736 std::string(), // No directory resource ID. |
| 2723 FindEntryCallback(), // Not used. | 2737 FindEntryCallback(), // Not used. |
| 2724 base::Bind(&GDataFileSystem::OnSearch, | 2738 base::Bind(&GDataFileSystem::OnSearch, |
| 2725 ui_weak_ptr_, callback)); | 2739 ui_weak_ptr_, callback)); |
| 2726 } | 2740 } |
| 2727 | 2741 |
| 2728 void GDataFileSystem::OnGetDocuments(ContentOrigin initial_origin, | 2742 void GDataFileSystem::OnGetDocuments(ContentOrigin initial_origin, |
| 2729 const LoadDocumentFeedCallback& callback, | 2743 const LoadDocumentFeedCallback& callback, |
| 2730 GetDocumentsParams* params, | 2744 GetDocumentsParams* params, |
| 2731 base::TimeTicks start_time, | 2745 base::TimeTicks start_time, |
| (...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4093 // must go through here. Removes the |file_path| from the remembered set so | 4107 // must go through here. Removes the |file_path| from the remembered set so |
| 4094 // that subsequent operations can open the file again. | 4108 // that subsequent operations can open the file again. |
| 4095 open_files_.erase(file_path); | 4109 open_files_.erase(file_path); |
| 4096 | 4110 |
| 4097 // Then invokes the user-supplied callback function. | 4111 // Then invokes the user-supplied callback function. |
| 4098 if (!callback.is_null()) | 4112 if (!callback.is_null()) |
| 4099 callback.Run(result); | 4113 callback.Run(result); |
| 4100 } | 4114 } |
| 4101 | 4115 |
| 4102 } // namespace gdata | 4116 } // namespace gdata |
| OLD | NEW |