diff --git a/c++/demo.cc b/c++/demo.cc
new file mode 100644
index 0000000..ddd5f2b
--- /dev/null
+++ b/c++/demo.cc
@@ -0,0 +1,563 @@
+// * This makes emacs happy -*-Mode: C++;-*-
+/****************************************************************************
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/*
+ *   Silly demo program for the NCursesPanel class.
+ *
+ *   written by Anatoly Ivasyuk (anatoly@nick.csh.rit.edu)
+ *
+ *   Demo code for NCursesMenu and NCursesForm written by
+ *   Juergen Pfeifer
+ *
+ * $Id: demo.cc,v 1.38 2008/08/04 17:16:57 tom Exp $
+ */
+
+#include "internal.h"
+#include "cursesapp.h"
+#include "cursesm.h"
+#include "cursesf.h"
+
+extern "C" unsigned int sleep(unsigned int);
+
+#undef index // needed for NeXT
+
+//
+// -------------------------------------------------------------------------
+//
+class SillyDemo
+{
+  public:
+  void run(int sleeptime) {
+
+    NCursesPanel *mystd = new NCursesPanel();
+
+    //  Make a few small demo panels
+
+    NCursesPanel *u = new NCursesPanel(8, 20, 12, 4);
+    NCursesPanel *v = new NCursesPanel(8, 20, 10, 6);
+    NCursesPanel *w = new NCursesPanel(8, 20, 8, 8);
+    NCursesPanel *x = new NCursesPanel(8, 20, 6, 10);
+    NCursesPanel *y = new NCursesPanel(8, 20, 4, 12);
+    NCursesPanel *z = new NCursesPanel(8, 30, 2, 14);
+
+    //  Draw something on the main screen, so we can see what happens
+    //  when panels get moved or deleted.
+
+    mystd->box();
+    mystd->move(mystd->height()/2, 1);
+    mystd->hline(mystd->width()-2);
+    mystd->move(1, mystd->width()/2);
+    mystd->vline(mystd->height()-2);
+    mystd->addch(0, mystd->width()/2, ACS_TTEE);
+    mystd->addch(mystd->height()-1, mystd->width()/2, ACS_BTEE);
+    mystd->addch(mystd->height()/2, 0, ACS_LTEE);
+    mystd->addch(mystd->height()/2, mystd->width()-1, ACS_RTEE);
+    mystd->addch(mystd->height()/2, mystd->width()/2, ACS_PLUS);
+
+    //  Draw frames with titles around panels so that we can see where
+    //  the panels are located.
+    u->boldframe("Win U");
+    v->frame("Win V");
+    w->boldframe("Win W");
+    x->frame("Win X");
+    y->boldframe("Win Y");
+    z->frame("Win Z");
+    if (NCursesApplication::getApplication()->useColors()) {
+      u->bkgd(' '|COLOR_PAIR(1));
+      w->bkgd(' '|COLOR_PAIR(1));
+      y->bkgd(' '|COLOR_PAIR(1));
+      v->bkgd(' '|COLOR_PAIR(2));
+      x->bkgd(' '|COLOR_PAIR(2));
+      z->bkgd(' '|COLOR_PAIR(2));
+    }
+
+    //  A refresh to any valid panel updates all panels and refreshes
+    //  the screen.  Using mystd is just convenient - We know it's always
+    //  valid until the end of the program.
+
+    mystd->refresh();
+    sleep(sleeptime);
+
+    //  Show what happens when panels are deleted and moved.
+
+    sleep(sleeptime);
+    delete u;
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete z;
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete v;
+    mystd->refresh();
+
+    // show how it looks when a panel moves
+    sleep(sleeptime);
+    y->mvwin(5, 30);
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete y;
+    mystd->refresh();
+
+    // show how it looks when you raise a panel
+    sleep(sleeptime);
+    w->top();
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete w;
+    mystd->refresh();
+
+    sleep(sleeptime);
+    delete x;
+
+    mystd->clear();
+    mystd->refresh();
+
+    //  Don't forget to clean up the main screen.  Since this is the
+    //  last thing using NCursesWindow, this has the effect of
+    //  shutting down ncurses and restoring the terminal state.
+
+    sleep(sleeptime);
+    delete mystd;
+  }
+};
+
+class UserData
+{
+private:
+  int u;
+public:
+  UserData(int x) : u(x) {}
+  int sleeptime() const { return u; }
+};
+//
+// -------------------------------------------------------------------------
+//
+template<class T> class MyAction : public NCursesUserItem<T>
+{
+public:
+  MyAction (const char* p_name,
+            const T* p_UserData)
+    : NCursesUserItem<T>(p_name, static_cast<const char*>(0), p_UserData)
+  {}
+
+  virtual ~MyAction() {}
+
+  bool action() {
+    SillyDemo a;
+    a.run(NCursesUserItem<T>::UserData()->sleeptime());
+    return FALSE;
+  }
+};
+
+template class MyAction<UserData>;
+template class NCURSES_IMPEXP NCursesUserItem<UserData>;
+
+class QuitItem : public NCursesMenuItem
+{
+public:
+  QuitItem() : NCursesMenuItem("Quit") {
+  }
+
+  bool action() {
+    return TRUE;
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class Label : public NCursesFormField
+{
+public:
+  Label(const char* title,
+        int row, int col)
+    : NCursesFormField(1, static_cast<int>(::strlen(title)), row, col) {
+      set_value(title);
+      options_off(O_EDIT|O_ACTIVE);
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class MyFieldType : public UserDefinedFieldType
+{
+private:
+  int chk;
+protected:
+  bool field_check(NCursesFormField& f) {
+    return TRUE;
+  }
+  bool char_check(int c) {
+    return (c==chk?TRUE:FALSE);
+  }
+public:
+  MyFieldType(int x) : chk(x) {
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class TestForm : public NCursesForm
+{
+private:
+  NCursesFormField** F;
+  MyFieldType* mft;
+  Integer_Field *ift;
+  Enumeration_Field *eft;
+
+  static const char *weekdays[];
+
+public:
+  TestForm()
+    : NCursesForm(13, 51, (lines() - 15)/2, (cols() - 53)/2),
+      F(0),
+      mft(0),
+      ift(0),
+      eft(0)
+  {
+
+    F     = new NCursesFormField*[10];
+    mft   = new MyFieldType('X');
+    ift   = new Integer_Field(0, 1, 10);
+    eft   = new Enumeration_Field(weekdays);
+
+    F[0]  = new Label("Demo Entry Form", 0, 16);
+    F[1]  = new Label("Weekday Enum", 2, 1);
+    F[2]  = new Label("Number(1-10)", 2, 21);
+    F[3]  = new Label("Only 'X'", 2, 35);
+    F[4]  = new Label("Multiline Field (Dynamic and Scrollable)", 5, 1);
+    F[5]  = new NCursesFormField(1, 18, 3, 1);
+    F[6]  = new NCursesFormField(1, 12, 3, 21);
+    F[7]  = new NCursesFormField(1, 12, 3, 35);
+    F[8]  = new NCursesFormField(4, 46, 6, 1, 2);
+    F[9]  = new NCursesFormField();
+
+    InitForm(F, TRUE, TRUE);
+    boldframe();
+
+    F[5]->set_fieldtype(*eft);
+    F[6]->set_fieldtype(*ift);
+
+    F[7]->set_fieldtype(*mft);
+    F[7]->set_maximum_growth(20); // max. 20 characters
+    F[7]->options_off(O_STATIC);  // make field dynamic
+
+    F[8]->set_maximum_growth(10); // max. 10 lines
+    F[8]->options_off(O_STATIC);  // make field dynamic
+  }
+
+  TestForm& operator=(const TestForm& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  TestForm(const TestForm& rhs)
+    : NCursesForm(rhs), F(0), mft(0), ift(0), eft(0)
+  {
+  }
+
+  ~TestForm() {
+    delete mft;
+    delete ift;
+    delete eft;
+  }
+};
+
+const char* TestForm::weekdays[] = {
+    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+    "Friday", "Saturday", NULL };
+//
+// -------------------------------------------------------------------------
+//
+class FormAction : public NCursesMenuItem
+{
+public:
+  FormAction(const char *s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    TestForm F;
+    Soft_Label_Key_Set* S = new Soft_Label_Key_Set;
+    for(int i=1; i <= S->labels(); i++) {
+      char buf[8];
+      assert(i < 100);
+      ::sprintf(buf, "Frm%02d", i);
+      (*S)[i] = buf;                                      // Text
+      (*S)[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
+    }
+    NCursesApplication::getApplication()->push(*S);
+    F();
+    NCursesApplication::getApplication()->pop();
+    delete S;
+    return FALSE;
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class PadAction : public NCursesMenuItem
+{
+public:
+  PadAction(const char* s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    const int GRIDSIZE = 3;
+    const int PADSIZE  = 200;
+    unsigned gridcount = 0;
+
+    NCursesPanel mystd;
+    NCursesPanel P(mystd.lines()-2, mystd.cols()-2, 1, 1);
+    NCursesFramedPad FP(P, PADSIZE, PADSIZE);
+
+    for (int i=0; i < PADSIZE; i++) {
+      for (int j=0; j < PADSIZE; j++) {
+        if (i % GRIDSIZE == 0 && j % GRIDSIZE == 0) {
+          if (i==0 || j==0)
+            FP.addch('+');
+          else
+            FP.addch(static_cast<chtype>('A' + (gridcount++ % 26)));
+        }
+        else if (i % GRIDSIZE == 0)
+          FP.addch('-');
+        else if (j % GRIDSIZE == 0)
+          FP.addch('|');
+        else
+          FP.addch(' ');
+      }
+    }
+
+    P.label("Pad Demo", NULL);
+    FP();
+    P.clear();
+    return FALSE;
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class PassiveItem : public NCursesMenuItem
+{
+public:
+  PassiveItem(const char* text) : NCursesMenuItem(text) {
+    options_off(O_SELECTABLE);
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class ScanAction : public NCursesMenuItem
+{
+public:
+  ScanAction(const char* s) : NCursesMenuItem(s) {
+  }
+
+  bool action() {
+    NCursesPanel *mystd = new NCursesPanel();
+
+    NCursesPanel *w = new NCursesPanel(mystd->lines() - 2, mystd->cols() - 2, 1, 1);
+    w->box();
+    w->refresh();
+
+    NCursesPanel *s = new NCursesPanel(w->lines() - 6, w->cols() - 6, 3, 3);
+    s->scrollok(TRUE);
+    ::echo();
+
+    s->printw("Enter decimal integers.  The running total will be shown\n");
+    int nvalue = -1;
+    int result = 0;
+    while (nvalue != 0) {
+      nvalue = 0;
+      s->scanw("%d", &nvalue);
+      if (nvalue != 0) {
+        s->printw("%d: ", result += nvalue);
+      }
+      s->refresh();
+    }
+    s->printw("\nPress any key to continue...");
+    s->getch();
+
+    delete s;
+    delete w;
+    delete mystd;
+    ::noecho();
+    return FALSE;
+  }
+};
+
+//
+// -------------------------------------------------------------------------
+//
+class MyMenu : public NCursesMenu
+{
+private:
+  NCursesPanel* P;
+  NCursesMenuItem** I;
+  UserData *u;
+  #define n_items 7
+
+public:
+  MyMenu ()
+    : NCursesMenu (n_items+2, 8, (lines()-10)/2, (cols()-10)/2),
+      P(0), I(0), u(0)
+  {
+    u = new UserData(1);
+    I = new NCursesMenuItem*[1+n_items];
+    I[0] = new PassiveItem("One");
+    I[1] = new PassiveItem("Two");
+    I[2] = new MyAction<UserData> ("Silly", u);
+    I[3] = new FormAction("Form");
+    I[4] = new PadAction("Pad");
+    I[5] = new ScanAction("Scan");
+    I[6] = new QuitItem();
+    I[7] = new NCursesMenuItem(); // Terminating empty item
+
+    InitMenu(I, TRUE, TRUE);
+
+    P = new NCursesPanel(1, n_items, LINES-1, 1);
+    boldframe("Demo", "Silly");
+    P->show();
+  }
+
+  MyMenu& operator=(const MyMenu& rhs)
+  {
+    if (this != &rhs) {
+      *this = rhs;
+    }
+    return *this;
+  }
+
+  MyMenu(const MyMenu& rhs)
+    : NCursesMenu(rhs), P(0), I(0), u(0)
+  {
+  }
+
+  ~MyMenu()
+  {
+    P->hide();
+    delete P;
+    delete u;
+  }
+
+  virtual void On_Menu_Init()
+  {
+    NCursesWindow W(::stdscr);
+    P->move(0, 0);
+    P->clrtoeol();
+    for(int i=1; i<=count(); i++)
+      P->addch('0' + i);
+    P->bkgd(W.getbkgd());
+    refresh();
+  }
+
+  virtual void On_Menu_Termination()
+  {
+    P->move(0, 0);
+    P->clrtoeol();
+    refresh();
+  }
+
+  virtual void On_Item_Init(NCursesMenuItem& item)
+  {
+    P->move(0, item.index());
+    P->attron(A_REVERSE);
+    P->printw("%1d", 1+item.index());
+    P->attroff(A_REVERSE);
+    refresh();
+  }
+
+  virtual void On_Item_Termination(NCursesMenuItem& item)
+  {
+    P->move(0, item.index());
+    P->attroff(A_REVERSE);
+    P->printw("%1d", 1+item.index());
+    refresh();
+  }
+};
+//
+// -------------------------------------------------------------------------
+//
+class TestApplication : public NCursesApplication
+{
+protected:
+  int titlesize() const { return 1; }
+  void title();
+  Soft_Label_Key_Set::Label_Layout useSLKs() const {
+    return Soft_Label_Key_Set::PC_Style_With_Index;
+  }
+  void init_labels(Soft_Label_Key_Set& S) const;
+
+public:
+  TestApplication() : NCursesApplication(TRUE) {
+  }
+
+  int run();
+};
+
+void TestApplication::init_labels(Soft_Label_Key_Set& S) const
+{
+  for(int i=1; i <= S.labels(); i++) {
+    char buf[8];
+    assert(i < 100);
+    ::sprintf(buf, "Key%02d", i);
+    S[i] = buf;                                      // Text
+    S[i] = Soft_Label_Key_Set::Soft_Label_Key::Left; // Justification
+  }
+}
+
+void TestApplication::title()
+{
+  const char * const titleText = "Simple C++ Binding Demo";
+  const int len = ::strlen(titleText);
+
+  titleWindow->bkgd(screen_titles());
+  titleWindow->addstr(0, (titleWindow->cols() - len)/2, titleText);
+  titleWindow->noutrefresh();
+}
+
+
+int TestApplication::run()
+{
+  MyMenu M;
+  M();
+  return 0;
+}
+
+//
+// -------------------------------------------------------------------------
+//
+static TestApplication *Demo = new TestApplication();
