/// <summary>
      /// Convert a given object into a PropertyListDataTable.
      /// </summary>
      /// <param name="obj">Object to convert</param>
      /// <returns>DataTable filled out for each property of the given item</returns>
      private static GridDataTables.PropertyListDataTable GetPropertyList(object obj)
      {
          if (obj == null)
          {
              throw new ApplicationException("Cannot load null object in PropertyList");
          }

          GridDataTables.PropertyListDataTable propList = new GridDataTables.PropertyListDataTable();

          ServiceObject so = obj as ServiceObject;

          if (so != null)
          {
              foreach (PropertyDefinitionBase baseProp in so.GetLoadedPropertyDefinitions())
              {
                  if (baseProp != ItemSchema.ExtendedProperties)
                  {
                      GridDataTables.PropertyListRow row = propList.NewPropertyListRow();

                      PropertyInterpretation propInter = new PropertyInterpretation(so, baseProp);

                      if (propInter.Name != null)
                      {
                          row.Name = propInter.Name;
                      }
                      else
                      {
                          row.Name = "";
                      }

                      row.Value          = propInter.Value;
                      row.SmartView      = propInter.SmartView;
                      row.Type           = propInter.TypeName;
                      row.KnownNames     = propInter.AlternateNames;
                      row.PropertyObject = baseProp;

                      // SortName is simply the property name with a prefix to ensure
                      // that first class properties and extended properties stay grouped
                      // together.
                      if (baseProp is PropertyDefinition)
                      {
                          row.Icon     = global::EWSEditor.Properties.Resources.FirstProp;
                          row.SortName = string.Concat("a", row.Name);
                      }
                      else if (baseProp is ExtendedPropertyDefinition)
                      {
                          row.Icon     = global::EWSEditor.Properties.Resources.ExtProp;
                          row.SortName = string.Concat("b", row.Name);
                      }

                      // Add the row to the table
                      propList.AddPropertyListRow(row);
                  }
              }
          }
          else
          {
              Type objType = obj.GetType();

              foreach (PropertyInfo propInfo in objType.GetProperties())
              {
                  GridDataTables.PropertyListRow row = propList.NewPropertyListRow();

                  PropertyInterpretation propInter = new PropertyInterpretation(obj, propInfo);

                  row.Name = propInter.Name;

                  row.Value = propInter.Value.Substring(
                      0,
                      propInter.Value.Length > MAX_VALUE_LENGTH ? MAX_VALUE_LENGTH : propInter.Value.Length);
                  row.Type           = propInter.TypeName;
                  row.PropertyObject = propInfo;
                  row.Icon           = global::EWSEditor.Properties.Resources.FirstProp;
                  row.SortName       = string.Concat("a", row.Name);

                  // Add the row to the table
                  propList.AddPropertyListRow(row);
              }
          }

          return(propList);
      }
      public void LoadItem(ExchangeService service, ItemId itemId, PropertySet propertySet)
      {
          Item item = null;
          Dictionary <PropertyDefinitionBase, Exception> errorProperties = new Dictionary <PropertyDefinitionBase, Exception>();

          bool retry = false;

          do
          {
              try
              {
                  service.ClientRequestId = Guid.NewGuid().ToString();    // Set a new GUID
                  item  = Item.Bind(service, itemId, propertySet);
                  retry = false;
                  this.CurrentObject = item;
              }
              catch (ServiceResponseException srex)
              {
                  DebugLog.WriteVerbose("Handled exception when retrieving property", srex);

                  // Remove the bad properties from the PropertySet and try again.
                  foreach (PropertyDefinitionBase propDef in srex.Response.ErrorProperties)
                  {
                      errorProperties.Add(propDef, srex);
                      propertySet.Remove(propDef);
                      retry = true;
                  }
              }
          } while (retry);

          GridDataTables.PropertyListDataTable propList = GetPropertyList(item);

          // Add properties which had errors to the list
          foreach (PropertyDefinitionBase errProp in errorProperties.Keys)
          {
              GridDataTables.PropertyListRow errRow = propList.NewPropertyListRow();

              errRow.Name       = PropertyInterpretation.GetPropertyName(errProp);
              errRow.KnownNames = PropertyInterpretation.GetAlternateNames(errProp);

              errRow.Value = errorProperties[errProp].Message;
              //errRow.SmartView = PropertyInterpretation.GetSmartView(errorProperties[errProp]);
              errRow.Type           = errorProperties[errProp].GetType().ToString();
              errRow.PropertyObject = errProp;

              // SortName is simply the property name with a prefix to ensure
              // that first class properties and extended properties stay grouped
              // together.
              if (errProp is PropertyDefinition)
              {
                  errRow.Icon     = global::EWSEditor.Properties.Resources.FirstProp;
                  errRow.SortName = string.Concat("a", errRow.Name);
              }
              else if (errProp is ExtendedPropertyDefinition)
              {
                  errRow.Icon     = global::EWSEditor.Properties.Resources.ExtProp;
                  errRow.SortName = string.Concat("b", errRow.Name);
              }

              // Add the row to the table
              propList.AddPropertyListRow(errRow);
          }

          // Add properties to the list who were not found on the item
          bool isFound = false;

          foreach (ExtendedPropertyDefinition propDef in propertySet)
          {
              foreach (ExtendedProperty extProp in item.ExtendedProperties)
              {
                  if (propDef == extProp.PropertyDefinition)
                  {
                      isFound = true;
                      break;
                  }
              }

              if (isFound == false)
              {
                  GridDataTables.PropertyListRow missRow = propList.NewPropertyListRow();
                  missRow.Name       = PropertyInterpretation.GetPropertyName(propDef);
                  missRow.KnownNames = PropertyInterpretation.GetAlternateNames(propDef);
                  missRow.Type       = PropertyInterpretation.GetPropertyType(propDef);
                  propList.AddPropertyListRow(missRow);
              }
          }

          this.PropertyListDataGridView.DataSource = GetPropertyList(this.CurrentObject);
          this.PropertyListDataGridView.Sort(this.NameColumn, ListSortDirection.Ascending);

          // If the width of the control minus all other column widths is greater
          // than the default width of the ValueColumn, extend the width of the
          // ValueColumn to display as much data as possible.
          int availableWidth = this.PropertyListDataGridView.Width -
                               (this.NameColumn.Width + this.KnownNamesColumn.Width + this.TypeColumn.Width + this.SmartViewColumn.Width);

          if (availableWidth > this.ValueColumn.Width)
          {
              this.ValueColumn.Width = availableWidth;
          }
      }