public void equality()
    {
      Assert.True(ObjectExtensions.Equality<object>(null, null, (string[]) null));
      Assert.True(ObjectExtensions.Equality(null, null, (Expression<Func<object, object>>[]) null));
      Assert.False(ObjectExtensions.Equality(null, new object(), (string[])null));
      Assert.False(ObjectExtensions.Equality(null, new object(), (Expression<Func<object, object>>[])null));
      Assert.False(new object().Equality(null, (string[])null));
      Assert.False(new object().Equality(null, (Expression<Func<object, object>>[]) null));
      Assert.False(new object().Equality(string.Empty, (string[]) null));
      Assert.False(new object().Equality(string.Empty, (Expression<Func<object, object>>[])null));
      Assert.False(new object().Equality(new object(), (string[])null));
      Assert.False(new object().Equality(new object(), (Expression<Func<object, object>>[])null));

      var subject = new object();
      Assert.True(subject.Equality(subject, (string[])null));
      Assert.True(subject.Equality(subject, (Expression<Func<object, object>>[]) null));
      Assert.True(Guid.Empty.ToString().Equality(Guid.Empty.ToString(), (string[]) null));
      Assert.True(Guid.Empty.ToString().Equality(Guid.Empty.ToString(), (Expression<Func<object, object>>[]) null));
      Assert.True(Guid.NewGuid().ToString().Equality(Guid.NewGuid().ToString(), new[] { "Length" }));
      Assert.True(Guid.NewGuid().ToString().Equality(Guid.NewGuid().ToString(), it => it.Length));
      Assert.False("first".Equality("second", "Length"));
      Assert.False("first".Equality("second", it => it.Length));
      Assert.True("text".Equality("text", "property"));
      Assert.False("first".Equality("second", "property"));
      
      var testSubject = new TestObject();
      Assert.True(testSubject.Equality(testSubject, (string[]) null));
      Assert.True(testSubject.Equality(testSubject, (Expression<Func<TestObject, object>>[]) null));
      Assert.True(new TestObject().Equality(new TestObject(), (string[])null));
      Assert.True(new TestObject().Equality(new TestObject(), (Expression<Func<TestObject, object>>[])null));
      Assert.True(new TestObject { PublicProperty = "property" }.Equality(new TestObject { PublicProperty = "property" }, (string[]) null));
      Assert.True(new TestObject { PublicProperty = "property" }.Equality(new TestObject { PublicProperty = "property" }, (Expression<Func<TestObject, object>>[]) null));
      Assert.False(new TestObject { PublicProperty = "property" }.Equality(new TestObject(), (string[])null));
      Assert.False(new TestObject { PublicProperty = "property" }.Equality(new TestObject(), (Expression<Func<TestObject, object>>[])null));
      Assert.False(new TestObject { PublicProperty = "first" }.Equality(new TestObject { PublicProperty = "second" }, (string[])null));
      Assert.False(new TestObject { PublicProperty = "first" }.Equality(new TestObject { PublicProperty = "second" }, (Expression<Func<TestObject, object>>[])null));
    }
    public void properties()
    {
      Assert.Throws<ArgumentNullException>(() => ObjectExtensions.Properties<object>(null, new Dictionary<string, object>()));
      Assert.Throws<ArgumentNullException>(() => new object().Properties((IDictionary<string, object>)null));
      Assert.Throws<ArgumentNullException>(() => ObjectExtensions.Properties<object>(null, (object)null));
      Assert.Throws<ArgumentNullException>(() => new object().Properties((object)null));

      var subject = new TestObject();
      var property = Guid.NewGuid().ToString();

      Assert.Throws<ArgumentException>(() => subject.Properties(new Dictionary<string, object>{ { "ReadOnlyProperty", property } }));
      Assert.True(ReferenceEquals(subject.Properties(new Dictionary<string, object> { { "PublicProperty", property }, { "property", new object() } }), subject));
      Assert.Equal(property, subject.Property("PublicProperty"));

      Assert.Throws<ArgumentException>(() => subject.Properties(new { ReadOnlyProperty = property }));
      Assert.True(ReferenceEquals(subject.Properties(new { PublicProperty = property, property = new object() }), subject));
      Assert.Equal(property, subject.Property("PublicProperty"));
    }
    public void get_hash_code()
    {
      Assert.Equal(0, ObjectExtensions.GetHashCode<object>(null, (string[]) null));
      Assert.Equal(0, ObjectExtensions.GetHashCode<object>(null, Enumerable.Empty<string>().ToArray()));
      Assert.Equal(0, ObjectExtensions.GetHashCode(null, (Expression<Func<object, object>>[]) null));
      Assert.Equal(0, ObjectExtensions.GetHashCode(null, Enumerable.Empty<Expression<Func<object, object>>>().ToArray()));

      Assert.NotEqual(0, new object().GetHashCode((string[])null));
      Assert.NotEqual(0, new object().GetHashCode((Expression<Func<object, object>>[]) null));

      Assert.NotEqual(new object().GetHashCode((string[])null), new object().GetHashCode((string[])null));
      Assert.NotEqual(new object().GetHashCode((Expression<Func<object, object>>[]) null), new object().GetHashCode((Expression<Func<object, object>>[]) null));

      var subject = new object();
      Assert.Equal(subject.GetHashCode((string[])null), subject.GetHashCode((string[])null));
      Assert.Equal(subject.GetHashCode((Expression<Func<object, object>>[]) null), subject.GetHashCode((Expression<Func<object, object>>[]) null));
      Assert.Equal(subject.GetHashCode(), subject.GetHashCode((string[])null));
      Assert.Equal(subject.GetHashCode(), subject.GetHashCode((Expression<Func<object, object>>[])null));
      Assert.NotEqual(new object().GetHashCode((string[]) null), string.Empty.GetHashCode((string[]) null));
      Assert.Equal( string.Empty.GetHashCode((string[]) null), string.Empty.GetHashCode((string[]) null));

      Assert.Equal(Guid.NewGuid().ToString().GetHashCode(new[] { "Length" }), Guid.NewGuid().ToString().GetHashCode(new[] { "Length" }));
      Assert.Equal(Guid.NewGuid().ToString().GetHashCode(it => it.Length), Guid.NewGuid().ToString().GetHashCode(new[] { "Length" }));
      Assert.Equal(Guid.NewGuid().ToString().GetHashCode(it => it.Length), Guid.NewGuid().ToString().GetHashCode(it => it.Length));

      var testObject = new TestObject();
      Assert.Equal(testObject.GetHashCode((string[])null), testObject.GetHashCode((string[])null));
      Assert.Equal(testObject.GetHashCode(new[] { "PublicProperty" }), testObject.GetHashCode(new[] { "PublicProperty" }));
      Assert.Equal(testObject.GetHashCode(new[] { "PublicProperty" }), testObject.GetHashCode(it => it.PublicProperty));
      Assert.Equal(testObject.GetHashCode(it => it.PublicProperty), testObject.GetHashCode(it => it.PublicProperty));
      Assert.Equal(testObject.GetHashCode(new[] { "ProtectedProperty" }), testObject.GetHashCode(new[] { "PublicProperty" }));
      Assert.Equal(testObject.GetHashCode(new[] { "ProtectedProperty" }), testObject.GetHashCode(it => it.PublicProperty));
      Assert.Equal(testObject.GetHashCode(new[] { "invalid" }), testObject.GetHashCode(new[] { "invalid" }));
      Assert.Equal(testObject.GetHashCode(new[] { "invalid_2" }), testObject.GetHashCode(new[] { "invalid_1" }));
      testObject.PublicProperty = "property";
      Assert.Equal(new TestObject { PublicProperty = "property" }.GetHashCode((string[]) null), new TestObject { PublicProperty = "property" }.GetHashCode((string[])null));
      Assert.NotEqual(new TestObject { PublicProperty = "second" }.GetHashCode((string[])null), new TestObject { PublicProperty = "first" }.GetHashCode((string[])null));
      Assert.Equal(testObject.GetHashCode(new[] { "PublicProperty" }), testObject.GetHashCode(new[] { "PublicProperty" }));
      Assert.Equal(testObject.GetHashCode(new[] { "PublicProperty" }), testObject.GetHashCode(it => it.PublicProperty));
      Assert.Equal(testObject.GetHashCode(it => it.PublicProperty), testObject.GetHashCode(it => it.PublicProperty));
      Assert.NotEqual(testObject.GetHashCode(new[] { "ProtectedProperty" }), testObject.GetHashCode(new[] { "PublicProperty" }));
      Assert.NotEqual(testObject.GetHashCode(new[] { "ProtectedProperty" }), testObject.GetHashCode(it => it.PublicProperty));
    }
    public void property()
    {
      Assert.Throws<ArgumentNullException>(() => ObjectExtensions.Property(null, "property"));
      Assert.Throws<ArgumentNullException>(() => new object().Property(null));
      Assert.Throws<ArgumentException>(() => new object().Property(string.Empty));

      Assert.Null(new object().Property("property"));

      var subject = new TestObject { PublicProperty = "value" };
      Assert.Equal("value", subject.Property("PublicProperty").To<string>());


      Assert.Throws<ArgumentNullException>(() => ObjectExtensions.Property<object>(null, "property", new object()));
      Assert.Throws<ArgumentNullException>(() => new object().Property(null, new object()));
      Assert.Throws<ArgumentException>(() => new object().Property(string.Empty, new object()));

      subject = new TestObject();
      var property = Guid.NewGuid().ToString();
      Assert.True(ReferenceEquals(subject.Property("PublicProperty", null), subject));
      Assert.Throws<ArgumentException>(() => subject.Property("ReadOnlyProperty", property));

      subject.Property("PublicStaticProperty", property);
      Assert.Equal(property, subject.Property("PublicStaticProperty"));

      subject.Property("ProtectedStaticProperty", property);
      Assert.Equal(property, subject.Property("ProtectedStaticProperty"));

      subject.Property("PrivateStaticProperty", property);
      Assert.Equal(property, subject.Property("PrivateStaticProperty"));

      subject.Property("PublicProperty", property);
      Assert.Equal(property, subject.Property("PublicProperty"));

      subject.Property("ProtectedProperty", property);
      Assert.Equal(property, subject.Property("ProtectedProperty"));

      subject.Property("PrivateProperty", property);
      Assert.Equal(property, subject.Property("PrivateProperty"));
    }
    public void field()
    {
      Assert.Throws<ArgumentNullException>(() => ObjectExtensions.Field(null, "field"));
      Assert.Throws<ArgumentNullException>(() => new object().Field(null));
      Assert.Throws<ArgumentException>(() => new object().Field(string.Empty));

      Assert.Null(new object().Field("field"));

      var subject = new TestObject { PublicField = "value" };
      Assert.Equal("value", subject.Field("PublicField").To<string>());
    }