public T ContentAs <T>()
        {
            EnsureNotDisposed();

            //basic GET or other non-projection operation
            if (OpCode == OpCode.Get || OpCode == OpCode.ReplicaRead || OpCode == OpCode.GetL || OpCode == OpCode.GAT)
            {
                _logger.LogDebug("using the {transcoder} Transcoder.", _transcoder.GetType());
                return(_transcoder.Decode <T>(_contentBytes.Memory, Flags, OpCode));
            }

            //oh mai, its a projection
            ParseSpecs();

            // normal GET
            if (_specs.Count == 1 && _projectList?.Count == 0)
            {
                var spec = _specs[0];
                return(_transcoder.Decode <T>(spec.Bytes, Flags, OpCode.Get));
            }

            var root = new JObject();

            foreach (var spec in _specs)
            {
                //skip the expiry if it was included; it must fetched from this.Expiry
                if (spec.Path == VirtualXttrs.DocExpiryTime)
                {
                    continue;
                }
                var content = _serializer.Deserialize <JToken>(spec.Bytes);
                if (spec.OpCode == OpCode.Get)
                {
                    //a full doc is returned if the projection count exceeds the server limit
                    //so we remove any non-requested fields from the content returned.
                    if (_projectList?.Count > 16)
                    {
                        foreach (var child in content.Children())
                        {
                            if (_projectList.Contains(child.Path))
                            {
                                root.Add(child);
                            }
                        }

                        //root projection for empty path
                        return(root.ToObject <T>());
                    }
                }
                var projection = CreateProjection(spec.Path, content);

                try
                {
                    root.Add(projection.First);
                }
                catch (Exception e)
                {
                    //these are cases where a root attribute is already mapped
                    //for example "attributes" and "attributes.hair" will cause exceptions
                    _logger.LogInformation(e, "Deserialization failed.");
                }
            }

            if (root.Path == string.Empty && typeof(T).IsPrimitive)
            {
                return(root.First.ToObject <T>());
            }
            return(root.ToObject <T>());
        }