/// <summary>
        /// Reads the value of a Property inside a object instance.
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="binary"></param>
        /// <returns>A NdfValueWrapper Instance.</returns>
        protected NdfValueWrapper ReadValue(Stream ms, NdfBinary binary)
        {
            uint contBufferlen;
            NdfValueWrapper value;
            var buffer = new byte[4];

            ms.Read(buffer, 0, buffer.Length);
            NdfType type = NdfTypeManager.GetType(buffer);

            if (type == NdfType.Unknown)
                throw new InvalidDataException("Unknown datatypes are not supported!");

            if (type == NdfType.Reference)
            {
                ms.Read(buffer, 0, buffer.Length);
                type = NdfTypeManager.GetType(buffer);
            }

            switch (type)
            {
                case NdfType.WideString:
                case NdfType.List:
                case NdfType.MapList:
                case NdfType.Blob:
                case NdfType.ZipBlob:
                    ms.Read(buffer, 0, buffer.Length);
                    contBufferlen = BitConverter.ToUInt32(buffer, 0);

                    if (type == NdfType.ZipBlob)
                        if (ms.ReadByte() != 1)
                            throw new InvalidDataException("has to be checked.");
                    break;
                default:
                    contBufferlen = NdfTypeManager.SizeofType(type);
                    break;
            }

            switch (type)
            {
                case NdfType.MapList:
                case NdfType.List:
                    NdfCollection lstValue = type == NdfType.List ? new NdfCollection() : new NdfMapList();

                    for (int i = 0; i < contBufferlen; i++)
                    {
                        CollectionItemValueHolder res;
                        if (type == NdfType.List)
                            res = new CollectionItemValueHolder(ReadValue(ms, binary), binary);
                        else
                            res = new CollectionItemValueHolder(
                                new NdfMap(
                                    new MapValueHolder(ReadValue(ms, binary), binary),
                                    new MapValueHolder(ReadValue(ms, binary), binary),
                                    binary), binary);

                        lstValue.Add(res);
                    }

                    value = lstValue;
                    break;
                case NdfType.Map:
                    value = new NdfMap(
                        new MapValueHolder(ReadValue(ms, binary), binary),
                        new MapValueHolder(ReadValue(ms, binary), binary),
                        binary);
                    break;
                default:
                    var contBuffer = new byte[contBufferlen];
                    ms.Read(contBuffer, 0, contBuffer.Length);

                    value = NdfTypeManager.GetValue(contBuffer, type, binary);
                    break;
            }

            return value;
        }
        private NdfValueWrapper GetCopiedValue(IValueHolder toCopy)
        {
            NdfValueWrapper copiedValue = null;

            switch (toCopy.Value.Type)
            {
                case NdfType.ObjectReference:
                    var origInst = toCopy.Value as NdfObjectReference;

                    if (origInst != null && !origInst.Instance.IsTopObject)
                        copiedValue = new NdfObjectReference(origInst.Class, CopyInstance(origInst.Instance).Id);
                    else
                        copiedValue = NdfTypeManager.GetValue(toCopy.Value.GetBytes(), toCopy.Value.Type, toCopy.Manager);

                    break;
                case NdfType.List:
                case NdfType.MapList:
                    var copiedItems = new List<CollectionItemValueHolder>();
                    var collection = toCopy.Value as NdfCollection;
                    if (collection != null)
                        copiedItems.AddRange(collection.Select(entry => new CollectionItemValueHolder(GetCopiedValue(entry), toCopy.Manager)));
                    copiedValue = new NdfCollection(copiedItems);
                    break;

                case NdfType.Map:
                    var map = toCopy.Value as NdfMap;
                    if (map != null)
                        copiedValue = new NdfMap(new MapValueHolder(GetCopiedValue(map.Key), toCopy.Manager),
                            new MapValueHolder(GetCopiedValue(map.Value as IValueHolder), toCopy.Manager), toCopy.Manager);
                    break;

                default:
                    copiedValue = NdfTypeManager.GetValue(toCopy.Value.GetBytes(), toCopy.Value.Type, toCopy.Manager);
                    break;
            }

            return copiedValue;
        }