Index: Src/GoogleApis.DotNet4/Apis/Util/Store/FileDataStore.cs
===================================================================
new file mode 100644
--- /dev/null
+++ b/Src/GoogleApis.DotNet4/Apis/Util/Store/FileDataStore.cs
@@ -0,0 +1,151 @@
+/*
+Copyright 2011 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+using System;
+using System.IO;
+using System.Threading.Tasks;
+
+using Google.Apis.Util.Store;
+using Google.Apis.Json;
+
+namespace Google.Apis.Apis.Util.Store
+{
+ ///
+ /// File data store that implements . This store creates a different file for each
+ /// combination of type and key.
+ ///
+ public class FileDataStore : IDataStore
+ {
+ readonly string folderPath;
+ /// Gets the full folder path.
+ public string FolderPath { get { return folderPath; } }
+
+ ///
+ /// Constructs a new file data store with the specified folder. This folder is created (if it doesn't exist
+ /// yet) under .
+ ///
+ /// Folder name
+ public FileDataStore(string folder)
+ {
+ folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), folder);
+ if (!Directory.Exists(folderPath))
+ {
+ Directory.CreateDirectory(folderPath);
+ }
+ }
+
+ ///
+ /// Stores the given value for the given key. It creates a new file (named ) in
+ /// .
+ ///
+ /// The type to store in the data store
+ /// The key
+ /// The value to store in the data store
+ public Task Store(string key, T value)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentException("Key MUST have a value");
+ }
+
+ var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value);
+ var filePath = Path.Combine(folderPath, GetStoredKey(key, typeof(T)));
+ File.WriteAllText(filePath, serialized);
+ return TaskEx.Delay(0);
+ }
+
+ ///
+ /// Deletes the given key. It deletes the named file in .
+ ///
+ /// The key to delete from the data store
+ /// The type of the stored value
+ public Task Delete(string key, Type t)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentException("Key MUST have a value");
+ }
+ if (t == null)
+ {
+ throw new ArgumentException("Type can't be null");
+ }
+
+ var filePath = Path.Combine(folderPath, GetStoredKey(key, t));
+ if (File.Exists(filePath))
+ {
+ File.Delete(filePath);
+ }
+ return TaskEx.Delay(0);
+ }
+
+ ///
+ /// Returns the stored value for the given key or null if the matching file (
+ /// in doesn't exist.
+ ///
+ /// The type to retrieve
+ /// The key to retrieve from the data store
+ /// The stored object
+ public Task Get(string key)
+ {
+ if (string.IsNullOrEmpty(key))
+ {
+ throw new ArgumentException("Key MUST have a value");
+ }
+
+ TaskCompletionSource tcs = new TaskCompletionSource();
+ var filePath = Path.Combine(folderPath, GetStoredKey(key, typeof(T)));
+ if (File.Exists(filePath))
+ {
+ try
+ {
+ var obj = File.ReadAllText(filePath);
+ tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize(obj));
+ }
+ catch (Exception ex)
+ {
+ tcs.SetException(ex);
+ }
+ }
+ else
+ {
+ tcs.SetResult(default(T));
+ }
+ return tcs.Task;
+ }
+
+ ///
+ /// Clears all values in the data store. This method deletes all files in .
+ ///
+ public Task Clear()
+ {
+ if (Directory.Exists(folderPath))
+ {
+ Directory.Delete(folderPath, true);
+ Directory.CreateDirectory(folderPath);
+ }
+
+ return TaskEx.Delay(0);
+ }
+
+ /// Creates a unique stored key based on the key and the class type.
+ /// The object key
+ /// The type to store or retrieve
+ public static string GetStoredKey(string key, Type t)
+ {
+ return string.Format("{0}-{1}", t.FullName, key);
+ }
+ }
+}