diff --git a/src/client.rs b/src/client.rs
index 55fc68f..bed58bf 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -440,169 +440,14 @@
 
     // TODO this should check the local repo first
     fn _fetch_target(&mut self, target: &TargetPath) -> Result<SafeReader<R::TargetRead>> {
-        fn lookup<D_, L_, R_, T_>(
-            tuf: &mut Tuf<D_>,
-            config: &Config<T_>,
-            default_terminate: bool,
-            current_depth: u32,
-            target: &VirtualTargetPath,
-            snapshot: &SnapshotMetadata,
-            targets: Option<&TargetsMetadata>,
-            local: &mut L_,
-            remote: &mut R_,
-        ) -> (bool, Result<TargetDescription>)
-        where
-            D_: DataInterchange,
-            L_: Repository<D_>,
-            R_: Repository<D_>,
-            T_: PathTranslator,
-        {
-            if current_depth > config.max_delegation_depth {
-                warn!(
-                    "Walking the delegation graph would have exceeded the configured max depth: {}",
-                    config.max_delegation_depth
-                );
-                return (default_terminate, Err(Error::NotFound));
-            }
-
-            // these clones are dumb, but we need immutable values and not references for update
-            // tuf in the loop below
-            let targets = match targets {
-                Some(t) => t.clone(),
-                None => match tuf.targets() {
-                    Some(t) => t.clone(),
-                    None => {
-                        return (
-                            default_terminate,
-                            Err(Error::MissingMetadata(Role::Targets)),
-                        )
-                    }
-                },
-            };
-
-            if let Some(t) = targets.targets().get(target) {
-                return (default_terminate, Ok(t.clone()));
-            }
-
-            let delegations = match targets.delegations() {
-                Some(d) => d,
-                None => return (default_terminate, Err(Error::NotFound)),
-            };
-
-            for delegation in delegations.roles().iter() {
-                if !delegation.paths().iter().any(|p| target.is_child(p)) {
-                    if delegation.terminating() {
-                        return (true, Err(Error::NotFound));
-                    } else {
-                        continue;
-                    }
-                }
-
-                let role_meta = match snapshot.meta().get(delegation.role()) {
-                    Some(m) => m,
-                    None if !delegation.terminating() => continue,
-                    None => return (true, Err(Error::NotFound)),
-                };
-
-                let (alg, value) = match crypto::hash_preference(role_meta.hashes()) {
-                    Ok(h) => h,
-                    Err(e) => return (delegation.terminating(), Err(e)),
-                };
-
-                let version = if tuf.root().consistent_snapshot() {
-                    MetadataVersion::Hash(value.clone())
-                } else {
-                    MetadataVersion::None
-                };
-
-                let signed_meta = match local
-                    .fetch_metadata::<TargetsMetadata>(
-                        delegation.role(),
-                        &MetadataVersion::None,
-                        &Some(role_meta.size()),
-                        config.min_bytes_per_second(),
-                        Some((alg, value.clone())),
-                    )
-                    .or_else(|_| {
-                        remote.fetch_metadata::<TargetsMetadata>(
-                            delegation.role(),
-                            &version,
-                            &Some(role_meta.size()),
-                            config.min_bytes_per_second(),
-                            Some((alg, value.clone())),
-                        )
-                    }) {
-                    Ok(m) => m,
-                    Err(ref e) if !delegation.terminating() => {
-                        warn!("Failed to fetch metadata {:?}: {:?}", delegation.role(), e);
-                        continue;
-                    }
-                    Err(e) => {
-                        warn!("Failed to fetch metadata {:?}: {:?}", delegation.role(), e);
-                        return (true, Err(e));
-                    }
-                };
-
-                match tuf.update_delegation(delegation.role(), signed_meta.clone()) {
-                    Ok(_) => {
-                        match local.store_metadata(
-                            delegation.role(),
-                            &MetadataVersion::None,
-                            &signed_meta,
-                        ) {
-                            Ok(_) => (),
-                            Err(e) => warn!(
-                                "Error storing metadata {:?} locally: {:?}",
-                                delegation.role(),
-                                e
-                            ),
-                        }
-
-                        let meta = tuf.delegations().get(delegation.role()).unwrap().clone();
-                        let (term, res) = lookup(
-                            tuf,
-                            config,
-                            delegation.terminating(),
-                            current_depth + 1,
-                            target,
-                            snapshot,
-                            Some(meta.as_ref()),
-                            local,
-                            remote,
-                        );
-
-                        if term && res.is_err() {
-                            return (true, res);
-                        }
-
-                        // TODO end recursion early
-                    }
-                    Err(_) if !delegation.terminating() => continue,
-                    Err(e) => return (true, Err(e)),
-                };
-            }
-
-            (default_terminate, Err(Error::NotFound))
-        }
-
         let virt = self.config.path_translator.real_to_virtual(target)?;
 
-        let snapshot = self
-            .tuf
+        let snapshot = self.tuf
             .snapshot()
             .ok_or_else(|| Error::MissingMetadata(Role::Snapshot))?
             .clone();
-        let (_, target_description) = lookup(
-            &mut self.tuf,
-            &self.config,
-            false,
-            0,
-            &virt,
-            &snapshot,
-            None,
-            &mut self.local,
-            &mut self.remote,
-        );
+        let (_, target_description) =
+            self.lookup_target_description(false, 0, &virt, &snapshot, None);
         let target_description = target_description?;
 
         self.remote.fetch_target(
@@ -611,6 +456,142 @@
             self.config.min_bytes_per_second,
         )
     }
+
+    fn lookup_target_description(
+        &mut self,
+        default_terminate: bool,
+        current_depth: u32,
+        target: &VirtualTargetPath,
+        snapshot: &SnapshotMetadata,
+        targets: Option<&TargetsMetadata>,
+    ) -> (bool, Result<TargetDescription>) {
+        if current_depth > self.config.max_delegation_depth {
+            warn!(
+                "Walking the delegation graph would have exceeded the configured max depth: {}",
+                self.config.max_delegation_depth
+            );
+            return (default_terminate, Err(Error::NotFound));
+        }
+
+        // these clones are dumb, but we need immutable values and not references for update
+        // tuf in the loop below
+        let targets = match targets {
+            Some(t) => t.clone(),
+            None => match self.tuf.targets() {
+                Some(t) => t.clone(),
+                None => {
+                    return (
+                        default_terminate,
+                        Err(Error::MissingMetadata(Role::Targets)),
+                    )
+                }
+            },
+        };
+
+        if let Some(t) = targets.targets().get(target) {
+            return (default_terminate, Ok(t.clone()));
+        }
+
+        let delegations = match targets.delegations() {
+            Some(d) => d,
+            None => return (default_terminate, Err(Error::NotFound)),
+        };
+
+        for delegation in delegations.roles().iter() {
+            if !delegation.paths().iter().any(|p| target.is_child(p)) {
+                if delegation.terminating() {
+                    return (true, Err(Error::NotFound));
+                } else {
+                    continue;
+                }
+            }
+
+            let role_meta = match snapshot.meta().get(delegation.role()) {
+                Some(m) => m,
+                None if !delegation.terminating() => continue,
+                None => return (true, Err(Error::NotFound)),
+            };
+
+            let (alg, value) = match crypto::hash_preference(role_meta.hashes()) {
+                Ok(h) => h,
+                Err(e) => return (delegation.terminating(), Err(e)),
+            };
+
+            let version = if self.tuf.root().consistent_snapshot() {
+                MetadataVersion::Hash(value.clone())
+            } else {
+                MetadataVersion::None
+            };
+
+            let signed_meta = match self.local
+                .fetch_metadata::<TargetsMetadata>(
+                    delegation.role(),
+                    &MetadataVersion::None,
+                    &Some(role_meta.size()),
+                    self.config.min_bytes_per_second(),
+                    Some((alg, value.clone())),
+                )
+                .or_else(|_| {
+                    self.remote.fetch_metadata::<TargetsMetadata>(
+                        delegation.role(),
+                        &version,
+                        &Some(role_meta.size()),
+                        self.config.min_bytes_per_second(),
+                        Some((alg, value.clone())),
+                    )
+                }) {
+                Ok(m) => m,
+                Err(ref e) if !delegation.terminating() => {
+                    warn!("Failed to fetch metadata {:?}: {:?}", delegation.role(), e);
+                    continue;
+                }
+                Err(e) => {
+                    warn!("Failed to fetch metadata {:?}: {:?}", delegation.role(), e);
+                    return (true, Err(e));
+                }
+            };
+
+            match self.tuf.update_delegation(delegation.role(), signed_meta.clone()) {
+                Ok(_) => {
+                    match self.local.store_metadata(
+                        delegation.role(),
+                        &MetadataVersion::None,
+                        &signed_meta,
+                    ) {
+                        Ok(_) => (),
+                        Err(e) => warn!(
+                            "Error storing metadata {:?} locally: {:?}",
+                            delegation.role(),
+                            e
+                        ),
+                    }
+
+                    let meta = self.tuf
+                        .delegations()
+                        .get(delegation.role())
+                        .unwrap()
+                        .clone();
+                    let (term, res) = self.lookup_target_description(
+                        delegation.terminating(),
+                        current_depth + 1,
+                        target,
+                        snapshot,
+                        Some(meta.as_ref()),
+                    );
+
+                    if term && res.is_err() {
+                        return (true, res);
+                    }
+
+                    // TODO end recursion early
+                }
+                Err(_) if !delegation.terminating() => continue,
+                Err(e) => return (true, Err(e)),
+            };
+        }
+
+        (default_terminate, Err(Error::NotFound))
+    }
 }
 
 /// Configuration for a TUF `Client`.
