/// <summary>
        /// Converts an array of OPCCONDITIONSTATE structs to an array of Condition objects.
        /// </summary>
        internal static Technosoftware.DaAeHdaClient.Ae.TsCAeCondition[] GetConditions(ref IntPtr pInput, int count, bool deallocate)
        {
            Technosoftware.DaAeHdaClient.Ae.TsCAeCondition[] output = null;

            if (pInput != IntPtr.Zero && count > 0)
            {
                output = new Technosoftware.DaAeHdaClient.Ae.TsCAeCondition[count];

                IntPtr pos = pInput;

                for (int ii = 0; ii < count; ii++)
                {
                    OpcRcw.Ae.OPCCONDITIONSTATE condition = (OpcRcw.Ae.OPCCONDITIONSTATE)Marshal.PtrToStructure(pos, typeof(OpcRcw.Ae.OPCCONDITIONSTATE));

                    output[ii] = new Technosoftware.DaAeHdaClient.Ae.TsCAeCondition();

                    output[ii].State             = condition.wState;
                    output[ii].Quality           = new TsCDaQuality(condition.wQuality);
                    output[ii].Comment           = condition.szComment;
                    output[ii].AcknowledgerID    = condition.szAcknowledgerID;
                    output[ii].CondLastActive    = Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(Convert(condition.ftCondLastActive));
                    output[ii].CondLastInactive  = Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(Convert(condition.ftCondLastInactive));
                    output[ii].SubCondLastActive = Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(Convert(condition.ftSubCondLastActive));
                    output[ii].LastAckTime       = Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(Convert(condition.ftLastAckTime));

                    output[ii].ActiveSubCondition.Name        = condition.szActiveSubCondition;
                    output[ii].ActiveSubCondition.Definition  = condition.szASCDefinition;
                    output[ii].ActiveSubCondition.Severity    = condition.dwASCSeverity;
                    output[ii].ActiveSubCondition.Description = condition.szASCDescription;

                    // unmarshal sub-conditions.
                    string[] names        = Technosoftware.DaAeHdaClient.Com.Interop.GetUnicodeStrings(ref condition.pszSCNames, condition.dwNumSCs, deallocate);
                    int[]    severities   = Technosoftware.DaAeHdaClient.Com.Interop.GetInt32s(ref condition.pdwSCSeverities, condition.dwNumSCs, deallocate);
                    string[] definitions  = Technosoftware.DaAeHdaClient.Com.Interop.GetUnicodeStrings(ref condition.pszSCDefinitions, condition.dwNumSCs, deallocate);
                    string[] descriptions = Technosoftware.DaAeHdaClient.Com.Interop.GetUnicodeStrings(ref condition.pszSCDescriptions, condition.dwNumSCs, deallocate);

                    output[ii].SubConditions.Clear();

                    if (condition.dwNumSCs > 0)
                    {
                        for (int jj = 0; jj < names.Length; jj++)
                        {
                            TsCAeSubCondition subcondition = new TsCAeSubCondition();

                            subcondition.Name        = names[jj];
                            subcondition.Severity    = severities[jj];
                            subcondition.Definition  = definitions[jj];
                            subcondition.Description = descriptions[jj];

                            output[ii].SubConditions.Add(subcondition);
                        }
                    }

                    // unmarshal attributes.
                    object[] values = Technosoftware.DaAeHdaClient.Com.Interop.GetVARIANTs(ref condition.pEventAttributes, condition.dwNumEventAttrs, deallocate);
                    int[]    errors = Technosoftware.DaAeHdaClient.Com.Interop.GetInt32s(ref condition.pErrors, condition.dwNumEventAttrs, deallocate);

                    output[ii].Attributes.Clear();

                    if (condition.dwNumEventAttrs > 0)
                    {
                        for (int jj = 0; jj < values.Length; jj++)
                        {
                            Technosoftware.DaAeHdaClient.Ae.TsCAeAttributeValue attribute = new Technosoftware.DaAeHdaClient.Ae.TsCAeAttributeValue();

                            attribute.ID     = 0;
                            attribute.Value  = values[jj];
                            attribute.Result = Technosoftware.DaAeHdaClient.Com.Ae.Interop.GetResultID(errors[jj]);

                            output[ii].Attributes.Add(attribute);
                        }
                    }

                    // deallocate structure.
                    if (deallocate)
                    {
                        Marshal.DestroyStructure(pos, typeof(OpcRcw.Ae.OPCCONDITIONSTATE));
                    }

                    pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Ae.OPCCONDITIONSTATE)));
                }

                // deallocate array.
                if (deallocate)
                {
                    Marshal.FreeCoTaskMem(pInput);
                    pInput = IntPtr.Zero;
                }
            }

            return(output);
        }