void SerializePromotedProperties(SqlParameterCollection parameters, StringBuilder commandTextBuilder, SaveWorkflowCommand saveWorkflowCommand)
        {
            const int    SqlVariantStartColumn  = 1;
            const string promotionNameParameter = "@promotionName=";
            const string instanceIdParameter    = "@instanceId=";
            int          promotionNumber        = 0;

            foreach (KeyValuePair <string, Tuple <List <XName>, List <XName> > > promotion in base.Store.Promotions)
            {
                StringBuilder storedProcInvocationBuilder = new StringBuilder(SqlWorkflowInstanceStoreConstants.DefaultStringBuilderCapacity);
                int           column                = SqlVariantStartColumn;
                bool          addPromotion          = false;
                string        promotionNameArgument = string.Format(CultureInfo.InvariantCulture, "@promotionName{0}", promotionNumber);
                string        instanceIdArgument    = string.Format(CultureInfo.InvariantCulture, "@instanceId{0}", promotionNumber);

                storedProcInvocationBuilder.Append(string.Format(CultureInfo.InvariantCulture, "exec {0}.[InsertPromotedProperties] ", SqlWorkflowInstanceStoreConstants.DefaultSchema));
                storedProcInvocationBuilder.Append(promotionNameParameter);
                storedProcInvocationBuilder.Append(promotionNameArgument);
                storedProcInvocationBuilder.Append(",");
                storedProcInvocationBuilder.Append(instanceIdParameter);
                storedProcInvocationBuilder.Append(instanceIdArgument);

                foreach (XName name in promotion.Value.Item1)
                {
                    InstanceValue propertyValue;

                    if (saveWorkflowCommand.InstanceData.TryGetValue(name, out propertyValue))
                    {
                        if (!SerializationUtilities.IsPropertyTypeSqlVariantCompatible(propertyValue))
                        {
                            throw FxTrace.Exception.AsError(new InstancePersistenceException(SR.CannotPromoteAsSqlVariant(propertyValue.Value.GetType().ToString(), name.ToString())));
                        }

                        string parameterName = string.Format(CultureInfo.InvariantCulture, "@value{0}=", column);
                        string argumentName  = string.Format(CultureInfo.InvariantCulture, "@value{0}_promotion{1}", column, promotionNumber);
                        parameters.Add(new SqlParameter()
                        {
                            SqlDbType = SqlDbType.Variant, ParameterName = argumentName, Value = propertyValue.Value ?? DBNull.Value
                        });

                        storedProcInvocationBuilder.Append(", ");
                        storedProcInvocationBuilder.Append(parameterName);
                        storedProcInvocationBuilder.Append(argumentName);
                        addPromotion = true;
                    }
                    column++;
                }

                column = SqlVariantStartColumn + SqlWorkflowInstanceStoreConstants.MaximumPropertiesPerPromotion;

                foreach (XName name in promotion.Value.Item2)
                {
                    InstanceValue     propertyValue;
                    IObjectSerializer serializer = ObjectSerializerFactory.GetObjectSerializer(base.Store.InstanceEncodingOption);

                    if (saveWorkflowCommand.InstanceData.TryGetValue(name, out propertyValue))
                    {
                        string parameterName = string.Format(CultureInfo.InvariantCulture, "@value{0}=", column);
                        string argumentName  = string.Format(CultureInfo.InvariantCulture, "@value{0}_promotion{1}", column, promotionNumber);

                        SaveWorkflowAsyncResult.AddSerializedProperty(serializer.SerializeValue(propertyValue.Value), parameters, argumentName);
                        storedProcInvocationBuilder.Append(", ");
                        storedProcInvocationBuilder.Append(parameterName);
                        storedProcInvocationBuilder.Append(argumentName);
                        addPromotion = true;
                    }
                    column++;
                }

                if (addPromotion)
                {
                    parameters.Add(new SqlParameter()
                    {
                        SqlDbType = SqlDbType.NVarChar, Size = 400, ParameterName = promotionNameArgument, Value = promotion.Key
                    });
                    parameters.Add(new SqlParameter()
                    {
                        SqlDbType = SqlDbType.UniqueIdentifier, ParameterName = instanceIdArgument, Value = base.InstancePersistenceContext.InstanceView.InstanceId
                    });
                    storedProcInvocationBuilder.Append(";");
                    commandTextBuilder.AppendLine(storedProcInvocationBuilder.ToString());
                    promotionNumber++;
                }
            }
        }
        void SerializeAssociatedData(SqlParameterCollection parameters, SaveWorkflowCommand saveWorkflowCommand, StringBuilder commandTextBuilder)
        {
            if (saveWorkflowCommand.CompleteInstance && base.Store.InstanceCompletionAction == InstanceCompletionAction.DeleteAll)
            {
                parameters.Add(new SqlParameter {
                    ParameterName = "@keysToAssociate", SqlDbType = SqlDbType.Xml, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@singleKeyId", SqlDbType = SqlDbType.UniqueIdentifier, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@keysToComplete", SqlDbType = SqlDbType.Xml, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@keysToFree", SqlDbType = SqlDbType.Xml, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@concatenatedKeyProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@primitiveDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@complexDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@writeOnlyPrimitiveDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@writeOnlyComplexDataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@metadataProperties", SqlDbType = SqlDbType.VarBinary, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@metadataIsConsistent", SqlDbType = SqlDbType.Bit, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@encodingOption", SqlDbType = SqlDbType.TinyInt, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@lastMachineRunOn", SqlDbType = SqlDbType.NVarChar, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@executionStatus", SqlDbType = SqlDbType.NVarChar, Value = DBNull.Value
                });
                parameters.Add(new SqlParameter {
                    ParameterName = "@blockingBookmarks", SqlDbType = SqlDbType.NVarChar, Value = DBNull.Value
                });

                return;
            }

            List <CorrelationKey> keysToAssociate = CorrelationKey.BuildKeyList(saveWorkflowCommand.InstanceKeysToAssociate, base.Store.InstanceEncodingOption);
            List <CorrelationKey> keysToComplete  = CorrelationKey.BuildKeyList(saveWorkflowCommand.InstanceKeysToComplete);
            List <CorrelationKey> keysToFree      = CorrelationKey.BuildKeyList(saveWorkflowCommand.InstanceKeysToFree);

            ArraySegment <byte>[] dataProperties     = SerializationUtilities.SerializePropertyBag(saveWorkflowCommand.InstanceData, base.Store.InstanceEncodingOption);
            ArraySegment <byte>   metadataProperties = SerializationUtilities.SerializeMetadataPropertyBag(saveWorkflowCommand, base.InstancePersistenceContext, base.Store.InstanceEncodingOption);

            byte[] concatenatedKeyProperties = SerializationUtilities.CreateKeyBinaryBlob(keysToAssociate);
            bool   metadataConsistency       = (base.InstancePersistenceContext.InstanceView.InstanceMetadataConsistency == InstanceValueConsistency.None);
            bool   singleKeyToAssociate      = (keysToAssociate != null && keysToAssociate.Count == 1);

            parameters.Add(new SqlParameter {
                ParameterName = "@keysToAssociate", SqlDbType = SqlDbType.Xml, Value = singleKeyToAssociate ? DBNull.Value : SerializationUtilities.CreateCorrelationKeyXmlBlob(keysToAssociate)
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@singleKeyId", SqlDbType = SqlDbType.UniqueIdentifier, Value = singleKeyToAssociate ? keysToAssociate[0].KeyId : (object)DBNull.Value
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@keysToComplete", SqlDbType = SqlDbType.Xml, Value = SerializationUtilities.CreateCorrelationKeyXmlBlob(keysToComplete)
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@keysToFree", SqlDbType = SqlDbType.Xml, Value = SerializationUtilities.CreateCorrelationKeyXmlBlob(keysToFree)
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@concatenatedKeyProperties", SqlDbType = SqlDbType.VarBinary, Size = -1, Value = (object)concatenatedKeyProperties ?? DBNull.Value
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@metadataIsConsistent", SqlDbType = SqlDbType.Bit, Value = metadataConsistency
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@encodingOption", SqlDbType = SqlDbType.TinyInt, Value = base.Store.InstanceEncodingOption
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@lastMachineRunOn", SqlDbType = SqlDbType.NVarChar, Size = 450, Value = SqlWorkflowInstanceStoreConstants.MachineName
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@executionStatus", SqlDbType = SqlDbType.NVarChar, Size = 450, Value = GetExecutionStatus(saveWorkflowCommand) ?? (object)DBNull.Value
            });
            parameters.Add(new SqlParameter {
                ParameterName = "@blockingBookmarks", SqlDbType = SqlDbType.NVarChar, Size = -1, Value = GetBlockingBookmarks(saveWorkflowCommand) ?? (object)DBNull.Value
            });

            ArraySegment <byte>[] properties = { dataProperties[0], dataProperties[1], dataProperties[2], dataProperties[3], metadataProperties };
            string[] dataPropertyParameters  = { "@primitiveDataProperties", "@complexDataProperties", "@writeOnlyPrimitiveDataProperties", @"writeOnlyComplexDataProperties", "@metadataProperties" };

            for (int i = 0; i < 5; i++)
            {
                SaveWorkflowAsyncResult.AddSerializedProperty(properties[i], parameters, dataPropertyParameters[i]);
            }

            this.SerializePromotedProperties(parameters, commandTextBuilder, saveWorkflowCommand);
        }