diff --git a/source/javascripts/phonebook.js b/source/javascripts/phonebook.js
new file mode 100644
index 0000000..74a4b31
--- /dev/null
+++ b/source/javascripts/phonebook.js
@@ -0,0 +1,917 @@
+var pmcs = [] // array of PMC names (excludes non-PMC committees)
+var people = {} // public_ldap_people.json
+var ldapauth = {} // public_ldap_authgroups.json
+// TODO don't rely on ldap_groups containing PMC :members groups
+var ldapgroups = {} //  public_ldap_groups.json
+var ldapservices = {} // public_ldap_services.json
+var ldapprojects = {} // public_ldap_projects.json
+
+var members = {} // copy of member-info.json
+var committees = {} // copy of committee-info.json (plus details for 'member' dummy PMC)
+var iclainfo = {} // copy of icla-info.json (committers only)
+var podlings = {} // public_ldap_projects.json where podling is 'current'
+
+var info = {} // copies of json info
+
+// Constants for query types. 
+// Do NOT change the values once established, as they are part of the public API
+// For example they may be used in projects.a.o and reporter.a.o
+// The values are used for matching HTTP queries and linkifying lists (to generate a valid HTML link)
+
+var Q_USER = 'user' // search users
+var Q_PROJECT = 'project' // search PMC names
+var Q_UID = 'uid' // availid, exact match
+var Q_PMC = 'pmc' // PMC, exact match
+var Q_UNIX = 'unix' // LDAP group
+var Q_CTTE = 'ctte' // LDAP group
+var Q_SERVICE = 'service' // LDAP group
+var Q_PODLING = 'podling' // podling (non-LDAP group)
+var Q_AUTH = 'auth' // podling (LDAP auth group)
+
+
+// Not intended for general use; may change at any time
+var Q_DEBUG = 'debug' // print some debug info
+
+// compatibility shim for IE8 and other older browsers
+if (!Date.now) {
+   Date.now = function() {
+      return new Date().getTime();
+   }
+}
+
+// This is faster than parseInt, and it's more obvious why it is being done
+function toInt(number) {
+   return number | 0 //
+}
+
+var fetchCount = 0;
+// Fetch an array of URLs, each with their description and own callback plus a final callback
+// Used to fetch everything before rendering a page that relies on multiple JSON sources.
+
+
+function getAsyncJSONArray(urls, finalCallback) {
+   var obj = document.getElementById('progress');
+   if (fetchCount == 0) {
+      fetchCount = urls.length;
+   }
+
+   if (urls.length > 0) {
+      var a = urls.shift();
+      var URL = a[0];
+      var desc = a[1];
+      var cb = a[2];
+      var xmlHttp = null;
+      if (window.XMLHttpRequest) {
+         xmlHttp = new XMLHttpRequest();
+      } else {
+         xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
+      }
+
+      if (obj) {
+         obj.innerHTML = "loading file #" + (fetchCount - urls.length) + " / " + fetchCount + "<br>" + desc
+      }
+      var start = Date.now()
+      xmlHttp.open("GET", URL, true);
+      xmlHttp.onreadystatechange = function(state) {
+         if (xmlHttp.readyState == 4) {
+            if (cb) {
+               if (xmlHttp.status == 200) {
+                  elapsed = Date.now() - start
+                  cb(JSON.parse(xmlHttp.responseText));
+                  // must be done after as cb creates the hash
+                  info[desc]['elapsed'] = elapsed
+               } else {
+                  cb({});
+                  alert("Error: '" + xmlHttp.statusText + "' while loading " + URL)
+               }
+            }
+            getAsyncJSONArray(urls, finalCallback);
+         }
+      }
+      xmlHttp.send(null);
+   } else {
+      if (obj) {
+         obj.innerHTML = "building page content..."
+      }
+      finalCallback();
+   }
+}
+
+// get list of projects on which uid is a committer
+function getProjectCommittership(uid) {
+   var cl = []
+   for (var i in ldapprojects) {
+      if (ldapprojects[i].pmc && ldapprojects[i].members.indexOf(uid) > -1) {
+         cl.push(i)
+      }
+   }
+   return cl
+}
+
+//get list of projects on which uid is an owner (member karma)
+function getProjectOwnership(uid) {
+   var cl = []
+   for (var i in ldapprojects) {
+      if (ldapprojects[i].pmc && ldapprojects[i].owners.indexOf(uid) > -1) {
+         cl.push(i)
+      }
+   }
+   return cl
+}
+
+// Get the roster from a json group
+// returns: all the keys where the uid is [not] a member
+function getRoster(json, uid, notIn) {
+   var cl = []
+   for (var i in json) {
+      if (json[i].roster.indexOf(uid) > -1) {
+         if (typeof notIn === 'undefined') {
+            cl.push(i)
+         } else {
+            if (notIn.indexOf(i) == -1) {
+               cl.push(i)
+            }
+         }
+      }
+   }
+   return cl
+}
+
+// get data from committee-info for a person
+// return [list of pmcs, list of chairs]
+function getCommitteeRoles(uid) {
+   var pl = []
+   var ch = []
+   for (var i in committees) {
+      // Only list actual PMCs
+      if (committees[i].pmc && uid in committees[i].roster) {
+         pl.push(i)
+      }
+      //var chair = committees[i].chair // might not be one (eg members)
+      //if (chair && uid in committees[i].chair) {
+         ch.push(i)
+      //}
+   }
+   return [pl, ch]
+}
+
+function getCommitterName(uid) {
+   var noicla = {
+      'andrei': '(Andrei Zmievski)',
+      'pcs': '(Paul Sutton)',
+      'rasmus': '(Rasmus Lerdorf)'
+   }
+   var name
+   if (uid in people) { // it's possible for a list to contain a uid that is not in people (e.g. andrei in member)
+      name = people[uid].name
+   }
+   if (!name) {
+      name = iclainfo[uid]
+   }
+   if (!name) { // try the backup specials
+      name = noicla[uid]
+   }
+   return name
+}
+
+// Linkify list of group names by adding the appropriate ?type= href
+
+function linkifyList(type, names) {
+   var text = ''
+   var index, len, i
+   names.sort()
+   for (i = 0, len = names.length; i < len; ++i) {
+      if (i > 0) {
+         text = text + ", "
+      }
+      text = text + "<a href='?" + type + "=" + names[i] + "'>" + names[i] + "</a>"
+   }
+   return text
+}
+
+// Linkify user ids
+
+function userList(ua) {
+   var text = ''
+   var index, len
+   ua.sort()
+   for (index = 0, len = ua.length; index < len; ++index) {
+      if (index > 0) {
+         text = text + ", "
+      }
+      text = text + hiliteMember(ua[index])
+   }
+   return text
+}
+
+//Linkify URLs
+
+function linkifyURLs(ua) {
+   var text = ''
+   var index, len
+   ua.sort()
+   for (index = 0, len = ua.length; index < len; ++index) {
+      if (index > 0) {
+         text = text + ", "
+      }
+      text = text + "<a target='_blank' href='" + ua[index] + "'>" + ua[index] + "</a>"
+   }
+   return text
+}
+
+function showCommitter(obj, uid) {
+   var details = document.getElementById('details_committer_' + uid)
+   if (!details) {
+      details = document.createElement('p')
+      details.setAttribute("id", 'details_committer_' + uid)
+      var cl = getProjectCommittership(uid) // committer(in :members) of these LDAP PMC projects 
+      var roles = getCommitteeRoles(uid)
+      var cttees = getProjectOwnership(uid) // member(in :owners) of these LDAP PMC projects
+      var pl = roles[0] // pmc membership
+      var ch = roles[1] // chairs
+      if (isNologin(uid)) {
+         details.innerHTML += "<b>Login is currently disabled</b><br/><br/>"
+      }
+      if (isMember(uid)) {
+         details.innerHTML += "<i>Foundation member</i><br/><br/>"
+      }
+      if (ch.length > 0) {
+         details.innerHTML += "<b>Chair of:</b> " + linkifyList(Q_PMC, ch)
+         if (!isChair(uid)) {
+            details.innerHTML += " <b>Not a member of pmc-chairs!</b>"
+         }
+         details.innerHTML += "<br/><br/>"
+      }
+      var purls = urls(uid)
+      if (purls.length > 0) {
+         details.innerHTML += "<b>Personal URLs:</b> " + linkifyURLs(purls) + "<br/><br/>"
+      }
+      if (cl.length > 0) {
+         details.innerHTML += "<b>Committer on:</b> " + linkifyList(Q_UNIX, cl) + "<br/><br/>"
+      }
+      var nc = [] // On PMC but not in LDAP unix
+      var nl = [] // On PMC but not in LDAP committee
+      var np = [] // Not in PMC even though in LDAP committee
+      var nu = [] // In LDAP committee but not in LDAP unix
+      var pn;
+      if (pl.length > 0) {
+         details.innerHTML += "<b>PMC member of:</b> " + linkifyList(Q_PMC, pl) + "<br/><br/>"
+         for (p in pl) {
+            pn = pl[p]
+            // There is an LDAP PMC group but the uid is not in the committer(:members) group
+            if (isProjectPMC(pn) && cl.indexOf(pn) < 0) {
+               nc.push(pn)
+            }
+            // There is an LDAP PMC group but the uid is not in the committee(:owners) group
+            if (isProjectPMC(pn) && cttees.indexOf(pn) < 0) {
+               nl.push(pn)
+            }
+         }
+      }
+
+      if (cttees.length > 0) {
+         for (p in cttees) {
+            pn = cttees[p]
+            // name is a PMC but uid is not on the PMC
+            if (isPMC(pn) && pl.indexOf(pn) < 0) {
+               np.push(pn)
+            }
+            // name has LDAP project entry but uid is not in the committer (member) list  
+            if (isProjectPMC(pn) && cl.indexOf(pn) < 0) {
+               nu.push(pn)
+            }
+         }
+         details.innerHTML += "<b>LDAP committee group membership:</b> " + linkifyList(Q_CTTE, cttees) + "<br/><br/>"
+      }
+
+      var services = getRoster(ldapservices, uid)
+      if (services.length > 0) {
+         details.innerHTML += "<b>Service group membership:</b> " + linkifyList(Q_SERVICE, services) + "<br/><br/>"
+      }
+      var auths = getRoster(ldapauth, uid)
+      if (auths.length > 0) {
+         details.innerHTML += "<b>Auth group membership:</b> " + linkifyList(Q_AUTH, auths) + "<br/><br/>"
+      }
+      var pods = getRoster(podlings, uid)
+      if (pods.length > 0) {
+         details.innerHTML += "<b>Podling membership:</b> " + linkifyList(Q_PODLING, pods) + "<br/><br/>"
+      }
+
+      // Note any discrepancies
+      if (np.length > 0) {
+         details.innerHTML += "<span class='error'>In LDAP committee group, but <b>not a PMC member</b>:</span> " + linkifyList(Q_CTTE, np) + "<br/><br/>"
+      }
+      if (nc.length > 0) {
+         details.innerHTML += "<span class='error'>On PMC, but not a member of the committer group:</span> " + linkifyList(Q_PMC, nc) + "<br/><br/>"
+      }
+      if (nl.length > 0) {
+         details.innerHTML += "<span class='error'>On PMC, but not member of the LDAP committee group:</span> " + linkifyList(Q_CTTE, nl) + "<br/><br/>"
+      }
+      if (nu.length > 0) {
+         details.innerHTML += "<span class='error'>In LDAP committee group but not a member of the committer group:</span> " + linkifyList(Q_UNIX, nu) + "<br/><br/>"
+      }
+      obj.appendChild(details)
+   } else {
+      obj.removeChild(details)
+   }
+}
+
+function hoverCommitter(parent, uid) {
+   var div = document.getElementById('hoverbar')
+
+   // If the datepicker object doesn't exist, spawn it
+   if (!div) {
+      div = document.createElement('div')
+      document.body.appendChild(div)
+      div.setAttribute("id", "hoverbar")
+      div.style.position = "fixed"
+      div.style.width = "400px"
+      div.style.background = "linear-gradient(to bottom, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%)"
+      div.style.borderRadius = "4px"
+      div.style.border = "1px solid #333"
+      div.style.zIndex = "9999"
+   }
+
+   // Reset the contents of the datepicker object
+   div.innerHTML = ""
+
+   var bb = parent.getBoundingClientRect()
+   div.style.top = (bb.bottom + 24) + "px"
+   div.style.left = (bb.left + 32) + "px"
+
+   if (uid) {
+      div.style.display = "block"
+      div.innerHTML = "<h4>" + getCommitterName(uid) + "</h4>"
+      var cl = getProjectCommittership(uid)
+      var roles = getCommitteeRoles(uid)
+      var pl = roles[0]
+      var ch = roles[1]
+      if (isMember(uid) == true) {
+         div.innerHTML += "<i>Foundation member</i><br/><br/>"
+      }
+      if (isNologin(uid)) {
+         div.innerHTML += "<b>Login is currently disabled</b><br/><br/>"
+      }
+      if (ch.length > 0) {
+         ch.sort()
+         div.innerHTML += "<b>Chair of:</b> " + ch.join(", ")
+         if (!isChair(uid)) {
+            div.innerHTML += " <b>Not a member of pmc-chairs!</b>"
+         }
+         div.innerHTML += "<br/><br/>"
+      }
+      if (cl.length > 0) {
+         cl.sort()
+         div.innerHTML += "<b>Committer on:</b> " + cl.join(", ") + "<br/><br/>"
+      }
+      var nc = []
+      if (pl.length > 0) {
+         pl.sort()
+         div.innerHTML += "<b>PMC member of:</b> " + pl.join(", ") + "<br/><br/>"
+         for (p in pl) {
+            var pn = pl[p]
+            if (pn != 'member' && cl.indexOf(pn) < 0) {
+               nc.push(pn)
+            }
+         }
+      }
+      if (nc.length > 0) {
+         div.innerHTML += "<i>On PMC, but not a Committer on:</i> " + nc.join(", ") + "<br/><br/>"
+      }
+
+
+   } else {
+      div.style.display = "none"
+   }
+}
+
+function isNologin(uid) {
+   return !(uid in people) || people[uid].noLogin
+}
+
+function isMember(uid) {
+   return members['members'].indexOf(uid) > -1
+}
+
+function isChair(uid) {
+   return ldapservices['pmc-chairs'].roster.indexOf(uid) > -1
+}
+
+function urls(uid) {
+   return people[uid].urls || []
+}
+
+// Is a PMC according to committee-info
+function isPMC(name) {
+   return pmcs.indexOf(name) >= 0;
+}
+
+//Is a PMC according to ldap_projects
+function isProjectPMC(name) {
+   return name in ldapprojects && ldapprojects[name].pmc
+}
+
+function linkifyUid(uid) {
+   if (isNologin(uid)) {
+      return uid
+   }
+   return uid
+}
+
+function hiliteMember(uid) {
+   if (isMember(uid)) {
+      return linkifyUid(uid)
+   } else {
+      return linkifyUid(uid)
+   }
+}
+
+function getChair(uid) {
+   var chair = committees[uid].chair
+   if (chair) {
+      for (var x in chair) {
+         return chair[x].name
+      }
+   }
+   return null
+}
+
+function showProject(obj, prj) {
+   var details = document.getElementById('details_project_' + prj)
+   if (!details) {
+      details = document.createElement('p')
+      details.setAttribute("id", 'details_project_' + prj)
+      var desc = committees[prj].description
+      if (!desc) {
+         desc = 'TBA (please ensure that <a href="http://www.apache.org/index.html#projects-list">the projects list</a> is updated)'
+      }
+      var chair = getChair(prj)
+      if (chair) {
+         details.innerHTML += "<b>Chair:</b> " + chair + "<br/><br/>"
+      }
+      var url = committees[prj].site
+      var cl
+      var clExists = false // Does the unix group exist?
+      try {
+         cl = ldapgroups[prj].roster.slice()
+         clExists = true
+      } catch (err) { // Allow for missing Unix group
+         cl = []
+      }
+      var pl = []
+      var pmc = committees[prj]
+
+      var pmcnoctte = [] // on pmc but not in LDAP committee
+      var cttenopmc = [] // In LDAP ctte but not on PMC
+      var ldappmc = []
+      var ctteeExists = false
+      if (isProjectPMC(prj)) { // may not exist, e.g. for 'member' PMC and if group has yet to be created
+         ldappmc = ldapprojects[prj].owners
+         ctteeExists = true
+      }
+      var pmcnounix = [] // on PMC but not in LDAP unix group
+      var cttenounix = [] // In LDAP ctte but not in LDAP unix
+      if (pmc) {
+         for (var c in pmc.roster) {
+            pl.push(c)
+         }
+         for (var i in ldappmc) {
+            if (!(ldappmc[i] in pmc.roster)) {
+               cttenopmc.push(ldappmc[i])
+            }
+         }
+      }
+      cl.sort()
+      pl.sort()
+
+      // Must use cl before it is re-used to hold the entries
+      if (clExists && prj != 'member') { // does not exist for 'member' PMC
+         for (var i in ldappmc) {
+            var id = ldappmc[i]
+            if (cl.indexOf(id) < 0) { // in LDAP cttee but not in LDAP unix
+               cttenounix.push(id)
+            }
+         }
+      }
+
+      for (var i in pl) {
+         var id = pl[i]
+         pl[i] = "<tr><td><b>" + getCommitterName(pl[i]) + "</b></td><td>(" + hiliteMember(pl[i]) + ")</td></tr>"
+         if (clExists && cl.indexOf(id) < 0) { // On PMC but not in LDAP unix group
+            pmcnounix.push(id)
+         }
+         if (prj != 'member' && ldappmc && ldappmc.indexOf(id) < 0) { // in PMC but not in LDAP committee (does not apply to member)
+            pmcnoctte.push(id)
+         }
+      }
+
+      for (var i in cl) {
+         cl[i] = "<tr><td><b>" + getCommitterName(cl[i]) + "</b></td><td>(" + hiliteMember(cl[i]) + ")</td></tr>"
+      }
+
+      if (pl.length > 0) {
+         if (prj == 'member') {
+            details.innerHTML += "<b>ASF members</b><br><br><table>" + pl.join("\n") + "</table><br/>"
+         } else {
+            details.innerHTML += "<h4>PMC members (also in the committer group): " + pl.length + "</h4><table>" + pl.join("\n") + "</table><br/>"
+         }
+      }
+
+      if (cl && cl.length > 0) {
+         details.innerHTML += "<h4>Committers: " + cl.length + "</h4><table>" + cl.join("\n") + "</table>"
+         if (podlings[prj]) {
+            details.innerHTML += "<span class='error'>WARNING: <a href='?podling=" + prj + "'>" + prj + " podling group</a> also exists - this can cause authentication issues</span><br/><br/>"
+         }
+      } else {
+         if (!clExists) {
+            details.innerHTML += "<span class='error'>LDAP unix group not present!</span><br/><br/>"
+         }
+      }
+
+      if (pmcnoctte.length) {
+         if (ctteeExists) {
+            details.innerHTML += "<span class='error'>PMC members not in LDAP committee group:</span> " + userList(pmcnoctte) + "<br/><br/>"
+         } else {
+            details.innerHTML += "<span class='error'>LDAP committee group not present!</span><br/><br/>"
+         }
+      }
+      if (pmcnounix.length) {
+         if (prj == 'member') {
+            details.innerHTML += "<span class='error'>ASF members not in committers(unix) group:</span> " + userList(pmcnounix) + "<br/><br/>"
+         } else {
+            details.innerHTML += "<span class='error'>PMC members not in committers(unix) group:</span> " + userList(pmcnounix) + "<br/><br/>"
+         }
+      }
+      if (cttenounix.length) {
+         details.innerHTML += "<span class='error'>LDAP committee group members not in committers(unix) group:</span> " + userList(cttenounix) + "<br/><br/>"
+      }
+      if (cttenopmc.length) {
+         details.innerHTML += "<span class='error'>LDAP committee group members not on PMC:</span> " + userList(cttenopmc) + "<br/><br/>"
+      }
+
+
+      obj.appendChild(details)
+   } else {
+      obj.removeChild(details)
+   }
+}
+
+// Generic group display function
+// attr is either missing or 'owners' or 'members'
+function showJsonRoster(obj, type, json, name, attr, checkUnix) {
+   var id = 'details_' + type + '_' + name
+   var details = document.getElementById(id)
+   if (!details) {
+      details = document.createElement('p')
+      details.setAttribute("id", id)
+      var podtype = json[name]['podling']
+      if (podtype) {
+         details.innerHTML += "<b>podling:</b> " + podtype + "<br><br>"
+      }
+      var cl;
+      if (attr == 'owners') {
+         cl = json[name].owners.slice()
+      } else if (attr == 'members') {
+         cl = json[name].members.slice()
+      } else {
+         cl = json[name].roster.slice()
+      }
+      cl.sort()
+      for (var i in cl) {
+         var uid = cl[i]
+         cl[i] = "<tr><td onmouseover='hoverCommitter(this, \"" + uid + "\");' onmouseout='hoverCommitter(this, null);'><kbd>" + hiliteMember(uid) + "</kbd></td><td>" + getCommitterName(uid) + "</td>"
+         if (checkUnix) { // check against Unix group
+            if (ldapgroups[name]) { // make sure group exists!
+               if (ldapgroups[name].roster.indexOf(uid) > -1) {
+                  cl[i] += "<td>&nbsp;</td>"
+               } else {
+                  cl[i] += "<td> N.B. not found in corresponding Unix group</td>"
+               }
+            }
+         }
+         cl[i] += "</tr>"
+      }
+
+      if (cl && cl.length > 0) {
+         details.innerHTML += "<b>Roster:</b><br><br><table>" + cl.join("\n") + "</table><br/>"
+      }
+      obj.appendChild(details)
+   } else {
+      obj.removeChild(details)
+   }
+}
+
+// Show a single Service group
+function showServiceRoster(obj, name) {
+   showJsonRoster(obj, 'service', ldapservices, name)
+}
+
+// Show a single Auth group
+function showAuthRoster(obj, name) {
+   showJsonRoster(obj, 'auth', ldapauth, name)
+}
+
+function showPodlingRoster(obj, name) {
+   showJsonRoster(obj, 'podling', podlings, name)
+}
+
+// Show an LDAP Unix group
+
+function showGroup(obj, name) {
+   showJsonRoster(obj, 'group', ldapgroups, name)
+}
+
+// Show an LDAP Commiteee group
+
+function showCommittee(obj, name) {
+   showJsonRoster(obj, 'ctte', ldapprojects, name, 'owners', true)
+}
+
+function searchProjects(keyword, open) {
+   var obj = document.getElementById('phonebook')
+   if (keyword != '') {
+      obj.innerHTML = ""
+   } else {
+      obj.innerHTML = ''
+   }
+   for (var i in pmcs) {
+      var pmc = pmcs[i]
+      if (pmc.search(keyword.toLowerCase()) != -1) {
+         var ppmc = committees[pmc].display_name
+         obj.innerHTML += "<div id='project_" + pmc + "' class='group'><h3>Apache " + ppmc + "</h3></div>"
+         if (open) {
+            showProject(document.getElementById('project_' + pmc), pmc)
+         }
+      }
+   }
+}
+
+function searchService(keyword, open) {
+   var obj = document.getElementById('phonebook')
+   if (keyword != '') {
+      obj.innerHTML = "<h3>Search results:</h3><hr/>"
+   } else {
+      obj.innerHTML = ''
+   }
+   for (var srv in ldapservices) {
+      if (srv.search(keyword.toLowerCase()) != -1) {
+         obj.innerHTML += "<div id='service_" + srv + "' class='group'><h3 onclick=\"showServiceRoster(this.parentNode, '" + srv + "');\">" + srv + "</h3></div>"
+         if (open) {
+            showServiceRoster(document.getElementById('service_' + srv), srv)
+         }
+      }
+   }
+}
+
+function searchAuth(keyword, open) {
+   var obj = document.getElementById('phonebook')
+   if (keyword != '') {
+      obj.innerHTML = "<h3>Search results:</h3><hr/>"
+   } else {
+      obj.innerHTML = ''
+   }
+   for (var auth in ldapauth) {
+      if (auth.search(keyword.toLowerCase()) != -1) {
+         obj.innerHTML += "<div id='auth_" + auth + "' class='group'><h3 onclick=\"showAuthRoster(this.parentNode, '" + auth + "');\">" + auth + "</h3></div>"
+         if (open) {
+            showauthRoster(document.getElementById('auth_' + auth), auth)
+         }
+      }
+   }
+}
+
+// Show a single PMC
+
+function showPMC(pmc) {
+   var obj = document.getElementById('phonebook')
+   if (pmc in committees) {
+      var ppmc = committees[pmc].display_name
+      obj.innerHTML = "<div id='project_" + pmc + "' class='group'><h3 onclick=\"showProject(this.parentNode, '" + pmc + "');\">Apache " + ppmc + "</h3></div>"
+      showProject(document.getElementById('project_' + pmc), pmc)
+   } else {
+      obj.innerHTML = "<h3>Could not find PMC: '" + pmc + "'</h3>"
+   }
+}
+
+// Show a single Unix Group
+
+function showUNIX(unix) {
+   var obj = document.getElementById('phonebook')
+   var id = 'group_' + unix
+   if (unix in ldapgroups) {
+      obj.innerHTML = "<div id='" + id + "' class='group'><h3 onclick=\"showGroup(this.parentNode, '" + unix + "');\">" + unix + " (LDAP unix group)</h3></div>"
+      showGroup(document.getElementById(id), unix)
+   } else {
+      obj.innerHTML = "<h3>Could not find unix group: '" + unix + "'</h3>"
+   }
+}
+
+// Show a single Committee group
+
+function showCTTE(ctte) {
+   var obj = document.getElementById('phonebook')
+   var id = 'ctte_' + ctte
+   if (ctte in ldapprojects && ldapprojects[ctte].pmc) {
+      obj.innerHTML = "<div id='" + id + "' class='group'><h3 onclick=\"showCommittee(this.parentNode, '" + ctte + "');\">" + ctte + " (LDAP committee group)</h3></div>"
+      showCommittee(document.getElementById(id), ctte)
+   } else {
+      obj.innerHTML = "<h3>Could not find committee group: '" + ctte + "'</h3>"
+   }
+}
+
+function showSVC(name) {
+   var obj = document.getElementById('phonebook')
+   var id = 'service_' + name
+   if (name in ldapservices) {
+      obj.innerHTML = "<div id='" + id + "' class='group'><h3 onclick=\"showServiceRoster(this.parentNode, '" + name + "');\">" + name + " (LDAP service group)</h3></div>"
+      showServiceRoster(document.getElementById(id), name)
+   } else {
+      obj.innerHTML = "<h3>Could not find the service group: '" + name + "'</h3>"
+   }
+}
+
+function showAUTH(name) {
+   var obj = document.getElementById('phonebook')
+   var id = 'auth_' + name
+   if (name in ldapauth) {
+      obj.innerHTML = "<div id='" + id + "' class='group'><h3 onclick=\"showAuthRoster(this.parentNode, '" + name + "');\">" + name + " (LDAP auth group)</h3></div>"
+      showAuthRoster(document.getElementById(id), name)
+   } else {
+      obj.innerHTML = "<h3>Could not find the auth group: '" + name + "'</h3>"
+   }
+}
+
+function showPOD(name) {
+   var obj = document.getElementById('phonebook')
+   var id = 'podling_' + name
+   if (name in podlings) {
+      obj.innerHTML = "<div id='" + id + "' class='group'><h3 onclick=\"showPodlingRoster(this.parentNode, '" + name + "');\">" + name + " (podling)</h3></div>"
+      showPodlingRoster(document.getElementById(id), name)
+   } else {
+      obj.innerHTML = "<h3>Could not find the podling: '" + name + "'</h3>"
+   }
+}
+
+function searchPodlings(keyword, open) {
+   var obj = document.getElementById('phonebook')
+   obj.innerHTML = "<h3>Search results:</h3><hr/>"
+   for (var name in podlings) {
+      if (name.search(keyword.toLowerCase()) != -1) {
+         var id = 'podling_' + name
+         obj.innerHTML += "<div id='" + id + "' class='group'><h3 onclick=\"showPodlingRoster(this.parentNode, '" + name + "');\">" + name + " (podling)</h3></div>"
+      }
+   }
+}
+
+function showDBG(name) {
+   var obj = document.getElementById('phonebook')
+   if (name == 'info') {
+      obj.innerHTML = "<h3>info</h3>"
+      obj.innerHTML += "<pre>" + JSON.stringify(info, null, 1) + "</pre>"
+
+   } else {
+      obj.innerHTML = "<h3>Unknown debug name: '" + name + "'</h3>"
+   }
+}
+
+// Show a single User
+
+function showUid(uid) {
+   var obj = document.getElementById('phonebook')
+   if (uid in people) {
+      var name = getCommitterName(uid)
+      obj.innerHTML = "<div class='group' id='committer_" + uid + "'><h4 onclick=\"showCommitter(this.parentNode, '" + uid + "');\">" + name + " (<kbd>" + uid + "</kbd>)</h4></div>"
+      showCommitter(document.getElementById('committer_' + uid), uid)
+   } else {
+      obj.innerHTML = "<h3>Could not find user id: '" + uid + "'</h3>"
+   }
+}
+
+function showError(error) {
+   var obj = document.getElementById('phonebook')
+   if (typeof(error) === 'string') {
+      obj.innerHTML = "<h3>Error detected</h3>"
+      obj.innerHTML += error
+   } else { // assume it's an error object
+      obj.innerHTML = "<h3>Javascript Error detected</h3>"
+      obj.innerHTML += "<hr/>"
+      obj.innerHTML += "<pre>" + error.message + "</pre>"
+      obj.innerHTML += "<pre>" + error.stack + "</pre>"
+      obj.innerHTML += "<hr/>"
+   }
+}
+
+function searchCommitters(keyword, open) {
+   if (keyword.length < 2) {
+      return
+   }
+   var n = 0
+   var obj = document.getElementById('phonebook')
+   obj.innerHTML = ""
+   for (var uid in people) {
+      if (!people[uid].noLogin) { // don't display disabled logins
+         var name = getCommitterName(uid)
+         if (uid.search(keyword.toLowerCase()) != -1 || name.toLowerCase().search(keyword.toLowerCase()) != -1) {
+            n++
+            if (n > 50) {
+               return;
+            }
+            obj.innerHTML += "<div class='group' id='committer_" + uid + "'><h4 onclick=\"showCommitter(this.parentNode, '" + uid + "');\">" + name +
+               " (<kbd>" + uid + "</kbd>) <a title='Link to committer details' href='phonebook.html?uid=" + uid + "'>&#149</a></h4></div>"
+            if (open) {
+               showCommitter(document.getElementById('committer_' + uid), uid)
+            }
+         }
+      }
+   }
+}
+
+function saveInfo(json, name) {
+   info[name] = {}
+   try {
+      info[name]['lastTimestamp'] = json.lastTimestamp
+   } catch (err) {} // ignored
+   try {
+      info[name]['lastCreateTimestamp'] = json.lastCreateTimestamp
+   } catch (err) {} // ignored
+   try {
+      info[name]['last_updated'] = json.last_updated
+   } catch (err) {} // ignored
+}
+
+function preRender() {
+   getAsyncJSONArray([
+         ['https://whimsy.apache.org/public/public_ldap_projects.json', "projects", function(json) {
+            ldapprojects = json.projects;
+            saveInfo(json, 'projects');
+         }],
+         ['https://whimsy.apache.org/public/member-info.json', "members", function(json) {
+            members = json;
+            saveInfo(json, 'members');
+         }],
+         ['https://whimsy.apache.org/public/public_ldap_people.json', "people", function(json) {
+            people = json.people;
+            saveInfo(json, 'people');
+         }],
+         ['https://whimsy.apache.org/public/committee-info.json', "committees", function(json) {
+            committees = json.committees;
+            saveInfo(json, 'committees');
+         }],
+         ['https://whimsy.apache.org/public/icla-info.json', "iclainfo", function(json) {
+            iclainfo = json.committers;
+            saveInfo(json, 'iclainfo');
+         }],
+         ['https://whimsy.apache.org/public/public_ldap_groups.json', "ldapgroups", function(json) {
+            ldapgroups = json.groups;
+            saveInfo(json, 'ldapgroups');
+         }],
+         ['https://whimsy.apache.org/public/public_ldap_authgroups.json', "ldapauth", function(json) {
+            ldapauth = json.auth;
+            saveInfo(json, 'ldapauth');
+         }],
+         ['https://whimsy.apache.org/public/public_ldap_services.json', "services", function(json) {
+            ldapservices = json.services;
+            saveInfo(json, 'services');
+         }],
+      ],
+      allDone);
+}
+
+// Called when all the async GETs have been completed
+
+function allDone() {
+   try {
+      pmcs = []
+      for (var k in committees) { // actual committees, not LDAP committee groups
+         if (committees[k].pmc) { // skip non-PMCs
+            pmcs.push(k)
+         }
+      }
+      for (var g in ldapprojects) {
+         // get podlings from projects
+         if (ldapprojects[g]['podling'] == 'current') {
+            podlings[g] = {}
+            podlings[g].roster = ldapprojects[g].members
+         }
+      }
+      pmcs.push('member')
+      pmcs.sort()
+      var mMap = {}
+      for (var m in members.members) {
+         mMap[members.members[m]] = {}
+      }
+      // copy across the members info
+      committees['member'] = {
+         'roster': mMap,
+         'display_name': 'Foundation Members',
+         'description': "Current ASF members (Committers == those with member karma)",
+         'site': 'http://www.apache.org/foundation/'
+      }
+
+      // Match ?type=name
+      searchProjects('cloudstack', true)
+
+   } catch (error) {
+      showError(error)
+   }
+}
\ No newline at end of file
diff --git a/source/who.html.markdown b/source/who.html.markdown
index bc10c5e..e44b827 100644
--- a/source/who.html.markdown
+++ b/source/who.html.markdown
@@ -15,208 +15,20 @@
 </div>
 
 </div>
+   <div id="phonebook">
 
-This page includes the Apache CloudStack Project Management Committee (PMC) members and committers.
-
-## PMC
-
-Active Project Management Committee contains (in alphabetical order of their usernames):
-
-{:.table-bordered}
-
-
-| Username | Name |
-|----------|------|
-|akarasulu|Alex Karasulu|
-|alena1108|Alena Prokharchyk|
-|animesh|Animesh|
-|andrijapanic|Andrija Panic|
-|boris|Boris Schrijver|
-|bstoyanov|Boris Stoyanov|
-|chipchilders|Chip Childers|
-|chiradeep|Chiradeep Vittal|
-|dahn|Daan|
-|ekho|Wilder Rodrigues|
-|erikw|Erik Weber|
-|giles|Giles Sirett|
-|gochiba|Go Chiba|
-|gabriel|Gabriel Beims Bräscher|
-|hogstrom|Matt Richard Hogstrom|
-|hugo|Hugo Trippaers|
-|ilya|Ilya Musayev|
-|jburwell|John Burwell|
-|jlk|John Kinsella|
-|jzb|Joe Brockmeier|
-|karenv|Karen Vuong|
-|ke4qqq|David Nalley|
-|kluge|Kevin Kluge|
-|milamber|Bruno Demion|
-|mlsorensen|Marcus Sorensen|
-|mnour|Mohammad Nour El-Din|
-|mrhinkle|Mark R. Hinkle|
-|mtutkowski|Mike Tutkowski|
-|nslater|Naomi Slater|
-|nux|Nux|
-|nathanejohnson|Nathan Johnson|
-|paul_a|Paul Angus|
-|pdion891|Pierre-Luc Dion|
-|rafael|Rafael Weingärtner|
-|rajani|Rajani Karuturi|
-|remi|Remi Bergsma|
-|resmo|Rene Moser|
-|rohit|Rohit Yadav|
-|sebgoa|Sebastien Goasguen|
-|sweller|Simon Weller|
-|swill|Will Stevens|
-|syed|Syed Ahmed|
-|svogel|Sven Vogel|
-|tsp|Prasanna|
-|weizhou|Wei Zhou|
-|widodh|Wido den Hollander|
-|willchan|William Chan|
-  
-  
-
-## Emeritus PMC Members
-
-PMC members who are no longer active include:
-
-+ Alex Huang (ahuang)
-+ Disheng Su (edison)
-+ Ian Duffy (duffy)
-+ Olivier Lamy (olamy)
-  
-  
-  
-## Committers
-
-Active list of committers (in alphabetical order of their usernames):
-
-{:.table-bordered}
-
-
-| Username | Name |
-|----------|------|
-|ahmad|Ahmad Emneina|
-|akarasulu|Alex Karasulu|
-|alena1108|Alena Prokharchyk|
-|amoghvk|Amogh Vasekar|
-|andrijapanic|Andrija Panic|
-|animesh|Animesh|
-|anthonyxu|Anthony Xu|
-|aprateek|Abhinandan Prateek|
-|bfederle|Brian Federle|
-|boris|Boris Schrijver|
-|brett|Brett Porter|
-|bstoyanov|Boris Stoyanov|
-|chipchilders|Chip Childers|
-|chiradeep|Chiradeep Vittal|
-|claytonweise|Clayton Weise|
-|csuich2|Chris Suich|
-|dahn|Daan|
-|darren|Darren Shepherd|
-|dcahill|Dave Cahill|
-|demetriust|Demetrius Tsitrelis|
-|devdeep|Devdeep Singh|
-|dkonrad|Dennis Konrad|
-|dsonstebo|Dag Sonstebo|
-|ekho|Wilder Rodrigues|
-|erikw|Erik Weber|
-|fmaximus|Frank Maximus|
-|frankzhang|Xin Zhang|
-|gabriel|Gabriel Beims Bräscher|
-|gaurav|Gaurav Nandkumar Aradhye|
-|gavinlee|Gavin Lee|
-|giles|Giles Sirett|
-|girish|Girish Prabhakar Shilamkar|
-|gochiba|Go Chiba|
-|haeena|Toshiaki Hatano|
-|harikrishna|Harikrishna Patnala|
-|higster|Geoff Higginbottom|
-|hogstrom|Matt Richard Hogstrom|
-|hugo|Hugo Trippaers|
-|ilya|Ilya Musayev|
-|isaacchiang|Isaac Chiang|
-|jayapal|Jayapal|
-|jbausewein|Jason Bausewein|
-|jburwell|John Burwell|
-|jessicawang|Jessica Wang|
-|jim|Jim Jagielski|
-|jlk|John Kinsella|
-|jtomechak|Jessica Tomechak|
-|jzb|Joe Brockmeier|
-|karenv|Karen Vuong|
-|kawai|Hiroaki Kawai|
-|kdamage|Kelcey Damage|
-|ke4qqq|David Nalley|
-|kelveny|Kelven Yang|
-|kirk|Kirk Kosinski|
-|kishan|Kishan|
-|kluge|Kevin Kluge|
-|kocka|Laszlo Hornyak|
-|koushik|Koushik Das|
-|likithas|Likitha Shetty|
-|marcaurele|Marc-Aurèle Brothier|
-|mchen|Min Chen|
-|mice|Mice Xia|
-|milamber|Bruno Demion|
-|mlsorensen|Marcus Sorensen|
-|mnour|Mohammad Nour El-Din|
-|mrhinkle|Mark R. Hinkle|
-|msinhore|Marco Sinhoreli|
-|mtutkowski|Mike Tutkowski|
-|muralireddy|Murali Mohan Reddy|
-|nathanejohnson|Nathan Johnson|
-|nitin|Nitin|
-|noa|Noa Resare|
-|nslater|Naomi Slater|
-|nux|Nux|
-|nvazquez|Nicolás Vázquez|
-|olgasmola|Olga Smola|
-|paul_a|Paul Angus|
-|pdion891|Pierre-Luc Dion|
-|pnguyen|Phong Nguyen|
-|prachidamle|Prachi Damle|
-|pranavs|Pranav Saxena|
-|pyr|Pierre-Yves Ritschard|
-|radhika|Radhika Nair|
-|rafael|Rafael Weingärtner|
-|rajani|Rajani Karuturi|
-|rajeshbattala|Rajesh Battala|
-|remi|Remi Bergsma|
-|resmo|Rene Moser|
-|rohit|Rohit Yadav|
-|sailajamada|Sailaja Mada|
-|saksham|Saksham Srivastava|
-|sangeethah|Sangeetha Hariharan|
-|sanjaytripathi|Sanjay Tripathi|
-|sanjeev|Sanjeev Neelarapu|
-|santhoshedukulla|Santhosh|
-|sateesh|Sateesh Chodapuneedi|
-|schhen|Sonny Heng Chhen|
-|sebgoa|Sebastien Goasguen|
-|serg38|Sergey Levitskiy|
-|slriv|Sam Robertson|
-|snuf|Funs Kessen|
-|sowmya|Sowmya Krishnan|
-|sudhap|Sudhap|
-|svogel|Sven Vogel|
-|swamy|Venkata Swamy|
-|sweller|Simon Weller|
-|swill|Will Stevens|
-|syed|Syed Ahmed|
-|talluri|Srikanteswararao Talluri|
-|tsp|Prasanna|
-|tuna|Anh Tu Nguyen|
-|vijayendrabvs|Vijayendra Bhamidipati|
-|weizhou|Wei Zhou|
-|widodh|Wido den Hollander|
-|willchan|William Chan|
-|yasker|Sheng Yang|
-|ynojima|Yoshikazu Nojima|
-  
-  
-  
-## Emeritus Committers
-
-Committers who are no longer active include:
+   <p>
+      Loading data, please wait...<br/>
+      <img src="images/loader.gif" alt=""/>
+   </p>
+   <p id="progress"></p>
+   <noscript>
+      <h2>Notice!</h2>
+      <p>
+         This site relies heavily on JavaScript.
+         Please enable it or get a browser that supports it.
+      </p>
+   </noscript>
+    
+   </div>
+   <script type='text/javascript' src="javascripts/phonebook.js" onload="preRender()"></script>
