delete *S;
 }
 
-vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
+template<typename CallC>
+void foreachTarget(std::string const URI, std::string const Dist,
+      std::map<std::string, std::vector<debReleaseIndex::debSectionEntry const *> > const &ArchEntries,
+      CallC Call)
 {
-   vector <IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
-
    bool const flatArchive = (Dist[Dist.length() - 1] == '/');
    std::string baseURI = URI;
    if (flatArchive)
    std::vector<std::string> lang = APT::Configuration::getLanguages(true);
    if (lang.empty())
       lang.push_back("none");
-   map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
+   map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
    if (src != ArchEntries.end())
    {
       std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb-src", "", true);
         if (URI.empty())
            continue;
 
-        vector<debSectionEntry const*> const SectionEntries = src->second;
-        for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
+        vector<debReleaseIndex::debSectionEntry const*> const SectionEntries = src->second;
+        for (vector<debReleaseIndex::debSectionEntry const*>::const_iterator I = SectionEntries.begin();
               I != SectionEntries.end(); ++I)
         {
            for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l)
                  { "$(LANGUAGE)", &(*l) },
                  { NULL, NULL }
               };
-              std::string const name = SubstVar(URI, subst);
-              IndexTarget * Target;
-              if (IsOptional == true)
-              {
-                 Target = new OptionalIndexTarget(
-                       name,
-                       SubstVar(ShortDesc, subst),
-                       SubstVar(LongDesc, subst),
-                       baseURI + name
-                       );
-              }
-              else
-              {
-                 Target = new IndexTarget(
-                       name,
-                       SubstVar(ShortDesc, subst),
-                       SubstVar(LongDesc, subst),
-                       baseURI + name
-                       );
-              }
-              IndexTargets->push_back(Target);
+              Call(baseURI, *T, URI, ShortDesc, LongDesc, IsOptional, subst);
 
               if (URI.find("$(LANGUAGE)") == std::string::npos)
                  break;
       }
    }
 
-   // Only source release
-   if (IndexTargets->empty() == false && ArchEntries.size() == 1)
-      return IndexTargets;
-
    std::vector<std::string> const targets = _config->FindVector("APT::Acquire::Targets::deb", "", true);
    for (std::vector<std::string>::const_iterator T = targets.begin(); T != targets.end(); ++T)
    {
       if (URI.empty())
         continue;
 
-      for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
+      for (map<string, vector<debReleaseIndex::debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
            a != ArchEntries.end(); ++a)
       {
         if (a->first == "source")
            continue;
 
-        for (vector <const debSectionEntry *>::const_iterator I = a->second.begin();
+        for (vector <const debReleaseIndex::debSectionEntry *>::const_iterator I = a->second.begin();
               I != a->second.end(); ++I) {
 
            for (vector<std::string>::const_iterator l = lang.begin(); l != lang.end(); ++l)
                  { "$(ARCHITECTURE)", &(a->first) },
                  { NULL, NULL }
               };
-              std::string const name = SubstVar(URI, subst);
-              IndexTarget * Target;
-              if (IsOptional == true)
-              {
-                 Target = new OptionalIndexTarget(
-                       name,
-                       SubstVar(ShortDesc, subst),
-                       SubstVar(LongDesc, subst),
-                       baseURI + name
-                       );
-              }
-              else
-              {
-                 Target = new IndexTarget(
-                       name,
-                       SubstVar(ShortDesc, subst),
-                       SubstVar(LongDesc, subst),
-                       baseURI + name
-                       );
-              }
-              IndexTargets->push_back(Target);
+              Call(baseURI, *T, URI, ShortDesc, LongDesc, IsOptional, subst);
 
               if (URI.find("$(LANGUAGE)") == std::string::npos)
                  break;
            break;
       }
    }
+}
+
+
+struct ComputeIndexTargetsClass
+{
+   vector <IndexTarget *> * const IndexTargets;
+
+   void operator()(std::string const &baseURI, std::string const &/*TargetName*/,
+        std::string const &URI, std::string const &ShortDesc, std::string const &LongDesc,
+        bool const IsOptional, struct SubstVar const * const subst)
+   {
+      std::string const name = SubstVar(URI, subst);
+      IndexTarget * Target;
+      if (IsOptional == true)
+      {
+        Target = new OptionalIndexTarget(
+              name,
+              SubstVar(ShortDesc, subst),
+              SubstVar(LongDesc, subst),
+              baseURI + name
+              );
+      }
+      else
+      {
+        Target = new IndexTarget(
+              name,
+              SubstVar(ShortDesc, subst),
+              SubstVar(LongDesc, subst),
+              baseURI + name
+              );
+      }
+      IndexTargets->push_back(Target);
+   }
 
-   return IndexTargets;
+   ComputeIndexTargetsClass() : IndexTargets(new vector <IndexTarget *>) {}
+};
+
+vector <IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
+{
+   ComputeIndexTargetsClass comp;
+   foreachTarget(URI, Dist, ArchEntries, comp);
+   return comp.IndexTargets;
 }
+
+
                                                                        /*}}}*/
 bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
 {
    return FileExists(VerifiedSigFile);
 }
 
-vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() {
-       if (Indexes != NULL)
-               return Indexes;
-
-       Indexes = new vector <pkgIndexFile*>;
-       map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
-       if (src != ArchEntries.end()) {
-               vector<debSectionEntry const*> const SectionEntries = src->second;
-               for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
-                    I != SectionEntries.end(); ++I)
-                       Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted()));
-       }
-
-       // Only source release
-       if (Indexes->empty() == false && ArchEntries.size() == 1)
-               return Indexes;
-
-       std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
-       map<string, set<string> > sections;
-       for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
-            a != ArchEntries.end(); ++a) {
-               if (a->first == "source")
-                       continue;
-               for (vector<debSectionEntry const*>::const_iterator I = a->second.begin();
-                    I != a->second.end(); ++I) {
-                       Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first));
-                       sections[(*I)->Section].insert(lang.begin(), lang.end());
-               }
-       }
-
-       for (map<string, set<string> >::const_iterator s = sections.begin();
-            s != sections.end(); ++s)
-               for (set<string>::const_iterator l = s->second.begin();
-                    l != s->second.end(); ++l) {
-                       if (*l == "none") continue;
-                       Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str()));
-               }
-
-       return Indexes;
+struct GetIndexFilesClass
+{
+   vector <pkgIndexFile *> * const Indexes;
+   std::string const URI;
+   std::string const Release;
+   bool const IsTrusted;
+
+   void operator()(std::string const &/*baseURI*/, std::string const &TargetName,
+        std::string const &/*URI*/, std::string const &/*ShortDesc*/, std::string const &/*LongDesc*/,
+        bool const /*IsOptional*/, struct SubstVar const * const subst)
+   {
+      if (TargetName == "Packages")
+      {
+        Indexes->push_back(new debPackagesIndex(
+                 URI,
+                 Release,
+                 SubstVar("$(COMPONENT)", subst),
+                 IsTrusted,
+                 SubstVar("$(ARCHITECTURE)", subst)
+                 ));
+      }
+      else if (TargetName == "Sources")
+        Indexes->push_back(new debSourcesIndex(
+                 URI,
+                 Release,
+                 SubstVar("$(COMPONENT)", subst),
+                 IsTrusted
+                 ));
+      else if (TargetName == "Translations")
+        Indexes->push_back(new debTranslationsIndex(
+                 URI,
+                 Release,
+                 SubstVar("$(COMPONENT)", subst),
+                 SubstVar("$(LANGUAGE)", subst)
+                 ));
+   }
+
+   GetIndexFilesClass(std::string const &URI, std::string const &Release, bool const IsTrusted) :
+      Indexes(new vector <pkgIndexFile*>), URI(URI), Release(Release), IsTrusted(IsTrusted) {}
+};
+
+std::vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
+{
+   if (Indexes != NULL)
+      return Indexes;
+
+   GetIndexFilesClass comp(URI, Dist, IsTrusted());
+   foreachTarget(URI, Dist, ArchEntries, comp);
+   return Indexes = comp.Indexes;
 }
 
 void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) {
 
 
 setupenvironment
 configarchitecture 'amd64'
+
+# note that in --print-uri we talk about .bz2 because that is the default.
+# This doesn't mean it is actually attempt to download it.
 configcompression '.' 'gz'
 
 buildsimplenativepackage 'foo' 'amd64' '1' 'unstable'
 setupaptarchive --no-update
 changetowebserver
 
+testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 
+'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 
+'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 
+'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris
+
 testsuccessequal "Get:1 http://localhost:8080 unstable InRelease [$(stat -c%s aptarchive/dists/unstable/InRelease) B]
 Get:2 http://localhost:8080 unstable/main Sources [$(stat -c%s aptarchive/dists/unstable/main/source/Sources.gz) B]
 Get:3 http://localhost:8080 unstable/main amd64 Packages [$(stat -c%s aptarchive/dists/unstable/main/binary-amd64/Packages.gz) B]
 };
 EOF
 
+testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 
+'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 
+'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 
+'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 
+'http://localhost:8080/dists/unstable/main/Contents-amd64.bz2' localhost:8080_dists_unstable_main_Contents-amd64 0 " aptget update --print-uris
+
 testsuccessequal "Hit http://localhost:8080 unstable InRelease
 Get:1 http://localhost:8080 unstable/main amd64 Contents [$(stat -c%s aptarchive/dists/unstable/main/Contents-amd64.gz) B]
 Reading package lists..." aptget update
 };
 EOF
 
+# the last line is utter bogus of course, but how should apt know…
+testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 
+'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 
+'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 
+'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 
+'http://localhost:8080/dists/unstable/main/Contents-amd64.gz.bz2' localhost:8080_dists_unstable_main_Contents-amd64.gz 0 " aptget update --print-uris
+
 testsuccessequal "Hit http://localhost:8080 unstable InRelease
 Get:1 http://localhost:8080 unstable/main amd64 Contents.gz [$(stat -c%s aptarchive/dists/unstable/main/Contents-amd64.gz) B]
 Reading package lists..." aptget update
 
 testequal 'rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_Contents-amd64.gz' find rootdir/var/lib/apt/lists -name '*Contents*'
 testsuccess cmp 'rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_Contents-amd64.gz' 'aptarchive/dists/unstable/main/Contents-amd64.gz'
+
+rm -f rootdir/etc/apt/apt.conf.d/content-target.conf
+
+testequal "'http://localhost:8080/dists/unstable/InRelease' localhost:8080_dists_unstable_InRelease 0 
+'http://localhost:8080/dists/unstable/main/source/Sources.bz2' localhost:8080_dists_unstable_main_source_Sources 0 
+'http://localhost:8080/dists/unstable/main/binary-amd64/Packages.bz2' localhost:8080_dists_unstable_main_binary-amd64_Packages 0 
+'http://localhost:8080/dists/unstable/main/i18n/Translation-en.bz2' localhost:8080_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris
+
+testsuccessequal "Hit http://localhost:8080 unstable InRelease
+Reading package lists..." aptget update
+
+testempty find rootdir/var/lib/apt/lists -name '*Contents*'