in vsintegration/src/FSharp.ProjectSystem.Base/Project/Misc/AutomationExtenderManager.cs [41:177]
public bool GetAllExtenders(object[] selectedObjects, ArrayList allExtenders, ref Hashtable[] extenderList, ref bool nullListFound)
{
// 1 : handle intrinsic extensions
string catID = null;
// do the intersection of intrinsic extensions
for (int i = 0; i < selectedObjects.Length; i++) {
string id = GetCatID(selectedObjects[i]);
// make sure this value is equal to
// all the others.
//
if (catID == null && i == 0) {
catID = id;
}
else if (catID == null || !catID.Equals(id)) {
catID = null;
break;
}
}
// okay, now we've got a common catID, get the names of each extender for each object for it
// here is also where we'll pickup the contextual extenders
//
// ask the extension manager for any contextual IDs
string[] contextualCATIDs = GetContextualCatIDs(extensionMgr);
// if we didn't get an intersection and we didn't get any contextual
// extenders, quit!
//
if ((contextualCATIDs == null || contextualCATIDs.Length == 0) && catID == null) {
return false;
}
extenderList = new Hashtable[selectedObjects.Length];
int firstWithItems = -1;
// right, here we go; build up the mappings from extender names to extensions
//
for (int i = 0; i < selectedObjects.Length;i++) {
// NOTE: this doesn't actually replace extenderList[i], it
// just adds items to it and returns a new one if one didn't
// get passed in. So it is possible to get extenders from both
// the catID and the contextualCATID.
//
if (catID != null) {
extenderList[i] = GetExtenders(extensionMgr, catID, selectedObjects[i], extenderList[i]);
}
if (contextualCATIDs != null) {
for (int c = 0; c < contextualCATIDs.Length; c++) {
extenderList[i] = GetExtenders(extensionMgr, contextualCATIDs[c], selectedObjects[i], extenderList[i]);
}
}
// did we create items for the first time?
//
if (firstWithItems == -1 && extenderList[i] != null && extenderList[i].Count > 0) {
firstWithItems = i;
}
// make sure the first one has items, otherwise
// we can't do an intersection, so quit
//
if (i == 0 && firstWithItems == -1) {
break;
}
}
// the very first item must have extenders or we can skip the merge too
//
if (firstWithItems == 0) {
// now we've gotta merge the extender names to get the common ones...
// so we just walk through the list of the first one and see if all
// the others have the values...
string[] hashKeys = new string[extenderList[0].Keys.Count];
extenderList[0].Keys.CopyTo(hashKeys, 0);
nullListFound = false;
// walk through all the others looking for the common items.
for (int n = 0; !nullListFound && n < hashKeys.Length; n++)
{
bool found = true;
string name = (string)hashKeys[n];
// add it to the total list
allExtenders.Add(extenderList[0][name]);
// walk through all the extender lists looking for
// and item of this name. If one doesn't have it,
// we remove it from all the lists, but continue
// to walk through because we need to
// add all of the extenders to the global list
// for the IFilterProperties walk below
//
for (int i = 1; i < extenderList.Length; i++) {
// if we find a null list, quit
if (extenderList[i] == null || extenderList[i].Count == 0) {
nullListFound = true;
break;
}
object extender = extenderList[i][name];
// do we have this item?
if (found) {
found &= (extender != null);
}
// add it to the total list
allExtenders.Add(extender);
// if we don't find it, remove it from this list
//
if (!found) {
// If this item is in the
// middle of the list, do we need to go back
// through and remove it from the prior lists?
//
extenderList[i].Remove(name);
}
}
// if we don't find it, remove it from the list
//
if (!found) {
object extenderItem = extenderList[0][name];
extenderList[0].Remove(name);
}
}
}
return true;
}