Convert Repository types to use interior mutability

This changes `Repository` to use interior mutability
in order to store state. At the moment, `EphemeralRepository`
is the only repository type that stores state. By switching
over to internally using `Arc<Mutex<...>>>` to wrap the state,
it allows repositories to be used concurrently across threads.
This trait will be especially important as we transition
over to using asynchronous io with Hyper 0.11+.
diff --git a/src/client.rs b/src/client.rs
index fe83d2c..5a9cb85 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -133,7 +133,7 @@
     ///
     /// **WARNING**: This method offers weaker security guarantees than the related method
     /// `with_root_pinned`.
-    pub fn new(config: Config<T>, mut local: L, remote: R) -> Result<Self> {
+    pub fn new(config: Config<T>, local: L, remote: R) -> Result<Self> {
         let root = local
             .fetch_metadata(
                 &MetadataPath::from_role(&Role::Root),
@@ -169,8 +169,8 @@
     pub fn with_root_pinned<'a, I>(
         trusted_root_keys: I,
         config: Config<T>,
-        mut local: L,
-        mut remote: R,
+        local: L,
+        remote: R,
     ) -> Result<Self>
     where
         I: IntoIterator<Item = &'a KeyId>,
@@ -776,7 +776,7 @@
 
     #[test]
     fn root_chain_update() {
-        let mut repo = EphemeralRepository::new();
+        let repo = EphemeralRepository::new();
         let root = RootMetadata::new(
             1,
             Utc.ymd(2038, 1, 1).and_hms(0, 0, 0),
diff --git a/src/repository.rs b/src/repository.rs
index 38e5191..1bfb705 100644
--- a/src/repository.rs
+++ b/src/repository.rs
@@ -9,6 +9,7 @@
 use std::io::{Cursor, Read, Write};
 use std::marker::PhantomData;
 use std::path::PathBuf;
+use std::sync::{Arc, RwLock};
 use tempfile::NamedTempFile;
 
 use crypto::{self, HashAlgorithm, HashValue};
@@ -34,7 +35,7 @@
     /// Note: This **MUST** canonicalize the bytes before storing them as a read will expect the
     /// hashes of the metadata to match.
     fn store_metadata<M>(
-        &mut self,
+        &self,
         meta_path: &MetadataPath,
         version: &MetadataVersion,
         metadata: &SignedMetadata<D, M>,
@@ -44,7 +45,7 @@
 
     /// Fetch signed metadata.
     fn fetch_metadata<M>(
-        &mut self,
+        &self,
         meta_path: &MetadataPath,
         version: &MetadataVersion,
         max_size: &Option<usize>,
@@ -55,13 +56,13 @@
         M: Metadata;
 
     /// Store the given target.
-    fn store_target<R>(&mut self, read: R, target_path: &TargetPath) -> Result<()>
+    fn store_target<R>(&self, read: R, target_path: &TargetPath) -> Result<()>
     where
         R: Read;
 
     /// Fetch the given target.
     fn fetch_target(
-        &mut self,
+        &self,
         target_path: &TargetPath,
         target_description: &TargetDescription,
         min_bytes_per_second: u32,
@@ -119,7 +120,7 @@
     type TargetRead = File;
 
     fn store_metadata<M>(
-        &mut self,
+        &self,
         meta_path: &MetadataPath,
         version: &MetadataVersion,
         metadata: &SignedMetadata<D, M>,
@@ -151,7 +152,7 @@
 
     /// Fetch signed metadata.
     fn fetch_metadata<M>(
-        &mut self,
+        &self,
         meta_path: &MetadataPath,
         version: &MetadataVersion,
         max_size: &Option<usize>,
@@ -176,7 +177,7 @@
         Ok(D::from_reader(read)?)
     }
 
-    fn store_target<R>(&mut self, mut read: R, target_path: &TargetPath) -> Result<()>
+    fn store_target<R>(&self, mut read: R, target_path: &TargetPath) -> Result<()>
     where
         R: Read,
     {
@@ -206,7 +207,7 @@
     }
 
     fn fetch_target(
-        &mut self,
+        &self,
         target_path: &TargetPath,
         target_description: &TargetDescription,
         min_bytes_per_second: u32,
@@ -316,7 +317,7 @@
 
     /// This always returns `Err` as storing over HTTP is not yet supported.
     fn store_metadata<M>(
-        &mut self,
+        &self,
         _: &MetadataPath,
         _: &MetadataVersion,
         _: &SignedMetadata<D, M>,
@@ -330,7 +331,7 @@
     }
 
     fn fetch_metadata<M>(
-        &mut self,
+        &self,
         meta_path: &MetadataPath,
         version: &MetadataVersion,
         max_size: &Option<usize>,
@@ -354,7 +355,7 @@
     }
 
     /// This always returns `Err` as storing over HTTP is not yet supported.
-    fn store_target<R>(&mut self, _: R, _: &TargetPath) -> Result<()>
+    fn store_target<R>(&self, _: R, _: &TargetPath) -> Result<()>
     where
         R: Read,
     {
@@ -362,7 +363,7 @@
     }
 
     fn fetch_target(
-        &mut self,
+        &self,
         target_path: &TargetPath,
         target_description: &TargetDescription,
         min_bytes_per_second: u32,
@@ -383,8 +384,8 @@
 where
     D: DataInterchange,
 {
-    metadata: HashMap<(MetadataPath, MetadataVersion), Vec<u8>>,
-    targets: HashMap<TargetPath, Vec<u8>>,
+    metadata: Arc<RwLock<HashMap<(MetadataPath, MetadataVersion), Vec<u8>>>>,
+    targets: Arc<RwLock<HashMap<TargetPath, Vec<u8>>>>,
     interchange: PhantomData<D>,
 }
 
@@ -395,8 +396,8 @@
     /// Create a new ephemercal repository.
     pub fn new() -> Self {
         EphemeralRepository {
-            metadata: HashMap::new(),
-            targets: HashMap::new(),
+            metadata: Arc::new(RwLock::new(HashMap::new())),
+            targets: Arc::new(RwLock::new(HashMap::new())),
             interchange: PhantomData,
         }
     }
@@ -418,7 +419,7 @@
     type TargetRead = Cursor<Vec<u8>>;
 
     fn store_metadata<M>(
-        &mut self,
+        &self,
         meta_path: &MetadataPath,
         version: &MetadataVersion,
         metadata: &SignedMetadata<D, M>,
@@ -429,13 +430,13 @@
         Self::check::<M>(meta_path)?;
         let mut buf = Vec::new();
         D::to_writer(&mut buf, metadata)?;
-        let _ = self.metadata
-            .insert((meta_path.clone(), version.clone()), buf);
+        let mut metadata = self.metadata.write().unwrap();
+        let _ = metadata.insert((meta_path.clone(), version.clone()), buf);
         Ok(())
     }
 
     fn fetch_metadata<M>(
-        &mut self,
+        &self,
         meta_path: &MetadataPath,
         version: &MetadataVersion,
         max_size: &Option<usize>,
@@ -447,7 +448,8 @@
     {
         Self::check::<M>(meta_path)?;
 
-        match self.metadata.get(&(meta_path.clone(), version.clone())) {
+        let metadata = self.metadata.read().unwrap();
+        match metadata.get(&(meta_path.clone(), version.clone())) {
             Some(bytes) => {
                 let reader = SafeReader::new(
                     &**bytes,
@@ -461,23 +463,25 @@
         }
     }
 
-    fn store_target<R>(&mut self, mut read: R, target_path: &TargetPath) -> Result<()>
+    fn store_target<R>(&self, mut read: R, target_path: &TargetPath) -> Result<()>
     where
         R: Read,
     {
         let mut buf = Vec::new();
         read.read_to_end(&mut buf)?;
-        let _ = self.targets.insert(target_path.clone(), buf);
+        let mut targets = self.targets.write().unwrap();
+        let _ = targets.insert(target_path.clone(), buf);
         Ok(())
     }
 
     fn fetch_target(
-        &mut self,
+        &self,
         target_path: &TargetPath,
         target_description: &TargetDescription,
         min_bytes_per_second: u32,
     ) -> Result<SafeReader<Self::TargetRead>> {
-        match self.targets.get(target_path) {
+        let targets = self.targets.read().unwrap();
+        match targets.get(target_path) {
             Some(bytes) => {
                 let cur = Cursor::new(bytes.clone());
                 let (alg, value) = crypto::hash_preference(target_description.hashes())?;
@@ -502,7 +506,7 @@
 
     #[test]
     fn ephemeral_repo_targets() {
-        let mut repo = EphemeralRepository::<Json>::new();
+        let repo = EphemeralRepository::<Json>::new();
 
         let data: &[u8] = b"like tears in the rain";
         let target_description =
@@ -524,7 +528,7 @@
     #[test]
     fn file_system_repo_targets() {
         let temp_dir = TempDir::new("rust-tuf").unwrap();
-        let mut repo = FileSystemRepository::<Json>::new(temp_dir.path().to_path_buf()).unwrap();
+        let repo = FileSystemRepository::<Json>::new(temp_dir.path().to_path_buf()).unwrap();
 
         // test that init worked
         assert!(temp_dir.path().join("metadata").exists());