Index: src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.h
===================================================================
--- src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.h	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.h	(working copy)
@@ -60,12 +60,14 @@
 		wxTextCtrl* m_TextThPath;
 		wxChoice* m_choiceDictionary;
 		wxStaticText* StaticText2;
+		wxCheckBox* m_checkThesaurusTooltips;
 		wxTextCtrl* m_TextDictPath;
 		wxButton* Button1;
 		wxStaticText* StaticText1;
 		wxStaticText* StaticText3;
 		wxHyperlinkCtrl* HyperlinkCtrl1;
 		wxButton* Button2;
+		wxCheckBox* m_checkSpellTooltips;
 		wxButton* Button3;
 		wxTextCtrl* m_TextBitmapPath;
 		wxStaticText* StaticText4;
Index: src/plugins/contrib/SpellChecker/SpellCheckerPlugin.cpp
===================================================================
--- src/plugins/contrib/SpellChecker/SpellCheckerPlugin.cpp	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellCheckerPlugin.cpp	(working copy)
@@ -51,6 +51,7 @@
 
     const int idSpellCheck                 = wxNewId();
     const int idThesaurus                  = wxNewId();
+    const int idCamelCase                  = wxNewId();
 
     const unsigned int MaxSuggestEntries = 5;
     const int idSuggest[MaxSuggestEntries] =
@@ -114,7 +115,7 @@
     ConfigureHunspellSpellCheckEngine();
     m_pSpellChecker->InitializeSpellCheckEngine();
 
-    // initialze Helper and online checker
+    // initialize Helper and online checker
     m_pSpellHelper = new SpellCheckHelper();
     m_pOnlineChecker = new OnlineSpellChecker(m_pSpellChecker, m_pSpellHelper);
     m_FunctorId = EditorHooks::RegisterHook( m_pOnlineChecker );
@@ -135,8 +136,10 @@
     Connect(idAddToDictionary, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SpellCheckerPlugin::OnAddToPersonalDictionary), NULL, this);
     Connect(idThesaurus,       wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SpellCheckerPlugin::OnThesaurus));
     Connect(idThesaurus,       wxEVT_UPDATE_UI,             wxUpdateUIEventHandler(SpellCheckerPlugin::OnUpdateThesaurus));
+    Connect(idCamelCase,       wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SpellCheckerPlugin::OnCamelCase));
 
     Manager::Get()->RegisterEventSink(cbEVT_EDITOR_SAVE, new cbEventFunctor<SpellCheckerPlugin, CodeBlocksEvent>(this, &SpellCheckerPlugin::OnEditorSaved));
+    Manager::Get()->RegisterEventSink(cbEVT_EDITOR_TOOLTIP, new cbEventFunctor<SpellCheckerPlugin, CodeBlocksEvent>(this, &SpellCheckerPlugin::OnEditorTooltip));
 }
 #ifdef wxUSE_STATUSBAR
 void SpellCheckerPlugin::CreateStatusField(cbStatusBar *bar)
@@ -216,7 +219,7 @@
     Disconnect(idAddToDictionary, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SpellCheckerPlugin::OnAddToPersonalDictionary), NULL, this);
     Disconnect(idThesaurus,  wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SpellCheckerPlugin::OnThesaurus));
     Disconnect(idThesaurus,  wxEVT_UPDATE_UI,             wxUpdateUIEventHandler(SpellCheckerPlugin::OnUpdateThesaurus));
-
+    Disconnect(idCamelCase,  wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SpellCheckerPlugin::OnCamelCase));
 }
 void SpellCheckerPlugin::SavePersonalDictionary()
 {
@@ -242,7 +245,7 @@
     // if not attached, exit
     if (!IsAttached()) return;
 
-    // insert entry in the View menu
+    // insert entry in the Edit menu
     int EditPos = menuBar->FindMenu(_("&Edit"));
     if (EditPos != wxNOT_FOUND)
     {
@@ -251,6 +254,22 @@
         EditMenu->AppendSeparator();
         EditMenu->Append(idSpellCheck, _("Spelling..."), _("Spell check the selected text"));
         EditMenu->Append(idThesaurus,  _("Thesaurus..."), _T(""));
+
+        // find menu - Edit/Special commands/Case
+        int id = EditMenu->FindItem(_("Special commands"));
+        if (id == wxNOT_FOUND) return;
+        wxMenuItem* subMenuItem = EditMenu->FindItem(id, 0);
+        if (!subMenuItem)      return;
+        wxMenu* subMenu = subMenuItem->GetSubMenu();
+        if (!subMenu)          return;
+        id = EditMenu->FindItem(_("Case"));
+        if (id == wxNOT_FOUND) return;
+        subMenuItem = EditMenu->FindItem(id, 0);
+        if (!subMenuItem)      return;
+        subMenu = subMenuItem->GetSubMenu();
+        if (!subMenu)          return;
+        // and append
+        subMenu->Append(idCamelCase, _("CamelCase"), _("Make selection CamelCase"));
     }
 }
 void SpellCheckerPlugin::BuildModuleMenu(const ModuleType type, wxMenu* menu, const FileTreeData* data)
@@ -266,6 +285,35 @@
     cbStyledTextCtrl *stc = ed->GetControl();
     if ( !stc ) return;
 
+    const int id = menu->FindItem(_("Edit"));
+    if (id != wxNOT_FOUND)
+    {
+        wxMenuItem* subMenuItem = menu->FindItem(id, 0);
+        wxMenu* subMenu;
+        if (subMenuItem)
+            subMenu = subMenuItem->GetSubMenu();
+        if (subMenu)
+        {
+            int insertPos = wxNOT_FOUND;
+            const wxMenuItemList itemsList = subMenu->GetMenuItems();
+            for (size_t i = 0; i < itemsList.GetCount(); ++i)
+            {
+                #if wxCHECK_VERSION(2, 9, 0)
+                if (itemsList[i]->GetItemLabelText() == _("lowercase"))
+                #else
+                if (itemsList[i]->GetLabel() == _("lowercase"))
+                #endif
+                {
+                    insertPos = i + 1;
+                    break;
+                }
+            }
+            if (insertPos != wxNOT_FOUND)
+                subMenu->Insert(insertPos, idCamelCase, _("CamelCase"));
+            else
+                subMenu->Append(idCamelCase, _("CamelCase"));
+        }
+    }
 
     int pos = stc->GetCurrentPos();
     stc->GetIndicatorValue();
@@ -397,7 +445,128 @@
     else
         event.Enable(false);
 }
+void SpellCheckerPlugin::OnCamelCase(wxCommandEvent &event)
+{
+    cbEditor *ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
+    if (!ed || !m_pSpellChecker->IsInitialized()) return;
+    cbStyledTextCtrl *stc = ed->GetControl();
+    if (!stc) return;
 
+    // take only the first word from the selection
+    int selstart = stc->GetSelectionStart();
+    while (selstart < stc->GetLength())
+    {
+        if ( !m_pSpellHelper->IsWhiteSpace(stc->GetCharAt(selstart)) )
+            break;
+        ++selstart;
+    }
+    // and scan back for the actual word start
+    while (selstart > 0)
+    {
+        if ( m_pSpellHelper->IsWhiteSpace(stc->GetCharAt(selstart - 1)) )
+            break;
+        --selstart;
+    }
+    if (selstart > stc->GetSelectionEnd())
+        return;
+    int selend = selstart;
+    while (selend < stc->GetLength())
+    {
+        if ( m_pSpellHelper->IsWhiteSpace(stc->GetCharAt(++selend)) )
+            break;
+    }
+
+    if (selend - selstart < 4) // too small
+        return;
+    else if (selend - selstart > 30) // max limit (DoGetWordStarts() is recursive, so watch out)
+        selend = selstart + 30;
+
+    wxString text = stc->GetTextRange(selstart, selend);
+    wxArrayString prefixes = GetArrayFromString(wxT("Get;Set;Do;On;Is;wx"));
+    prefixes.Add(wxEmptyString); // check without prefix
+    prefixes.Add(wxT("p")); // less common prefix, check last
+    for (size_t i = 0; i < prefixes.GetCount(); ++i)
+    {
+        wxString word = text;
+        if (!prefixes[i].IsEmpty()) // try with prefix
+        {
+            if (!text.Lower().StartsWith(prefixes[i].Lower(), &word))
+                continue; // no, try next prefix
+        }
+        wxString camelWord;
+        for (size_t j = 0; j < word.Length() / 2; ++j) // 0 index number of words to break into
+        {
+            wxArrayInt wordStarts;
+            if (DoGetWordStarts(word.Lower(), wordStarts, j))
+            {
+                for (size_t k = 0; k < word.Length(); ++k) // make CamelCase
+                {
+                    if (wordStarts.Index(k) == wxNOT_FOUND)
+                        camelWord << word.Lower()[k];
+                    else
+                        camelWord << word.Upper()[k];
+                }
+                break;
+            }
+        }
+        if (!camelWord.IsEmpty())
+        {
+            if (i != prefixes.GetCount())
+                camelWord.Prepend(prefixes[i]);
+            if (text == camelWord)
+                return; // already formed, so do nothing
+            stc->BeginUndoAction();
+            stc->DeleteRange(selstart, text.Length());
+            stc->InsertText(selstart, camelWord);
+            stc->SetSelectionStart(selstart);
+            stc->SetSelectionEnd(selend);
+            stc->EndUndoAction();
+            return; // exit
+        }
+    }
+}
+bool SpellCheckerPlugin::DoGetWordStarts(const wxString& word, wxArrayInt& wordStarts, int numWords)
+{
+    if (numWords <= 0) // finish split
+    {
+        wordStarts.Add(0); // first word
+        wxString currWord;
+        for (int i = wordStarts.GetCount() - 1; i > 0; --i) // reverse iteration (so numbers are checked lowest to highest)
+        {
+            currWord = word(wordStarts[i], wordStarts[i - 1] - wordStarts[i]);
+            if (currWord.Length() > 3) // capitalize medium/long words so proper nouns work
+                currWord = currWord(0, 1).Upper() + currWord.Mid(1);
+            if (!m_pSpellChecker->IsWordInDictionary(currWord))
+            {
+                wordStarts.RemoveAt(wordStarts.GetCount() - 1);
+                return false; // no, fall back a level
+            }
+        }
+        currWord = word.Mid(wordStarts[0]);
+        if (currWord.Length() > 3) // capitalize
+            currWord = currWord(0, 1).Upper() + currWord.Mid(1);
+        if (!m_pSpellChecker->IsWordInDictionary(currWord)) // last word (wordStarts[] is reverse sorted)
+        {
+            wordStarts.RemoveAt(wordStarts.GetCount() - 1);
+            return false; // no, fall back a level
+        }
+        return true; // all parts are correctly spelled
+    }
+
+    // iterate through possibilities of the current word start
+    for (int i = (wordStarts.IsEmpty() ? word.Length() : wordStarts[wordStarts.GetCount() - 1]) - 2;
+         i >= numWords * 2; --i)
+    {
+        wordStarts.Add(i);
+        if (DoGetWordStarts(word, wordStarts, numWords - 1))
+        {
+            return true; // yes, fall through and return
+        }
+        wordStarts.RemoveAt(wordStarts.GetCount() - 1);
+    }
+    return false; // no, fall back an iteration
+}
+
 bool SpellCheckerPlugin::ActiveEditorHasTextSelected(void)
 {
     cbEditor *ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
@@ -527,3 +696,139 @@
 
 
 }
+
+void SpellCheckerPlugin::OnEditorTooltip(CodeBlocksEvent& event)
+{
+    if (   !IsAttached() || wxGetKeyState(WXK_CONTROL)
+        || !(m_sccfg->GetEnableSpellTooltips() || m_sccfg->GetEnableThesaurusTooltips()))
+    {
+        event.Skip();
+        return;
+    }
+    EditorBase* base = event.GetEditor();
+    cbEditor* ed = base && base->IsBuiltinEditor() ? static_cast<cbEditor*>(base) : 0;
+    if (   !ed || ed->IsContextMenuOpened()
+        || wxWindow::FindFocus() != static_cast<wxWindow*>(ed->GetControl()) )
+    {
+        event.Skip();
+        return;
+    }
+    cbStyledTextCtrl* stc = ed->GetControl();
+    if (!stc)
+        return;
+    int pos = stc->PositionFromPointClose(event.GetX(), event.GetY());
+    if (pos < 0 || pos >= stc->GetLength())
+    {
+        event.Skip();
+        return;
+    }
+
+    wxString tip;
+    int wordstart = pos, wordend = pos;
+    while (wordstart)
+    {
+        if ( m_pSpellHelper->IsWhiteSpace( stc->GetCharAt(wordstart - 1) ) )
+            break;
+        --wordstart;
+    }
+    while ( wordend < stc->GetLength() )
+    {
+        if ( m_pSpellHelper->IsWhiteSpace( stc->GetCharAt(++wordend) ) )
+            break;
+    }
+    int tipWidth = 0;
+    if (   m_sccfg->GetEnableSpellTooltips()
+        && m_pSpellChecker->IsInitialized()
+        && stc->IndicatorValueAt(m_pOnlineChecker->GetIndicator(), pos))
+    {
+        // indicator is on -> check if we can find a suggestion
+        wxString misspelledWord = stc->GetTextRange(wordstart, wordend);
+        m_suggestions = m_pSpellChecker->GetSuggestions(misspelledWord);
+        if (!m_suggestions.IsEmpty())
+        {
+            // allow maximum 12 entries in 3 rows
+            int lineWidth = 0;
+            for (size_t i = 0; i < 12 && i < m_suggestions.size(); ++i)
+            {
+                tip << m_suggestions[i];
+                lineWidth += m_suggestions[i].Length();
+                if (i % 4 == 3)
+                {
+                    tip << wxT(",\n");
+                    if (lineWidth > tipWidth)
+                        tipWidth = lineWidth;
+                    lineWidth = 0;
+                }
+                else
+                {
+                    tip << wxT(", ");
+                    lineWidth += 2;
+                }
+            }
+            tip.RemoveLast(2);
+            lineWidth -= 2;
+            if (lineWidth > tipWidth) // in case the last line was not full, and thereby not checked
+                tipWidth = lineWidth;
+        }
+    }
+    else if (   m_sccfg->GetEnableThesaurusTooltips()
+             && m_pThesaurus->IsOk()
+             && m_pSpellHelper->HasStyleToBeChecked(ed->GetColourSet()->GetLanguageName(ed->GetLanguage()), event.GetInt()))
+    {
+        wxString word = stc->GetTextRange(wordstart, wordend);
+        synonyms syn = m_pThesaurus->GetSynonyms(word);
+        if (!syn.size()) // if not found, try lower case
+            syn = m_pThesaurus->GetSynonyms(word.Lower());
+        if (syn.size())
+        {
+            wxArrayString usedSyns; // avoid duplicate synonyms
+            // allow maximum 12 entries in 4 rows
+            synonyms::iterator it = syn.begin();
+            for (size_t i = 0; i < 4 && it != syn.end(); ++i, ++it)
+            {
+                wxString tipLine(it->first + wxT(": "));
+                std::vector< wxString > syns = syn[it->first];
+                size_t j = 0;
+                for (size_t k = 0; k < 3 && j < syns.size(); ++j, ++k)
+                {
+                    if (usedSyns.Index(syns[j]) == wxNOT_FOUND)
+                    {
+                        tipLine << syns[j] << wxT(", ");
+                        usedSyns.Add(syns[j]);
+                    }
+                    else
+                        --k; // synonym already listed, look for another word
+                }
+                tipLine.RemoveLast(2);
+                if (tipLine.Length() > tipWidth)
+                    tipWidth = tipLine.Length();
+                tip << tipLine << wxT("\n");
+            }
+            tip.RemoveLast();
+        }
+    }
+
+    if (tip.IsEmpty())
+    {
+        event.Skip();
+        return;
+    }
+
+    if (stc->CallTipActive())
+        stc->CallTipCancel();
+    // calculation from CC
+    int lnStart = stc->PositionFromLine(stc->LineFromPosition(pos));
+                  // pos - lnStart   == distance from start of line
+                  //  + tipWidth + 1 == projected virtual position of tip end (with a 1 character buffer) from start of line
+                  //  - (width_of_editor_in_pixels / width_of_character) == distance tip extends past window edge
+                  //       horizontal scrolling is accounted for by PointFromPosition().x
+    int offset = tipWidth + pos + 1 - lnStart -
+                 (stc->GetSize().x - stc->PointFromPosition(lnStart).x) /
+                  stc->TextWidth(wxSCI_STYLE_LINENUMBER, _T("W"));
+    if (offset > 0)
+        pos -= offset;
+    if (pos < lnStart) // do not go to previous line if tip is wider than editor
+        pos = lnStart;
+
+    stc->CallTipShow(pos, tip);
+}
Index: src/plugins/contrib/SpellChecker/SpellCheckerConfig.h
===================================================================
--- src/plugins/contrib/SpellChecker/SpellCheckerConfig.h	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellCheckerConfig.h	(working copy)
@@ -33,6 +33,10 @@
 
         bool GetEnableOnlineChecker();
         void SetEnableOnlineChecker(bool val);
+        bool GetEnableSpellTooltips();
+        void SetEnableSpellTooltips(bool val);
+        bool GetEnableThesaurusTooltips();
+        void SetEnableThesaurusTooltips(bool val);
         const wxString GetDictionaryName()const;
         void SetDictionaryName(wxString val);
         void Load();
@@ -64,6 +68,8 @@
         wxString m_ThesPath;
         wxString m_BitmPath;
         bool m_EnableOnlineChecker;
+        bool m_EnableSpellTooltips;
+        bool m_EnableThesaurusTooltips;
         wxString m_strDictionaryName;
         std::vector<wxString> m_dictionaries;
         int selectedDictionary;
Index: src/plugins/contrib/SpellChecker/Thesaurus.h
===================================================================
--- src/plugins/contrib/SpellChecker/Thesaurus.h	(revision 8417)
+++ src/plugins/contrib/SpellChecker/Thesaurus.h	(working copy)
@@ -26,6 +26,10 @@
 #include "wx/wx.h"
 #endif
 
+#include <map>
+#include <vector>
+typedef std::map<wxString, std::vector< wxString > > synonyms;
+
 class wxThes;
 class Thesaurus
 {
@@ -35,6 +39,7 @@
         virtual ~Thesaurus();
 
         bool GetSynonym(const wxString Word, wxString &Syn);
+        synonyms GetSynonyms(const wxString& Word);
         void SetFiles(wxString idxpath, const wxString datpath);
         bool IsOk();
 
Index: src/plugins/contrib/SpellChecker/Thesaurus.cpp
===================================================================
--- src/plugins/contrib/SpellChecker/Thesaurus.cpp	(revision 8417)
+++ src/plugins/contrib/SpellChecker/Thesaurus.cpp	(working copy)
@@ -123,6 +123,13 @@
 
 }
 
+synonyms Thesaurus::GetSynonyms(const wxString& Word)
+{
+    synonyms syn;
+    if (m_pT)
+        syn = m_pT->Lookup(Word);
+    return syn;
+}
 
 bool Thesaurus::IsOk()
 {
Index: src/plugins/contrib/SpellChecker/SpellChecker.cbp
===================================================================
--- src/plugins/contrib/SpellChecker/SpellChecker.cbp	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellChecker.cbp	(working copy)
@@ -65,7 +65,7 @@
 				<Option object_output="..\..\..\.objs\plugins\contrib\SpellChecker" />
 				<Option type="3" />
 				<Option compiler="gcc" />
-				<Option parameters="--debug-log --no-check-associations -ns -nd" />
+				<Option parameters="--debug-log --no-check-associations -ns -nd --multiple-instance" />
 				<Option host_application="..\..\..\devel\codeblocks.exe" />
 				<Option run_host_application_in_terminal="0" />
 				<Compiler>
@@ -99,20 +99,20 @@
 					<Add after="cmd /c if not exist ..\..\..\devel\share\CodeBlocks\SpellChecker mkdir ..\..\..\devel\share\CodeBlocks\SpellChecker" />
 					<Add after="cmd /c if not exist ..\..\..\devel\share\CodeBlocks\images\settings mkdir ..\..\..\devel\share\CodeBlocks\images\settings" />
 					<Add after="zip -j9 ..\..\..\devel\share\CodeBlocks\SpellChecker.zip manifest.xml SpellCheckSettingsPanel.xrc" />
-					<Add after='xcopy /Y *.png &quot;..\..\..\devel\share\Codeblocks\images\settings\*&quot;' />
-					<Add after='xcopy /Y *.png &quot;..\..\..\output\share\Codeblocks\images\settings\*&quot;' />
-					<Add after='xcopy /Y OnlineSpellChecking.xml  &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
-					<Add after='xcopy /Y dictionaries\*.aff &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
-					<Add after='xcopy /Y dictionaries\*.dic &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
-					<Add after='xcopy /Y dictionaries\th_*.dat &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
-					<Add after='xcopy /Y dictionaries\th_*.idx &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
-					<Add after='xcopy /Y rc\*.png &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
-					<Add after='xcopy /y &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\*&quot; &quot;..\..\..\output\share\CodeBlocks\SpellChecker\*&quot;' />
+					<Add after='xcopy /D /Y *.png &quot;..\..\..\devel\share\Codeblocks\images\settings\*&quot;' />
+					<Add after='xcopy /D /Y *.png &quot;..\..\..\output\share\Codeblocks\images\settings\*&quot;' />
+					<Add after='xcopy /D /Y OnlineSpellChecking.xml  &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
+					<Add after='xcopy /D /Y dictionaries\*.aff &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
+					<Add after='xcopy /D /Y dictionaries\*.dic &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
+					<Add after='xcopy /D /Y dictionaries\th_*.dat &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
+					<Add after='xcopy /D /Y dictionaries\th_*.idx &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
+					<Add after='xcopy /D /Y rc\*.png &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\&quot;' />
+					<Add after='xcopy /D /Y &quot;..\..\..\devel\share\CodeBlocks\SpellChecker\*&quot; &quot;..\..\..\output\share\CodeBlocks\SpellChecker\*&quot;' />
 					<Mode after="always" />
 				</ExtraCommands>
 				<Environment>
+					<Variable name="WX_CFG" value="" />
 					<Variable name="WX_SUFFIX" value="u" />
-					<Variable name="WX_CFG" value="" />
 				</Environment>
 			</Target>
 		</Build>
Index: src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.cpp
===================================================================
--- src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.cpp	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.cpp	(working copy)
@@ -47,6 +47,8 @@
     //(*Initialize(SpellCheckSettingsPanel)
     wxXmlResource::Get()->LoadObject(this,parent,_T("SpellCheckSettingsPanel"),_T("wxPanel"));
     m_checkEnableOnlineSpellChecker = (wxCheckBox*)FindWindow(XRCID("ID_CHECKBOX1"));
+    m_checkSpellTooltips = (wxCheckBox*)FindWindow(XRCID("ID_CHECKBOX2"));
+    m_checkThesaurusTooltips = (wxCheckBox*)FindWindow(XRCID("ID_CHECKBOX3"));
     StaticText3 = (wxStaticText*)FindWindow(XRCID("ID_STATICTEXT3"));
     m_choiceDictionary = (wxChoice*)FindWindow(XRCID("ID_CHOICE3"));
     StaticText1 = (wxStaticText*)FindWindow(XRCID("ID_STATICTEXT1"));
@@ -115,6 +117,8 @@
 
     m_checkEnableOnlineSpellChecker->Enable(!dics.empty());
     m_checkEnableOnlineSpellChecker->SetValue( m_sccfg->GetEnableOnlineChecker() && (!dics.empty()) );
+    m_checkSpellTooltips->SetValue( m_sccfg->GetEnableSpellTooltips() && (!dics.empty()) );
+    m_checkThesaurusTooltips->SetValue( m_sccfg->GetEnableThesaurusTooltips() && (!dics.empty()) );
 }
 wxString SpellCheckSettingsPanel::GetTitle() const {return _T("SpellChecker");}
 
@@ -123,6 +127,8 @@
 void SpellCheckSettingsPanel::PostConfig()
 {
     m_sccfg->SetEnableOnlineChecker(m_checkEnableOnlineSpellChecker->GetValue());
+    m_sccfg->SetEnableSpellTooltips(m_checkSpellTooltips->GetValue());
+    m_sccfg->SetEnableThesaurusTooltips(m_checkThesaurusTooltips->GetValue());
     std::vector<wxString> dics = m_sccfg->GetPossibleDictionaries();
     const int sel = m_choiceDictionary->GetSelection();
     if ( sel < static_cast<int>(dics.size()) && sel != wxNOT_FOUND )
Index: src/plugins/contrib/SpellChecker/wxsmith/SpellCheckSettingsPanel.wxs
===================================================================
--- src/plugins/contrib/SpellChecker/wxsmith/SpellCheckSettingsPanel.wxs	(revision 8417)
+++ src/plugins/contrib/SpellChecker/wxsmith/SpellCheckSettingsPanel.wxs	(working copy)
@@ -3,6 +3,8 @@
 	<resource_extra>
 		<object root="1" />
 		<object name="ID_CHECKBOX1" class="wxCheckBox" variable="m_checkEnableOnlineSpellChecker" member="yes" />
+		<object name="ID_CHECKBOX2" class="wxCheckBox" variable="m_checkSpellTooltips" member="yes" />
+		<object name="ID_CHECKBOX3" class="wxCheckBox" variable="m_checkThesaurusTooltips" member="yes" />
 		<object name="ID_STATICTEXT3" class="wxStaticText" variable="StaticText3" member="yes" />
 		<object name="ID_CHOICE3" class="wxChoice" variable="m_choiceDictionary" member="yes" />
 		<object name="ID_STATICTEXT1" class="wxStaticText" variable="StaticText1" member="yes" />
Index: src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.xrc
===================================================================
--- src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.xrc	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellCheckSettingsPanel.xrc	(working copy)
@@ -12,6 +12,22 @@
 				<border>5</border>
 			</object>
 			<object class="sizeritem">
+				<object class="wxCheckBox" name="ID_CHECKBOX2">
+					<label>Enable spelling suggestion tooltips</label>
+					<checked>1</checked>
+				</object>
+				<flag>wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_TOP</flag>
+				<border>5</border>
+			</object>
+			<object class="sizeritem">
+				<object class="wxCheckBox" name="ID_CHECKBOX3">
+					<label>Enable thesaurus tooltips</label>
+					<checked>1</checked>
+				</object>
+				<flag>wxALL|wxALIGN_LEFT|wxALIGN_TOP</flag>
+				<border>5</border>
+			</object>
+			<object class="sizeritem">
 				<object class="wxStaticBoxSizer">
 					<label>Language</label>
 					<object class="sizeritem">
Index: src/plugins/contrib/SpellChecker/SpellCheckerPlugin.h
===================================================================
--- src/plugins/contrib/SpellChecker/SpellCheckerPlugin.h	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellCheckerPlugin.h	(working copy)
@@ -149,6 +149,8 @@
         void OnUpdateSpelling(wxUpdateUIEvent &event);
         void OnUpdateThesaurus(wxUpdateUIEvent &event);
         void OnThesaurus(wxCommandEvent &event);
+        void OnCamelCase(wxCommandEvent &event);
+        bool DoGetWordStarts(const wxString& word, wxArrayInt& wordStarts, int numWords);
         void OnReplaceBySuggestion(wxCommandEvent &event);
         void OnMoreSuggestions(wxCommandEvent &event);
         void OnAddToPersonalDictionary(wxCommandEvent &event);
@@ -158,6 +160,7 @@
         void ConfigurePersonalDictionary();
         void SavePersonalDictionary();
         void OnEditorSaved(CodeBlocksEvent& event);
+        void OnEditorTooltip(CodeBlocksEvent& event);
         //void OnRightUpOverStatus(wxMouseEvent &event);
         bool ActiveEditorHasTextSelected(void);
 
Index: src/plugins/contrib/SpellChecker/SpellCheckerConfig.cpp
===================================================================
--- src/plugins/contrib/SpellChecker/SpellCheckerConfig.cpp	(revision 8417)
+++ src/plugins/contrib/SpellChecker/SpellCheckerConfig.cpp	(working copy)
@@ -26,11 +26,13 @@
 
 #include <configmanager.h>
 
-#define CFG_SPELLCHECK_ENABLE_ONLINE_CHECK _T("/SpellChecker/EnableOnlineChecker")
-#define CFG_SPELLCHECK_DICTIONARY_NAME     _T("/SpellChecker/Dictionary")
-#define CFG_SPELLCHECK_DICTIONARY_PATH     _T("/SpellChecker/DictPath")
-#define CFG_SPELLCHECK_THESAURI_PATH       _T("/SpellChecker/ThesPath")
-#define CFG_SPELLCHECK_BITMAPS_PATH        _T("/SpellChecker/BitmPath")
+#define CFG_SPELLCHECK_ENABLE_ONLINE_CHECK      _T("/SpellChecker/EnableOnlineChecker")
+#define CFG_SPELLCHECK_SPELL_TOOLTIPS_CHECK     _T("/SpellChecker/SpellTooltips")
+#define CFG_SPELLCHECK_THESAURUS_TOOLTIPS_CHECK _T("/SpellChecker/ThesTooltips")
+#define CFG_SPELLCHECK_DICTIONARY_NAME          _T("/SpellChecker/Dictionary")
+#define CFG_SPELLCHECK_DICTIONARY_PATH          _T("/SpellChecker/DictPath")
+#define CFG_SPELLCHECK_THESAURI_PATH            _T("/SpellChecker/ThesPath")
+#define CFG_SPELLCHECK_BITMAPS_PATH             _T("/SpellChecker/BitmPath")
 
 SpellCheckerConfig::SpellCheckerConfig(SpellCheckerPlugin *plugin)
     ://m_DictionaryPath(plugin->GetDic),
@@ -55,6 +57,22 @@
 {
     m_EnableOnlineChecker = val;
 }
+bool SpellCheckerConfig::GetEnableSpellTooltips()
+{
+    return m_EnableSpellTooltips;
+}
+void SpellCheckerConfig::SetEnableSpellTooltips(bool val)
+{
+    m_EnableSpellTooltips = val;
+}
+bool SpellCheckerConfig::GetEnableThesaurusTooltips()
+{
+    return m_EnableThesaurusTooltips;
+}
+void SpellCheckerConfig::SetEnableThesaurusTooltips(bool val)
+{
+    m_EnableThesaurusTooltips = val;
+}
 const wxString SpellCheckerConfig::GetDictionaryName()const
 {
     return m_strDictionaryName;
@@ -210,6 +228,8 @@
     if (ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("editor")))
     {
         m_EnableOnlineChecker = cfg->ReadBool(CFG_SPELLCHECK_ENABLE_ONLINE_CHECK, true);
+        m_EnableSpellTooltips = cfg->ReadBool(CFG_SPELLCHECK_SPELL_TOOLTIPS_CHECK, true);
+        m_EnableThesaurusTooltips = cfg->ReadBool(CFG_SPELLCHECK_THESAURUS_TOOLTIPS_CHECK, true);
         m_strDictionaryName = cfg->Read(CFG_SPELLCHECK_DICTIONARY_NAME, _T("de_CH") );
         m_DictPath = cfg->Read(CFG_SPELLCHECK_DICTIONARY_PATH, m_pPlugin->GetOnlineCheckerConfigPath());
         m_ThesPath = cfg->Read(CFG_SPELLCHECK_THESAURI_PATH, m_pPlugin->GetOnlineCheckerConfigPath());
@@ -221,6 +241,8 @@
     if(ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("editor")))
     {
         cfg->Write(CFG_SPELLCHECK_ENABLE_ONLINE_CHECK, m_EnableOnlineChecker);
+        cfg->Write(CFG_SPELLCHECK_SPELL_TOOLTIPS_CHECK, m_EnableSpellTooltips);
+        cfg->Write(CFG_SPELLCHECK_THESAURUS_TOOLTIPS_CHECK, m_EnableThesaurusTooltips);
         cfg->Write(CFG_SPELLCHECK_DICTIONARY_NAME, m_strDictionaryName);
         cfg->Write(CFG_SPELLCHECK_DICTIONARY_PATH, m_DictPath);
         cfg->Write(CFG_SPELLCHECK_THESAURI_PATH, m_ThesPath);
