function RxInstanceUtils.observePropertyBrio(r,m,x)assert(typeof(r)=="\073\110\115\116\097\110\099\101","\066\097\100 \105\110\115\116\097\110\099\101")assert(type(m)=="\115\116\114\105\110\103","\066\097\100 \112\114\111\112\101\114\116\121\078\097\109\101")assert(type(x)=="\102\117\110\099\116\105\111\110"or x==nil,"\066\097\100 \112\114\101\100\105\099\097\116\101")return Observable.new(function(L)local s=Maid.new()local Q=UNSET_VALUE local function q()local q=r[m]if Q~=q then Q=q if not x or x(q)then local x=Brio.new(r[m])s._lastBrio=x if s._lastBrio==x then L:Fire(x)end else s._lastBrio=nil end end end s:GiveTask((r:GetPropertyChangedSignal(m)):Connect(q))q()return s end)end

function RxInstanceUtils.observePropertyBrio(instance, propertyName, predicate)
	assert(typeof(instance) == "Instance", "Bad instance")
	assert(type(propertyName) == "string", "Bad propertyName")
	assert(type(predicate) == "function" or predicate == nil, "Bad predicate")

	return Observable.new(function(sub)
		local maid = Maid.new()
		local lastValue = UNSET_VALUE

		local function handlePropertyChanged()
			local propertyValue = instance[propertyName]

			-- Deferred events can cause multiple values to be queued at once
			-- but we operate at this post-deferred layer, so lets only output
			-- reflected values.
			if lastValue ~= propertyValue then
				lastValue = propertyValue

				if not predicate or predicate(propertyValue) then
					local brio = Brio.new(instance[propertyName])

					maid._lastBrio = brio

					-- The above line can cause us to be overwritten so make sure before firing.
					if maid._lastBrio == brio then
						sub:Fire(brio)
					end
				else
					maid._lastBrio = nil
				end
			end
		end

		maid:GiveTask(instance:GetPropertyChangedSignal(propertyName):Connect(handlePropertyChanged))
		handlePropertyChanged()

		return maid
	end)
end
