text: // ----------------------------------------------------------------------
  //
  // definition of ParameterSet's function members
  // ----------------------------------------------------------------------
  
  // ----------------------------------------------------------------------
  // prerequisite source files and headers
  // ----------------------------------------------------------------------
  
  #include "FWCore/ParameterSet/interface/ParameterSet.h"
  
  #include "FWCore/MessageLogger/interface/MessageLogger.h"
  #include "FWCore/ParameterSet/interface/Registry.h"
  #include "FWCore/ParameterSet/src/split.h"
  #include "FWCore/Utilities/interface/Algorithms.h"
  #include "FWCore/Utilities/interface/Digest.h"
  #include "FWCore/Utilities/interface/EDMException.h"
  
  #include "DataFormats/Provenance/interface/ModuleDescription.h"
  
  #include <algorithm>
  #include <iostream>
  #include <sstream>
  #include <cassert>
  
  // ----------------------------------------------------------------------
  // class invariant checker
  // ----------------------------------------------------------------------
  
  namespace edm {
  
    namespace pset::exceptions {
      void throwWrongNumberOfElements(std::string const& iName, size_t iExpected, size_t iGot) {
        throw Exception(errors::Configuration) << "The parameter '" << iName << "' should have " << iExpected
                                               << " elements, but has " << iGot << " elements in the configuration.\n";
      }
    }  // namespace pset::exceptions
  
    void ParameterSet::invalidateRegistration(std::string const& nameOfTracked) {
      // We have added a new parameter.  Invalidate the ID.
      if (isRegistered()) {
        id_ = ParameterSetID();
        if (!nameOfTracked.empty()) {
          // Give a warning (informational for now).
          LogInfo("ParameterSet") << "Warning: You have added a new tracked parameter\n"
                                  << "'" << nameOfTracked << "' to a previously registered parameter set.\n"
                                  << "This is a bad idea because the new parameter(s) will not be recorded.\n"
                                  << "Use the forthcoming ParameterSetDescription facility instead.\n"
                                  << "A warning is given only for the first such parameter in a pset.\n";
        }
      }
      assert(!isRegistered());
    }
  
    // ----------------------------------------------------------------------
    // constructors
    // ----------------------------------------------------------------------
  
    ParameterSet::ParameterSet() : tbl_(), psetTable_(), vpsetTable_(), id_() {}
  
    // ----------------------------------------------------------------------
    // from coded string
  
    ParameterSet::ParameterSet(std::string const& code) : tbl_(), psetTable_(), vpsetTable_(), id_() {
      if (!fromString(code)) {
        throw Exception(errors::Configuration, "InvalidInput")
            << "The encoded configuration string "
            << "passed to a ParameterSet during construction is invalid:\n"
            << code;
      }
    }
  
    // ----------------------------------------------------------------------
    // from coded string and ID.
  
    ParameterSet::ParameterSet(std::string const& code, ParameterSetID const& id)
        : tbl_(), psetTable_(), vpsetTable_(), id_(id) {
      if (!fromString(code)) {
        throw Exception(errors::Configuration, "InvalidInput")
            << "The encoded configuration string "
            << "passed to a ParameterSet during construction is invalid:\n"
            << code;
      }
    }
  
    void ParameterSet::registerFromString(std::string const& rep) {
      // from coded string.  Will cause registration
      cms::Digest dg(rep);
      edm::ParameterSetID psID(dg.digest().toString());
      edm::ParameterSet ps(rep, psID);
      pset::Registry::instance()->insertMapped(ps);
    }
  
    ParameterSetID ParameterSet::emptyParameterSetID() {  // const
      cms::Digest newDigest;
      ParameterSet().toDigest(newDigest);
      return ParameterSetID(newDigest.digest().toString());
    }
  
    void ParameterSet::copyForModify(ParameterSet const& other) {
      ParameterSet temp(other);
      swap(temp);
      id_ = ParameterSetID();
    }
  
    void ParameterSet::swap(ParameterSet& other) {
      tbl_.swap(other.tbl_);
      psetTable_.swap(other.psetTable_);
      vpsetTable_.swap(other.vpsetTable_);
      id_.swap(other.id_);
    }
  
    ParameterSet const& ParameterSet::registerIt() {
      if (!isRegistered()) {
        calculateID();
        pset::Registry::instance()->insertMapped(*this);
      }
      return *this;
    }
  
    std::unique_ptr<ParameterSet> ParameterSet::popParameterSet(std::string const& name) {
      assert(!isRegistered());
      psettable::iterator it = psetTable_.find(name);
      assert(it != psetTable_.end());
      auto pset = std::make_unique<ParameterSet>();
      std::swap(*pset, it->second.psetForUpdate());
      psetTable_.erase(it);
      return pset;
    }
  
    void ParameterSet::eraseSimpleParameter(std::string const& name) {
      assert(!isRegistered());
      table::iterator it = tbl_.find(name);
      assert(it != tbl_.end());
      tbl_.erase(it);
    }
  
    void ParameterSet::eraseOrSetUntrackedParameterSet(std::string const& name) {
      assert(!isRegistered());
      psettable::iterator it = psetTable_.find(name);
      assert(it != psetTable_.end());
      ParameterSet& pset = it->second.psetForUpdate();
      if (pset.isRegistered()) {
        it->second.setIsTracked(false);
      } else {
        psetTable_.erase(it);
      }
    }
  
    std::vector<ParameterSet> ParameterSet::popVParameterSet(std::string const& name) {
      assert(!isRegistered());
      vpsettable::iterator it = vpsetTable_.find(name);
      assert(it != vpsetTable_.end());
      std::vector<ParameterSet> vpset;
      std::swap(vpset, it->second.vpsetForUpdate());
      vpsetTable_.erase(it);
      return vpset;
    }
  
    void ParameterSet::calculateID() {
      // make sure contained tracked psets are updated
      for (auto& item : psetTable_) {
        ParameterSet& pset = item.second.psetForUpdate();
        if (!pset.isRegistered()) {
          pset.registerIt();
        }
        item.second.updateID();
      }
  
      // make sure contained tracked vpsets are updated
      for (vpsettable::iterator i = vpsetTable_.begin(), e = vpsetTable_.end(); i != e; ++i) {
        i->second.registerPsetsAndUpdateIDs();
      }
      //  The old, string base code is found below. Uncomment this and the assert to check whether
      //  there are discrepancies between old and new implementation.
      //    std::string stringrep;
      //    toString(stringrep);
      //    cms::Digest md5alg(stringrep);
      //    id_ = ParameterSetID(md5alg.digest().toString());
      cms::Digest newDigest;
      toDigest(newDigest);
      id_ = ParameterSetID(newDigest.digest().toString());
      //    assert(md5alg.digest().toString() == newDigest.digest().toString());
      assert(isRegistered());
    }
  
    // ----------------------------------------------------------------------
    // identification
    ParameterSetID ParameterSet::id() const {
      // checks if valid
      if (!isRegistered()) {
        throw Exception(errors::LogicError) << "ParameterSet::id() called prematurely\n"
                                            << "before ParameterSet::registerIt() has been called.\n";
      }
      return id_;
    }
  
    void ParameterSet::setID(ParameterSetID const& id) { id_ = id; }
  
    // ----------------------------------------------------------------------
    // Entry-handling
    // ----------------------------------------------------------------------
  
    Entry const* ParameterSet::getEntryPointerOrThrow_(char const* name) const {
      return getEntryPointerOrThrow_(std::string(name));
    }
  
    Entry const* ParameterSet::getEntryPointerOrThrow_(std::string const& name) const {
      Entry const* result = retrieveUntracked(name);
      if (result == nullptr)
        throw Exception(errors::Configuration, "MissingParameter:")
            << "The required parameter '" << name << "' was not specified.\n";
      return result;
    }
  
    template <typename T, typename U>
    T first(std::pair<T, U> const& p) {
      return p.first;
    }
  
    template <typename T, typename U>
    U second(std::pair<T, U> const& p) {
      return p.second;
    }
  
    Entry const& ParameterSet::retrieve(char const* name) const { return retrieve(std::string(name)); }
  
    Entry const& ParameterSet::retrieve(std::string const& name) const {
      table::const_iterator it = tbl_.find(name);
      if (it == tbl_.end()) {
        throw Exception(errors::Configuration, "MissingParameter:") << "Parameter '" << name << "' not found.";
      }
      if (it->second.isTracked() == false) {
        if (name[0] == '@') {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "Framework Error:  Parameter '" << name << "' is incorrectly designated as tracked in the framework.";
        } else {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "Parameter '" << name << "' is designated as tracked in the code,\n"
              << "but is designated as untracked in the configuration file.\n"
              << "Please remove 'untracked' from the configuration file for parameter '" << name << "'.";
        }
      }
      return it->second;
    }  // retrieve()
  
    Entry const* ParameterSet::retrieveUntracked(char const* name) const { return retrieveUntracked(std::string(name)); }
  
    Entry const* ParameterSet::retrieveUntracked(std::string const& name) const {
      table::const_iterator it = tbl_.find(name);
  
      if (it == tbl_.end())
        return nullptr;
      if (it->second.isTracked()) {
        if (name[0] == '@') {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "Framework Error:  Parameter '" << name << "' is incorrectly designated as untracked in the framework.";
        } else {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "Parameter '" << name << "' is designated as untracked in the code,\n"
              << "but is not designated as untracked in the configuration file.\n"
              << "Please change the configuration file to 'untracked <type> " << name << "'.";
        }
      }
      return &it->second;
    }  // retrieve()
  
    ParameterSetEntry const& ParameterSet::retrieveParameterSet(std::string const& name) const {
      psettable::const_iterator it = psetTable_.find(name);
      if (it == psetTable_.end()) {
        throw Exception(errors::Configuration, "MissingParameter:") << "ParameterSet '" << name << "' not found.";
      }
      if (it->second.isTracked() == false) {
        if (name[0] == '@') {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "Framework Error:  ParameterSet '" << name << "' is incorrectly designated as tracked in the framework.";
        } else {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "ParameterSet '" << name << "' is designated as tracked in the code,\n"
              << "but is designated as untracked in the configuration file.\n"
              << "Please remove 'untracked' from the configuration file for parameter '" << name << "'.";
        }
      }
      return it->second;
    }  // retrieve()
  
    ParameterSetEntry const* ParameterSet::retrieveUntrackedParameterSet(std::string const& name) const {
      psettable::const_iterator it = psetTable_.find(name);
  
      if (it == psetTable_.end())
        return nullptr;
      if (it->second.isTracked()) {
        if (name[0] == '@') {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "Framework Error:  ParameterSet '" << name
              << "' is incorrectly designated as untracked in the framework.";
        } else {
          throw Exception(errors::Configuration, "StatusMismatch:")
              << "ParameterSet '" << name << "' is designated as untracked in the code,\n"
              << "but is not designated as untracked in the configuration file.\n"
              << "Please change the configuration file to 'untracked <type> " << name << "'.";
        }
      }
      return &it->second;
    }  // retrieve()
  
    VParameterSetEntry const& ParameterSet::retrieveVParameterSet(std::string const& name) const {
      vpsettable::const_iterator it = vpsetTable_.find(name);
      if (it == vpsetTable_.end()) {
        throw Exception(errors::Configuration, "MissingParameter:") << "VParameterSet '" << name << "' not found.";
      }
      if (it->second.isTracked() == false) {
        throw Exception(errors::Configuration, "StatusMismatch:")
            << "VParameterSet '" << name << "' is designated as tracked in the code,\n"
            << "but is designated as untracked in the configuration file.\n"
            << "Please remove 'untracked' from the configuration file for parameter '" << name << "'.";
      }
      return it->second;
    }  // retrieve()
  
    VParameterSetEntry const* ParameterSet::retrieveUntrackedVParameterSet(std::string const& name) const {
      vpsettable::const_iterator it = vpsetTable_.find(name);
  
      if (it == vpsetTable_.end())
        return nullptr;
      if (it->second.isTracked()) {
        throw Exception(errors::Configuration, "StatusMismatch:")
            << "VParameterSet '" << name << "' is designated as untracked in the code,\n"
            << "but is not designated as untracked in the configuration file.\n"
            << "Please change the configuration file to 'untracked <type> " << name << "'.";
      }
      return &it->second;
    }  // retrieve()
  
    Entry const* ParameterSet::retrieveUnknown(char const* name) const { return retrieveUnknown(std::string(name)); }
  
    Entry const* ParameterSet::retrieveUnknown(std::string const& name) const {
      table::const_iterator it = tbl_.find(name);
      if (it == tbl_.end()) {
        return nullptr;
      }
      return &it->second;
    }
  
    ParameterSetEntry const* ParameterSet::retrieveUnknownParameterSet(std::string const& name) const {
      psettable::const_iterator it = psetTable_.find(name);
      if (it == psetTable_.end()) {
        return nullptr;
      }
      return &it->second;
    }
  
    VParameterSetEntry const* ParameterSet::retrieveUnknownVParameterSet(std::string const& name) const {
      vpsettable::const_iterator it = vpsetTable_.find(name);
      if (it == vpsetTable_.end()) {
        return nullptr;
      }
      return &it->second;
    }
  
    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
  
    std::string ParameterSet::getParameterAsString(std::string const& name) const {
      if (existsAs<ParameterSet>(name)) {
        return retrieveUnknownParameterSet(name)->toString();
      } else if (existsAs<std::vector<ParameterSet> >(name)) {
        return retrieveUnknownVParameterSet(name)->toString();
      } else if (exists(name)) {
        return retrieveUnknown(name)->toString();
      } else {
        throw Exception(errors::Configuration, "getParameterAsString")
            << "Cannot find parameter " << name << " in " << *this;
      }
    }
  
    // ----------------------------------------------------------------------
    // ----------------------------------------------------------------------
  
    void ParameterSet::insert(bool okay_to_replace, char const* name, Entry const& value) {
      insert(okay_to_replace, std::string(name), value);
    }
  
    void ParameterSet::insert(bool okay_to_replace, std::string const& name, Entry const& value) {
      // We should probably get rid of 'okay_to_replace', which will
      // simplify the logic in this function.
      table::iterator it = tbl_.find(name);
  
      if (it == tbl_.end()) {
        if (!tbl_.insert(std::make_pair(name, value)).second)
          throw Exception(errors::Configuration, "InsertFailure") << "cannot insert " << name << " into a ParameterSet\n";
      } else if (okay_to_replace) {
        it->second = value;
      }
    }  // insert()
  
    void ParameterSet::insertParameterSet(bool okay_to_replace, std::string const& name, ParameterSetEntry const& entry) {
      // We should probably get rid of 'okay_to_replace', which will
      // simplify the logic in this function.
      psettable::iterator it = psetTable_.find(name);
  
      if (it == psetTable_.end()) {
        if (!psetTable_.insert(std::make_pair(name, entry)).second)
          throw Exception(errors::Configuration, "InsertFailure") << "cannot insert " << name << " into a ParameterSet\n";
      } else if (okay_to_replace) {
        it->second = entry;
      }
    }  // insert()
  
    void ParameterSet::insertVParameterSet(bool okay_to_replace,
                                           std::string const& name,
                                           VParameterSetEntry const& entry) {
      // We should probably get rid of 'okay_to_replace', which will
      // simplify the logic in this function.
      vpsettable::iterator it = vpsetTable_.find(name);
  
      if (it == vpsetTable_.end()) {
        if (!vpsetTable_.insert(std::make_pair(name, entry)).second)
          throw Exception(errors::Configuration, "InsertFailure")
              << "cannot insert " << name << " into a VParameterSet\n";
      } else if (okay_to_replace) {
        it->second = entry;
      }
    }  // insert()
  
    void ParameterSet::augment(ParameterSet const& from) {
      // This preemptive invalidation may be more agressive than necessary.
      invalidateRegistration(std::string());
      if (&from == this) {
        return;
      }
  
      for (table::const_iterator b = from.tbl_.begin(), e = from.tbl_.end(); b != e; ++b) {
        this->insert(false, b->first, b->second);
      }
      for (psettable::const_iterator b = from.psetTable_.begin(), e = from.psetTable_.end(); b != e; ++b) {
        this->insertParameterSet(false, b->first, b->second);
      }
      for (vpsettable::const_iterator b = from.vpsetTable_.begin(), e = from.vpsetTable_.end(); b != e; ++b) {
        this->insertVParameterSet(false, b->first, b->second);
      }
    }  // augment()
  
    void ParameterSet::copyFrom(ParameterSet const& from, std::string const& name) {
      invalidateRegistration(std::string());
      if (from.existsAs<ParameterSet>(name)) {
        this->insertParameterSet(false, name, *(from.retrieveUnknownParameterSet(name)));
      } else if (from.existsAs<std::vector<ParameterSet> >(name)) {
        this->insertVParameterSet(false, name, *(from.retrieveUnknownVParameterSet(name)));
      } else if (from.exists(name)) {
        this->insert(false, name, *(from.retrieveUnknown(name)));
      } else {
        throw Exception(errors::Configuration, "copyFrom") << "Cannot find parameter " << name << " in " << from;
      }
    }
  
    ParameterSet* ParameterSet::getPSetForUpdate(std::string const& name, bool& isTracked) {
      assert(!isRegistered());
      isTracked = false;
      psettable::iterator it = psetTable_.find(name);
      if (it == psetTable_.end())
        return nullptr;
      isTracked = it->second.isTracked();
      return &it->second.psetForUpdate();
    }
  
    VParameterSetEntry* ParameterSet::getPSetVectorForUpdate(std::string const& name) {
      assert(!isRegistered());
      vpsettable::iterator it = vpsetTable_.find(name);
      if (it == vpsetTable_.end())
        return nullptr;
      return &it->second;
    }
  
    // ----------------------------------------------------------------------
    // coding
    // ----------------------------------------------------------------------
  
    void ParameterSet::toString(std::string& rep) const { toStringImp(rep, false); }
  
    void ParameterSet::allToString(std::string& rep) const { toStringImp(rep, true); }
  
    void ParameterSet::toStringImp(std::string& rep, bool useAll) const {
      // make sure the PSets get filled
      if (empty()) {
        rep += "<>";
        return;
      }
      size_t size = 1;
      for (table::const_iterator b = tbl_.begin(), e = tbl_.end(); b != e; ++b) {
        if (useAll || b->second.isTracked()) {
          size += 2;
          size += b->first.size();
          size += b->second.sizeOfString();
        }
      }
      for (psettable::const_iterator b = psetTable_.begin(), e = psetTable_.end(); b != e; ++b) {
        if (useAll || b->second.isTracked()) {
          size += 2;
          size += b->first.size();
          size += b->first.size();
          size += b->first.size();
          size += sizeof(ParameterSetID);
        }
      }
      for (vpsettable::const_iterator b = vpsetTable_.begin(), e = vpsetTable_.end(); b != e; ++b) {
        if (useAll || b->second.isTracked()) {
          size += 2;
          size += b->first.size();
          size += sizeof(ParameterSetID) * b->second.vpset().size();
        }
      }
  
      rep.reserve(rep.size() + size);
      rep += '<';
      std::string start;
      std::string const between(";");
      for (table::const_iterator b = tbl_.begin(), e = tbl_.end(); b != e; ++b) {
        if (useAll || b->second.isTracked()) {
          rep += start;
          rep += b->first;
          rep += '=';
          b->second.toString(rep);
          start = between;
        }
      }
      for (psettable::const_iterator b = psetTable_.begin(), e = psetTable_.end(); b != e; ++b) {
        if (useAll || b->second.isTracked()) {
          rep += start;
          rep += b->first;
          rep += '=';
          b->second.toString(rep);
          start = between;
        }
      }
      for (vpsettable::const_iterator b = vpsetTable_.begin(), e = vpsetTable_.end(); b != e; ++b) {
        if (useAll || b->second.isTracked()) {
          rep += start;
          rep += b->first;
          rep += '=';
          b->second.toString(rep);
          start = between;
        }
      }
  
      rep += '>';
    }  // to_string()
  
    void ParameterSet::toDigest(cms::Digest& digest) const {
      digest.append("<", 1);
      bool started = false;
      for (table::const_iterator b = tbl_.begin(), e = tbl_.end(); b != e; ++b) {
        if (b->second.isTracked()) {
          if (started)
            digest.append(";", 1);
          digest.append(b->first);
          digest.append("=", 1);
          b->second.toDigest(digest);
          started = true;
        }
      }
      for (psettable::const_iterator b = psetTable_.begin(), e = psetTable_.end(); b != e; ++b) {
        if (b->second.isTracked()) {
          if (started)
            digest.append(";", 1);
          digest.append(b->first);
          digest.append("=", 1);
          b->second.toDigest(digest);
          started = true;
        }
      }
      for (vpsettable::const_iterator b = vpsetTable_.begin(), e = vpsetTable_.end(); b != e; ++b) {
        if (b->second.isTracked()) {
          if (started)
            digest.append(";", 1);
          digest.append(b->first);
          digest.append("=", 1);
          b->second.toDigest(digest);
        }
      }
  
      digest.append(">", 1);
    }
  
    std::string ParameterSet::toString() const {
      std::string result;
      toString(result);
      return result;
    }
  
    // ----------------------------------------------------------------------
  
    bool ParameterSet::fromString(std::string const& from) {
      std::vector<std::string> temp;
      if (!split(std::back_inserter(temp), from, '<', ';', '>'))
        return false;
  
      tbl_.clear();  // precaution
      for (std::vector<std::string>::const_iterator b = temp.begin(), e = temp.end(); b != e; ++b) {
        // locate required name/value separator
        std::string::const_iterator q = find_in_all(*b, '=');
        if (q == b->end())
          return false;
  
        // form name unique to this ParameterSet
        std::string name = std::string(b->begin(), q);
        if (tbl_.find(name) != tbl_.end())
          return false;
  
        std::string rep(q + 1, b->end());
        // entries are generically of the form tracked-type-rep
        if (rep[0] == '-') {
        }
        if (rep[1] == 'Q') {
          ParameterSetEntry psetEntry(rep);
          if (!psetTable_.insert(std::make_pair(name, psetEntry)).second) {
            return false;
          }
        } else if (rep[1] == 'q') {
          VParameterSetEntry vpsetEntry(rep);
          if (!vpsetTable_.insert(std::make_pair(name, vpsetEntry)).second) {
            return false;
          }
        } else if (rep[1] == 'P') {
          Entry value(name, rep);
          ParameterSetEntry psetEntry(value.getPSet(), value.isTracked());
          if (!psetTable_.insert(std::make_pair(name, psetEntry)).second) {
            return false;
          }
        } else if (rep[1] == 'p') {
          Entry value(name, rep);
          VParameterSetEntry vpsetEntry(value.getVPSet(), value.isTracked());
          if (!vpsetTable_.insert(std::make_pair(name, vpsetEntry)).second) {
            return false;
          }
        } else {
          // form value and insert name/value pair
          Entry value(name, rep);
          if (!tbl_.insert(std::make_pair(name, value)).second) {
            return false;
          }
        }
      }
  
      return true;
    }  // from_string()
  
    std::vector<FileInPath>::size_type ParameterSet::getAllFileInPaths(std::vector<FileInPath>& output) const {
      std::vector<FileInPath>::size_type count = 0;
      table::const_iterator it = tbl_.begin();
      table::const_iterator end = tbl_.end();
      while (it != end) {
        Entry const& e = it->second;
        if (e.typeCode() == 'F') {
          ++count;
          output.push_back(e.getFileInPath());
        }
        ++it;
      }
      return count;
    }
  
    std::vector<std::string> ParameterSet::getParameterNames() const {
      using std::placeholders::_1;
      std::vector<std::string> returnValue;
      std::transform(tbl_.begin(),
                     tbl_.end(),
                     back_inserter(returnValue),
                     std::bind(&std::pair<std::string const, Entry>::first, _1));
      std::transform(psetTable_.begin(),
                     psetTable_.end(),
                     back_inserter(returnValue),
                     std::bind(&std::pair<std::string const, ParameterSetEntry>::first, _1));
      std::transform(vpsetTable_.begin(),
                     vpsetTable_.end(),
                     back_inserter(returnValue),
                     std::bind(&std::pair<std::string const, VParameterSetEntry>::first, _1));
      return returnValue;
    }
  
    bool ParameterSet::exists(std::string const& parameterName) const {
      return (tbl_.find(parameterName) != tbl_.end() || psetTable_.find(parameterName) != psetTable_.end() ||
              vpsetTable_.find(parameterName) != vpsetTable_.end());
    }
  
    ParameterSet ParameterSet::trackedPart() const {
      ParameterSet result;
      for (table::const_iterator tblItr = tbl_.begin(); tblItr != tbl_.end(); ++tblItr) {
        if (tblItr->second.isTracked()) {
          result.tbl_.insert(*tblItr);
        }
      }
      for (psettable::const_iterator psetItr = psetTable_.begin(); psetItr != psetTable_.end(); ++psetItr) {
        if (psetItr->second.isTracked()) {
          result.addParameter<ParameterSet>(psetItr->first, psetItr->second.pset().trackedPart());
        }
      }
      for (vpsettable::const_iterator vpsetItr = vpsetTable_.begin(); vpsetItr != vpsetTable_.end(); ++vpsetItr) {
        if (vpsetItr->second.isTracked()) {
          VParameterSet vresult;
          std::vector<ParameterSet> const& this_vpset = vpsetItr->second.vpset();
  
          typedef std::vector<ParameterSet>::const_iterator Iter;
          for (Iter i = this_vpset.begin(), e = this_vpset.end(); i != e; ++i) {
            vresult.push_back(i->trackedPart());
          }
          result.addParameter<VParameterSet>(vpsetItr->first, vresult);
        }
      }
      return result;
    }
  
    /*
    // Comment out unneeded function
    size_t
    ParameterSet::getAllParameterSetNames(std::vector<std::string>& output) const {
      using std::placeholders::_1;
      std::transform(psetTable_.begin(), psetTable_.end(), back_inserter(output),
                     std::bind(&std::pair<std::string const, ParameterSetEntry>::first, _1));
      return output.size();
    }
  */
  
    size_t ParameterSet::getParameterSetNames(std::vector<std::string>& output, bool trackiness) const {
      for (psettable::const_iterator psetItr = psetTable_.begin(); psetItr != psetTable_.end(); ++psetItr) {
        if (psetItr->second.isTracked() == trackiness) {
          output.push_back(psetItr->first);
        }
      }
      return output.size();
    }
  
    size_t ParameterSet::getParameterSetVectorNames(std::vector<std::string>& output, bool trackiness) const {
      for (vpsettable::const_iterator vpsetItr = vpsetTable_.begin(); vpsetItr != vpsetTable_.end(); ++vpsetItr) {
        if (vpsetItr->second.isTracked() == trackiness) {
          output.push_back(vpsetItr->first);
        }
      }
      return output.size();
    }
  
    size_t ParameterSet::getNamesByCode_(char code, bool trackiness, std::vector<std::string>& output) const {
      size_t count = 0;
      if (code == 'Q') {
        return getParameterSetNames(output, trackiness);
      }
      if (code == 'q') {
        return getParameterSetVectorNames(output, trackiness);
      }
      table::const_iterator it = tbl_.begin();
      table::const_iterator end = tbl_.end();
      while (it != end) {
        Entry const& e = it->second;
        if (e.typeCode() == code && e.isTracked() == trackiness) {  // if it is a vector of ParameterSet
          ++count;
          output.push_back(it->first);  // save the name
        }
        ++it;
      }
      return count;
    }
  
    template <>
    std::vector<std::string> ParameterSet::getParameterNamesForType<FileInPath>(bool trackiness) const {
      std::vector<std::string> result;
      getNamesByCode_('F', trackiness, result);
      return result;
    }
  
    bool operator==(ParameterSet const& a, ParameterSet const& b) {
      if (a.isRegistered() && b.isRegistered()) {
        return (a.id() == b.id());
      }
      return isTransientEqual(a.trackedPart(), b.trackedPart());
    }
  
    bool isTransientEqual(ParameterSet const& a, ParameterSet const& b) {
      if (a.tbl().size() != b.tbl().size()) {
        return false;
      }
      if (a.psetTable().size() != b.psetTable().size()) {
        return false;
      }
      if (a.vpsetTable().size() != b.vpsetTable().size()) {
        return false;
      }
      typedef ParameterSet::table::const_iterator Ti;
      for (Ti i = a.tbl().begin(), e = a.tbl().end(), j = b.tbl().begin(), f = b.tbl().end(); i != e && j != f;
           ++i, ++j) {
        if (*i != *j) {
          return false;
        }
      }
      typedef ParameterSet::psettable::const_iterator Pi;
      for (Pi i = a.psetTable().begin(), e = a.psetTable().end(), j = b.psetTable().begin(), f = b.psetTable().end();
           i != e && j != f;
           ++i, ++j) {
        if (i->first != j->first) {
          return false;
        }
        if (i->second.isTracked() != j->second.isTracked()) {
          return false;
        }
        if (!isTransientEqual(i->second.pset(), j->second.pset())) {
          return false;
        }
      }
      typedef ParameterSet::vpsettable::const_iterator PVi;
      for (PVi i = a.vpsetTable().begin(), e = a.vpsetTable().end(), j = b.vpsetTable().begin(), f = b.vpsetTable().end();
           i != e && j != f;
           ++i, ++j) {
        if (i->first != j->first) {
          return false;
        }
        if (i->second.isTracked() != j->second.isTracked()) {
          return false;
        }
        std::vector<ParameterSet> const& iv = i->second.vpset();
        std::vector<ParameterSet> const& jv = j->second.vpset();
        if (iv.size() != jv.size()) {
          return false;
        }
        for (size_t k = 0; k < iv.size(); ++k) {
          if (!isTransientEqual(iv[k], jv[k])) {
            return false;
          }
        }
      }
      return true;
    }
  
    std::string ParameterSet::dump(unsigned int indent) const {
      std::ostringstream os;
      // indent a bit
      std::string indentation(indent, ' ');
      os << "{" << std::endl;
      for (table::const_iterator i = tbl_.begin(), e = tbl_.end(); i != e; ++i) {
        os << indentation << "  " << i->first << ": " << i->second << std::endl;
      }
      for (psettable::const_iterator i = psetTable_.begin(), e = psetTable_.end(); i != e; ++i) {
        // indent a bit
        std::string n = i->first;
        ParameterSetEntry const& pe = i->second;
        os << indentation << "  " << n << ": " << pe.dump(indent + 2) << std::endl;
      }
      for (vpsettable::const_iterator i = vpsetTable_.begin(), e = vpsetTable_.end(); i != e; ++i) {
        // indent a bit
        std::string n = i->first;
        VParameterSetEntry const& pe = i->second;
        os << indentation << "  " << n << ": " << pe.dump(indent + 2) << std::endl;
      }
      os << indentation << "}";
      return os.str();
    }
  
    std::ostream& operator<<(std::ostream& os, ParameterSet const& pset) {
      os << pset.dump();
      return os;
    }
  
    // Free function to return a parameterSet given its ID.
    ParameterSet const& getParameterSet(ParameterSetID const& id) {
      ParameterSet const* result = nullptr;
      if (nullptr == (result = pset::Registry::instance()->getMapped(id))) {
        throw Exception(errors::LogicError, "MissingParameterSet:") << "Parameter Set ID '" << id << "' not found.";
      }
      return *result;
    }
  
    ParameterSet const& getProcessParameterSetContainingModule(ModuleDescription const& moduleDescription) {
      return getParameterSet(moduleDescription.mainParameterSetID());
    }
  
    void ParameterSet::deprecatedInputTagWarning(std::string const& name, std::string const& label) const {
      LogWarning("Configuration") << "Warning:\n\tstring " << name << " = \"" << label << "\"\nis deprecated, "
                                  << "please update your config file to use\n\tInputTag " << name << " = " << label;
    }
  
    // specializations
    // ----------------------------------------------------------------------
    // Bool, vBool
  
    template <>
    bool ParameterSet::getParameter<bool>(std::string const& name) const {
      return retrieve(name).getBool();
    }
  
    // ----------------------------------------------------------------------
    // Int32, vInt32
  
    template <>
    int ParameterSet::getParameter<int>(std::string const& name) const {
      return retrieve(name).getInt32();
    }
  
    template <>
    std::vector<int> ParameterSet::getParameter<std::vector<int> >(std::string const& name) const {
      return retrieve(name).getVInt32();
    }
  
    // ----------------------------------------------------------------------
    // Int64, vInt64
  
    template <>
    long long ParameterSet::getParameter<long long>(std::string const& name) const {
      return retrieve(name).getInt64();
    }
  
    template <>
    std::vector<long long> ParameterSet::getParameter<std::vector<long long> >(std::string const& name) const {
      return retrieve(name).getVInt64();
    }
  
    // ----------------------------------------------------------------------
    // Uint32, vUint32
  
    template <>
    unsigned int ParameterSet::getParameter<unsigned int>(std::string const& name) const {
      return retrieve(name).getUInt32();
    }
  
    template <>
    std::vector<unsigned int> ParameterSet::getParameter<std::vector<unsigned int> >(std::string const& name) const {
      return retrieve(name).getVUInt32();
    }
  
    // ----------------------------------------------------------------------
    // Uint64, vUint64
  
    template <>
    unsigned long long ParameterSet::getParameter<unsigned long long>(std::string const& name) const {
      return retrieve(name).getUInt64();
    }
  
    template <>
    std::vector<unsigned long long> ParameterSet::getParameter<std::vector<unsigned long long> >(
        std::string const& name) const {
      return retrieve(name).getVUInt64();
    }
  
    // ----------------------------------------------------------------------
    // Double, vDouble
  
    template <>
    double ParameterSet::getParameter<double>(std::string const& name) const {
      return retrieve(name).getDouble();
    }
  
    template <>
    std::vector<double> ParameterSet::getParameter<std::vector<double> >(std::string const& name) const {
      return retrieve(name).getVDouble();
    }
  
    // ----------------------------------------------------------------------
    // String, vString
  
    template <>
    std::string ParameterSet::getParameter<std::string>(std::string const& name) const {
      return retrieve(name).getString();
    }
  
    template <>
    std::vector<std::string> ParameterSet::getParameter<std::vector<std::string> >(std::string const& name) const {
      return retrieve(name).getVString();
    }
  
    // ----------------------------------------------------------------------
    // FileInPath
  
    template <>
    FileInPath ParameterSet::getParameter<FileInPath>(std::string const& name) const {
      return retrieve(name).getFileInPath();
    }
  
    // ----------------------------------------------------------------------
    // InputTag
  
    template <>
    InputTag ParameterSet::getParameter<InputTag>(std::string const& name) const {
      Entry const& e_input = retrieve(name);
      switch (e_input.typeCode()) {
        case 't':  // InputTag
          return e_input.getInputTag();
        case 'S':  // string
          std::string const& label = e_input.getString();
          deprecatedInputTagWarning(name, label);
          return InputTag(label);
      }
      throw Exception(errors::Configuration, "ValueError")
          << "type of " << name << " is expected to be InputTag or string (deprecated)";
    }
  
    // ----------------------------------------------------------------------
    // VInputTag
  
    template <>
    std::vector<InputTag> ParameterSet::getParameter<std::vector<InputTag> >(std::string const& name) const {
      return retrieve(name).getVInputTag();
    }
  
    // ----------------------------------------------------------------------
    // ESInputTag
  
    template <>
    ESInputTag ParameterSet::getParameter<ESInputTag>(std::string const& name) const {
      return retrieve(name).getESInputTag();
    }
  
    // ----------------------------------------------------------------------
    // VESInputTag
  
    template <>
    std::vector<ESInputTag> ParameterSet::getParameter<std::vector<ESInputTag> >(std::string const& name) const {
      return retrieve(name).getVESInputTag();
    }
  
    // ----------------------------------------------------------------------
    // EventID
  
    template <>
    EventID ParameterSet::getParameter<EventID>(std::string const& name) const {
      return retrieve(name).getEventID();
    }
  
    // ----------------------------------------------------------------------
    // VEventID
  
    template <>
    std::vector<EventID> ParameterSet::getParameter<std::vector<EventID> >(std::string const& name) const {
      return retrieve(name).getVEventID();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockID
  
    template <>
    LuminosityBlockID ParameterSet::getParameter<LuminosityBlockID>(std::string const& name) const {
      return retrieve(name).getLuminosityBlockID();
    }
  
    // ----------------------------------------------------------------------
    // VLuminosityBlockID
  
    template <>
    std::vector<LuminosityBlockID> ParameterSet::getParameter<std::vector<LuminosityBlockID> >(
        std::string const& name) const {
      return retrieve(name).getVLuminosityBlockID();
    }
  
    // ----------------------------------------------------------------------
    // EventRange
  
    template <>
    EventRange ParameterSet::getParameter<EventRange>(std::string const& name) const {
      return retrieve(name).getEventRange();
    }
  
    // ----------------------------------------------------------------------
    // VEventRange
  
    template <>
    std::vector<EventRange> ParameterSet::getParameter<std::vector<EventRange> >(std::string const& name) const {
      return retrieve(name).getVEventRange();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockRange
  
    template <>
    LuminosityBlockRange ParameterSet::getParameter<LuminosityBlockRange>(std::string const& name) const {
      return retrieve(name).getLuminosityBlockRange();
    }
  
    // ----------------------------------------------------------------------
    // VLuminosityBlockRange
  
    template <>
    std::vector<LuminosityBlockRange> ParameterSet::getParameter<std::vector<LuminosityBlockRange> >(
        std::string const& name) const {
      return retrieve(name).getVLuminosityBlockRange();
    }
  
    // ----------------------------------------------------------------------
    // PSet, vPSet
  
    template <>
    ParameterSet ParameterSet::getParameter<ParameterSet>(std::string const& name) const {
      return getParameterSet(name);
    }
  
    template <>
    VParameterSet ParameterSet::getParameter<VParameterSet>(std::string const& name) const {
      return getParameterSetVector(name);
    }
  
    // untracked parameters
  
    // ----------------------------------------------------------------------
    // Bool, vBool
  
    template <>
    bool ParameterSet::getUntrackedParameter<bool>(std::string const& name, bool const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getBool();
    }
  
    template <>
    bool ParameterSet::getUntrackedParameter<bool>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getBool();
    }
  
    // ----------------------------------------------------------------------
    // Int32, vInt32
  
    template <>
    int ParameterSet::getUntrackedParameter<int>(std::string const& name, int const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getInt32();
    }
  
    template <>
    int ParameterSet::getUntrackedParameter<int>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getInt32();
    }
  
    template <>
    std::vector<int> ParameterSet::getUntrackedParameter<std::vector<int> >(std::string const& name,
                                                                            std::vector<int> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVInt32();
    }
  
    template <>
    std::vector<int> ParameterSet::getUntrackedParameter<std::vector<int> >(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVInt32();
    }
  
    // ----------------------------------------------------------------------
    // Uint32, vUint32
  
    template <>
    unsigned int ParameterSet::getUntrackedParameter<unsigned int>(std::string const& name,
                                                                   unsigned int const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getUInt32();
    }
  
    template <>
    unsigned int ParameterSet::getUntrackedParameter<unsigned int>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getUInt32();
    }
  
    template <>
    std::vector<unsigned int> ParameterSet::getUntrackedParameter<std::vector<unsigned int> >(
        std::string const& name, std::vector<unsigned int> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVUInt32();
    }
  
    template <>
    std::vector<unsigned int> ParameterSet::getUntrackedParameter<std::vector<unsigned int> >(
        std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVUInt32();
    }
  
    // ----------------------------------------------------------------------
    // Uint64, vUint64
  
    template <>
    unsigned long long ParameterSet::getUntrackedParameter<unsigned long long>(
        std::string const& name, unsigned long long const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getUInt64();
    }
  
    template <>
    unsigned long long ParameterSet::getUntrackedParameter<unsigned long long>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getUInt64();
    }
  
    template <>
    std::vector<unsigned long long> ParameterSet::getUntrackedParameter<std::vector<unsigned long long> >(
        std::string const& name, std::vector<unsigned long long> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVUInt64();
    }
  
    template <>
    std::vector<unsigned long long> ParameterSet::getUntrackedParameter<std::vector<unsigned long long> >(
        std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVUInt64();
    }
  
    // ----------------------------------------------------------------------
    // Int64, Vint64
  
    template <>
    long long ParameterSet::getUntrackedParameter<long long>(std::string const& name,
                                                             long long const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getInt64();
    }
  
    template <>
    long long ParameterSet::getUntrackedParameter<long long>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getInt64();
    }
  
    template <>
    std::vector<long long> ParameterSet::getUntrackedParameter<std::vector<long long> >(
        std::string const& name, std::vector<long long> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVInt64();
    }
  
    template <>
    std::vector<long long> ParameterSet::getUntrackedParameter<std::vector<long long> >(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVInt64();
    }
  
    // ----------------------------------------------------------------------
    // Double, vDouble
  
    template <>
    double ParameterSet::getUntrackedParameter<double>(std::string const& name, double const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getDouble();
    }
  
    template <>
    double ParameterSet::getUntrackedParameter<double>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getDouble();
    }
  
    template <>
    std::vector<double> ParameterSet::getUntrackedParameter<std::vector<double> >(
        std::string const& name, std::vector<double> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVDouble();
    }
  
    template <>
    std::vector<double> ParameterSet::getUntrackedParameter<std::vector<double> >(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVDouble();
    }
  
    // ----------------------------------------------------------------------
    // String, vString
  
    template <>
    std::string ParameterSet::getUntrackedParameter<std::string>(std::string const& name,
                                                                 std::string const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getString();
    }
  
    template <>
    std::string ParameterSet::getUntrackedParameter<std::string>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getString();
    }
  
    template <>
    std::vector<std::string> ParameterSet::getUntrackedParameter<std::vector<std::string> >(
        std::string const& name, std::vector<std::string> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVString();
    }
  
    template <>
    std::vector<std::string> ParameterSet::getUntrackedParameter<std::vector<std::string> >(
        std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVString();
    }
  
    // ----------------------------------------------------------------------
    //  FileInPath
  
    template <>
    FileInPath ParameterSet::getUntrackedParameter<FileInPath>(std::string const& name,
                                                               FileInPath const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getFileInPath();
    }
  
    template <>
    FileInPath ParameterSet::getUntrackedParameter<FileInPath>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getFileInPath();
    }
  
    // ----------------------------------------------------------------------
    // InputTag, VInputTag
  
    template <>
    InputTag ParameterSet::getUntrackedParameter<InputTag>(std::string const& name, InputTag const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getInputTag();
    }
  
    template <>
    InputTag ParameterSet::getUntrackedParameter<InputTag>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getInputTag();
    }
  
    template <>
    std::vector<InputTag> ParameterSet::getUntrackedParameter<std::vector<InputTag> >(
        std::string const& name, std::vector<InputTag> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVInputTag();
    }
  
    template <>
    std::vector<InputTag> ParameterSet::getUntrackedParameter<std::vector<InputTag> >(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVInputTag();
    }
  
    // ----------------------------------------------------------------------
    // ESInputTag, VESInputTag
  
    template <>
    ESInputTag ParameterSet::getUntrackedParameter<ESInputTag>(std::string const& name,
                                                               ESInputTag const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getESInputTag();
    }
  
    template <>
    ESInputTag ParameterSet::getUntrackedParameter<ESInputTag>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getESInputTag();
    }
  
    template <>
    std::vector<ESInputTag> ParameterSet::getUntrackedParameter<std::vector<ESInputTag> >(
        std::string const& name, std::vector<ESInputTag> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVESInputTag();
    }
  
    template <>
    std::vector<ESInputTag> ParameterSet::getUntrackedParameter<std::vector<ESInputTag> >(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVESInputTag();
    }
  
    // ----------------------------------------------------------------------
    // EventID, VEventID
  
    template <>
    EventID ParameterSet::getUntrackedParameter<EventID>(std::string const& name, EventID const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getEventID();
    }
  
    template <>
    EventID ParameterSet::getUntrackedParameter<EventID>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getEventID();
    }
  
    template <>
    std::vector<EventID> ParameterSet::getUntrackedParameter<std::vector<EventID> >(
        std::string const& name, std::vector<EventID> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVEventID();
    }
  
    template <>
    std::vector<EventID> ParameterSet::getUntrackedParameter<std::vector<EventID> >(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVEventID();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockID, VLuminosityBlockID
  
    template <>
    LuminosityBlockID ParameterSet::getUntrackedParameter<LuminosityBlockID>(
        std::string const& name, LuminosityBlockID const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getLuminosityBlockID();
    }
  
    template <>
    LuminosityBlockID ParameterSet::getUntrackedParameter<LuminosityBlockID>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getLuminosityBlockID();
    }
  
    template <>
    std::vector<LuminosityBlockID> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockID> >(
        std::string const& name, std::vector<LuminosityBlockID> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVLuminosityBlockID();
    }
  
    template <>
    std::vector<LuminosityBlockID> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockID> >(
        std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVLuminosityBlockID();
    }
  
    // ----------------------------------------------------------------------
    // EventRange, VEventRange
  
    template <>
    EventRange ParameterSet::getUntrackedParameter<EventRange>(std::string const& name,
                                                               EventRange const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getEventRange();
    }
  
    template <>
    EventRange ParameterSet::getUntrackedParameter<EventRange>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getEventRange();
    }
  
    template <>
    std::vector<EventRange> ParameterSet::getUntrackedParameter<std::vector<EventRange> >(
        std::string const& name, std::vector<EventRange> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVEventRange();
    }
  
    template <>
    std::vector<EventRange> ParameterSet::getUntrackedParameter<std::vector<EventRange> >(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVEventRange();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockRange, VLuminosityBlockRange
  
    template <>
    LuminosityBlockRange ParameterSet::getUntrackedParameter<LuminosityBlockRange>(
        std::string const& name, LuminosityBlockRange const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getLuminosityBlockRange();
    }
  
    template <>
    LuminosityBlockRange ParameterSet::getUntrackedParameter<LuminosityBlockRange>(std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getLuminosityBlockRange();
    }
  
    template <>
    std::vector<LuminosityBlockRange> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockRange> >(
        std::string const& name, std::vector<LuminosityBlockRange> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVLuminosityBlockRange();
    }
  
    template <>
    std::vector<LuminosityBlockRange> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockRange> >(
        std::string const& name) const {
      return getEntryPointerOrThrow_(name)->getVLuminosityBlockRange();
    }
  
    // specializations
    // ----------------------------------------------------------------------
    // Bool, vBool
  
    template <>
    bool ParameterSet::getParameter<bool>(char const* name) const {
      return retrieve(name).getBool();
    }
  
    // ----------------------------------------------------------------------
    // Int32, vInt32
  
    template <>
    int ParameterSet::getParameter<int>(char const* name) const {
      return retrieve(name).getInt32();
    }
  
    template <>
    std::vector<int> ParameterSet::getParameter<std::vector<int> >(char const* name) const {
      return retrieve(name).getVInt32();
    }
  
    // ----------------------------------------------------------------------
    // Int64, vInt64
  
    template <>
    long long ParameterSet::getParameter<long long>(char const* name) const {
      return retrieve(name).getInt64();
    }
  
    template <>
    std::vector<long long> ParameterSet::getParameter<std::vector<long long> >(char const* name) const {
      return retrieve(name).getVInt64();
    }
  
    // ----------------------------------------------------------------------
    // Uint32, vUint32
  
    template <>
    unsigned int ParameterSet::getParameter<unsigned int>(char const* name) const {
      return retrieve(name).getUInt32();
    }
  
    template <>
    std::vector<unsigned int> ParameterSet::getParameter<std::vector<unsigned int> >(char const* name) const {
      return retrieve(name).getVUInt32();
    }
  
    // ----------------------------------------------------------------------
    // Uint64, vUint64
  
    template <>
    unsigned long long ParameterSet::getParameter<unsigned long long>(char const* name) const {
      return retrieve(name).getUInt64();
    }
  
    template <>
    std::vector<unsigned long long> ParameterSet::getParameter<std::vector<unsigned long long> >(char const* name) const {
      return retrieve(name).getVUInt64();
    }
  
    // ----------------------------------------------------------------------
    // Double, vDouble
  
    template <>
    double ParameterSet::getParameter<double>(char const* name) const {
      return retrieve(name).getDouble();
    }
  
    template <>
    std::vector<double> ParameterSet::getParameter<std::vector<double> >(char const* name) const {
      return retrieve(name).getVDouble();
    }
  
    // ----------------------------------------------------------------------
    // String, vString
  
    template <>
    std::string ParameterSet::getParameter<std::string>(char const* name) const {
      return retrieve(name).getString();
    }
  
    template <>
    std::vector<std::string> ParameterSet::getParameter<std::vector<std::string> >(char const* name) const {
      return retrieve(name).getVString();
    }
  
    // ----------------------------------------------------------------------
    // FileInPath
  
    template <>
    FileInPath ParameterSet::getParameter<FileInPath>(char const* name) const {
      return retrieve(name).getFileInPath();
    }
  
    // ----------------------------------------------------------------------
    // InputTag
  
    template <>
    InputTag ParameterSet::getParameter<InputTag>(char const* name) const {
      Entry const& e_input = retrieve(name);
      switch (e_input.typeCode()) {
        case 't':  // InputTag
          return e_input.getInputTag();
        case 'S':  // string
          std::string const& label = e_input.getString();
          deprecatedInputTagWarning(name, label);
          return InputTag(label);
      }
      throw Exception(errors::Configuration, "ValueError")
          << "type of " << name << " is expected to be InputTag or string (deprecated)";
    }
  
    // ----------------------------------------------------------------------
    // VInputTag
  
    template <>
    std::vector<InputTag> ParameterSet::getParameter<std::vector<InputTag> >(char const* name) const {
      return retrieve(name).getVInputTag();
    }
  
    // ----------------------------------------------------------------------
    // ESInputTag
  
    template <>
    ESInputTag ParameterSet::getParameter<ESInputTag>(char const* name) const {
      return retrieve(name).getESInputTag();
    }
  
    // ----------------------------------------------------------------------
    // VESInputTag
  
    template <>
    std::vector<ESInputTag> ParameterSet::getParameter<std::vector<ESInputTag> >(char const* name) const {
      return retrieve(name).getVESInputTag();
    }
  
    // ----------------------------------------------------------------------
    // EventID
  
    template <>
    EventID ParameterSet::getParameter<EventID>(char const* name) const {
      return retrieve(name).getEventID();
    }
  
    // ----------------------------------------------------------------------
    // VEventID
  
    template <>
    std::vector<EventID> ParameterSet::getParameter<std::vector<EventID> >(char const* name) const {
      return retrieve(name).getVEventID();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockID
  
    template <>
    LuminosityBlockID ParameterSet::getParameter<LuminosityBlockID>(char const* name) const {
      return retrieve(name).getLuminosityBlockID();
    }
  
    // ----------------------------------------------------------------------
    // VLuminosityBlockID
  
    template <>
    std::vector<LuminosityBlockID> ParameterSet::getParameter<std::vector<LuminosityBlockID> >(char const* name) const {
      return retrieve(name).getVLuminosityBlockID();
    }
  
    // ----------------------------------------------------------------------
    // EventRange
  
    template <>
    EventRange ParameterSet::getParameter<EventRange>(char const* name) const {
      return retrieve(name).getEventRange();
    }
  
    // ----------------------------------------------------------------------
    // VEventRange
  
    template <>
    std::vector<EventRange> ParameterSet::getParameter<std::vector<EventRange> >(char const* name) const {
      return retrieve(name).getVEventRange();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockRange
  
    template <>
    LuminosityBlockRange ParameterSet::getParameter<LuminosityBlockRange>(char const* name) const {
      return retrieve(name).getLuminosityBlockRange();
    }
  
    // ----------------------------------------------------------------------
    // VLuminosityBlockRange
  
    template <>
    std::vector<LuminosityBlockRange> ParameterSet::getParameter<std::vector<LuminosityBlockRange> >(
        char const* name) const {
      return retrieve(name).getVLuminosityBlockRange();
    }
  
    // ----------------------------------------------------------------------
    // PSet, vPSet
  
    template <>
    ParameterSet ParameterSet::getParameter<ParameterSet>(char const* name) const {
      return getParameterSet(name);
    }
  
    template <>
    VParameterSet ParameterSet::getParameter<VParameterSet>(char const* name) const {
      return getParameterSetVector(name);
    }
  
    // untracked parameters
  
    // ----------------------------------------------------------------------
    // Bool, vBool
  
    template <>
    bool ParameterSet::getUntrackedParameter<bool>(char const* name, bool const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getBool();
    }
  
    template <>
    bool ParameterSet::getUntrackedParameter<bool>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getBool();
    }
  
    // ----------------------------------------------------------------------
    // Int32, vInt32
  
    template <>
    int ParameterSet::getUntrackedParameter<int>(char const* name, int const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getInt32();
    }
  
    template <>
    int ParameterSet::getUntrackedParameter<int>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getInt32();
    }
  
    template <>
    std::vector<int> ParameterSet::getUntrackedParameter<std::vector<int> >(char const* name,
                                                                            std::vector<int> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVInt32();
    }
  
    template <>
    std::vector<int> ParameterSet::getUntrackedParameter<std::vector<int> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVInt32();
    }
  
    // ----------------------------------------------------------------------
    // Uint32, vUint32
  
    template <>
    unsigned int ParameterSet::getUntrackedParameter<unsigned int>(char const* name,
                                                                   unsigned int const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getUInt32();
    }
  
    template <>
    unsigned int ParameterSet::getUntrackedParameter<unsigned int>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getUInt32();
    }
  
    template <>
    std::vector<unsigned int> ParameterSet::getUntrackedParameter<std::vector<unsigned int> >(
        char const* name, std::vector<unsigned int> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVUInt32();
    }
  
    template <>
    std::vector<unsigned int> ParameterSet::getUntrackedParameter<std::vector<unsigned int> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVUInt32();
    }
  
    // ----------------------------------------------------------------------
    // Uint64, vUint64
  
    template <>
    unsigned long long ParameterSet::getUntrackedParameter<unsigned long long>(
        char const* name, unsigned long long const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getUInt64();
    }
  
    template <>
    unsigned long long ParameterSet::getUntrackedParameter<unsigned long long>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getUInt64();
    }
  
    template <>
    std::vector<unsigned long long> ParameterSet::getUntrackedParameter<std::vector<unsigned long long> >(
        char const* name, std::vector<unsigned long long> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVUInt64();
    }
  
    template <>
    std::vector<unsigned long long> ParameterSet::getUntrackedParameter<std::vector<unsigned long long> >(
        char const* name) const {
      return getEntryPointerOrThrow_(name)->getVUInt64();
    }
  
    // ----------------------------------------------------------------------
    // Int64, Vint64
  
    template <>
    long long ParameterSet::getUntrackedParameter<long long>(char const* name, long long const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getInt64();
    }
  
    template <>
    long long ParameterSet::getUntrackedParameter<long long>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getInt64();
    }
  
    template <>
    std::vector<long long> ParameterSet::getUntrackedParameter<std::vector<long long> >(
        char const* name, std::vector<long long> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVInt64();
    }
  
    template <>
    std::vector<long long> ParameterSet::getUntrackedParameter<std::vector<long long> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVInt64();
    }
  
    // ----------------------------------------------------------------------
    // Double, vDouble
  
    template <>
    double ParameterSet::getUntrackedParameter<double>(char const* name, double const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getDouble();
    }
  
    template <>
    double ParameterSet::getUntrackedParameter<double>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getDouble();
    }
  
    template <>
    std::vector<double> ParameterSet::getUntrackedParameter<std::vector<double> >(
        char const* name, std::vector<double> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVDouble();
    }
  
    template <>
    std::vector<double> ParameterSet::getUntrackedParameter<std::vector<double> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVDouble();
    }
  
    // ----------------------------------------------------------------------
    // String, vString
  
    template <>
    std::string ParameterSet::getUntrackedParameter<std::string>(char const* name,
                                                                 std::string const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getString();
    }
  
    template <>
    std::string ParameterSet::getUntrackedParameter<std::string>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getString();
    }
  
    template <>
    std::vector<std::string> ParameterSet::getUntrackedParameter<std::vector<std::string> >(
        char const* name, std::vector<std::string> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVString();
    }
  
    template <>
    std::vector<std::string> ParameterSet::getUntrackedParameter<std::vector<std::string> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVString();
    }
  
    // ----------------------------------------------------------------------
    //  FileInPath
  
    template <>
    FileInPath ParameterSet::getUntrackedParameter<FileInPath>(char const* name, FileInPath const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getFileInPath();
    }
  
    template <>
    FileInPath ParameterSet::getUntrackedParameter<FileInPath>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getFileInPath();
    }
  
    // ----------------------------------------------------------------------
    // InputTag, VInputTag
  
    template <>
    InputTag ParameterSet::getUntrackedParameter<InputTag>(char const* name, InputTag const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getInputTag();
    }
  
    template <>
    InputTag ParameterSet::getUntrackedParameter<InputTag>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getInputTag();
    }
  
    template <>
    std::vector<InputTag> ParameterSet::getUntrackedParameter<std::vector<InputTag> >(
        char const* name, std::vector<InputTag> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVInputTag();
    }
  
    template <>
    std::vector<InputTag> ParameterSet::getUntrackedParameter<std::vector<InputTag> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVInputTag();
    }
  
    // ----------------------------------------------------------------------
    // ESInputTag, VESInputTag
  
    template <>
    ESInputTag ParameterSet::getUntrackedParameter<ESInputTag>(char const* name, ESInputTag const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getESInputTag();
    }
  
    template <>
    ESInputTag ParameterSet::getUntrackedParameter<ESInputTag>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getESInputTag();
    }
  
    template <>
    std::vector<ESInputTag> ParameterSet::getUntrackedParameter<std::vector<ESInputTag> >(
        char const* name, std::vector<ESInputTag> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVESInputTag();
    }
  
    template <>
    std::vector<ESInputTag> ParameterSet::getUntrackedParameter<std::vector<ESInputTag> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVESInputTag();
    }
  
    // ----------------------------------------------------------------------
    // EventID, VEventID
  
    template <>
    EventID ParameterSet::getUntrackedParameter<EventID>(char const* name, EventID const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getEventID();
    }
  
    template <>
    EventID ParameterSet::getUntrackedParameter<EventID>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getEventID();
    }
  
    template <>
    std::vector<EventID> ParameterSet::getUntrackedParameter<std::vector<EventID> >(
        char const* name, std::vector<EventID> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVEventID();
    }
  
    template <>
    std::vector<EventID> ParameterSet::getUntrackedParameter<std::vector<EventID> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVEventID();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockID, VLuminosityBlockID
  
    template <>
    LuminosityBlockID ParameterSet::getUntrackedParameter<LuminosityBlockID>(
        char const* name, LuminosityBlockID const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getLuminosityBlockID();
    }
  
    template <>
    LuminosityBlockID ParameterSet::getUntrackedParameter<LuminosityBlockID>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getLuminosityBlockID();
    }
  
    template <>
    std::vector<LuminosityBlockID> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockID> >(
        char const* name, std::vector<LuminosityBlockID> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVLuminosityBlockID();
    }
  
    template <>
    std::vector<LuminosityBlockID> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockID> >(
        char const* name) const {
      return getEntryPointerOrThrow_(name)->getVLuminosityBlockID();
    }
  
    // ----------------------------------------------------------------------
    // EventRange, VEventRange
  
    template <>
    EventRange ParameterSet::getUntrackedParameter<EventRange>(char const* name, EventRange const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getEventRange();
    }
  
    template <>
    EventRange ParameterSet::getUntrackedParameter<EventRange>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getEventRange();
    }
  
    template <>
    std::vector<EventRange> ParameterSet::getUntrackedParameter<std::vector<EventRange> >(
        char const* name, std::vector<EventRange> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVEventRange();
    }
  
    template <>
    std::vector<EventRange> ParameterSet::getUntrackedParameter<std::vector<EventRange> >(char const* name) const {
      return getEntryPointerOrThrow_(name)->getVEventRange();
    }
  
    // ----------------------------------------------------------------------
    // LuminosityBlockRange, VLuminosityBlockRange
  
    template <>
    LuminosityBlockRange ParameterSet::getUntrackedParameter<LuminosityBlockRange>(
        char const* name, LuminosityBlockRange const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getLuminosityBlockRange();
    }
  
    template <>
    LuminosityBlockRange ParameterSet::getUntrackedParameter<LuminosityBlockRange>(char const* name) const {
      return getEntryPointerOrThrow_(name)->getLuminosityBlockRange();
    }
  
    template <>
    std::vector<LuminosityBlockRange> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockRange> >(
        char const* name, std::vector<LuminosityBlockRange> const& defaultValue) const {
      Entry const* entryPtr = retrieveUntracked(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->getVLuminosityBlockRange();
    }
  
    template <>
    std::vector<LuminosityBlockRange> ParameterSet::getUntrackedParameter<std::vector<LuminosityBlockRange> >(
        char const* name) const {
      return getEntryPointerOrThrow_(name)->getVLuminosityBlockRange();
    }
  
    // ----------------------------------------------------------------------
    // PSet, vPSet
  
    template <>
    ParameterSet ParameterSet::getUntrackedParameter<ParameterSet>(char const* name,
                                                                   ParameterSet const& defaultValue) const {
      return getUntrackedParameterSet(name, defaultValue);
    }
  
    template <>
    VParameterSet ParameterSet::getUntrackedParameter<VParameterSet>(char const* name,
                                                                     VParameterSet const& defaultValue) const {
      return getUntrackedParameterSetVector(name, defaultValue);
    }
  
    template <>
    ParameterSet ParameterSet::getUntrackedParameter<ParameterSet>(std::string const& name,
                                                                   ParameterSet const& defaultValue) const {
      return getUntrackedParameterSet(name, defaultValue);
    }
  
    template <>
    VParameterSet ParameterSet::getUntrackedParameter<VParameterSet>(std::string const& name,
                                                                     VParameterSet const& defaultValue) const {
      return getUntrackedParameterSetVector(name, defaultValue);
    }
  
    template <>
    ParameterSet ParameterSet::getUntrackedParameter<ParameterSet>(char const* name) const {
      return getUntrackedParameterSet(name);
    }
  
    template <>
    VParameterSet ParameterSet::getUntrackedParameter<VParameterSet>(char const* name) const {
      return getUntrackedParameterSetVector(name);
    }
  
    template <>
    ParameterSet ParameterSet::getUntrackedParameter<ParameterSet>(std::string const& name) const {
      return getUntrackedParameterSet(name);
    }
  
    template <>
    VParameterSet ParameterSet::getUntrackedParameter<VParameterSet>(std::string const& name) const {
      return getUntrackedParameterSetVector(name);
    }
  
    //----------------------------------------------------------------------------------
    // specializations for addParameter and addUntrackedParameter
  
    template <>
    void ParameterSet::addParameter<ParameterSet>(std::string const& name, ParameterSet const& value) {
      invalidateRegistration(name);
      insertParameterSet(true, name, ParameterSetEntry(value, true));
    }
  
    template <>
    void ParameterSet::addParameter<VParameterSet>(std::string const& name, VParameterSet const& value) {
      invalidateRegistration(name);
      insertVParameterSet(true, name, VParameterSetEntry(value, true));
    }
  
    template <>
    void ParameterSet::addParameter<ParameterSet>(char const* name, ParameterSet const& value) {
      invalidateRegistration(name);
      insertParameterSet(true, name, ParameterSetEntry(value, true));
    }
  
    template <>
    void ParameterSet::addParameter<VParameterSet>(char const* name, VParameterSet const& value) {
      invalidateRegistration(name);
      insertVParameterSet(true, name, VParameterSetEntry(value, true));
    }
  
    template <>
    void ParameterSet::addUntrackedParameter<ParameterSet>(std::string const& name, ParameterSet const& value) {
      insertParameterSet(true, name, ParameterSetEntry(value, false));
    }
  
    template <>
    void ParameterSet::addUntrackedParameter<VParameterSet>(std::string const& name, VParameterSet const& value) {
      insertVParameterSet(true, name, VParameterSetEntry(value, false));
    }
  
    template <>
    void ParameterSet::addUntrackedParameter<ParameterSet>(char const* name, ParameterSet const& value) {
      insertParameterSet(true, name, ParameterSetEntry(value, false));
    }
  
    template <>
    void ParameterSet::addUntrackedParameter<VParameterSet>(char const* name, VParameterSet const& value) {
      insertVParameterSet(true, name, VParameterSetEntry(value, false));
    }
  
    //----------------------------------------------------------------------------------
    // specializations for getParameterNamesForType
  
    template <>
    std::vector<std::string> ParameterSet::getParameterNamesForType<ParameterSet>(bool trackiness) const {
      std::vector<std::string> output;
      getParameterSetNames(output, trackiness);
      return output;
    }
  
    template <>
    std::vector<std::string> ParameterSet::getParameterNamesForType<VParameterSet>(bool trackiness) const {
      std::vector<std::string> output;
      getParameterSetVectorNames(output, trackiness);
      return output;
    }
  
    ParameterSet const& ParameterSet::getParameterSet(std::string const& name) const {
      return retrieveParameterSet(name).pset();
    }
  
    ParameterSet const& ParameterSet::getParameterSet(char const* name) const {
      return retrieveParameterSet(name).pset();
    }
  
    ParameterSet ParameterSet::getUntrackedParameterSet(std::string const& name, ParameterSet const& defaultValue) const {
      return getUntrackedParameterSet(name.c_str(), defaultValue);
    }
  
    ParameterSet ParameterSet::getUntrackedParameterSet(char const* name, ParameterSet const& defaultValue) const {
      ParameterSetEntry const* entryPtr = retrieveUntrackedParameterSet(name);
      if (entryPtr == nullptr) {
        return defaultValue;
      }
      return entryPtr->pset();
    }
  
    ParameterSet const& ParameterSet::getUntrackedParameterSet(std::string const& name) const {
      return getUntrackedParameterSet(name.c_str());
    }
  
    ParameterSet const& ParameterSet::getUntrackedParameterSet(char const* name) const {
      ParameterSetEntry const* result = retrieveUntrackedParameterSet(name);
      if (result == nullptr)
        throw Exception(errors::Configuration, "MissingParameter:")
            << "The required ParameterSet '" << name << "' was not specified.\n";
      return result->pset();
    }
  
    VParameterSet const& ParameterSet::getParameterSetVector(std::string const& name) const {
      return retrieveVParameterSet(name).vpset();
    }
  
    VParameterSet const& ParameterSet::getParameterSetVector(char const* name) const {
      return retrieveVParameterSet(name).vpset();
    }
  
    VParameterSet ParameterSet::getUntrackedParameterSetVector(std::string const& name,
                                                               VParameterSet const& defaultValue) const {
      return getUntrackedParameterSetVector(name.c_str(), defaultValue);
    }
  
    VParameterSet ParameterSet::getUntrackedParameterSetVector(char const* name,
                                                               VParameterSet const& defaultValue) const {
      VParameterSetEntry const* entryPtr = retrieveUntrackedVParameterSet(name);
      return entryPtr == nullptr ? defaultValue : entryPtr->vpset();
    }
  
    VParameterSet const& ParameterSet::getUntrackedParameterSetVector(std::string const& name) const {
      return getUntrackedParameterSetVector(name.c_str());
    }
  
    VParameterSet const& ParameterSet::getUntrackedParameterSetVector(char const* name) const {
      VParameterSetEntry const* result = retrieveUntrackedVParameterSet(name);
      if (result == nullptr)
        throw Exception(errors::Configuration, "MissingParameter:")
            << "The required ParameterSetVector '" << name << "' was not specified.\n";
      return result->vpset();
    }
  }  // namespace edm
  