private void AddWorkflowActivityAttributes(OrganizationServiceContext ctx, CodeParser parser, string pluginType)
        {
            // If so, search CRM for matches
            var steps = ServiceLocator.Queries.GetWorkflowPluginActivities(ctx, pluginType);

            if (steps != null)
            {
                _trace.WriteLine("Found Workflow Activity Type Registration {0}", pluginType);
                // Get the activities
                foreach (var activity in steps)
                {
                    // Create attribute
                    CrmPluginRegistrationAttribute attribute = new CrmPluginRegistrationAttribute(
                        activity.Name,
                        activity.FriendlyName,
                        activity.Description,
                        activity.WorkflowActivityGroupName,
                        activity.pluginassembly_plugintype.IsolationMode == pluginassembly_isolationmode.Sandbox ? IsolationModeEnum.Sandbox : IsolationModeEnum.None
                        )
                    ;
                    // Add attribute
                    parser.AddAttribute(attribute, activity.TypeName);
                }
            }
        }
        private void AddPluginAttributes(OrganizationServiceContext ctx, CodeParser parser, string pluginType)
        {
            // Get existing Steps
            var steps = ServiceLocator.Queries.GetPluginSteps(ctx, pluginType);

            // Check that there are no duplicates
            var duplicateNames = steps.GroupBy(s => s.Name).SelectMany(grp => grp.Skip(1));

            if (duplicateNames.Count() > 0)
            {
                throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.DUPLICATE_STEP, String.Format("More than one step found with the same name for plugin type {0} - {1}", pluginType, string.Join(",", duplicateNames.Select(a => a.Name))));
            }

            if (steps != null)
            {
                _trace.WriteLine("Found Plugin Type Registration {0}", pluginType);
                // Get the steps
                foreach (var step in steps)
                {
                    SdkMessageFilter filter = null;
                    // If there is an entity filter then get it
                    if (step.SdkMessageFilterId != null)
                    {
                        filter = ServiceLocator.Queries.GetMessageFilter(ctx, step.SdkMessageFilterId.Id);
                    }

                    // Get the images
                    SdkMessageProcessingStepImage[] images = ServiceLocator.Queries.GetPluginStepImages(ctx, step);

                    // Only support two images - Why would you need more?!
                    if (images.Length > 2)
                    {
                        throw new Exception(String.Format("More than 2 images found on step {0}", step.Name));
                    }

                    // Create attribute
                    // we output the ID so that we can be independant of name - but it's not neededed for new attributes
                    CrmPluginRegistrationAttribute attribute = new CrmPluginRegistrationAttribute(
                        step.sdkmessageid_sdkmessageprocessingstep.Name,
                        filter == null ? "none" : filter.PrimaryObjectTypeCode,
                        (StageEnum)Enum.ToObject(typeof(StageEnum), step.Stage.Value),
                        step.Mode.Value == 0 ? ExecutionModeEnum.Synchronous : ExecutionModeEnum.Asynchronous,
                        step.FilteringAttributes,
                        step.Name,
                        step.Rank.HasValue ? step.Rank.Value : 1,
                        step.plugintypeid_sdkmessageprocessingstep.pluginassembly_plugintype.IsolationMode == pluginassembly_isolationmode.Sandbox
                            ? IsolationModeEnum.Sandbox : IsolationModeEnum.None
                        )
                    {
                        Id = step.Id.ToString()
                    };

                    // Image 1
                    if (images.Length >= 1)
                    {
                        var image = images[0];
                        attribute.Image1Type       = (ImageTypeEnum)Enum.ToObject(typeof(ImageTypeEnum), image.ImageType.Value);
                        attribute.Image1Name       = image.EntityAlias;
                        attribute.Image1Attributes = image.Attributes1;
                    }
                    // Image 2
                    if (images.Length >= 2)
                    {
                        var image = images[1];
                        attribute.Image2Type       = (ImageTypeEnum)Enum.ToObject(typeof(ImageTypeEnum), image.ImageType.Value);
                        attribute.Image2Name       = image.EntityAlias;
                        attribute.Image2Attributes = image.Attributes1;
                    }
                    // Add config
                    if (step.Configuration != null)
                    {
                        attribute.UnSecureConfiguration = step.Configuration;
                    }

                    if (step.Description != null)
                    {
                        attribute.Description = step.Description;
                    }

                    // Add attribute to code
                    parser.AddAttribute(attribute, step.plugintypeid_sdkmessageprocessingstep.TypeName);
                }
            }
        }