/// <summary>
        /// Check the Publishing queue and determine whether the given TcmUri is already present in the queue.
        /// </summary>
        /// <param name="engine">Engine object</param>
        /// <param name="tcmUri">String representing the tcmuri of the item to check</param>
        /// <param name="state">PublishTransactionState the publish state to filter on</param>
        public static bool IsInPublishingQueue(Engine engine, String tcmUri, PublishTransactionState state)
        {
            Log.Debug(String.Format("Check Publishing queue for item '{0}'", tcmUri));

            Session session = engine.GetSession();
            PublishTransactionsFilter filter = new PublishTransactionsFilter(session);

            filter.PublishTransactionState = state;
            RepositoryLocalObject item = engine.GetObject(tcmUri) as RepositoryLocalObject;
            if (item != null) filter.ForRepository = item.ContextRepository;

            PublicationTarget publicationTarget = engine.PublishingContext.PublicationTarget;
            if (publicationTarget != null)
            {
                filter.PublicationTarget = publicationTarget;
            }

            XmlElement element = PublishEngine.GetListPublishTransactions(filter);
            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
            namespaceManager.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");

            String xPath = String.Format("tcm:ListPublishTransactions/tcm:Item[@ItemID='{0}']", tcmUri);
            XmlNodeList nodeList = element.SelectNodes(xPath, namespaceManager);

            return nodeList.Count > 0;
        }
        /// <summary>
        /// Check the Publishing queue and determine whether the given TcmUri is already present in the queue.
        /// </summary>
        /// <param name="engine">Engine object</param>
        /// <param name="tcmUri">String representing the tcmuri of the item to check</param>
        /// <param name="state">PublishTransactionState the publish state to filter on</param>
        public static bool IsInPublishingQueue(Engine engine, String tcmUri, PublishTransactionState state)
        {
            Log.Debug(String.Format("Check Publishing queue for item '{0}'", tcmUri));

            Session session = engine.GetSession();
            PublishTransactionsFilter filter = new PublishTransactionsFilter(session);

            filter.PublishTransactionState = state;
            RepositoryLocalObject item = engine.GetObject(tcmUri) as RepositoryLocalObject;

            if (item != null)
            {
                filter.ForRepository = item.ContextRepository;
            }

            PublicationTarget publicationTarget = engine.PublishingContext.PublicationTarget;

            if (publicationTarget != null)
            {
                filter.PublicationTarget = publicationTarget;
            }

            XmlElement          element          = PublishEngine.GetListPublishTransactions(filter);
            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());

            namespaceManager.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");

            String      xPath    = String.Format("tcm:ListPublishTransactions/tcm:Item[@ItemID='{0}']", tcmUri);
            XmlNodeList nodeList = element.SelectNodes(xPath, namespaceManager);

            return(nodeList.Count > 0);
        }
        /// <summary>
        /// Get 'current' PublishTransaction. It tries to identify a PublishTransaction from the publish queue that is on the
        /// given TcmUri, Publication, User, etc.
        /// </summary>
        /// <param name="engine">Engine object</param>
        /// <param name="tcmUri">String representing the tcmuri of the item to check</param>
        /// <returns>PublishTransaction if found; or null, otherwise</returns>
        private static PublishTransaction FindPublishTransaction(Engine engine, String tcmUri)
        {
            Log.Debug(String.Format("Find PublishTransaction for item '{0}'", tcmUri));

            PublishTransaction        result  = null;
            Session                   session = engine.GetSession();
            PublishTransactionsFilter filter  = new PublishTransactionsFilter(session);

            filter.PublishTransactionState = PublishTransactionState.Resolving;
            RepositoryLocalObject item = engine.GetObject(tcmUri) as RepositoryLocalObject;

            if (item != null)
            {
                filter.ForRepository = item.ContextRepository;
            }

            PublicationTarget publicationTarget = engine.PublishingContext.PublicationTarget;

            if (publicationTarget != null)
            {
                filter.PublicationTarget = publicationTarget;
            }

            XmlElement element = PublishEngine.GetListPublishTransactions(filter);


            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());

            namespaceManager.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");

            String      xPath    = String.Format("tcm:ListPublishTransactions/tcm:Item[@ItemID='{0}']", tcmUri);
            XmlNodeList nodeList = element.SelectNodes(xPath, namespaceManager);

            String transactionId;

            if (nodeList != null && nodeList.Count == 1)
            {
                transactionId = nodeList[0].Attributes["ID"].Value;
                TcmUri transactionUri = new TcmUri(transactionId);
                result = new PublishTransaction(transactionUri, session);
            }
            else
            {
                foreach (XmlNode node in element.ChildNodes)
                {
                    transactionId = node.Attributes["ID"].Value;
                    TcmUri transactionUri = new TcmUri(transactionId);
                    result = new PublishTransaction(transactionUri, session);
                    if (IsPublishTransactionForTcmUri(result, tcmUri))
                    {
                        break;
                    }
                    result = null;
                }
            }

            Log.Debug("Returning PublishTransaction " + result);
            return(result);
        }
        /// <summary>
        /// Publishes an <see cref="T:Tridion.ContentManager.IdentifiableObject" /> intelligently if and only if, <see cref="T:Tridion.ContentManager.IdentifiableObject" /> is not in
        /// "Waiting For Publish" state or "Scheduled For Publish" state within the scheduleDateFilter <see cref="T:System.DateTime" />
        /// </summary>
        /// <param name="identifiableObject">The <see cref="T:Tridion.ContentManager.IdentifiableObject" />.</param>
        /// <param name="startDateFilter">The start <see cref="T:System.DateTime"/> filter.</param>
        /// <param name="scheduleDateFilter">The schedule <see cref="T:System.DateTime"/> filter.</param>
        /// <param name="publishStartDate">The publish start <see cref="T:System.DateTime"/>.</param>
        public void PublishIntelligently(IdentifiableObject identifiableObject, DateTime startDateFilter, DateTime scheduleDateFilter, DateTime publishStartDate)
        {
            PublishTransactionsFilter filter = new PublishTransactionsFilter(Engine.GetSession())
            {
                StartDate         = startDateFilter,
                PublicationTarget = PublicationTarget,
                ForRepository     = GetObject <Repository>(Publication.Id)
            };

            PublishTransaction publishTransaction = PublishEngine.GetPublishTransactions(filter)
                                                    .FirstOrDefault(t => t.Items.Count > 0 &&
                                                                    t.Items.First().Id == identifiableObject.Id &&
                                                                    (t.State == PublishTransactionState.WaitingForPublish ||
                                                                     (t.State == PublishTransactionState.ScheduledForPublish && scheduleDateFilter >= t.Instruction.StartAt)));

            if (publishTransaction == null)
            {
                PublishItem(identifiableObject, publishStartDate);
            }
        }
        /// <summary>
        /// Get 'current' PublishTransaction. It tries to identify a PublishTransaction from the publish queue that is on the 
        /// given TcmUri, Publication, User, etc.
        /// </summary>
        /// <param name="engine">Engine object</param>
        /// <param name="tcmUri">String representing the tcmuri of the item to check</param>
        /// <returns>PublishTransaction if found; or null, otherwise</returns>
        private static PublishTransaction FindPublishTransaction(Engine engine, String tcmUri)
        {
            Log.Debug(String.Format("Find PublishTransaction for item '{0}'", tcmUri));

            PublishTransaction result = null;
            Session session = engine.GetSession();
            PublishTransactionsFilter filter = new PublishTransactionsFilter(session);

            filter.PublishTransactionState = PublishTransactionState.Resolving;
            RepositoryLocalObject item = engine.GetObject(tcmUri) as RepositoryLocalObject;
            if (item != null) filter.ForRepository = item.ContextRepository;

            PublicationTarget publicationTarget = engine.PublishingContext.PublicationTarget;
            if (publicationTarget != null)
            {
                filter.PublicationTarget = publicationTarget;
            }

            XmlElement element = PublishEngine.GetListPublishTransactions(filter);

            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
            namespaceManager.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");

            String xPath = String.Format("tcm:ListPublishTransactions/tcm:Item[@ItemID='{0}']", tcmUri);
            XmlNodeList nodeList = element.SelectNodes(xPath, namespaceManager);

            String transactionId;
            if (nodeList != null && nodeList.Count == 1)
            {
                transactionId = nodeList[0].Attributes["ID"].Value;
                TcmUri transactionUri = new TcmUri(transactionId);
                result = new PublishTransaction(transactionUri, session);
            }
            else
            {
                foreach (XmlNode node in element.ChildNodes)
                {
                    transactionId = node.Attributes["ID"].Value;
                    TcmUri transactionUri = new TcmUri(transactionId);
                    result = new PublishTransaction(transactionUri, session);
                    if (IsPublishTransactionForTcmUri(result, tcmUri))
                    {
                        break;
                    }
                    result = null;
                }
            }

            Log.Debug("Returning PublishTransaction " + result);
            return result;
        }