private Guid CreateMessageProcessingtStep(
            IOrganizationService service,
            ITracingService tracer,
            string entityLogicalName,
            CrmData.SdkMessageName messageName,
            IEnumerable <string> attributeNames,
            string assemblyName,
            string pluginName)
        {
            var messageReference = GetMessageReference(service, messageName);
            var existingSteps    = GetStepReferences(service, entityLogicalName, messageName, assemblyName, pluginName);

            if (existingSteps.Any())
            {
                tracer.Trace("A '{0}' step already exists for entity [{1}].", messageName.ToString(), entityLogicalName);
                return(existingSteps.First().Id);
            }
            else
            {
                tracer.Trace("Creating a '{0}' step for the entity [{1}].", messageName.ToString(), entityLogicalName);

                // Register a "create" step under the Number Generator plugin for the requested entity type
                var step = new Entity(CrmData.SdkMessageProccessingStepEntityName);
                step[CrmData.SdkMessageProccessingStep_Name]                = string.Format("{0}: {1} of {2}", pluginName, messageName, entityLogicalName);
                step[CrmData.SdkMessageProccessingStep_Mode]                = new OptionSetValue((int)CrmData.CrmPluginStepMode.Synchronous);
                step[CrmData.SdkMessageProccessingStep_PluginTypeId]        = GetPluginTypeReference(service, assemblyName, pluginName);
                step[CrmData.SdkMessageProccessingStep_Rank]                = 1;
                step[CrmData.SdkMessageProccessingStep_SdkMessageId]        = messageReference;
                step[CrmData.SdkMessageProccessingStep_Stage]               = new OptionSetValue((int)CrmData.CrmPluginStepStage.PreOperation);
                step[CrmData.SdkMessageProccessingStep_SupportedDeployment] = new OptionSetValue((int)CrmData.CrmPluginStepDeployment.ServerOnly);
                step[CrmData.SdkMessageProccessingStep_SdkMessageFilterId]  = GetMessageFilterReference(service, messageReference, entityLogicalName);

                if (attributeNames != null && attributeNames.Any())
                {
                    step[CrmData.SdkMessageProccessingStep_FilteringAttributes] = String.Join(",", attributeNames);
                }

                var stepId = service.Create(step);
                return(stepId);
            }
        }
        private EntityReference GetMessageReference(IOrganizationService service, CrmData.SdkMessageName messageName)
        {
            var query = new QueryExpression
            {
                EntityName = CrmData.SdkMessageEntityName,
                ColumnSet  = new ColumnSet(CrmData.SdkMessage_Id)
            };

            query.Criteria.AddCondition(
                CrmData.SdkMessage_Name,
                ConditionOperator.Equal,
                messageName.ToString());

            var sdkMessages = service.RetrieveMultiple(query);
            var sdkMessage  = sdkMessages.Entities.First();

            return(sdkMessage.ToEntityReference());
        }