/// <summary>
        /// Graph object <paramref name="o"/> onto stream <paramref name="s"/>
        /// </summary>
        /// <param name="s">The stream to graph to</param>
        /// <param name="o">The object to graph to</param>
        public ResultCode GraphObject(System.IO.Stream s, MARC.Everest.Interfaces.IGraphable o)
        {
            var result = Graph(s, o);

            this.Details = result.Details;
            return(result.Code);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Send a request to the remote endpoint with the specified message headers
        /// </summary>
        /// <param name="data">The data to be sent to the remote endpoint</param>
        /// <param name="headers">The SOAP headers to append to the request</param>
        /// <returns>A <see cref="T:MARC.Everest.Connectors.WCF.WcfSendResult"/> instance containing the result of the send operation</returns>
        public ISendResult Send(MARC.Everest.Interfaces.IGraphable data, MessageHeaders headers)
        {
            //TODO: Convert this into a method call for reuability.
            // Formatter check
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen);
            }

            // Create the work that will perform the operations
            Worker w = new Worker();

            w.Formatter = (IXmlStructureFormatter)Formatter;
#if WINDOWS_PHONE
            w.Actions = this.m_actions;
#else
            w.WcfConfiguration = wcfConfiguration;
#endif
            w.MessageVersion = wcfClient.Endpoint.Binding.MessageVersion;
            w.CustomHeaders  = headers;
            // Work
            w.WorkSend(data);

            // Send over the channel
            if (w.SendResult.Code == ResultCode.Accepted ||
                w.SendResult.Code == ResultCode.AcceptedNonConformant)
            {
                lock (results)
                    results.Add(w.SendResult, wcfClient.ProcessInboundMessage(w.SendResult.Message));
            }

            // Return the result
            return(w.SendResult);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Send a response back to the remote endpoint.
        /// </summary>
        /// <param name="data">The data to send back.</param>
        /// <param name="correlate">The result to correlate this response with.</param>
        /// <returns>A send result structure that details the result of the send operation.</returns>
        public ISendResult Send(MARC.Everest.Interfaces.IGraphable data, IReceiveResult correlate)
        {
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen);
            }

            Worker w       = new Worker();
            var    cresult = correlate as WcfReceiveResult;

            w.MessageId       = cresult.MessageIdentifier;
            w.MessageVersion  = cresult.MessageVersion; // Prepare
            w.Formatter       = (IXmlStructureFormatter)Formatter;
            w.ResponseHeaders = cresult.ResponseHeaders;
            w.InvalidResponse = InvalidResponse;

            w.WorkSend(data); // Work

            // Publish so WCF connector can send a result
            lock (results)
                results.Add(w.MessageId, w.SendResult);

            // Notify
            PublishResult(w.MessageId);

            // Return result
            return(w.SendResult);
        }
        /// <summary>
        /// Send the structure <paramref name="data"/> to the file system.
        /// </summary>
        /// <param name="data">The <see cref="MARC.Everest.Interfaces.IGraphable"/> data to be sent.</param>
        /// <returns>The result of the send operation.</returns>
        /// <example>
        /// Get the result of a send operation
        /// <code>
        /// FileSendResult result = conn.Send(instance);
        /// if(result.Code != ResultCode.Accepted) // Result was not successful
        ///     foreach(IResultDetail dtl in result.Details)
        ///         Console.WriteLine(dtl.Message);
        ///         </code>
        /// </example>
        /// <seealso cref="BeginSend"/>
        public ISendResult Send(MARC.Everest.Interfaces.IGraphable data)
        {
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen);
            }

            // Setup the Worker
            Worker w = new Worker();

            w.Formatter  = (IStructureFormatter)this.Formatter.Clone();
            w.TargetFile = GenerateTargetFile(data);
            w.Work(data);

            return(w.Result);
        }
Exemplo n.º 5
0
        public IAsyncResult BeginSend(MARC.Everest.Interfaces.IGraphable data, IReceiveResult correlate, AsyncCallback callback, object state)
        {
            // Formatter check
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen);
            }

            // Setup wroker
            Worker w = new Worker();

            // Create a new instance of the formatter
            w.Formatter = (IXmlStructureFormatter)Formatter;
            var cresult = correlate as WcfReceiveResult;

            w.MessageId       = (correlate as WcfReceiveResult).MessageIdentifier;
            w.MessageVersion  = (correlate as WcfReceiveResult).MessageVersion;
            w.InvalidResponse = InvalidResponse;
            w.ResponseHeaders = cresult.ResponseHeaders;

            // Set async result
            IAsyncResult Result = new SendResultAsyncResult(state, new AutoResetEvent(false));

            // Completed delegate
            w.Completed += delegate(object Sender)
            {
                Worker sWorker = Sender as Worker; // Strong type sender
                // Lookup the result in the dictionary
                if (!asyncResults.ContainsKey(Result))
                {
                    lock (asyncResults) { asyncResults.Add(Result, sWorker.SendResult); }
                }
                (Result as SendResultAsyncResult).SetComplete();  // Set completed
                (Result.AsyncWaitHandle as AutoResetEvent).Set(); // send signal
                if (callback != null)
                {
                    callback(Result);                   // callback
                }
            };

            // Add to thread pool
            ThreadPool.QueueUserWorkItem(new WaitCallback(w.WorkSend), data);

            return(Result);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Publish a message to the currently opened queue
        /// </summary>
        /// <param name="data">The data to publish to the queue</param>
        /// <returns>A <see cref="ISendResult"/> structure representing the result of the send operation </returns>
        public ISendResult Send(MARC.Everest.Interfaces.IGraphable data)
        {
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen);
            }

            // Send
            Worker w = new Worker();

            w.Formatter = Formatter.Clone() as IStructureFormatter;
            w.Queue     = queue;

            // Perform the work
            w.Work(data);

            return(w.Result);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Synchronous send operation
        /// </summary>
        /// <param name="data">The data to send</param>
        /// <returns>The result of the send operation</returns>
        public ISendResult Send(MARC.Everest.Interfaces.IGraphable data)
        {
            // Good practice to check if the connector is open
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen, null);
            }

            // Create a new worker
            Worker w = new Worker();

            // Always clone the current formatter
            w.Formatter = (IStructureFormatter)Formatter.Clone();

            // Perform the work
            w.Work(data);

            return(w.Result);
        }
Exemplo n.º 8
0
        public IAsyncResult BeginSend(MARC.Everest.Interfaces.IGraphable data, AsyncCallback callback, object state)
        {
            // Formatter check
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen);
            }

            // Create the work that will perform the operations
            Worker w = new Worker();

            w.Formatter = (IXmlStructureFormatter)Formatter;

#if !WINDOWS_PHONE
            w.WcfConfiguration = wcfConfiguration;
#endif
            w.MessageVersion = wcfClient.Endpoint.Binding.MessageVersion;

            // Result
            IAsyncResult result = new SendResultAsyncResult(state, new AutoResetEvent(false));

            // Work
            w.Completed += new WaitCallback(delegate(object sender)
            {
                lock (results)
                    results.Add((sender as Worker).SendResult, wcfClient.ProcessInboundMessage((sender as Worker).SendResult.Message));
                lock (asyncResults)
                    asyncResults.Add(result, (sender as Worker).SendResult);
                (result.AsyncWaitHandle as AutoResetEvent).Set();
                if (callback != null)
                {
                    callback(result);
                }
            });

            ThreadPool.QueueUserWorkItem(w.WorkSend, data);

            // Return the result
            return(result);
        }
        /// <summary>
        /// Starts an asynchronous send to the file system.
        /// </summary>
        /// <param name="data">The <see cref="MARC.Everest.Interfaces.IGraphable"/> data to be sent.</param>
        /// <param name="callback">The callback to execute when the send is complete.</param>
        /// <param name="state">An object representing state.</param>
        /// <returns>An instance of a callback pointer.</returns>
        /// <example>
        /// Sending an instance asynchronously using a wait handle
        /// <code>
        /// IAsyncResult sendResult = conn.BeginSend(instance, null, null);
        /// sendResult.AsyncWaitHandle.WaitOne(); // Wait for send to finish
        /// FileSendResult result = conn.EndSend(sendResult);
        /// if(result.Code != ResultCode.Accepted) // Result was not successful
        ///     foreach(IResultDetail dtl in result.Details)
        ///         Console.WriteLine(dtl.Message);
        /// </code>
        /// </example>
        /// <seealso cref="Send"/>
        public IAsyncResult BeginSend(MARC.Everest.Interfaces.IGraphable data, AsyncCallback callback, object state)
        {
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen);
            }

            // Setup wroker
            Worker w = new Worker();

            // Create a new instance of the formatter
            w.Formatter  = Formatter.Clone() as IStructureFormatter;
            w.TargetFile = GenerateTargetFile(data);

            // Set async result
            IAsyncResult Result = new SendResultAsyncResult(state, new AutoResetEvent(false));

            // Completed delegate
            w.Completed += delegate(object Sender)
            {
                Worker sWorker = Sender as Worker; // Strong type sender
                // Lookup the result in the dictionary
                if (!asyncResults.ContainsKey(Result))
                {
                    lock (asyncResults) { asyncResults.Add(Result, sWorker.Result); }
                }
                (Result as SendResultAsyncResult).SetComplete();  // Set completed
                (Result.AsyncWaitHandle as AutoResetEvent).Set(); // send signal
                if (callback != null)
                {
                    callback(Result);                   // callback
                }
            };

            // Add to thread pool
            ThreadPool.QueueUserWorkItem(new WaitCallback(w.Work), data);

            return(Result);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Asynchronous send operation
        /// </summary>
        /// <param name="data">The data being sent</param>
        /// <param name="callback">A callback to execute when the method is complete</param>
        /// <param name="state">A user state</param>
        /// <returns>An IAsyncResult representing the asynchronous operation</returns>
        public IAsyncResult BeginSend(MARC.Everest.Interfaces.IGraphable data, AsyncCallback callback, object state)
        {
            // Good practice to check if the connector is open
            if (!IsOpen())
            {
                throw new ConnectorException(ConnectorException.MSG_INVALID_STATE, ConnectorException.ReasonType.NotOpen, null);
            }

            // Create a new worker
            Worker w = new Worker();

            // Always clone the current formatter
            w.Formatter = (IStructureFormatter)Formatter.Clone();

            // Create the async result
            IAsyncResult result = new SendResultAsyncResult(state, new AutoResetEvent(false));

            // Set the callback
            w.Completed += new WaitCallback(delegate(object sender)
            {
                Worker sWorker = sender as Worker;

                // Set the result in the dictionary
                lock (this.results)
                    this.results.Add(result, sWorker.Result);

                // Notify any listeners
                (result.AsyncWaitHandle as AutoResetEvent).Set();
                if (callback != null)
                {
                    callback(result);
                }
            });

            // Execute
            ThreadPool.QueueUserWorkItem(w.Work, data);

            return(result);
        }
Exemplo n.º 11
0
 /// <summary>
 /// Start an asynchronous send operation
 /// </summary>
 /// <param name="data">The data to publish to the queue</param>
 /// <param name="callback">An <see cref="AsyncCallback"/> delegate to call when the operation is completed</param>
 /// <param name="state">An object representing user state</param>
 /// <returns>An <see cref="IAsyncResult"/> structure that represent the asynchronous method</returns>
 public IAsyncResult BeginSend(MARC.Everest.Interfaces.IGraphable data, AsyncCallback callback, object state)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 12
0
 /// <summary>
 /// Send a request to the remote endpoint.
 /// </summary>
 /// <param name="data">The IGraphable data to send.</param>
 public ISendResult Send(MARC.Everest.Interfaces.IGraphable data)
 {
     return(Send(data, null));
 }
Exemplo n.º 13
0
        /// <summary>
        /// Validates the specified object
        /// </summary>
        public bool Validate(MARC.Everest.Interfaces.IGraphable o, string location, out MARC.Everest.Connectors.IResultDetail[] details)
        {
            List <IResultDetail> dtls = new List <IResultDetail>(10);
            bool isValid = true;

            // Null return bool
            if (o == null)
            {
                details = dtls.ToArray();
                return(true);
            }

            PropertyInfo nullFlavorAttrib = o.GetType().GetProperty("NullFlavor");

            if (nullFlavorAttrib != null && nullFlavorAttrib.GetValue(o, null) != null)
            {
                details = dtls.ToArray();
                return(true);
            }

            // Scan property info for violations
            foreach (var pi in this.GetBuildProperties(o.GetType()))
            {
                if (pi.GetGetMethod().GetParameters().Length != 0)
                {
                    dtls.Add(new NotImplementedResultDetail(
                                 ResultDetailType.Warning,
                                 String.Format("Could not validate '{0}' as the property is indexed", pi.Name),
                                 location
                                 ));
                    continue;
                }

                object   piValue        = pi.GetValue(o, null);
                object[] propAttributes = pi.GetCustomAttributes(typeof(PropertyAttribute), true);

                if (propAttributes.Length > 0)
                {
                    PropertyAttribute pa = propAttributes[0] as PropertyAttribute;
                    if (pa.Conformance == PropertyAttribute.AttributeConformanceType.Mandatory &&
                        pi.PropertyType.GetInterface(typeof(IImplementsNullFlavor).FullName, false) != null &&
                        (piValue == null || (piValue as IImplementsNullFlavor).NullFlavor != null))
                    {
                        isValid = false;
                        dtls.Add(new MandatoryElementMissingResultDetail(ResultDetailType.Error, String.Format("Property {0} in {1} is marked mandatory and is either not assigned, or is assigned a null flavor. This is not permitted.", pi.Name, o.GetType().FullName), location));
                    }
                    else if (pa.Conformance == PropertyAttribute.AttributeConformanceType.Populated && piValue == null)
                    {
                        isValid &= Host.CreateRequiredElements;
                        dtls.Add(new RequiredElementMissingResultDetail(isValid ? ResultDetailType.Warning : ResultDetailType.Error, String.Format("Property {0} in {1} is marked 'populated' and isn't assigned (you must at minimum, assign a nullFlavor for this attribute)!", pi.Name, o.GetType().FullName), location));
                    }
                    else if (pa.MinOccurs != 0)
                    {
                        int minOccurs    = pa.MinOccurs,
                            maxOccurs    = pa.MaxOccurs < 0 ? Int32.MaxValue : pa.MaxOccurs;
                        var piCollection = piValue as ICollection;
                        if (piCollection != null && (piCollection.Count > maxOccurs || piCollection.Count < minOccurs))
                        {
                            isValid = false;
                            dtls.Add(new InsufficientRepetitionsResultDetail(ResultDetailType.Error, String.Format("Property {0} in {2} does not have enough elements in the list, need between {1} and {3} elements!", pi.Name, minOccurs, o.GetType().FullName, maxOccurs), location));
                        }
                    }
                }
            }

            details = dtls.ToArray();
            return(isValid);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Graphs an object to the specified stream
        /// </summary>
        public void Graph(System.Xml.XmlWriter s, object o, MARC.Everest.Interfaces.IGraphable context, XmlIts1FormatterGraphResult resultContext)
        {
            ResultCode rc           = ResultCode.Accepted;
            Type       instanceType = o.GetType();

            // Verify o is not null
            if (o == null)
            {
                throw new System.ArgumentNullException("o");
            }

            // Attempt to get null flavor

            var  nfp            = o.GetType().GetProperty("NullFlavor");
            bool isInstanceNull = false,
                 isEntryPoint   = false;

            if (nfp != null)
            {
                isInstanceNull = nfp.GetValue(o, null) != null;
            }

            // Interaction?
            object[]           structureAttributes = instanceType.GetCustomAttributes(typeof(StructureAttribute), false);
            StructureAttribute structureAttribute  = structureAttributes[0] as StructureAttribute;

            if (structureAttribute.StructureType == StructureAttribute.StructureAttributeType.Interaction)
            {
                isEntryPoint = true;
                s.WriteStartElement(structureAttribute.Name, structureAttribute.NamespaceUri);
                s.WriteAttributeString("ITSVersion", "XML_1.0"); // Add ITS version
                s.WriteAttributeString("xmlns", "xsi", null, XmlIts1Formatter.NS_XSI);
            }
            else if (structureAttribute.IsEntryPoint && (s is MARC.Everest.Xml.XmlStateWriter && (s as MARC.Everest.Xml.XmlStateWriter).ElementStack.Count == 0 || s.WriteState == System.Xml.WriteState.Start))
            {
                isEntryPoint = true;
                if (isEntryPoint)
                {
                    s.WriteStartElement(structureAttribute.Name, structureAttribute.NamespaceUri);
                    s.WriteAttributeString("xmlns", "xsi", null, XmlIts1Formatter.NS_XSI);
                }
            }

            // Validate
            this.Host.ValidateHelper(s, o as IGraphable, this, resultContext);

            // Reflect the properties and ensure they are in the appropriate order
            List <PropertyInfo> buildProperties = GetBuildProperties(instanceType);

            // Attributes first
            foreach (var pi in buildProperties)
            {
                object[] propertyAttributes = pi.GetCustomAttributes(typeof(PropertyAttribute), false);
                object   instance           = pi.GetValue(o, null);

                if (propertyAttributes.Length == 1) // Not a choice
                {
                    PropertyAttribute pa = propertyAttributes[0] as PropertyAttribute;

                    // Validation Rule Change: We'll require the user to perform this
                    // Is this a required attribute that is null? We'll set a null flavor
                    if ((pa.Conformance == PropertyAttribute.AttributeConformanceType.Required || pa.Conformance == PropertyAttribute.AttributeConformanceType.Populated) &&
                        pa.PropertyType != PropertyAttribute.AttributeAttributeType.Structural &&
                        pi.PropertyType.GetProperty("NullFlavor") != null &&
                        !pi.PropertyType.IsAbstract &&
                        pi.CanWrite)
                    {
                        var nullFlavorProperty = pi.PropertyType.GetProperty("NullFlavor");
                        // Locate the default property
                        if (instance == null && Host.CreateRequiredElements && nullFlavorProperty != null)
                        {
                            ConstructorInfo ci = pi.PropertyType.GetConstructor(Type.EmptyTypes);
                            instance = ci.Invoke(null);
                            nullFlavorProperty.SetValue(instance, Util.FromWireFormat("NI", nullFlavorProperty.PropertyType), null);
                        }
                    }


                    // Property type
                    switch (pa.PropertyType)
                    {
                    case PropertyAttribute.AttributeAttributeType.Structural:
                        if ((Host.Settings & SettingsType.SuppressNullEnforcement) == 0)
                        {
                            if (instance != null && !isInstanceNull)
                            {
                                s.WriteAttributeString(pa.Name, Util.ToWireFormat(instance));
                            }
                            else if (isInstanceNull && pi.Name == "NullFlavor")
                            {
                                Host.WriteNullFlavorUtil(s, (IGraphable)instance);
                            }
                        }
                        else if (instance != null)
                        {
                            if (instance != null && pi.Name == "NullFlavor")
                            {
                                Host.WriteNullFlavorUtil(s, (IGraphable)instance);
                            }
                            else if (instance != null)
                            {
                                s.WriteAttributeString(pa.Name, Util.ToWireFormat(instance));
                            }
                        }

                        break;

                    default:

                        // Instance is null
                        if (instance == null)
                        {
                            continue;
                        }
                        else if (isInstanceNull && (Host.Settings & (SettingsType.SuppressNullEnforcement | SettingsType.SuppressXsiNil)) != 0)
                        {
                            resultContext.AddResultDetail(new FormalConstraintViolationResultDetail(ResultDetailType.Information, "The context is null however SuppressNullEnforcement and SuppressXsiNil are set, therefore elements will be graphed. This is not necessarily HL7v3 compliant", s.ToString(), null));
                        }
                        else if (isInstanceNull)
                        {
                            continue;
                        }

                        // Impose flavors or code?
                        if (pa.DefaultUpdateMode != MARC.Everest.DataTypes.UpdateMode.Unknown &&
                            pi.PropertyType.GetProperty("UpdateMode") != null &&
                            pi.PropertyType.GetProperty("UpdateMode").GetValue(instance, null) == null &&
                            (this.Host.Settings & SettingsType.AllowUpdateModeImposing) == SettingsType.AllowUpdateModeImposing)
                        {
                            pi.PropertyType.GetProperty("UpdateMode").SetValue(instance, Util.FromWireFormat(pa.DefaultUpdateMode, pi.PropertyType.GetProperty("UpdateMode").PropertyType), null);
                        }
                        if (pa.ImposeFlavorId != null &&
                            instance is IAny &&
                            (Host.Settings & SettingsType.AllowFlavorImposing) == SettingsType.AllowFlavorImposing)
                        {
                            (instance as IAny).Flavor = pa.ImposeFlavorId;
                        }
                        if (pa.SupplierDomain != null &&
                            instance is ICodedValue &&
                            (instance as ICodedSimple).CodeValue != null &&
                            (instance as ICodedValue).CodeSystem == null &&
                            (instance as IImplementsNullFlavor).NullFlavor == null &&
                            (Host.Settings & SettingsType.AllowSupplierDomainImposing) == SettingsType.AllowSupplierDomainImposing)
                        {
                            (instance as ICodedValue).CodeSystem = pa.SupplierDomain;
                        }

                        // Instance is graphable
                        if (instance is IGraphable)
                        {
                            // Ensure the data is not empty
                            if (instance is IColl && (instance as IColl).IsEmpty && (instance as IImplementsNullFlavor).NullFlavor == null)
                            {
                                continue;
                            }
                            Host.WriteElementUtil(s, pa.NamespaceUri, pa.Name, instance as IGraphable, pi.PropertyType, context, resultContext);
                        }
                        else if (instance is ICollection)
                        {
                            Type genType = pi.PropertyType.GetGenericArguments()[0];
                            foreach (object itm in (instance as ICollection))
                            {
                                Host.WriteElementUtil(s, pa.NamespaceUri, pa.Name, itm as IGraphable, genType, context, resultContext);
                            }
                        }
                        else
                        {
                            s.WriteElementString(pa.Name, instance.ToString());
                        }
                        break;
                    }
                }
                else if (propertyAttributes.Length > 1) // Choice
                {
                    // Instance is null
                    if (instance == null)
                    {
                        continue;
                    }
                    else if (isInstanceNull && (Host.Settings & (SettingsType.SuppressNullEnforcement | SettingsType.SuppressXsiNil)) != 0)
                    {
                        resultContext.AddResultDetail(new FormalConstraintViolationResultDetail(ResultDetailType.Information, "The context is null however SuppressNullEnforcement and SuppressXsiNil are set, therefore elements will be graphed. This is not necessarily HL7v3 compliant", s.ToString(), null));
                    }
                    else if (isInstanceNull)
                    {
                        continue;
                    }
#if WINDOWS_PHONE
                    PropertyAttribute formatAs = propertyAttributes.Find(cpa => (cpa as PropertyAttribute).Type == null) as PropertyAttribute;
#else
                    PropertyAttribute formatAs = Array.Find(propertyAttributes, cpa => (cpa as PropertyAttribute).Type == null) as PropertyAttribute;
#endif
                    // Search by type and interaction
                    foreach (PropertyAttribute pa in propertyAttributes)
                    {
                        if (pa.Type != null && instance.GetType() == pa.Type && (context != null && context.GetType() == pa.InteractionOwner || (pa.InteractionOwner == null && formatAs == null)))
                        {
                            formatAs = pa;
                            if (context == null || context.GetType() == formatAs.InteractionOwner)
                            {
                                break;
                            }
                        }
                    }

                    // Slow check
                    if (formatAs == null && (this.Host.Settings & SettingsType.AlwaysCheckForOverrides) != 0)
                    {
                        foreach (PropertyAttribute pa in propertyAttributes)
                        {
                            if (pa.Type != null && pa.Type.IsAssignableFrom(instance.GetType()) && (context != null && context.GetType() == pa.InteractionOwner || (pa.InteractionOwner == null && formatAs == null)))
                            {
                                formatAs = pa;
                                if (context == null || context.GetType() == formatAs.InteractionOwner)
                                {
                                    break;
                                }
                            }
                        }
                    }

                    //if(formatAs == null) // try to find a regular choice
                    //    foreach(PropertyAttribute pa in propertyAttributes)
                    //        if (pa.Type != null && instance.GetType() == pa.Type)
                    //        {
                    //            formatAs = pa;
                    //            break;
                    //        }


                    // Format
                    if (formatAs == null)
                    {
                        resultContext.AddResultDetail(new NotSupportedChoiceResultDetail(ResultDetailType.Error, String.Format("Type {0} is not a valid choice according to available choice elements and won't be formatted", instance.GetType()), s.ToString(), null));
                    }
                    else if (instance.GetType().GetInterface("MARC.Everest.Interfaces.IGraphable", false) != null) // Non Graphable
                    {
                        Host.WriteElementUtil(s, formatAs.NamespaceUri, formatAs.Name, (MARC.Everest.Interfaces.IGraphable)instance, formatAs.Type, context, resultContext);
                    }
                    else if (instance.GetType().GetInterface("System.Collections.IEnumerable", false) != null) // List
                    {
                        foreach (MARC.Everest.Interfaces.IGraphable ig in instance as IEnumerable)
                        {
                            Host.WriteElementUtil(s, formatAs.NamespaceUri, formatAs.Name, ig, instance.GetType(), context, resultContext);
                        }
                    }
                    else // Not recognized
                    {
                        s.WriteElementString(formatAs.Name, formatAs.NamespaceUri, instance.ToString());
                    }
                }
            }

            // Is Entry point
            if (isEntryPoint)
            {
                s.WriteEndElement();
            }
        }