//---------------------------------------------------------------------
        // FindLoader()
        //---------------------------------------------------------------------
        public static void FindLoader( clsDevice pobjDevice, clsSerialPort pobjPort , clsDownloadSettings pobjSettings, int iTabLevel, ref bool pbResult )
        {
            int iDeviceIdFound = -1;
            bool bGetResponseResult = false;
            bool bPortWasOpened = false;

            pbResult = false;

            //-----------------------------------------------------------------
            // Test-mode
            //-----------------------------------------------------------------
            if ( bTestMode == true ) {
                iFWVerMaj = iTestVerMaj;
                iFWVerMin = iTestVerMin;
                iFWVerRev = iTestVerRev;
                iDeviceIdFound = iTestDeviceID;
                //return true;

            //-----------------------------------------------------------------
            // Real-mode
            //-----------------------------------------------------------------
            } else {

                int iVerMaj = 0, iVerMinRev = 0;
                int iTimeIdReceived = 0;

                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "Searching for bl ", iTabLevel) );

                //--------------------------------------------------------------------------
                // Open port if not open
                //--------------------------------------------------------------------------
                if ( pobjPort.isOpen == false ) {
                    pobjPort.Open();
                    if ( pobjPort.isOpen == false ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Failed to open port", iTabLevel) );
                        return;
                    }
                    bPortWasOpened = true;
                }

                // Empty buffers prior to hello command incase there's some crap
                pobjPort.EmptyBuffers( true, false );

                //--------------------------------------------------------------------------
                // Send hello to bootloader
                //--------------------------------------------------------------------------
                bool bDeviceIDReceived = false;
                {
                    int iLastSend = Environment.TickCount - pobjSettings.polltime;
                    int iLastPoll = Environment.TickCount - pobjSettings.polltime;
                    int iStartTime = Environment.TickCount;

                    bool bByteReceived = false;

                    bool bTimedOut = false;

                    do {
                        // Check first byte, discard if null
                        if ( Environment.TickCount - iLastPoll >= pobjSettings.polltime/10) {
                            iLastPoll = Environment.TickCount;

                            if ( bByteReceived == false && pobjPort.inBufferCount > 0 ) {
                                bByteReceived = true;
                                iDeviceIdFound = GetResponse( pobjPort, ref bGetResponseResult );
                                if ( bGetResponseResult == false ) {
                                    if ( bPortWasOpened == true ) pobjPort.Close();
                                    return;
                                }
                                if ( iDeviceIdFound == 0 ) {
                                    OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, "(discarded null byte)", -1) );
                                } else {
                                    bDeviceIDReceived = true;
                                    iTimeIdReceived = Environment.TickCount;
                                    break;
                                }

                            }
                        }

                        // Send hello
                       if ( Environment.TickCount - iLastSend >= pobjSettings.polltime ) {
                            iLastSend = Environment.TickCount;
                            pobjPort.SendByte( cHello );
                            OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.info, ". ", -1) );
                        }

                        // Check for timeout
                        bTimedOut = ( Environment.TickCount - iStartTime >= pobjSettings.timeout );

                        // Handle message queue
                        Application.DoEvents();
                    } while (
                        bAbort == false &&
                        bTimedOut == false &&
                        (bByteReceived == false || pobjPort.inBufferCount == 0)
                    );

                    if ( bAbort == true  ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "aborted", -1) );
                        bAbort = false;
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    } else if ( bTimedOut == true ) {
                        OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "timed out", -1) );
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                }

                //--------------------------------------------------------------------------
                // Read device id
                //--------------------------------------------------------------------------
                if ( bDeviceIDReceived == false ) {
                    iDeviceIdFound = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        iTimeIdReceived = Environment.TickCount;
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                }

                //--------------------------------------------------------------------------
                // Delay to receive firmware version if any
                //--------------------------------------------------------------------------
                int iTime = 1 + 30000 / pobjPort.baudrate;
                while ( Environment.TickCount - iTimeIdReceived < iTime && pobjPort.inBufferCount < 3 ) {
                }

                //--------------------------------------------------------------------------
                // Firmware doesn´t send version, assume 0.9.4
                //--------------------------------------------------------------------------
                if ( pobjPort.inBufferCount == 1 ) {
                        iFWVerMaj = 0;
                        iFWVerMin = 9;
                        iFWVerRev = 4;

                //--------------------------------------------------------------------------
                // Firmware that sends major and minor
                //--------------------------------------------------------------------------
                } else if ( pobjPort.inBufferCount == 2 ) {
                    iVerMaj = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                    iFWVerMaj = ( (iVerMaj & 0x70) >> 4 );
                    iFWVerMin = ( iVerMaj & 0xF );
                    iFWVerRev = 0;

                //--------------------------------------------------------------------------
                // Firmware that sends major, minor and revision
                //--------------------------------------------------------------------------
                } else if ( pobjPort.inBufferCount == 3 ) {
                    iVerMaj = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }
                    iVerMinRev = GetResponse( pobjPort, ref bGetResponseResult );
                    if ( bGetResponseResult == false ) {
                        if ( bPortWasOpened == true ) pobjPort.Close();
                        return;
                    }

                    iFWVerMaj = ( iVerMaj & 0x7F );
                    iFWVerMin = ( (iVerMinRev & 0xF0) >> 4 );
                    iFWVerRev = ( iVerMinRev & 0xF );
                }

                //--------------------------------------------------------------------------
                // PIC18 indicated by msb in fw ver major
                //--------------------------------------------------------------------------
                if ( (iVerMaj & 0x80) > 0 ) {
                    iDeviceIdFound += 300;
                }
            }//Test-/real-mode

            //--------------------------------------------------------------------------
            // Find device from device id
            //--------------------------------------------------------------------------
            clsDevice objFoundDevice = clsDevices.DeviceGet( iDeviceIdFound );

            //--------------------------------------------------------------------------
            // Invalid ID returned
            //--------------------------------------------------------------------------
            if ( objFoundDevice == null ) {
                OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Found unknown device id(" + iDeviceIdFound.ToString() + ") fw ver. " + iFWVerMaj.ToString() + "." + iFWVerMin.ToString() + "." + iFWVerRev.ToString(), iTabLevel) );
                if ( bPortWasOpened == true ) pobjPort.Close();
                return;
            }

            //--------------------------------------------------------------------------
            // Bootloader found
            //--------------------------------------------------------------------------
            OnDownloading( new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.success, "Found " + objFoundDevice.name + " fw ver. " + iFWVerMaj.ToString() + "." + iFWVerMin.ToString() + "." + iFWVerRev.ToString(), iTabLevel) );

            //--------------------------------------------------------------------------
            // Different device found from choosen
            //--------------------------------------------------------------------------
            if ( objFoundDevice.id != pobjDevice.id ) {
                OnDownloading(new clsDownloadingEventArgs(clsDownloadingEventArgs.EventType.error, "Wrong pic detected(" + objFoundDevice.id.ToString() + ")/selected(" + pobjDevice.id.ToString() + "), aborting", iTabLevel));
                if ( bPortWasOpened == true ) pobjPort.Close();
                return;
            }

            pbResult = true;

            // Close port if it was openeed
            if ( bPortWasOpened == true ) {
                pobjPort.Close();
            }
        }