/// <summary>
 /// 
 /// </summary>
 /// <param name="parentPD"></param>
 /// <param name="list"></param>
 private void GetList(PropertyDescriptor parentPD,ref IList list)
 {
     PropertyDescriptorCollection childPDs = parentPD.GetChildProperties();
     // if childPDs count < 0 then return
     if(childPDs.Count<=0 )
     {
         return;
     }
     // if parentPD is immultable type then return
     Type parentType = parentPD.PropertyType;
     if(    parentType.Name.Equals("String")
         || parentType.Name.Equals("Int32")
         || parentType.Name.Equals("Int64")
         || parentType.Name.Equals("Float")
         || parentType.Name.Equals("Double")
         || parentType.Name.Equals("Boolean")
         || parentType.Name.Equals("DateTime"))
     {
         return;
     }
     foreach (PropertyDescriptor childPD in childPDs)
     {
         ComplexPropertyDescriptor subPropertyDescriptor = new ComplexPropertyDescriptor(parentPD, childPD, parentPD.Name + "." + childPD.Name);
         if (PropertyDescriptorNotInList((PropertyDescriptor)subPropertyDescriptor, list))
         {
             list.Add(subPropertyDescriptor);
         }
         PropertyDescriptorCollection subChildPDs = childPD.GetChildProperties();
         if(subChildPDs.Count> 0 )
         {
             GetList(childPD,ref list);
         }
         else
         {
             return;
         }
     }
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentPD"></param>
        /// <param name="list"></param>
        /// <param name="typeList"></param>
        private static void GetList(PropertyDescriptor parentPD, ref IList list,ref IList typeList)
        {
            if (parentPD.PropertyType.Name.Equals("Product"))
            {

            }
            if(list.Count> MAX_VISIBLE_PROPERTIES)
            {
                return;
            }
            // check if descriptor contains any bidirectional property
            /*foreach (PropertyInfo propertyInfo in parentPD.PropertyType.GetProperties())
            {
                if (!TypeNotInList(propertyInfo.PropertyType, typeList))
                {
                    // return, if continue we will get loop forever
                    return;
                }
            }*/

            PropertyDescriptorCollection childPDs = ((PropertyDescriptor) parentPD).GetChildProperties();
            PropertyInfo[] properties = parentPD.PropertyType.GetProperties();
            // if childPDs count < 0 then return
            if (childPDs.Count <= 0)
            {
                return;
            }
            // if parentPD is immultable type then return
            Type parentType = parentPD.PropertyType;
            if (IsPrimitiveOrCollectionType(parentType)
                ||  parentType.IsArray
                || parentType is  IEnumerable )
            {
                return;
            }

            // check child type
            foreach (PropertyDescriptor childPD in childPDs)
            {

                ComplexPropertyDescriptor subPropertyDescriptor = new ComplexPropertyDescriptor(parentPD, childPD, parentPD.Name + "." + childPD.Name);

                // if is primitive types
                if (IsPrimitiveOrCollectionType(childPD.PropertyType))
                {
                    if (subPropertyDescriptor.PropertyType.Name.Equals("PurchaseOrderDetailPK.DepartmentId"))
                    {

                    }

                    list.Add(subPropertyDescriptor);
                }
                else // custom type
                {
                    if (TypeNotInList(childPD, typeList))
                    {
                        if (subPropertyDescriptor.PropertyType.Name.Equals("PurchaseOrderDetailPK.DepartmentId"))
                        {
                            //Console.WriteLine("Here");
                        }

                        //Console.WriteLine("Sub:" + subPropertyDescriptor.Name);
                        list.Add(subPropertyDescriptor);
                        typeList.Add(childPD.PropertyType.FullName);

                        /*PropertyDescriptorCollection subChildPDs = ((PropertyDescriptor)childPD).GetChildProperties();
                        if (subChildPDs.Count > 0)
                        {*/
                            GetList(subPropertyDescriptor, ref list, ref typeList);
                        /*}*/
                    }
                }
            }
        }