예제 #1
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Given a treeID for this product's feature tree, returns the full path for that
        /// tree node.
        /// </summary>
        //------------------------------------------------------------------------------------
        public virtual string GetTreePath(int treeID, ProductTreeFormat treeFormat)
        {
            DatastoreItemList storeItemList = GetStoreItemList();

            if (storeItemList != null)
            {
                ProductStudio.PsCoreTreeTypeEnum treeType = ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct;
                ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(treeType);
                ProductStudio.Node currNode = rootNode.FindNodeInSubtree(treeID);

                List <string> nodeNames = new List <string>();
                while (currNode != null && currNode.ID > 1)
                {
                    nodeNames.Insert(0, currNode.Name);
                    currNode = currNode.Parent;
                }

                string fullPath = treeFormat == ProductTreeFormat.IncludeProduct ? StoreID.Name : "";
                foreach (string name in nodeNames)
                {
                    fullPath += "\\" + name;
                }

                return(fullPath);
            }

            return(null);
        }
예제 #2
0
        /// <summary>
        /// Get changed BUGs from last modified time
        /// </summary>
        /// <param name="LastModifiedTime"></param>
        /// <returns></returns>
        public DatastoreItems GetBugListStartingFrom(DateTime LastModifiedTime)
        {
            string psQueryXml = "<Query>";

            psQueryXml += "<Group GroupOperator='And'>";
            psQueryXml += "<Expression Column='Changed Date' Operator='equalsGreater'><DateTime>" + LastModifiedTime.ToUniversalTime().ToString() + "</DateTime></Expression>";
            //psQueryXml += "<Expression Column='Status' Operator='notequals'><String>Closed</String></Expression>";
            psQueryXml += "</Group>";
            psQueryXml += "</Query>";

            DatastoreItemList psDataList = null;

            try
            {
                Query psQuery = new Query();
                psQuery.CountOnly         = false;
                psQuery.SelectionCriteria = psQueryXml;

                psDataList           = new DatastoreItemList();
                psDataList.Query     = psQuery;
                psDataList.Datastore = this.psDataStore;
                psDataList.Execute();
            }
            catch (Exception e)
            {
                throw new Exception(String.Format("Failed to Query bugs."), e);
            }

            return(psDataList.DatastoreItems);
        }
예제 #3
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Create a new blank bug - the fields can be filled out, and then saved back to PS.
        /// </summary>
        //------------------------------------------------------------------------------------
        public DatastoreItem CreateDSItem()
        {
            DatastoreItemList storeItemList = GetStoreItemList();

            storeItemList.CreateBlank(ProductStudio.PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs);
            return(storeItemList.DatastoreItems.Add(null, ProductStudio.PsApplyRulesMask.psApplyRulesAll));
        }
예제 #4
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Returns the root node of the Product Tree for this product.
        /// </summary>
        //------------------------------------------------------------------------------------
        public Node GetProductTreeRootNode()
        {
            DatastoreItemList storeItemList = GetStoreItemList();

            if (storeItemList != null)
            {
                ProductStudio.PsCoreTreeTypeEnum treeType = ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct;
                return(storeItemList.Datastore.get_RootNodeEx(treeType));
            }

            return(null);
        }
예제 #5
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Returns the complete product tree for the current product. The root will have
        /// parent id = -200. The returned tree is a depth-first representation of the product
        /// hierarchy.
        /// </summary>
        //------------------------------------------------------------------------------------
        public virtual void PopulateTree(TreeView treeView, int startingTreeID)
        {
            DatastoreItemList storeItemList = GetStoreItemList();

            if (storeItemList != null)
            {
                ProductStudio.PsCoreTreeTypeEnum treeType = ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct;
                ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(treeType);

                ProductAreaTree tree = new ProductAreaTree(rootNode);
                tree.PopulateTree(treeView, startingTreeID);
            }
        }
예제 #6
0
        private DatastoreItemList GetStoreItemList(bool cacheStoreItemList = true)
        {
            try
            {
                if (m_storeItemList == null || ConnectionTime.Elapsed.Minutes > MaxConnectionMinutes)
                {
                    ConnectionTime.Reset();
                    ProductStudio.Directory psDir = new ProductStudio.Directory();
                    psDir.Connect();

                    ProductStudio.Product psProduct     = psDir.GetProductByName(StoreID.Name);
                    DatastoreItemList     storeItemList = new DatastoreItemList();
                    storeItemList.Datastore = psProduct.Connect();

                    // Simulate outdated Product Studio error
                    //if (storeItemList.Datastore == null || storeItemList.Datastore != null)
                    //{
                    //    throw new Exception("[Product Studio] 80044005. Access to this product requires updated client components.");
                    //}

                    ConnectionTime.Start();

                    FieldDefs = storeItemList.Datastore.FieldDefinitions;

                    if (cacheStoreItemList)
                    {
                        m_storeItemList = storeItemList;
                    }
                    else
                    {
                        return(storeItemList);
                    }
                }

                return(m_storeItemList);
            }

            catch (Exception exception)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("Unable to connect to " + StoreID.Name);
                sb.AppendLine();
                sb.AppendLine(exception.Message);
                sb.AppendLine();
                Planner.Instance.WriteToEventLog(sb.ToString());

                throw new Exception(sb.ToString());
            }
        }
예제 #7
0
        public List <int> GetTreeIDChildNodes(int treeID)
        {
            List <int> nodes = new List <int>();

            nodes.Add(treeID);
            DatastoreItemList storeItemList = GetStoreItemList();

            if (storeItemList != null)
            {
                ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct);
                Node startingNode           = rootNode.FindNodeInSubtree(treeID);
                if (startingNode != null)
                {
                    AddTreeIDChildNode(startingNode, nodes);
                }
            }

            return(nodes);
        }
예제 #8
0
        public bool IsItemUnderTreeID(int treeID, int itemTreeID)
        {
            if (treeID == itemTreeID)
            {
                return(true);
            }

            DatastoreItemList storeItemList = GetStoreItemList();

            if (storeItemList != null)
            {
                ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct);
                Node startingNode           = rootNode.FindNodeInSubtree(treeID);
                if (startingNode != null)
                {
                    return(IsItemUnderTreeNode(startingNode, itemTreeID));
                }
            }

            return(false);
        }
예제 #9
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Given a path in this store's tree hierarchy, returns the treeID for that path.  If
        /// the path isn't found, zero will be returned.
        /// </summary>
        //------------------------------------------------------------------------------------
        public int GetTreePathID(string treePath)
        {
            if (treePath == null)
            {
                return(0);
            }

            DatastoreItemList storeItemList = GetStoreItemList();

            if (storeItemList == null)
            {
                return(0);
            }

            char[] trim = { '\\' };
            treePath = treePath.Trim(trim);
            ProductStudio.Node currentNode = storeItemList.Datastore.get_RootNodeEx(ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct);
            string[]           pathNodes   = treePath.Split('\\');
            foreach (string pathNode in pathNodes)
            {
                bool foundNode = false;
                foreach (Node node in currentNode.Nodes)
                {
                    if (node.Name == pathNode)
                    {
                        currentNode = node;
                        foundNode   = true;
                        break;
                    }
                }

                if (!foundNode)
                {
                    return(0);
                }
            }

            return(currentNode.ID);
        }
예제 #10
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Executes the given query against this data store.  Returns false if a cancellation
        /// request is detected via the given taskWorker.
        /// </summary>
        //------------------------------------------------------------------------------------
        public BackgroundTaskResult ExecuteQuery(IRepository repository, BaseQuery query, ShouldRefresh shouldRefresh, BackgroundTask taskWorker, bool deferItemCreation)
        {
            DatastoreItemList storeItemList = GetStoreItemList();
            FieldDefinitions  fieldDefs     = storeItemList.Datastore.FieldDefinitions;

            // Set up a query, using QueryDefinition to define the query XML
            ProductStudio.Query psQuery = new ProductStudio.Query();
            psQuery.CountOnly         = false;
            psQuery.DatastoreItemType = PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs;
            psQuery.SelectionCriteria = query.QueryXml;

            psQuery.QueryFields.Clear();
            psQuery.QuerySortFields.Clear();
            psQuery.QuerySortFields.Add(fieldDefs["ID"], PsSortTypeEnum.psSortTypeDescending);

            // Execute the query
            try
            {
                storeItemList.Query = psQuery;
                storeItemList.Execute();
            }

            catch (Exception e)
            {
                return(new BackgroundTaskResult {
                    ResultType = ResultType.Failed, ResultMessage = e.Message
                });
            }

            Planner.Instance.WriteToEventLog(StoreName + ": Query results count: " + storeItemList.DatastoreItems.Count.ToString());

            repository.ReceiveDSItems(this, storeItemList.DatastoreItems, shouldRefresh, deferItemCreation);

            return(new BackgroundTaskResult {
                ResultType = ResultType.Completed
            });
        }
예제 #11
0
        public Int32 CreateNewBug(string psFieldDefXml)
        {
            bool hasInvalidField = false;

            // Create a new datastore instance
            DatastoreItemList psDataList = new DatastoreItemList();

            psDataList.Datastore = this.psDataStore;

            // Craete a blank bug
            psDataList.CreateBlank(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs);
            DatastoreItem psDataItem = psDataList.DatastoreItems.Add(null, PsApplyRulesMask.psApplyRulesAll);

            // Set fields for the new bug
            Fields psFields = psDataItem.Fields;


            // New PS Bug Field Description XML file will look like
            // =======================================================
            // <psfieldDef>
            //     <Title>
            //         Title (Ex. RFH: Hotfix for ...)
            //     </Title>
            //     <Tree Path>
            //         Path (Ex. SCCM 2007 SP2)
            //     </Tree Path>
            //     <Issue type>
            //         Issue Type (Ex. RFH / CDCR)
            //     </Issue type>
            //     <Get Help>
            //         Get Help (Ex. Yes / No)
            //     </Get Help>
            //     <Priority>
            //         Priority (Ex. 1, 2, 3, 4)
            //     </Priority>
            //     <Severity>
            //         Severity (Ex. 1, 2, 3, 4)
            //     </Severity>
            //     <SMS Product>
            //         SMS Product (Ex. x86 / x64)
            //     </SMS Product>
            //     <Component>
            //         Component (Ex. component name)
            //     </Component>
            //     <FeatureArea>
            //         Feature Area (Ex. feature area name)
            //     </FeatureArea>
            //     <Open Build>
            //         Open Build (Ex. build version 6487.2000)
            //     </Open Build>
            //     <Language>
            //         Language (Ex. ENU)
            //     </Language>
            //     <How found>
            //         How Found (Ex. Internal)
            //     </How found>
            //     <Source>
            //         Source (Ex. Ad Hoc)
            //     </Source>
            //     <Source ID>
            //         Source ID (ex. Airforce)
            //     </Source ID>
            //     <PSS>
            //         SR Number (ex. SR Number)
            //     </PSS>
            //     <KB Article>
            //         KB Number (ex. KB Number 98765432)
            //     </KB Article>
            //     <Repro Steps>
            //         Repro Steps (ex. Repro Steps)
            //     </Repro Steps>
            //     <Description>
            //         Description (ex. Description)
            //     </Description>
            //     <Related Bugs>
            //         SMS Sustained Engineering:5991
            //     </Related Bugs>
            //     <QFE Status>
            //         Core Review
            //     </QFE Status>
            // </psfieldDef>
            XmlReader xmlReader = XmlReader.Create(new StringReader(psFieldDefXml));

            while (xmlReader.Read())
            {
                if (xmlReader.NodeType == XmlNodeType.Element)
                {
                    if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "psfieldDef", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.Read(); // Read psfieldDef
                    }
                    else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Tree Path", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.ReadStartElement(xmlReader.Name); // Read <Tree Path>
                        psFields["TreeID"].Value = this.GetTreeIDFromTreePath(this.psDataStore.RootNode, xmlReader.Value);
                        xmlReader.Read();
                        xmlReader.ReadEndElement();
                    }
                    else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Related Bugs", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.ReadStartElement(xmlReader.Name); // Read <RelatedBugs>
                        string product = xmlReader.Value.Substring(0, xmlReader.Value.IndexOf(':'));
                        Int32  bugId   = 0;
                        Int32.TryParse(xmlReader.Value.Substring(xmlReader.Value.IndexOf(':') + 1), out bugId);
                        ((Bug)psDataItem).AddRelatedLink(bugId, product);
                        xmlReader.Read();
                        xmlReader.ReadEndElement();
                    }
                    else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "File", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.ReadStartElement(xmlReader.Name); // Read <File>
                        ((Bug)psDataItem).Files.Add(xmlReader.Value);
                        xmlReader.Read();
                        xmlReader.ReadEndElement();
                    }
                    else
                    {
                        string fieldName = XmlConvert.DecodeName(xmlReader.Name);
                        xmlReader.ReadStartElement(xmlReader.Name); // Read Start Element Ex. <Title>
                        psFields[fieldName].Value = xmlReader.Value;
                        xmlReader.Read();
                        xmlReader.ReadEndElement(); // Read End Element Ex. </Title>
                    }
                }
            }

            //  Let's make sure all fields are valid before saving
            foreach (Field psField in psDataItem.Fields)
            {
                if (psField.Validity != PsFieldStatusEnum.psFieldStatusValid)
                {
                    hasInvalidField = true;
                    throw new Exception("Invalid Field (" + psField.Name + ") with Value (" + psField.Value + "). Counld not new bug!");
                }
            }

            if (hasInvalidField)
            {
                throw (new ApplicationException("Invalid Field(s) were found.  Could not create new bug."));
            }
            else
            {
                psDataItem.Save(true);
                return(Convert.ToInt32(psFields["ID"].Value));
            }
        }
예제 #12
0
        /// <summary>
        /// Get changed BUGs from last modified time
        /// </summary>
        /// <param name="LastModifiedTime"></param>
        /// <returns></returns>
        public DatastoreItems GetBugListStartingFrom(DateTime LastModifiedTime)
        {
            string psQueryXml = "<Query>";
            psQueryXml += "<Group GroupOperator='And'>";
            psQueryXml += "<Expression Column='Changed Date' Operator='equalsGreater'><DateTime>" + LastModifiedTime.ToUniversalTime().ToString() + "</DateTime></Expression>";
            //psQueryXml += "<Expression Column='Status' Operator='notequals'><String>Closed</String></Expression>";
            psQueryXml += "</Group>";
            psQueryXml += "</Query>";

            DatastoreItemList psDataList = null;
            try
            {
                Query psQuery = new Query();
                psQuery.CountOnly = false;
                psQuery.SelectionCriteria = psQueryXml;

                psDataList = new DatastoreItemList();
                psDataList.Query = psQuery;
                psDataList.Datastore = this.psDataStore;
                psDataList.Execute();
            }
            catch (Exception e)
            {
                throw new Exception(String.Format("Failed to Query bugs."), e);
            }

            return psDataList.DatastoreItems;
        }
예제 #13
0
        public Int32 CreateNewBug(string psFieldDefXml)
        {
            bool hasInvalidField = false;

            // Create a new datastore instance
            DatastoreItemList psDataList = new DatastoreItemList();
            psDataList.Datastore = this.psDataStore;

            // Craete a blank bug
            psDataList.CreateBlank(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs);
            DatastoreItem psDataItem = psDataList.DatastoreItems.Add(null, PsApplyRulesMask.psApplyRulesAll);

            // Set fields for the new bug
            Fields psFields = psDataItem.Fields;

            // New PS Bug Field Description XML file will look like
            // =======================================================
            // <psfieldDef>
            //     <Title>
            //         Title (Ex. RFH: Hotfix for ...)
            //     </Title>
            //     <Tree Path>
            //         Path (Ex. SCCM 2007 SP2)
            //     </Tree Path>
            //     <Issue type>
            //         Issue Type (Ex. RFH / CDCR)
            //     </Issue type>
            //     <Get Help>
            //         Get Help (Ex. Yes / No)
            //     </Get Help>
            //     <Priority>
            //         Priority (Ex. 1, 2, 3, 4)
            //     </Priority>
            //     <Severity>
            //         Severity (Ex. 1, 2, 3, 4)
            //     </Severity>
            //     <SMS Product>
            //         SMS Product (Ex. x86 / x64)
            //     </SMS Product>
            //     <Component>
            //         Component (Ex. component name)
            //     </Component>
            //     <FeatureArea>
            //         Feature Area (Ex. feature area name)
            //     </FeatureArea>
            //     <Open Build>
            //         Open Build (Ex. build version 6487.2000)
            //     </Open Build>
            //     <Language>
            //         Language (Ex. ENU)
            //     </Language>
            //     <How found>
            //         How Found (Ex. Internal)
            //     </How found>
            //     <Source>
            //         Source (Ex. Ad Hoc)
            //     </Source>
            //     <Source ID>
            //         Source ID (ex. Airforce)
            //     </Source ID>
            //     <PSS>
            //         SR Number (ex. SR Number)
            //     </PSS>
            //     <KB Article>
            //         KB Number (ex. KB Number 98765432)
            //     </KB Article>
            //     <Repro Steps>
            //         Repro Steps (ex. Repro Steps)
            //     </Repro Steps>
            //     <Description>
            //         Description (ex. Description)
            //     </Description>
            //     <Related Bugs>
            //         SMS Sustained Engineering:5991
            //     </Related Bugs>
            //     <QFE Status>
            //         Core Review
            //     </QFE Status>
            // </psfieldDef>
            XmlReader xmlReader = XmlReader.Create(new StringReader(psFieldDefXml));

            while (xmlReader.Read())
            {
                if (xmlReader.NodeType == XmlNodeType.Element)
                {
                    if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "psfieldDef", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.Read(); // Read psfieldDef
                    }
                    else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Tree Path", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.ReadStartElement(xmlReader.Name); // Read <Tree Path>
                        psFields["TreeID"].Value = this.GetTreeIDFromTreePath(this.psDataStore.RootNode, xmlReader.Value);
                        xmlReader.Read();
                        xmlReader.ReadEndElement();
                    }
                    else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Related Bugs", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.ReadStartElement(xmlReader.Name); // Read <RelatedBugs>
                        string product = xmlReader.Value.Substring(0, xmlReader.Value.IndexOf(':'));
                        Int32 bugId = 0;
                        Int32.TryParse(xmlReader.Value.Substring(xmlReader.Value.IndexOf(':') + 1), out bugId);
                        ((Bug)psDataItem).AddRelatedLink(bugId, product);
                        xmlReader.Read();
                        xmlReader.ReadEndElement();
                    }
                    else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "File", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        xmlReader.ReadStartElement(xmlReader.Name); // Read <File>
                        ((Bug)psDataItem).Files.Add(xmlReader.Value);
                        xmlReader.Read();
                        xmlReader.ReadEndElement();
                    }
                    else
                    {
                        string fieldName = XmlConvert.DecodeName(xmlReader.Name);
                        xmlReader.ReadStartElement(xmlReader.Name); // Read Start Element Ex. <Title>
                        psFields[fieldName].Value = xmlReader.Value;
                        xmlReader.Read();
                        xmlReader.ReadEndElement(); // Read End Element Ex. </Title>
                    }
                }
            }

            //  Let's make sure all fields are valid before saving
            foreach (Field psField in psDataItem.Fields)
            {
                if (psField.Validity != PsFieldStatusEnum.psFieldStatusValid)
                {
                    hasInvalidField = true;
                    throw new Exception("Invalid Field (" + psField.Name + ") with Value (" + psField.Value + "). Counld not new bug!");
                }
            }

            if (hasInvalidField)
            {
                throw (new ApplicationException("Invalid Field(s) were found.  Could not create new bug."));
            }
            else
            {
                psDataItem.Save(true);
                return Convert.ToInt32(psFields["ID"].Value);
            }
        }
예제 #14
0
        //------------------------------------------------------------------------------------
        /// <summary>
        /// Pulls the DatastoreItem with the given ID from the backing store.
        /// </summary>
        //------------------------------------------------------------------------------------
        private DatastoreItem DSItemByID(int itemID)
        {
            DatastoreItemList storeItemList = GetStoreItemList(false);

            return(storeItemList.Datastore.GetDatastoreItem(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs, itemID));
        }
예제 #15
0
        //Details
        //http://bgit/applications/help/productstudiosdk/default.asp?URL=PSSDK_Main.htm

        public static int FileABug(string title, string reproSteps, string expectedResult, string actualResult, string attachmentFolder)
        {
            int               bugID           = 0;
            bool              hasInvalidField = false;
            Directory         psDirectory     = null;
            Product           psProduct       = null;
            Datastore         psDataStore     = null;
            Fields            psFields        = null;
            DatastoreItemList psDataList      = null;
            DatastoreItem     psDataItem      = null;
            Bug               psBug           = null;

            // Specify the product database to use and the domain in which
            // the database is located.
            string strProductName = "Office15";
            string strDomain1     = "fareast.corp.microsoft.com";
            string strDomain2     = "redmond.corp.microsoft.com";
            string strDomain3     = "corp.microsoft.com";

            try
            {
                //
                // Connect to the directory with your current domain under your credentials .
                //
                psDirectory = new Directory();

                try
                {
                    //first try with fareast
                    psDirectory.Connect(strDomain1, "", "");
                }
                catch (Exception e1)
                {
                    Console.WriteLine("Fareast Connect Error: {0}", e1.Message);

                    try
                    {
                        //if fareast fails, try redmond
                        psDirectory.Connect(strDomain2, "", "");
                    }
                    catch (Exception e2)
                    {
                        Console.WriteLine("Redmond Connect Error: {0}", e2.Message);

                        //if both fareast & redmond fail, try global domain
                        psDirectory.Connect(strDomain3, "", "");
                    }
                }

                psProduct   = psDirectory.GetProductByName(strProductName);
                psDataStore = psProduct.Connect("", "", "");

                //
                // Bind the query and Datastore to our DatastoreItemList.
                //
                psDataList           = new DatastoreItemList();
                psDataList.Datastore = psDataStore;

                //
                // Create a blank bug
                //
                psDataList.CreateBlank(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs);
                psDataItem = psDataList.DatastoreItems.Add(null, PsApplyRulesMask.psApplyRulesAll);
                psBug      = psDataItem as Bug;

                //
                // Set fields for the new bug
                //
                psFields = psBug.Fields;

                psFields["Title"].Value       = "[LWA]" + title;
                psFields["TreeID"].Value      = TreeIDFromPath(psDataStore.RootNode, "Current\\Lync Client\\Lync Web App");
                psFields["Assigned to"].Value = "Active";
                psFields["Severity"].Value    = 2;
                psFields["Priority"].Value    = 2;
                psFields["Open Build"].Value  = "5.0.0000.0000";
                psFields["Ship Cycle"].Value  = "O15 Main Wave";
                psFields["Fix By"].Value      = "Beta1Refresh";

                psFields["Repro Steps"].Value =
                    "Repro Steps:" + Environment.NewLine +
                    "============" + Environment.NewLine +
                    (string.IsNullOrEmpty(reproSteps) ? "1. Sign in as User A from LWA" : reproSteps) + Environment.NewLine +
                    Environment.NewLine +
                    "Actual Results:" + Environment.NewLine +
                    "===============" + Environment.NewLine +
                    (string.IsNullOrEmpty(actualResult) ? "1. " : actualResult) + Environment.NewLine +
                    Environment.NewLine +
                    "Expected Results:" + Environment.NewLine +
                    "=================" + Environment.NewLine +
                    (string.IsNullOrEmpty(expectedResult) ? "1. " : expectedResult) + Environment.NewLine;

                //
                //  Let's make sure all fields are valid before saving
                //
                foreach (ProductStudio.Field psField in psBug.Fields)
                {
                    if (psField.Validity != PsFieldStatusEnum.psFieldStatusValid)
                    {
                        hasInvalidField = true;
                        Console.WriteLine("Invalid Field '{0}': {1}", psField.Name, psField.Validity.ToString());
                        Console.WriteLine("Current Value: '{0}'", psField.Value);
                        Console.WriteLine();
                    }
                }

                if (hasInvalidField)
                {
                    throw (new ApplicationException("Invalid Field(s) were found.  Could not create."));
                }
                else
                {
                    if (!string.IsNullOrEmpty(attachmentFolder))
                    {
                        string[] files = System.IO.Directory.GetFiles(attachmentFolder);
                        foreach (string file in files)
                        {
                            psBug.Files.Add(file, false);
                        }
                    }

                    psBug.Save(true);
                    bugID = Convert.ToInt32(psFields["ID"].Value);
                    Console.WriteLine("Bug #{0} Successfully Created.", bugID);
                }
            }
            catch (Exception e3)
            {
                Console.WriteLine("Error: {0}", e3.Message);
            }
            finally
            {
                if (null != psDirectory)
                {
                    try
                    {
                        psDirectory.Disconnect();
                    }
                    catch (Exception e4)
                    {
                        Console.WriteLine("Disconnect Error: {0}", e4.Message);
                    }
                }
            }

            return(bugID);
        }