/// <summary>
        /// 
        /// </summary>
        /// <param name="actual"></param>
        public DynamicPageProxy(IDynamicPage actual)
            : base(actual)
        {
            //Construct the fields of the DetailPanelPage class
            FieldInfo[] fields = actual.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            for (int i = 0; i < fields.Count(); i++)
            {
                FieldInfo field = fields[i];
                if (field.GetCustomAttributes(typeof(BindingAttribute), false).Count() > 0)
                    fields[i].SetValue(actual, Activator.CreateInstance(field.FieldType));
            }
        }
        /// <summary>
        /// Convert QueryResults by generate decorate serializable class with transformed values.
        /// </summary>
        /// <param name="dynamicPageService"></param>
        /// <param name="results"></param>
        /// <returns></returns>
        private DataSource ConvertQueryResults(IDynamicPage dynamicPageService, IEnumerable results)
        {
            IEnumerable<object> originalObjects = results.Cast<object>();

            DataSource dataSource = new DataSource
            {
                Author = this.applicationContext.Identity.Name,
                CreatedOn = LocalizationUtility.ConvertUtcTimeToClientTime(DateTime.UtcNow),
                Name = dynamicPageService.Configuration.Title,
                Description = string.Format(CultureInfo.InvariantCulture, Resources.DP_DynamicPage_Print_HeadBar_Template, originalObjects.Count(), LocalizationUtility.ToDateTimeString(DateTime.Now), this.applicationContext.Identity.Name),
                LogoUrl = Path.Combine(Kit.WebSiteBaseUrl, "resources/images/logo.png")
            };

            if (originalObjects.Count() == 0) return dataSource;

            IDictionary<PropertyDefinition, string> propertyDefinitionAndHeaderText = CreatePropertyDecorateConfigs(dynamicPageService);
            IEnumerable<PropertyDefinition> propertyDefinitionEnumerable = propertyDefinitionAndHeaderText.Keys;
            IEnumerable<object> convertResults = null;

            try
            {
                convertResults = ClassDecorator.CreateDecorateObjects(originalObjects, propertyDefinitionEnumerable).Cast<object>();
            }
            catch (CompileException exp)
            {
                string loggingMessage = string.Format(CultureInfo.InvariantCulture, "There has errors to compile a dynamic class from dynamic page configuration to render UI grid of the dynamic page with object id equals to \"{0}\".", QueryStringUtility.ObjectId);
                Logger.Instance(typeof(DynamicPagePrinter)).Error(loggingMessage, exp);
                throw;
            }

            FillQueryResult(dataSource, propertyDefinitionAndHeaderText, convertResults);
            return dataSource;
        }
        /// <summary>
        /// Create a collection of <see cref="PropertyDefinition"/> to configure how to create decorate class and clone objects into new types from original query results.
        /// </summary>
        /// <param name="dynamicPageService"></param>
        /// <returns></returns>
        private static IDictionary<PropertyDefinition, string> CreatePropertyDecorateConfigs(IDynamicPage dynamicPageService)
        {
            GridViewPanelConfiguration gridViewPanel = dynamicPageService.Configuration.Panels.FirstOrDefault(p => p.PanelType == DynamicPagePanelTypes.GridViewPanel) as GridViewPanelConfiguration;
            if (gridViewPanel == null)
                return new Dictionary<PropertyDefinition, string>();

            Dictionary<PropertyDefinition, string> results = new Dictionary<PropertyDefinition, string>();

            ExtGridConfiguration extGridConfiguration = ExtGridConfigurationResolver.Resolve();

            // Add wrappers for original properties
            for (int index = 0; index < gridViewPanel.Fields.Count; index++)
            {
                if (extGridConfiguration != null)
                {
                    int findingColumnIndex = index + 1;
                    if (gridViewPanel.EnabledCheckBoxField) findingColumnIndex++;
                    ExtGridColumnConfiguration extGridColumnConfiguration = extGridConfiguration.Columns.FirstOrDefault(col => col.ColumnIndex == findingColumnIndex);
                    if (extGridColumnConfiguration == null || extGridColumnConfiguration.Hidden) continue;
                }

                GridViewFieldConfiguration gridViewField = gridViewPanel.Fields[index];
                PropertyDefinition propertyDecorateConfig = new PropertyDefinition(typeof(string))
                {
                    PropertyName = gridViewField.FieldName,
                    NewPropertyName = FieldNameTransformUtility.DataBoundFieldName(gridViewField.FieldName, index)
                };

                GridViewFieldValueTransformConfiguration transformer = gridViewField.Transformer;
                if (transformer != null && transformer.TransformType != GridViewFieldValueTransformTypes.None)
                {
                    propertyDecorateConfig.PropertyValueConvertCallback = arg => { return TransformFieldValue(transformer, gridViewField.FieldName, arg); };
                }
                else
                {
                    propertyDecorateConfig.PropertyValueConvertCallback = arg =>
                    {
                        if (!(arg is string) && arg is IEnumerable) return arg;
                        return arg != null ? arg.ToString() : "";
                    };
                }

                results.Add(propertyDecorateConfig, gridViewField.HeaderText);
            }

            // Add wrapper for row view property.
            if (gridViewPanel.RowView != null)
            {
                results.Add(new PropertyDefinition(typeof(string))
                {
                    PropertyName = gridViewPanel.RowView.FieldName,
                    NewPropertyName = FieldNameTransformUtility.ViewFragmentFieldName(gridViewPanel.RowView.FieldName),
                    PropertyValueConvertCallback = (arg) => { return arg != null ? arg.ToString() : ""; }
                }, Resources.DP_RowView_HeaderText);
            }

            return results;
        }
        /// <summary>
        /// Print queried data in the dynamic page to any format depends on the implementation.
        /// </summary>
        /// <param name="dynamicPageService">The dynamic page handler.</param>
        /// <param name="queryStringParameters">The query string parameters.</param>
        /// <returns></returns>
        public DynamicPagePrintResult Print(IDynamicPage dynamicPageService, NameValueCollection queryStringParameters)
        {
            try
            {
                QueryParameter queryParameter = QueryParameter.CreateQueryParameter(dynamicPageService, queryStringParameters, 0, int.MaxValue, null, null);

                // Execute query.
                QueryResults queryResults = dynamicPageService.Query(queryParameter);
                DataSource dataSource = ConvertQueryResults(dynamicPageService, queryResults.Results);

                return TransformDataSource(dataSource);
            }
            catch (ValidationException exp)
            {
                Logger.Instance(typeof(DynamicPagePrinter)).Warn(exp);
                throw;
            }
            catch (Exception exp)
            {
                Logger.Instance(typeof(DynamicPagePrinter)).Error(exp);
                throw;
            }
        }
        /// <summary>
        /// Execute query for specified dynamic page by object id.
        /// </summary>
        /// <param name="dynamicPageService">dynamic page service</param>
        /// <param name="start">start offset of returned results</param>
        /// <param name="limit">total count of returned results</param>
        /// <param name="sortField">sorting field name</param>
        /// <param name="sortDirection">sorting field direction</param>
        /// <param name="errorMessage">error messages response to the client.</param>
        /// <returns>returns json-serialized string from <see cref="QueryResultObject"/></returns>
        private static string ExecuteQuery(IDynamicPage dynamicPageService, int start, int limit, string sortField, string sortDirection, string errorMessage)
        {
            IEnumerable convertedQueryResults = null;
            int totalRecordCount = 0;
            string returnedErrorMessage = errorMessage;

            if (string.IsNullOrEmpty(returnedErrorMessage))
            {
                try
                {
                    QueryParameter queryParameter = QueryParameter.CreateQueryParameter(dynamicPageService, HttpContext.Current.Request.QueryString, start, limit, sortField, sortDirection);

                    // Execute query.
                    QueryResults queryResults = dynamicPageService.Query(queryParameter);
                    convertedQueryResults = ConvertQueryResults(dynamicPageService, queryResults.Results);
                    totalRecordCount = queryResults.RecordCount;
                }
                catch (ValidationException exp)
                {
                    returnedErrorMessage = exp.Message;
                }
                catch (Exception exp)
                {
                    returnedErrorMessage = Resources.DP_UnknownErrorDetail;
                    Logger.Instance(typeof(DynamicPageDataServiceHandler)).Error(exp);
                }
            }

            // Construct query result object for serialization.
            QueryResultObject queryResultObject = new QueryResultObject
            {
                Records = convertedQueryResults,
                TotalRecordCount = totalRecordCount,
                Start = start,
                Limit = limit,
                HasError = !string.IsNullOrEmpty(returnedErrorMessage),
                ErrorMessage = returnedErrorMessage
            };

            return serializer.Serialize(queryResultObject);
        }
 /// <summary>
 /// Delete an existed entity by id.
 /// </summary>
 /// <param name="dynamicPageService"></param>
 /// <param name="entityId"></param>
 private static string DeleteEntityById(IDynamicPage dynamicPageService, string entityId)
 {
     try
     {
         dynamicPageService.Delete(entityId);
         return null;
     }
     catch (ValidationException exp)
     {
         return exp.Message;
     }
     catch (Exception exp)
     {
         Logger.Instance(typeof(DynamicPageDataServiceHandler)).Error(exp);
         return Resources.DP_UnknownErrorDetail;
     }
 }
        /// <summary>
        /// Create a collection of <see cref="PropertyDefinition"/> to configure how to create decorate class and clone objects into new types from original query results.
        /// </summary>
        /// <param name="dynamicPageService"></param>
        /// <returns></returns>
        private static IEnumerable<PropertyDefinition> CreatePropertyDecorateConfigs(IDynamicPage dynamicPageService)
        {
            GridViewPanelConfiguration gridViewPanel = dynamicPageService.Configuration.Panels.FirstOrDefault(p => p.PanelType == DynamicPagePanelTypes.GridViewPanel) as GridViewPanelConfiguration;
            if (gridViewPanel == null)
                return new PropertyDefinition[0];

            Collection<PropertyDefinition> results = new Collection<PropertyDefinition>();
            results.Add(new PropertyDefinition(typeof(string)) { PropertyName = gridViewPanel.PrimaryKeyFieldName, NewPropertyName = FieldNameTransformUtility.PrimaryKeyFieldName(gridViewPanel.PrimaryKeyFieldName) });

            // Add wrappers for original properties
            for (int index = 0; index < gridViewPanel.Fields.Count; index++)
            {
                GridViewFieldConfiguration gridViewField = gridViewPanel.Fields[index];
                PropertyDefinition propertyDecorateConfig = new PropertyDefinition(typeof(string))
                {
                    PropertyName = gridViewField.FieldName,
                    NewPropertyName = FieldNameTransformUtility.DataBoundFieldName(gridViewField.FieldName, index)
                };

                GridViewFieldValueTransformConfiguration transformer = gridViewField.Transformer;
                if (transformer != null && transformer.TransformType != GridViewFieldValueTransformTypes.None)
                {
                    propertyDecorateConfig.PropertyValueConvertCallback = arg => { return TransformFieldValue(transformer, gridViewField.FieldName, arg); };
                }
                else
                {
                    propertyDecorateConfig.PropertyValueConvertCallback = arg =>
                    {
                        if (!(arg is string) && arg is IEnumerable) return arg;
                        return arg != null ? arg.ToString() : "";
                    };
                }

                results.Add(propertyDecorateConfig);
            }

            // Add wrapper for row view property.
            if (gridViewPanel.RowView != null)
            {
                results.Add(new PropertyDefinition(typeof(string))
                {
                    PropertyName = gridViewPanel.RowView.FieldName,
                    NewPropertyName = FieldNameTransformUtility.ViewFragmentFieldName(gridViewPanel.RowView.FieldName),
                    PropertyValueConvertCallback = (arg) => { return arg != null ? arg.ToString() : ""; }
                });
            }

            // Add wrapper for ShowCheckBox
            results.Add(new PropertyDefinition(typeof(bool))
            {
                PropertyName = null,
                NewPropertyName = DynamicPageDataServiceHandler.ShowCheckBoxColumnPropertyName,
                PropertyValueConvertCallback = (arg) => { return gridViewPanel.EnabledCheckBoxField; }
            });

            // Add wrapper for EditButton
            results.Add(new PropertyDefinition(typeof(bool))
            {
                PropertyName = null,
                NewPropertyName = DynamicPageDataServiceHandler.ShowEditButtonColumnPropertyName,
                PropertyValueConvertCallback = (arg) => { return gridViewPanel.EditButton != null; }
            });

            // Add wrapper for ViewButton
            results.Add(new PropertyDefinition(typeof(bool))
            {
                PropertyName = null,
                NewPropertyName = DynamicPageDataServiceHandler.ShowViewButtonColumnPropertyName,
                PropertyValueConvertCallback = (arg) => { return gridViewPanel.ViewButton != null; }
            });

            // Add wrapper for DeleteButton
            results.Add(new PropertyDefinition(typeof(bool))
            {
                PropertyName = null,
                NewPropertyName = DynamicPageDataServiceHandler.ShowDeleteButtonColumnPropertyName,
                PropertyValueConvertCallback = (arg) => { return gridViewPanel.DeleteButton != null; }
            });

            return results;
        }
        /// <summary>
        /// Convert QueryResults by generate decorate serializable class with transformed values.
        /// </summary>
        /// <param name="dynamicPageService"></param>
        /// <param name="results"></param>
        /// <returns></returns>
        private static IEnumerable ConvertQueryResults(IDynamicPage dynamicPageService, IEnumerable results)
        {
            IEnumerable<object> originalObjects = results.Cast<object>();
            if (originalObjects.Count() == 0) return results;

            IEnumerable<PropertyDefinition> propertyDecorateConfigs = CreatePropertyDecorateConfigs(dynamicPageService);
            IEnumerable<object> convertResults = null;

            try
            {
                convertResults = ClassDecorator.CreateDecorateObjects(originalObjects, propertyDecorateConfigs.ToArray()).Cast<object>();
            }
            catch (CompileException exp)
            {
                string loggingMessage = string.Format(CultureInfo.InvariantCulture, "There has errors to compile a dynamic class from dynamic page configuration to render UI grid of the dynamic page with object id equals to \"{0}\".", QueryStringUtility.ObjectId);
                Logger.Instance(typeof(DynamicPageDataServiceHandler)).Error(loggingMessage, exp);
                throw;
            }

            ObjectWrapper convertResultObjectWrapper = new ObjectWrapper(convertResults.First().GetType());
            for (int i = 0; i < originalObjects.Count(); i++)
            {
                object originalObject = originalObjects.ElementAt(i);
                GridRowControlBindEventArgs arg = new GridRowControlBindEventArgs(originalObject);
                dynamicPageService.OnGridRowControlsBind(arg);
                convertResultObjectWrapper.WrappedInstance = convertResults.ElementAt(i);

                // set visibility of checkbox
                bool showCheckBoxColumn = (bool)convertResultObjectWrapper.GetPropertyValue(DynamicPageDataServiceHandler.ShowCheckBoxColumnPropertyName);
                convertResultObjectWrapper.SetPropertyValue(DynamicPageDataServiceHandler.ShowCheckBoxColumnPropertyName, showCheckBoxColumn && arg.ShowCheckBoxColumn);

                // set visibility of edit button
                string permissionValue = string.Format(CultureInfo.InvariantCulture, "{0}.Update", dynamicPageService.Configuration.PermissionValue);
                bool hasUpdatePermission = permissionBridge.HasPermission(permissionValue);
                bool showEditButtonColumn = (bool)convertResultObjectWrapper.GetPropertyValue(DynamicPageDataServiceHandler.ShowEditButtonColumnPropertyName);
                convertResultObjectWrapper.SetPropertyValue(DynamicPageDataServiceHandler.ShowEditButtonColumnPropertyName, showEditButtonColumn && arg.ShowEditButton && hasUpdatePermission);

                // set visibility of view button
                bool showViewButtonColumn = (bool)convertResultObjectWrapper.GetPropertyValue(DynamicPageDataServiceHandler.ShowViewButtonColumnPropertyName);
                convertResultObjectWrapper.SetPropertyValue(DynamicPageDataServiceHandler.ShowViewButtonColumnPropertyName, showViewButtonColumn && arg.ShowViewButton);

                // set visibility of delete button
                permissionValue = string.Format(CultureInfo.InvariantCulture, "{0}.Delete", dynamicPageService.Configuration.PermissionValue);
                bool hasDeletePermission = permissionBridge.HasPermission(permissionValue);
                bool showDeleteButtonColumn = (bool)convertResultObjectWrapper.GetPropertyValue(DynamicPageDataServiceHandler.ShowDeleteButtonColumnPropertyName);
                convertResultObjectWrapper.SetPropertyValue(DynamicPageDataServiceHandler.ShowDeleteButtonColumnPropertyName, showDeleteButtonColumn && arg.ShowDeleteButton && hasDeletePermission);
            }

            return convertResults;
        }
        /// <summary>
        /// The method is working on validating the permission and authentication of user to the page.
        /// </summary>
        private void Initialize()
        {
            try
            {
                this.dynamicPage = DynamicPageContext.Current.GetDynamicPage(QueryStringUtility.ObjectId, false, this.GetRequestHandler());
                this.dynamicPage.ShowMessage += new Action<MessageTypes, string>(this.ShowMesage);
            }
            catch (ConfigurationErrorsException exp)
            {
                throw new InternalServerErrorException(exp);
            }

            string permissionValue = this.dynamicPage.Configuration.PermissionValue;
            if (!permissionBridge.HasPermission(permissionValue))
                throw new UnauthorizedException(string.Format(CultureInfo.InvariantCulture, @"The user doesn't have the permission to access the frame page with permission value ""{0}"".", this.dynamicPage.Configuration.PermissionValue));
        }
        /// <summary>
        /// The method is working on 
        /// </summary>
        private void Initialize()
        {
            try
            {
                this.dynamicPage = DynamicPageContext.Current.GetDynamicPage(QueryStringUtility.ObjectId);
            }
            catch (ConfigurationErrorsException exp)
            {
                Logger.Instance(this).Warn(exp);
                throw new InternalServerErrorException(exp);
            }

            this.detailPanelConfiguration = this.dynamicPage.Configuration.Panels.FirstOrDefault(p => p.PanelType == DynamicPagePanelTypes.DetailPanel) as DetailPanelConfiguration;
            if (this.detailPanelConfiguration == null)
            {
                Logger.Instance(this).WarnFormat("The dynamic page {0} doesn't include detail panel configuration.", QueryStringUtility.ObjectId);
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, @"There is no detail panel configured in the dynamic page ""{0}"".", QueryStringUtility.ObjectId));
            }

            this.currentEntityId = QueryStringUtility.EntityId;
            this.renderMode = QueryStringUtility.DetailPanelPageRenderMode;
        }
        /// <summary>
        /// The method is working on 
        /// </summary>
        private void Initialize()
        {
            if (string.IsNullOrEmpty(this.CommandArgument))
                throw new BadRequestException(@"The query string parameter ""CommandArgument"" is not specified.");

            try
            {
                this.dynamicPage = DynamicPageContext.Current.GetDynamicPage(QueryStringUtility.ObjectId);
            }
            catch (ConfigurationErrorsException exp)
            {
                Logger.Instance(this).Warn(exp);
                throw new InternalServerErrorException(exp);
            }

            IEnumerable<AggregatePanelConfiguration> aggregatePanelConfigurations = this.dynamicPage.Configuration.Panels
                .Where(p => p.PanelType == DynamicPagePanelTypes.AggregatePanel)
                .Cast<AggregatePanelConfiguration>();

            aggregatePanelConfiguration = aggregatePanelConfigurations.FirstOrDefault(p => string.Equals(p.CommandArgument, this.CommandArgument, StringComparison.OrdinalIgnoreCase));
            if (aggregatePanelConfiguration == null)
                aggregatePanelConfiguration = aggregatePanelConfigurations.FirstOrDefault(p => string.Equals(p.CommandArgument, "", StringComparison.OrdinalIgnoreCase));
            if (this.aggregatePanelConfiguration == null)
                throw new BadRequestException(@"Aggregate panel of the dynamic page is not configured.");
        }