static Collection<Exception> ProcessVariableData(PropertyInfo[] propertyList, object obj, Stream sourceData, int index, bool[] IncludedFields)
        {
            int position = index;
            Collection<Exception> errors = new Collection<Exception>();
            if (propertyList != null && obj != null && sourceData != null && IncludedFields != null)
            {

                using (MemoryStream dataStream = sourceData.GetMemoryStream(index))
                {
                    dataStream.Position = 0;

                    for (int i = 0; i < IncludedFields.Length; i++)
                    {

                        if (IncludedFields[i])
                        {
                            try
                            {
                                

                                position += Utility.LoadProperty(obj, dataStream, propertyList[i], errors);

                                
                            }
                            catch (Exception ex)
                            {
                                errors.Add(ex);
                            }
                        }

                    }
                }
            }
            return errors;
        }
 void RaiseBytesReceived(Stream buffer)
 {
     if (BytesReceived != null)
     {
         BytesReceived(this, new BytesReceivedEventArgs(buffer.GetMemoryStream(0), this.ID));
     }
 }
        public ShipAction2Packet(Stream stream, int index) : base()
        {
            try
            {
                if (stream != null)
                {
                    if (stream.CanSeek)
                    {
                        stream.Position = index;
                    }
                    if (index < stream.Length - 3)
                    {
                        SubPacketType = (ShipAction2SubPacketType)stream.ToInt32();
                    }
                    if (index < stream.Length - 4)
                    {
                        SubPacketData = stream.GetMemoryStream(index + 4);

                        _subPacket = GetSubPacket(SubPacketData);
                    }
                    else
                    {
                        _subPacket = null;
                        SubPacketData = null;
                    }
                }
            }
            catch (Exception ex)
            {
                AddError(ex);
            }
        }
        public ShipActionPacket(Stream stream, int index)
            : base()
        {

            if (stream != null)
            {
                if (stream.CanSeek)
                {
                    stream.Position = index;
                }
                if (index < stream.Length - 3)
                {
                    SubPacketType = (ShipActionSubPackets.ShipActionSubPacketType)stream.ToInt32();
                }
                if (index < stream.Length - 4)
                {
                    SubPacketData = stream.GetMemoryStream(index + 4);
                    _subPacket = GetSubPacket(SubPacketData);
                }
                else
                {
                    _subPacket = null;
                    SubPacketData = null;
                }
            }
        }
        void LoadData(Stream stream, int index)
        {
            if (stream != null)
            {
                try
                {
                    List<PlayerShip> ships = new List<PlayerShip>();
                    using (MemoryStream dataStream = stream.GetMemoryStream(index))
                    {
                        int position = 0;
                        do
                        {
                            PlayerShip p = new PlayerShip(dataStream, position);
                            ships.Add(p);
                            position += p.Length;

                        } while (position < dataStream.Length);
                    }
                    Ships = new ReadOnlyCollection<PlayerShip>(ships);
                }
                catch (Exception ex)
                {
                    errors.Add(ex);
                }
            }
        }
        //**CONFIRMED

     

        public AllShipSettingsSubPacket(Stream stream, int index)
        {

            RawData = stream.GetMemoryStream(index);
            LoadData(RawData, 0);

        }
        // GameStartSubPacket = 0,
        //GameOverSubPacket = 6,
        //Unknown1SubPacket = 8,
        //Unknown2SubPacket = 9,
        //GameTextMessageSubPacket = 10,
        //JumpStartSubPacket = 12,
        //JumpCompleteSubPacket = 13,
        //AllShipSettingsSubPacket = 15,
        public GameMessagePacket(Stream stream, int index)
        {
            try
            {
                if (stream != null)
                {
                    if (stream.CanSeek)
                    {
                        stream.Position = index;
                    }
                    if (stream.Length > 3)
                    {
                        SubPacketType = (GameMessageSubPacketType)stream.ToInt32();
                       
                    }
                    if (stream.Length >= 4)
                    {
                        SubPacketData = stream.GetMemoryStream(index + 4);

                     
                        _subPacket = GetSubPacket(stream, index + 4);
                    }
                    else
                    {
                        _subPacket = null;
                        SubPacketData = null;
                    }
                }
            }
            catch (Exception ex)
            {
                errors.Add(ex);
            }
        }
        private void LoadProperties(Stream stream, int index)
        {

            _rawData = stream.GetMemoryStream(index);

            Length = Utility.LoadProperties(this, _rawData, 0, errors);
        
        }
        public ObjectStatusUpdatePacket(Stream stream, int index) : base()
        {
            if (stream != null)
            {
                try
                {
                    if (stream.Length > index + 1)
                    {
                        SubPacketType = (ObjectStatusUpdateSubPacketType)Convert.ToByte(stream.ReadByte());
                    }
                    SubPacketData = stream.GetMemoryStream(index + 1);

                    if (SubPacketData != null)
                    {
                        _subPacket = GetSubPacket(SubPacketData);
                    }
                }
                catch (Exception ex)
                {
                    AddError(ex);
                }
            }
        }
        public Packet(Stream stream)
        {
            if (stream != null)
            {
                if (stream.CanSeek)
                {
                    stream.Position = 0;
                }
#if DEBUG
                HexFormattedData = FormatIt(stream.GetMemoryStream(0).ToArray());
                if (stream.CanSeek)
                {
                    stream.Position = 0;
                }
#endif
                _rawData = stream.GetMemoryStream(0);

                if (ThrowWhenInvalid && _rawData.Length < HeaderLength)
                {
                    throw new InvalidPacketException();
                }
                else
                {
                    if (_rawData.Length > 3) ID = _rawData.ToInt32();
                    if (ThrowWhenInvalid && ID != Connector.StandardID)
                    {
                        throw new InvalidPacketException();
                    }
                    else
                    {
                        if (_rawData.Length > 7) Length = _rawData.ToInt32();
                        if (_rawData.Length > 11) Origin = (OriginType)_rawData.ToInt32();
                        if (_rawData.Length > 15) Padding = _rawData.ToInt32();
                        if (_rawData.Length > 19) PayloadLength = _rawData.ToInt32();
                        if (_rawData.Length > 23) PacketType = (PacketType)_rawData.ToInt32();


                        int ln = Convert.ToInt32(_rawData.Length);
                        if (ln > Length)
                        {
                            ln = Length;
                        }

                        Payload = _rawData.GetMemoryStream(HeaderLength);

                        _package = BuildPackage(_rawData, HeaderLength, Type.GetType(typeof(Packet).Namespace + "." + this.PacketType.ToString()));
                                //GetPackage(byteArray);
                        int packetLength = 0;
                        if (_package != null)
                        {
                            if (_package.GetErrors().Count > 0)
                            {
                                ConversionFailed = true;
                                
                            }
                            packetLength = Convert.ToInt32(Payload.Length);
                            if (Length - HeaderLength != packetLength)
                            {
                                if (ThrowWhenInvalid)
                                {
                                    throw new InvalidPacketException();
                                }
                                else
                                {
                                    ConversionException = new InvalidPacketException();
                                    ConversionFailed = true;
                                }
                            }
                        }
                        else
                        {
                            //Unknown package found!!
                        }
                    }
                }
            }

        }
        void Initialize(Stream stream, int index)
        {
            if (stream != null)
            {
                if (stream.CanRead)
                {
                    stream.Position = index;
                }
                _rawData = stream.GetMemoryStream(index);
                if (stream.CanRead)
                {
                    stream.Position = index;
                }
                _rawData.Position = 0;
                ID = _rawData.ToInt32();
                

                List<PropertyInfo> propertyList = new List<PropertyInfo>();

                Type t = this.GetType();
                PropertyInfo[] properties = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (PropertyInfo prop in properties)
                {
                    bool skip = false;
                    foreach (System.Attribute attrib in prop.GetCustomAttributes(true))
                    {
                        if (attrib is ArtemisExcludedAttribute)
                        {
                            skip = true;
                            break;
                        }
                    }
                    if (!skip)
                    {
                        if (prop.Name != "ID" && prop.Name != "IncludedFields")
                        {
                            propertyList.Add(prop);
                        }
                    }
                }

                IncludedFields = new ReadOnlyCollection<bool>(ProcessBitFlags(propertyList.Count, _rawData, 4));
                int flagsize = (propertyList.Count - 1)/ 8 + 1;

                int position = 4 + flagsize;

                errors = ProcessVariableData(propertyList.ToArray(), this, _rawData, position, IncludedFields.ToArray<bool>());
                
            }
            
        }
 //public BytesReceivedEventArgs(byte[] byteArray, Guid connectionID) : base(connectionID)
 //{
     
 //    Buffer = byteArray;
 //    DataStream = new MemoryStream(Buffer);
 //}
 public BytesReceivedEventArgs(Stream stream, Guid connectionID)
     : base(connectionID)
 {
     DataStream = stream.GetMemoryStream(0);
     //Buffer = DataStream.GetBuffer();
 }
        void Initialize(Stream stream, int index)
        {

            
            if (stream != null && index < stream.Length)
            {
                if (stream.CanSeek)
                {
                    stream.Position = index;
                }
                _rawData = stream.GetMemoryStream(index);
                if (Convert.ToByte(_rawData.ReadByte()) < 0x0a)
                {

                }
                try
                {
                    _rawData.Position = index;

                    TeamNumber = Convert.ToByte(_rawData.ReadByte() - 0x0a);

                 
                    if (_rawData.Position < _rawData.Length - 3)
                    {
                        
                        GoalX = _rawData.ToInt32();
                    }
                    if (_rawData.Position < _rawData.Length - 3)
                    {

                        CurrentX = _rawData.ToInt32();
                    }
                    if (_rawData.Position < _rawData.Length - 3)
                    {

                        GoalY = _rawData.ToInt32();
                    }
                    if (_rawData.Position < _rawData.Length - 3)
                    {
                        CurrentY = _rawData.ToInt32();
                    }
                    if (_rawData.Position < _rawData.Length - 3)
                    {
                        GoalZ = _rawData.ToInt32();
                    }
                    if (_rawData.Position < _rawData.Length - 3)
                    {
                        CurrentZ = _rawData.ToInt32();
                    }
                    if (_rawData.Position < _rawData.Length - 3)
                    {
                        Progress = _rawData.ToSingle();
                    }
                    if (_rawData.Position < _rawData.Length - 3)
                    {

                        NumberOfTeamMembers = _rawData.ToInt32();
                    }
                    _rawData.Position = 0;
                }
                catch (Exception ex)
                {
                    errors.Add(ex);
                }


            }
        }
        public static int LoadProperties(object baseObject, Stream stream, int index, Collection<Exception> errors)
        {

            int retVal = 0;
            if (baseObject == null || stream == null || errors == null)
            {

            }
            else
            {
                if (index < stream.Length)
                {

                    using (MemoryStream RawData = stream.GetMemoryStream(index))
                    {

                        RawData.Position = 0;
                        foreach (PropertyInfo prop in baseObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
                        {
                            //@@@@@@@
                            bool exclude = false;
                            foreach (object a in prop.GetCustomAttributes(false))
                            {
                                if (a.GetType() == typeof(ArtemisExcludedAttribute))
                                {
                                    exclude = true;
                                    break;
                                }
                               

                            }
                            if (!exclude)
                            {
                                retVal += LoadProperty(baseObject, RawData, prop, errors);
                            }
                            long i = RawData.Position;
                        }
                        if (stream.CanSeek)
                        {
                            stream.Position = retVal + index;
                        }
                    }

                }
            }
            return retVal;
        }
        public ArtemisString(Stream stream, int index)
        {
            
            if (stream != null && index < stream.Length - 3)
            {
                using (MemoryStream Data = stream.GetMemoryStream(index))
                {
                    Data.Position = 0;

                    Length = Data.ToInt32();
                    if (Length <= LongestAllowedLength)
                    {

                        //Only last character should be a null character (two zeroes together).  If there are two null characters together elsewhere--the parsing is WRONG and needs fixed.
                        bool badString = false;
                        for (int i = index; i < (Length * 2) - 2; i += 2)
                        {
                            byte[] buffer = new byte[2];
                            Data.Read(buffer, 0, 2);
                            if (BitConverter.ToInt16(buffer, 0) == 0)
                            {
                                badString = true;
                                break;
                            }
                        }
                        if (badString)
                        {
                            throw new ParseException("Stream for ArtemisString not correct.");
                        }
                        else
                        {
                            Data.Position = 0;
                            Value = System.Text.ASCIIEncoding.Unicode.GetString(Data.GetBuffer(), 4, Length * 2 - 2);
                            if (Value != "Artemis" && Value != "Intrepid")
                            {

                            }
                            else
                            {

                            }
                        }
                    }
                    else
                    {
                        throw new ParseException("Stream for ArtemisString not correct: Length too long.");
                    }
                }
                if (stream.CanSeek)
                {
                    stream.Position = index;
                }

                byte[] buff = new byte[Length * 2 + 4];
                stream.Read(buff, 0, buff.Length);
                _rawData = new MemoryStream(buff);
                if (stream.CanSeek)
                {
                    stream.Position += Length * 2 + 4;
                }
            }

        }