private static ArrayList UnsortedMerge(PropertyDescriptor[] baseEntries, ArrayList sortedMergedEntries)
 {
     ArrayList list = new ArrayList();
     PropertyDescriptor[] destinationArray = new PropertyDescriptor[((PropertyDescriptor[]) sortedMergedEntries[0]).Length + 1];
     for (int i = 0; i < baseEntries.Length; i++)
     {
         PropertyDescriptor descriptor = baseEntries[i];
         PropertyDescriptor[] sourceArray = null;
         string strA = descriptor.Name + " " + descriptor.PropertyType.FullName;
         int count = sortedMergedEntries.Count;
         int num3 = count / 2;
         int num4 = 0;
         while (count > 0)
         {
             PropertyDescriptor[] descriptorArray3 = (PropertyDescriptor[]) sortedMergedEntries[num4 + num3];
             PropertyDescriptor descriptor2 = descriptorArray3[0];
             string strB = descriptor2.Name + " " + descriptor2.PropertyType.FullName;
             int num5 = string.Compare(strA, strB, false, CultureInfo.InvariantCulture);
             if (num5 == 0)
             {
                 sourceArray = descriptorArray3;
                 break;
             }
             if (num5 < 0)
             {
                 count = num3;
             }
             else
             {
                 int num6 = num3 + 1;
                 num4 += num6;
                 count -= num6;
             }
             num3 = count / 2;
         }
         if (sourceArray != null)
         {
             destinationArray[0] = descriptor;
             Array.Copy(sourceArray, 0, destinationArray, 1, sourceArray.Length);
             list.Add(destinationArray.Clone());
         }
     }
     return list;
 }
         /// <include file='doc\MultiSelectRootGridEntry.uex' path='docs/doc[@for="MultiSelectRootGridEntry.UnsortedMerge"]/*' />
         /// <devdoc>
         /// merges an unsorted array of grid entries with a sorted array of grid entries that
         /// have already been merged.  The resulting array is the intersection of entries between the two,
         /// but in the order of baseEntries.
         /// </devdoc>
         private static ArrayList UnsortedMerge(PropertyDescriptor[] baseEntries, ArrayList sortedMergedEntries) {
             
             ArrayList mergedEntries = new ArrayList();
             PropertyDescriptor[] mergeArray = new PropertyDescriptor[((PropertyDescriptor[])sortedMergedEntries[0]).Length + 1];
             
             for (int i = 0; i < baseEntries.Length; i++) {
 
                 PropertyDescriptor basePd = baseEntries[i];
 
                 // first, do a binary search for a matching item
                 PropertyDescriptor[] mergedEntryList = null;
                 string entryName = basePd.Name + " " + basePd.PropertyType.FullName;
 
                 int len = sortedMergedEntries.Count;
                 // perform a binary search
                 int offset = len / 2;
                 int start = 0;
                 
                 while (len > 0) {
                     PropertyDescriptor[] pdList = (PropertyDescriptor[])sortedMergedEntries[start + offset];
                     PropertyDescriptor pd = pdList[0];
                     string sortString = pd.Name + " " + pd.PropertyType.FullName;
                     int result = String.Compare(entryName, sortString, false, CultureInfo.InvariantCulture);
                     if (result == 0) {
                         mergedEntryList = pdList;
                         break;
                     }
                     else if (result < 0) {
                         len = offset;
                     }
                     else {
                         int delta = offset + 1;
                         start += delta;
                         len -= delta;
                     }
                     offset = len / 2;
                 }
                 
                 if (mergedEntryList != null) {
                     mergeArray[0] = basePd;
                     Array.Copy(mergedEntryList, 0, mergeArray, 1,  mergedEntryList.Length);
                     mergedEntries.Add(mergeArray.Clone());
                 }
             }
             return mergedEntries;
         }
 private static ArrayList GetCommonProperties(object[] objs, bool presort, PropertyTab tab, GridEntry parentEntry)
 {
     PropertyDescriptorCollection[] descriptorsArray = new PropertyDescriptorCollection[objs.Length];
     Attribute[] array = new Attribute[parentEntry.BrowsableAttributes.Count];
     parentEntry.BrowsableAttributes.CopyTo(array, 0);
     for (int i = 0; i < objs.Length; i++)
     {
         PropertyDescriptorCollection descriptors = tab.GetProperties(parentEntry, objs[i], array);
         if (presort)
         {
             descriptors = descriptors.Sort(MultiSelectRootGridEntry.PropertyComparer);
         }
         descriptorsArray[i] = descriptors;
     }
     ArrayList list = new ArrayList();
     PropertyDescriptor[] descriptorArray = new PropertyDescriptor[objs.Length];
     int[] numArray = new int[descriptorsArray.Length];
     for (int j = 0; j < descriptorsArray[0].Count; j++)
     {
         PropertyDescriptor descriptor = descriptorsArray[0][j];
         bool flag = descriptor.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute();
         for (int k = 1; flag && (k < descriptorsArray.Length); k++)
         {
             if (numArray[k] >= descriptorsArray[k].Count)
             {
                 flag = false;
                 break;
             }
             PropertyDescriptor descriptor2 = descriptorsArray[k][numArray[k]];
             if (descriptor.Equals(descriptor2))
             {
                 numArray[k]++;
                 if (!descriptor2.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute())
                 {
                     flag = false;
                     break;
                 }
                 descriptorArray[k] = descriptor2;
                 continue;
             }
             int num4 = numArray[k];
             descriptor2 = descriptorsArray[k][num4];
             flag = false;
             while (MultiSelectRootGridEntry.PropertyComparer.Compare(descriptor2, descriptor) <= 0)
             {
                 if (descriptor.Equals(descriptor2))
                 {
                     if (!descriptor2.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute())
                     {
                         flag = false;
                         num4++;
                     }
                     else
                     {
                         flag = true;
                         descriptorArray[k] = descriptor2;
                         numArray[k] = num4 + 1;
                     }
                     break;
                 }
                 num4++;
                 if (num4 >= descriptorsArray[k].Count)
                 {
                     break;
                 }
                 descriptor2 = descriptorsArray[k][num4];
             }
             if (!flag)
             {
                 numArray[k] = num4;
                 break;
             }
         }
         if (flag)
         {
             descriptorArray[0] = descriptor;
             list.Add(descriptorArray.Clone());
         }
     }
     return list;
 }
         // this returns an array list of the propertydescriptor arrays, one for each
         // component
         //
         private static ArrayList GetCommonProperties(object[] objs, bool presort, PropertyTab tab, GridEntry parentEntry) {
             PropertyDescriptorCollection[] propCollections = new PropertyDescriptorCollection[objs.Length];
 
             Attribute[] attrs = new Attribute[parentEntry.BrowsableAttributes.Count];
             parentEntry.BrowsableAttributes.CopyTo(attrs, 0);
             
             for (int i = 0; i < objs.Length; i++) {
                 PropertyDescriptorCollection pdc = tab.GetProperties(parentEntry, objs[i], attrs);
                 if (presort) {
                     pdc = pdc.Sort(PropertyComparer);
                 }
                 propCollections[i] = pdc;
             }
             
             ArrayList mergedList = new ArrayList();
             PropertyDescriptor[] matchArray = new PropertyDescriptor[objs.Length];
 
            // 
            // Merge the property descriptors
            //
            int[] posArray = new int[propCollections.Length];
            for (int i = 0; i < propCollections[0].Count; i++) {
                PropertyDescriptor pivotDesc = propCollections[0][i];
                
                bool match = pivotDesc.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute();
                     
                for (int j = 1; match && j < propCollections.Length; j++) {
     
                    if (posArray[j] >= propCollections[j].Count) {
                        match = false;
                        break;
                    }
     
                    // check to see if we're on a match
                    //
                    PropertyDescriptor jProp = propCollections[j][posArray[j]];
                    if (pivotDesc.Equals(jProp)) {
                        posArray[j] += 1;
                        
                        if (!jProp.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute()) {
                             match = false;
                             break;
                        }
                        matchArray[j] = jProp;
                        continue;
                    }
                    
                    int jPos = posArray[j];
                    jProp = propCollections[j][jPos];
 
                    match = false;
     
                    // if we aren't on a match, check all the items until we're past
                    // where the matching item would be
                    while (PropertyComparer.Compare(jProp, pivotDesc) <= 0) {
     
                        // got a match!
                        if (pivotDesc.Equals(jProp)) {
 
                            if (!jProp.Attributes[typeof(MergablePropertyAttribute)].IsDefaultAttribute()) {
                               match = false;
                               jPos++;
                            }
                            else {
                               match = true;
                               matchArray[j] = jProp;
                               posArray[j] = jPos + 1;
                            }
                            break;
                        }
     
                        // try again
                        jPos++;
                        if (jPos < propCollections[j].Count) {
                            jProp = propCollections[j][jPos];
                        }
                        else {
                            break;
                        }
                    }
     
                    // if we got here, there is no match, quit for this guy
                    if (!match) {
                         posArray[j] = jPos;
                         break;
                    }
                }
     
                // do we have a match?
                if (match) {
                    matchArray[0] = pivotDesc;
                    mergedList.Add(matchArray.Clone());
                }
            }
 
            return mergedList;
         }