#include <cstdlib> // for std::abort ()
#include <string>
#include <iostream>
#include "Utility/ExH/System/Exception.hpp"
#include "Utility/ExH/Logic/Exception.hpp"
using std::cerr;
using std::cout;
using std::endl;
using namespace Utility;
class Application
{
public:
  class Exception : public ExH::Logic::Exception {};
  class FeelingDizzy  : public Exception {};
  class InvalidArg : public Exception {};
public:
  Application () throw (ExH::System::Exception)
      : greeting_ ("Hello, world!")
  {
  }
  Application (char const * greeting) throw (InvalidArg,
                                             ExH::System::Exception)
      : greeting_ (greeting == 0 ? "" : greeting)
  {
    if (greeting == 0) throw InvalidArg ();
  }
public:
  void
  run () throw (FeelingDizzy, ExH::System::Exception)
  {
    static unsigned int dizzy_count (0);
    if (dizzy_count++ < 5) throw FeelingDizzy ();
    cout << greeting_.c_str () << endl;
  }
private:
  std::string  greeting_;
};
int
main ()
{
  try
  {
    try
    {
      try
      {
        try
        {
          for (int i = 0; i < 10; i++)
          {
            try
            {
              Application app ("Hi dude!");
              app.run ();
              break;
            }
            catch (Application::FeelingDizzy const& )
            {
              if (i == 9)
              {
                cerr << "Given up!" << endl;
                return -1;
              }
              else
              {
                cerr << "Application is feeling dizzy. Trying again..."
                     << endl;
              }
            }
          }
        }
        catch (Application::InvalidArg const& )
        {
          cerr << "Cought Application::InvalidArg : ...hmm... strange!"
               << endl;
          return -1;
        }
      }
      catch (ExH::Logic::Exception const& e)
      {
        cerr << "Caught Logic::Exception : " << e.what () << endl;
        return -1;
      }
    }
    catch (const ExH::System::Exception& e)
    {
      cerr << "Caught System::Exception : " << e.what () << endl;
      return -1;
    }
    catch (...)
    {
      cerr << "Caught unknown exception using catch-all handler. " << endl;
      return -1;
    }
  }
  catch (...)
  {
    std::abort ();
  }
}