Merge pull request #22 from Havret/reset_absolute_expiry_time

AMQNET-607: It should be possible to reset AbsoluteExpiryTime
diff --git a/src/NMS.AMQP/Message/Facade/INmsMessageFacade.cs b/src/NMS.AMQP/Message/Facade/INmsMessageFacade.cs
index f610a6f..4b855ff 100644
--- a/src/NMS.AMQP/Message/Facade/INmsMessageFacade.cs
+++ b/src/NMS.AMQP/Message/Facade/INmsMessageFacade.cs
@@ -37,7 +37,7 @@
         string NMSType { get; set; }
         string GroupId { get; set; }
         uint GroupSequence { get; set; }
-        DateTime Expiration { get; set; }
+        DateTime? Expiration { get; set; }
         sbyte JmsMsgType { get; }
         
         /// <summary>
diff --git a/src/NMS.AMQP/Message/NmsMessage.cs b/src/NMS.AMQP/Message/NmsMessage.cs
index c8cba84..16871ab 100644
--- a/src/NMS.AMQP/Message/NmsMessage.cs
+++ b/src/NMS.AMQP/Message/NmsMessage.cs
@@ -237,8 +237,8 @@
 
         public bool IsExpired()
         {
-            DateTime expireTime = Facade.Expiration;
-            return expireTime > DateTime.MinValue && DateTime.UtcNow > expireTime;
+            DateTime? expireTime = Facade.Expiration;
+            return expireTime != null && DateTime.UtcNow > expireTime;
         }
 
         public virtual NmsMessage Copy()
diff --git a/src/NMS.AMQP/NmsSession.cs b/src/NMS.AMQP/NmsSession.cs
index e45062e..5843606 100644
--- a/src/NMS.AMQP/NmsSession.cs
+++ b/src/NMS.AMQP/NmsSession.cs
@@ -406,15 +406,12 @@
             if (isNmsMessage)
                 outbound = (NmsMessage) original;
             else
-            {
                 outbound = NmsMessageTransformation.TransformMessage(Connection.MessageFactory, original);
-            }
 
             if (hasTTL)
                 outbound.Facade.Expiration = timeStamp + timeToLive;
-            // TODO: Reset Expiration when https://github.com/Azure/amqpnetlite/commit/13009980e40aedcb6310f8fa796fbee53be8a389 merged
-            // else
-            //     outbound.Facade.Expiration = DateTime.MinValue;
+            else
+                outbound.Facade.Expiration = null;
 
             outbound.OnSend(timeToLive);
 
diff --git a/src/NMS.AMQP/Provider/Amqp/Message/AmqpNmsMessageFacade.cs b/src/NMS.AMQP/Provider/Amqp/Message/AmqpNmsMessageFacade.cs
index 29ec18c..6766602 100644
--- a/src/NMS.AMQP/Provider/Amqp/Message/AmqpNmsMessageFacade.cs
+++ b/src/NMS.AMQP/Provider/Amqp/Message/AmqpNmsMessageFacade.cs
@@ -29,12 +29,14 @@
 {
     public class AmqpNmsMessageFacade : INmsMessageFacade
     {
+        private const int ABSOLUTE_EXPIRY_TIME_INDEX = 8;
+        
         private TimeSpan? amqpTimeToLiveOverride;
         private IDestination destination;
         private IDestination replyTo;
         private IDestination consumerDestination;
         private IAmqpConnection connection;
-        private DateTime syntheticExpiration;
+        private DateTime? syntheticExpiration;
         public global::Amqp.Message Message { get; private set; }
 
         public virtual bool HasBody()
@@ -206,19 +208,19 @@
             }
         }
 
-        public DateTime Expiration
+        public DateTime? Expiration
         {
-            get => Message.Properties?.AbsoluteExpiryTime ?? syntheticExpiration;
+            get => Message.Properties?.HasField(ABSOLUTE_EXPIRY_TIME_INDEX) == true ? Message.Properties.AbsoluteExpiryTime : syntheticExpiration;
             set
             {
-                if (value != default)
+                if (value != null)
                 {
                     LazyCreateProperties();
-                    Message.Properties.AbsoluteExpiryTime = value;
+                    Message.Properties.AbsoluteExpiryTime = value.Value;
                 }
-                else if (Message.Properties != null)
+                else
                 {
-                    Message.Properties.AbsoluteExpiryTime = default;
+                    Message.Properties?.ResetField(ABSOLUTE_EXPIRY_TIME_INDEX);
                 }
             }
         }
@@ -376,8 +378,8 @@
             InitializeHeader();
 
             TimeSpan ttl = NMSTimeToLive;
-            DateTime absoluteExpiryTime = Expiration;
-            if (absoluteExpiryTime == default && ttl != default)
+            DateTime? absoluteExpiryTime = Expiration;
+            if (absoluteExpiryTime == null && ttl != default)
             {
                 syntheticExpiration = DateTime.UtcNow + ttl;
             }
diff --git a/test/Apache-NMS-AMQP-Test/Message/Facade/NmsTestMessageFacade.cs b/test/Apache-NMS-AMQP-Test/Message/Facade/NmsTestMessageFacade.cs
index d7f3e09..b1d017d 100644
--- a/test/Apache-NMS-AMQP-Test/Message/Facade/NmsTestMessageFacade.cs
+++ b/test/Apache-NMS-AMQP-Test/Message/Facade/NmsTestMessageFacade.cs
@@ -74,7 +74,7 @@
         public string NMSType { get; set; }
         public string GroupId { get; set; }
         public uint GroupSequence { get; set; }
-        public DateTime Expiration { get; set; }
+        public DateTime? Expiration { get; set; }
         public sbyte JmsMsgType { get; }
         public bool IsPersistent { get; set; }
 
diff --git a/test/Apache-NMS-AMQP-Test/Provider/Amqp/AmqpNmsMessageFacadeTest.cs b/test/Apache-NMS-AMQP-Test/Provider/Amqp/AmqpNmsMessageFacadeTest.cs
index 0da7b33..658d352 100644
--- a/test/Apache-NMS-AMQP-Test/Provider/Amqp/AmqpNmsMessageFacadeTest.cs
+++ b/test/Apache-NMS-AMQP-Test/Provider/Amqp/AmqpNmsMessageFacadeTest.cs
@@ -1016,11 +1016,11 @@
 
         // --- absolute-expiry-time field  ---
         [Test]
-        public void TestGetExpirationIsZeroForNewMessage()
+        public void TestGetExpirationIsNullForNewMessage()
         {
             AmqpNmsMessageFacade amqpNmsMessageFacade = CreateNewMessageFacade();
 
-            Assert.AreEqual(default(DateTime), amqpNmsMessageFacade.Expiration);
+            Assert.IsNull(amqpNmsMessageFacade.Expiration);
         }
 
         [Test]
@@ -1049,17 +1049,18 @@
         }
 
         [Test]
-        public void TestSetExpirationZeroOnMessageWithExistingExpiryTime()
+        public void TestSetExpirationNullOnMessageWithExistingExpiryTime()
         {
             DateTime timestamp = DateTime.UtcNow;
 
             AmqpNmsMessageFacade amqpNmsMessageFacade = CreateNewMessageFacade();
 
             amqpNmsMessageFacade.Expiration = timestamp;
-            amqpNmsMessageFacade.Expiration = default;
+            amqpNmsMessageFacade.Expiration = null;
 
             Assert.AreEqual(default(DateTime), amqpNmsMessageFacade.Message.Properties.AbsoluteExpiryTime, "Expected absolute-expiry-time to be default");
-            Assert.AreEqual(default(DateTime), amqpNmsMessageFacade.Expiration, "Expected no expiration");
+            Assert.IsFalse(amqpNmsMessageFacade.Message.Properties.HasField(8), "Expected absolute-expiry-time is not set");
+            Assert.AreEqual(null, amqpNmsMessageFacade.Expiration, "Expected no expiration");
         }
 
         // --- user-id field  ---
@@ -1352,7 +1353,7 @@
             Assert.AreEqual(source.IsPersistent, copy.IsPersistent);
             Assert.AreEqual(source.UserId, copy.UserId);
             Assert.AreEqual(source.NMSTimeToLive, copy.NMSTimeToLive);
-            Assert.IsTrue(Math.Abs((copy.Expiration - source.Expiration).TotalMilliseconds) < 1);
+            Assert.IsTrue(Math.Abs((copy.Expiration.Value - source.Expiration.Value).TotalMilliseconds) < 1);
             Assert.IsTrue(Math.Abs((copy.NMSTimestamp - source.NMSTimestamp).TotalMilliseconds) < 1);
             Assert.AreEqual(source.Properties.GetString("APP-Prop-1"), copy.Properties.GetString("APP-Prop-1"));
             Assert.AreEqual(source.GetMessageAnnotation("test-annotation"), copy.GetMessageAnnotation("test-annotation"));