diff --git a/.gitignore b/.gitignore
index 9734ac35c..776e2b659 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,5 @@ makefile
 data
 *.kdev4
 CMakeLists.txt.user
+*.swp
+*.swo
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 208d348fb..2313d2d95 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,35 +67,6 @@ endif()
 # We probably support older versions than this.
 cmake_minimum_required(VERSION 2.6)
 
-#
-# Pre-built binaries being used?
-#
-IF(EXISTS "${CMAKE_SOURCE_DIR}/prebuilt/vc100-mt-gd/ogre_1_7_1")
-    set(PREBUILT_DIR "${CMAKE_SOURCE_DIR}/prebuilt/vc100-mt-gd")
-    message (STATUS "OpenMW pre-built binaries found at ${PREBUILT_DIR}.")
-
-    SET(ENV{OGRE_HOME} "${PREBUILT_DIR}/ogre_1_7_1")
-
-    SET(ENV{BOOST_ROOT} "${PREBUILT_DIR}/boost_1_42_0")
-    set(Boost_USE_STATIC_LIBS   ON)
-    set(Boost_USE_MULTITHREADED ON)
-    set(ENV{BOOST_INCLUDEDIR} "${BOOST_ROOT}/include")
-    set(ENV{BOOST_LIBRARYDIR} "${BOOST_ROOT}/lib")
-
-    set(ENV{FREETYPE_DIR} "${PREBUILT_DIR}/freetype-2.3.5-1")
-
-    set(USE_MPG123 OFF)
-    set(USE_AUDIERE ON)
-    set(AUDIERE_INCLUDE_DIR "${PREBUILT_DIR}/audiere-1.9.4/include")
-    set(AUDIERE_LIBRARY "${PREBUILT_DIR}/audiere-1.9.4/lib/audiere.lib")
-
-    set(ENV{OPENALDIR} "${PREBUILT_DIR}/OpenAL 1.1 SDK")
-
-    set(BULLET_ROOT "${PREBUILT_DIR}/bullet")
-ELSE()
-    message (STATUS "OpenMW pre-built binaries not found.  Using standard locations.")
-ENDIF()
-
 # source directory: libs
 
 set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp
index 7adc7e6c3..134c582c4 100644
--- a/apps/opencs/model/world/columnbase.cpp
+++ b/apps/opencs/model/world/columnbase.cpp
@@ -1,8 +1,8 @@
 
 #include "columnbase.hpp"
 
-CSMWorld::ColumnBase::ColumnBase (const std::string& title, int flags)
-: mTitle (title), mFlags (flags)
+CSMWorld::ColumnBase::ColumnBase (const std::string& title, Display displayType, int flags)
+: mTitle (title), mDisplayType (displayType), mFlags (flags)
 {}
 
 CSMWorld::ColumnBase::~ColumnBase() {}
diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp
index dc077eff6..38b73ee3f 100644
--- a/apps/opencs/model/world/columnbase.hpp
+++ b/apps/opencs/model/world/columnbase.hpp
@@ -14,7 +14,8 @@ namespace CSMWorld
     {
         enum Roles
         {
-            Role_Flags = Qt::UserRole
+            Role_Flags = Qt::UserRole,
+            Role_Display = Qt::UserRole+1
         };
 
         enum Flags
@@ -23,10 +24,18 @@ namespace CSMWorld
             Flag_Dialogue = 2 // column should be displayed in dialogue view
         };
 
+        enum Display
+        {
+            Display_String,
+            Display_Integer,
+            Display_Float
+        };
+
         std::string mTitle;
         int mFlags;
+        Display mDisplayType;
 
-        ColumnBase (const std::string& title, int flag);
+        ColumnBase (const std::string& title, Display displayType, int flag);
 
         virtual ~ColumnBase();
 
@@ -34,6 +43,7 @@ namespace CSMWorld
 
         virtual bool isUserEditable() const;
         ///< Can this column be edited directly by the user?
+
     };
 
     template<typename ESXRecordT>
@@ -42,8 +52,8 @@ namespace CSMWorld
         std::string mTitle;
         int mFlags;
 
-        Column (const std::string& title, int flags = Flag_Table | Flag_Dialogue)
-        : ColumnBase (title, flags) {}
+        Column (const std::string& title, Display displayType, int flags = Flag_Table | Flag_Dialogue)
+        : ColumnBase (title, displayType, flags) {}
 
         virtual QVariant get (const Record<ESXRecordT>& record) const = 0;
 
diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp
index 5abf4ea8b..1e2de9265 100644
--- a/apps/opencs/model/world/columns.hpp
+++ b/apps/opencs/model/world/columns.hpp
@@ -8,7 +8,7 @@ namespace CSMWorld
     template<typename ESXRecordT>
     struct FloatValueColumn : public Column<ESXRecordT>
     {
-        FloatValueColumn() : Column<ESXRecordT> ("Value") {}
+        FloatValueColumn() : Column<ESXRecordT> ("Value", ColumnBase::Display_Float) {}
 
         virtual QVariant get (const Record<ESXRecordT>& record) const
         {
@@ -31,7 +31,7 @@ namespace CSMWorld
     template<typename ESXRecordT>
     struct StringIdColumn : public Column<ESXRecordT>
     {
-        StringIdColumn() : Column<ESXRecordT> ("ID") {}
+        StringIdColumn() : Column<ESXRecordT> ("ID", ColumnBase::Display_String) {}
 
         virtual QVariant get (const Record<ESXRecordT>& record) const
         {
@@ -47,7 +47,7 @@ namespace CSMWorld
     template<typename ESXRecordT>
     struct RecordStateColumn : public Column<ESXRecordT>
     {
-        RecordStateColumn() : Column<ESXRecordT> ("*") {}
+        RecordStateColumn() : Column<ESXRecordT> ("*", ColumnBase::Display_Integer) {}
 
         virtual QVariant get (const Record<ESXRecordT>& record) const
         {
@@ -78,7 +78,8 @@ namespace CSMWorld
     {
         int mType;
 
-        FixedRecordTypeColumn (int type) : Column<ESXRecordT> ("Type", 0), mType (type) {}
+        FixedRecordTypeColumn (int type)
+        : Column<ESXRecordT> ("Type", ColumnBase::Display_Integer, 0), mType (type) {}
 
         virtual QVariant get (const Record<ESXRecordT>& record) const
         {
diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp
index 2815e318c..afed6b6ed 100644
--- a/apps/opencs/model/world/idtable.cpp
+++ b/apps/opencs/model/world/idtable.cpp
@@ -51,6 +51,9 @@ QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation
     if (role==ColumnBase::Role_Flags)
         return mIdCollection->getColumn (section).mFlags;
 
+    if (role==ColumnBase::Role_Display)
+        return mIdCollection->getColumn (section).mDisplayType;
+
     return QVariant();
 }
 
diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp
index 354223757..2bf6577b1 100644
--- a/apps/opencs/view/world/dialoguesubview.cpp
+++ b/apps/opencs/view/world/dialoguesubview.cpp
@@ -4,8 +4,13 @@
 #include <QGridLayout>
 #include <QLabel>
 #include <QAbstractTableModel>
+#include <QDoubleSpinBox>
+#include <QSpinBox>
+#include <QLineEdit>
+#include <QDataWidgetMapper>
 
 #include "../../model/world/columnbase.hpp"
+#include "../../model/world/idtable.hpp"
 
 CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
     bool createAndDelete)
@@ -23,6 +28,9 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
 
     int columns = model->columnCount();
 
+    mWidgetMapper = new QDataWidgetMapper (this);
+    mWidgetMapper->setModel (model);
+
     for (int i=0; i<columns; ++i)
     {
         int flags = model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
@@ -30,8 +38,54 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM
         if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
         {
             layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0);
+
+            CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
+                (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
+
+            QWidget *widget = 0;
+
+            if (model->flags (model->index (0, i)) & Qt::ItemIsEditable)
+            {
+                switch (display)
+                {
+                    case CSMWorld::ColumnBase::Display_String:
+
+                        layout->addWidget (widget = new QLineEdit, i, 1);
+                        break;
+
+                    case CSMWorld::ColumnBase::Display_Integer:
+
+                        /// \todo configure widget properly (range)
+                        layout->addWidget (widget = new QSpinBox, i, 1);
+                        break;
+
+                    case CSMWorld::ColumnBase::Display_Float:
+
+                        /// \todo configure widget properly (range, format?)
+                        layout->addWidget (widget = new QDoubleSpinBox, i, 1);
+                        break;
+                }
+            }
+            else
+            {
+                switch (display)
+                {
+                    case CSMWorld::ColumnBase::Display_String:
+                    case CSMWorld::ColumnBase::Display_Integer:
+                    case CSMWorld::ColumnBase::Display_Float:
+
+                        layout->addWidget (widget = new QLabel, i, 1);
+                        break;
+                }
+            }
+
+            if (widget)
+                mWidgetMapper->addMapping (widget, i);
         }
     }
+
+    mWidgetMapper->setCurrentModelIndex (
+        dynamic_cast<CSMWorld::IdTable&> (*model).getModelIndex (id.getId(), 0));
 }
 
 void CSVWorld::DialogueSubView::setEditLock (bool locked)
diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp
index c57dab108..64715f5b7 100644
--- a/apps/opencs/view/world/dialoguesubview.hpp
+++ b/apps/opencs/view/world/dialoguesubview.hpp
@@ -3,6 +3,8 @@
 
 #include "../doc/subview.hpp"
 
+class QDataWidgetMapper;
+
 namespace CSMDoc
 {
     class Document;
@@ -12,6 +14,7 @@ namespace CSVWorld
 {
     class DialogueSubView : public CSVDoc::SubView
     {
+            QDataWidgetMapper *mWidgetMapper;
 
         public:
 
diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp
index bb4bb76c6..f4deceb49 100644
--- a/apps/opencs/view/world/tablesubview.cpp
+++ b/apps/opencs/view/world/tablesubview.cpp
@@ -21,5 +21,6 @@ void CSVWorld::TableSubView::setEditLock (bool locked)
 
 void CSVWorld::TableSubView::rowActivated (const QModelIndex& index)
 {
-    focusId (mTable->getUniversalId (index.row()));
+    /// \todo re-enable, after dialogue sub views have been fixed up
+//    focusId (mTable->getUniversalId (index.row()));
 }
\ No newline at end of file
diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp
index c75e96a6e..a426e3454 100644
--- a/apps/openmw/mwbase/world.hpp
+++ b/apps/openmw/mwbase/world.hpp
@@ -46,6 +46,7 @@ namespace MWWorld
     class LocalScripts;
     class TimeStamp;
     class ESMStore;
+    class RefData;
 }
 
 namespace MWBase
@@ -139,6 +140,9 @@ namespace MWBase
 
             virtual std::string getCurrentCellName() const = 0;
 
+            virtual void removeRefScript (MWWorld::RefData *ref) = 0;
+            //< Remove the script attached to ref from mLocalScripts
+
             virtual MWWorld::Ptr getPtr (const std::string& name, bool activeOnly) = 0;
             ///< Return a pointer to a liveCellRef with the given name.
             /// \param activeOnly do non search inactive cells.
diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp
index 586f9638d..cfbc64b87 100644
--- a/apps/openmw/mwclass/npc.cpp
+++ b/apps/openmw/mwclass/npc.cpp
@@ -100,14 +100,15 @@ namespace MWClass
             }
             else
             {
-                /// \todo do something with mNpdt12 maybe:p
                 for (int i=0; i<8; ++i)
                     data->mCreatureStats.getAttribute (i).set (10);
 
                 for (int i=0; i<3; ++i)
                     data->mCreatureStats.setDynamic (i, 10);
 
-                data->mCreatureStats.setLevel (1);
+                data->mCreatureStats.setLevel(ref->mBase->mNpdt12.mLevel);
+                data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt12.mDisposition);
+                data->mNpcStats.setReputation(ref->mBase->mNpdt12.mReputation);
             }
 
             data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello);
diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp
index b83f495ad..f548c46f7 100644
--- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp
+++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp
@@ -20,6 +20,7 @@
 
 #include "../mwbase/environment.hpp"
 #include "../mwbase/world.hpp"
+#include "../mwbase/journal.hpp"
 #include "../mwbase/scriptmanager.hpp"
 #include "../mwbase/windowmanager.hpp"
 #include "../mwbase/mechanicsmanager.hpp"
@@ -138,7 +139,8 @@ namespace MWDialogue
         {
             if(it->mType == ESM::Dialogue::Greeting)
             {
-                if (const ESM::DialInfo *info = filter.search (*it))
+                // Search a response (we do not accept a fallback to "Info refusal" here)
+                if (const ESM::DialInfo *info = filter.search (*it, false))
                 {
                     //initialise the GUI
                     MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
@@ -247,12 +249,12 @@ namespace MWDialogue
 
         const ESM::Dialogue& dialogue = *dialogues.find (topic);
 
-        if (const ESM::DialInfo *info = filter.search (dialogue))
+        MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
+
+        if (const ESM::DialInfo *info = filter.search (dialogue, true))
         {
             parseText (info->mResponse);
 
-            MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
-
             if (dialogue.mType==ESM::Dialogue::Persuasion)
             {
                 std::string modifiedTopic = "s" + topic;
@@ -269,12 +271,20 @@ namespace MWDialogue
 
             MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
             win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
+            MWBase::Environment::get().getJournal()->addTopic (topic, info->mId);
 
             executeScript (info->mResultScript);
 
             mLastTopic = topic;
             mLastDialogue = *info;
         }
+        else
+        {
+            // no response found, print a fallback text
+            win->addTitle (topic);
+            win->addText ("…");
+
+        }
     }
 
     void DialogueManager::updateTopics()
@@ -293,7 +303,7 @@ namespace MWDialogue
         {
             if (iter->mType == ESM::Dialogue::Topic)
             {
-                if (filter.search (*iter))
+                if (filter.responseAvailable (*iter))
                 {
                     std::string lower = Misc::StringUtils::lowerCase(iter->mId);
                     mActorKnownTopics.push_back (lower);
@@ -410,7 +420,7 @@ namespace MWDialogue
                 {
                     Filter filter (mActor, mChoice, mTalkedTo);
 
-                    if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic]))
+                    if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic], true))
                     {
                         mChoiceMap.clear();
                         mChoice = -1;
@@ -420,6 +430,7 @@ namespace MWDialogue
 
                         MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
                         MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (Interpreter::fixDefinesDialog(text, interpreterContext));
+                        MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId);
                         executeScript (info->mResultScript);
                         mLastTopic = mLastTopic;
                         mLastDialogue = *info;
diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp
index 99be5554a..09bb0ddc4 100644
--- a/apps/openmw/mwdialogue/filter.cpp
+++ b/apps/openmw/mwdialogue/filter.cpp
@@ -121,6 +121,18 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const
     return true;
 }
 
+bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info) const
+{
+    bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name());
+
+    if (isCreature)
+        return true;
+
+    int actorDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor);
+
+    return actorDisposition >= info.mData.mDisposition;
+}
+
 bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const
 {
     if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name())
@@ -162,7 +174,7 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
             int i = 0;
 
             for (; i<static_cast<int> (script->mVarNames.size()); ++i)
-                if (script->mVarNames[i]==name)
+                if (Misc::StringUtils::lowerCase(script->mVarNames[i]) == name)
                     break;
 
             if (i>=static_cast<int> (script->mVarNames.size()))
@@ -547,18 +559,50 @@ MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedTo
 : mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer)
 {}
 
-bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const
+const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const
 {
-    return testActor (info) && testPlayer (info) && testSelectStructs (info);
-}
+    bool infoRefusal = false;
 
-const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue) const
-{
+    // Iterate over topic responses to find a matching one
     for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin();
         iter!=dialogue.mInfo.end(); ++iter)
-        if ((*this) (*iter))
-            return &*iter;
+    {
+        if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
+        {
+            if (testDisposition (*iter))
+                return &*iter;
+            else
+                infoRefusal = true;
+        }
+    }
+
+    if (infoRefusal && fallbackToInfoRefusal)
+    {
+        // No response is valid because of low NPC disposition,
+        // search a response in the topic "Info Refusal"
+
+        const MWWorld::Store<ESM::Dialogue> &dialogues =
+            MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
+
+        const ESM::Dialogue& infoRefusalDialogue = *dialogues.find ("Info Refusal");
+
+        for (std::vector<ESM::DialInfo>::const_iterator iter = infoRefusalDialogue.mInfo.begin();
+            iter!=infoRefusalDialogue.mInfo.end(); ++iter)
+            if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter))
+                return &*iter;
+    }
 
     return 0;
 }
 
+bool MWDialogue::Filter::responseAvailable (const ESM::Dialogue& dialogue) const
+{
+    for (std::vector<ESM::DialInfo>::const_iterator iter = dialogue.mInfo.begin();
+        iter!=dialogue.mInfo.end(); ++iter)
+    {
+        if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter))
+            return true;
+    }
+
+    return false;
+}
diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp
index 7c8f1116f..707c0154b 100644
--- a/apps/openmw/mwdialogue/filter.hpp
+++ b/apps/openmw/mwdialogue/filter.hpp
@@ -18,40 +18,45 @@ namespace MWDialogue
             MWWorld::Ptr mActor;
             int mChoice;
             bool mTalkedToPlayer;
-    
+
             bool testActor (const ESM::DialInfo& info) const;
             ///< Is this the right actor for this \a info?
-    
+
             bool testPlayer (const ESM::DialInfo& info) const;
             ///< Do the player and the cell the player is currently in match \a info?
-    
+
             bool testSelectStructs (const ESM::DialInfo& info) const;
             ///< Are all select structs matching?
-    
+
+            bool testDisposition (const ESM::DialInfo& info) const;
+            ///< Is the actor disposition toward the player high enough?
+
             bool testSelectStruct (const SelectWrapper& select) const;
-    
+
             bool testSelectStructNumeric (const SelectWrapper& select) const;
-            
+
             int getSelectStructInteger (const SelectWrapper& select) const;
-            
+
             bool getSelectStructBoolean (const SelectWrapper& select) const;
-    
+
             int getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const;
-            
+
             bool hasFactionRankSkillRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
                 int rank) const;
 
             bool hasFactionRankReputationRequirements (const MWWorld::Ptr& actor, const std::string& factionId,
                 int rank) const;
-    
-        public:
-        
-            Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);    
 
-            bool operator() (const ESM::DialInfo& info) const;    
-            ///< \return does the dialogue match?
-            
-            const ESM::DialInfo *search (const ESM::Dialogue& dialogue) const;
+        public:
+
+            Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer);
+
+            const ESM::DialInfo *search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const;
+            ///< Get a matching response for the requested dialogue.
+            ///  Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition.
+
+            bool responseAvailable (const ESM::Dialogue& dialogue) const;
+            ///< Does a matching response exist? (disposition is ignored for this check)
     };
 }
 
diff --git a/apps/openmw/mwdialogue/journalentry.cpp b/apps/openmw/mwdialogue/journalentry.cpp
index e6141884c..5ffde5499 100644
--- a/apps/openmw/mwdialogue/journalentry.cpp
+++ b/apps/openmw/mwdialogue/journalentry.cpp
@@ -61,8 +61,8 @@ namespace MWDialogue
     StampedJournalEntry StampedJournalEntry::makeFromQuest (const std::string& topic, int index)
     {
         int day = MWBase::Environment::get().getWorld()->getGlobalVariable ("dayspassed").mLong;
-        int month = MWBase::Environment::get().getWorld()->getGlobalVariable ("day").mLong;
-        int dayOfMonth = MWBase::Environment::get().getWorld()->getGlobalVariable ("month").mLong;
+        int month = MWBase::Environment::get().getWorld()->getGlobalVariable ("month").mLong;
+        int dayOfMonth = MWBase::Environment::get().getWorld()->getGlobalVariable ("day").mLong;
 
         return StampedJournalEntry (topic, idFromIndex (topic, index), day, month, dayOfMonth);
     }
diff --git a/apps/openmw/mwdialogue/journalimp.cpp b/apps/openmw/mwdialogue/journalimp.cpp
index 2b2c60381..5e2bc6bc0 100644
--- a/apps/openmw/mwdialogue/journalimp.cpp
+++ b/apps/openmw/mwdialogue/journalimp.cpp
@@ -31,6 +31,12 @@ namespace MWDialogue
 
     void Journal::addEntry (const std::string& id, int index)
     {
+        // bail out of we already have heard this...
+        std::string infoId = JournalEntry::idFromIndex (id, index);
+        for (TEntryIter i = mJournal.begin (); i != mJournal.end (); ++i)
+            if (i->mTopic == id && i->mInfoId == infoId)
+                return;
+
         StampedJournalEntry entry = StampedJournalEntry::makeFromQuest (id, index);
 
         mJournal.push_back (entry);
diff --git a/apps/openmw/mwdialogue/topic.cpp b/apps/openmw/mwdialogue/topic.cpp
index b6e7c07ae..3253b20d6 100644
--- a/apps/openmw/mwdialogue/topic.cpp
+++ b/apps/openmw/mwdialogue/topic.cpp
@@ -27,17 +27,17 @@ namespace MWDialogue
         mEntries.push_back (entry.mInfoId);
     }
 
-    Topic::TEntryIter Topic::begin()
+    Topic::TEntryIter Topic::begin() const
     {
         return mEntries.begin();
     }
 
-    Topic::TEntryIter Topic::end()
+    Topic::TEntryIter Topic::end() const
     {
         return mEntries.end();
     }
 
-    JournalEntry Topic::getEntry (const std::string& infoId)
+    JournalEntry Topic::getEntry (const std::string& infoId) const
     {
         return JournalEntry (mTopic, infoId);
     }
diff --git a/apps/openmw/mwdialogue/topic.hpp b/apps/openmw/mwdialogue/topic.hpp
index 566f60ab0..c3f0baabc 100644
--- a/apps/openmw/mwdialogue/topic.hpp
+++ b/apps/openmw/mwdialogue/topic.hpp
@@ -34,13 +34,15 @@ namespace MWDialogue
             ///
             /// \note Redundant entries are ignored.
 
-            TEntryIter begin();
+            std::string const & getName () const { return mTopic; }
+
+            TEntryIter begin() const;
             ///< Iterator pointing to the begin of the journal for this topic.
 
-            TEntryIter end();
+            TEntryIter end() const;
             ///< Iterator pointing past the end of the journal for this topic.
 
-            JournalEntry getEntry (const std::string& infoId);
+            JournalEntry getEntry (const std::string& infoId) const;
     };
 }
 
diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp
index db4537daf..bca4073b5 100644
--- a/apps/openmw/mwworld/containerstore.cpp
+++ b/apps/openmw/mwworld/containerstore.cpp
@@ -15,6 +15,8 @@
 #include "manualref.hpp"
 #include "refdata.hpp"
 #include "class.hpp"
+#include "localscripts.hpp"
+#include "player.hpp"
 
 namespace
 {
@@ -71,6 +73,31 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
 }
 
 MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& ptr)
+{
+    MWWorld::ContainerStoreIterator it = addImp(ptr);
+    MWWorld::Ptr item = *it;
+
+    std::string script = MWWorld::Class::get(item).getScript(item);
+    if(script != "")
+    {
+        CellStore *cell;
+
+        Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer();
+        // Items in players inventory have cell set to 0, so their scripts will never be removed
+        if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
+            cell = 0;
+        else
+            cell = player.getCell();
+
+        item.mCell = cell;
+        item.mContainerStore = 0;
+        MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
+    }
+
+    return it;
+}
+
+MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr)
 {
     int type = getType(ptr);
 
@@ -162,7 +189,7 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const MWWor
         }
 
         ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
-        add (ref.getPtr());
+        addImp (ref.getPtr());
     }
 
     flagAsModified();
diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp
index 1297fc53c..e4f75d547 100644
--- a/apps/openmw/mwworld/containerstore.hpp
+++ b/apps/openmw/mwworld/containerstore.hpp
@@ -52,6 +52,7 @@ namespace MWWorld
             int mStateId;
             mutable float mCachedWeight;
             mutable bool mWeightUpToDate;
+            ContainerStoreIterator addImp (const Ptr& ptr);
 
         public:
 
diff --git a/apps/openmw/mwworld/localscripts.cpp b/apps/openmw/mwworld/localscripts.cpp
index a821ad486..5ec5ca9b5 100644
--- a/apps/openmw/mwworld/localscripts.cpp
+++ b/apps/openmw/mwworld/localscripts.cpp
@@ -3,6 +3,10 @@
 #include "esmstore.hpp"
 #include "cellstore.hpp"
 
+#include "class.hpp"
+#include "containerstore.hpp"
+
+
 namespace
 {
     template<typename T>
@@ -19,6 +23,32 @@ namespace
             }
         }
     }
+
+    // Adds scripts for items in containers (containers/npcs/creatures)
+    template<typename T>
+    void listCellScriptsCont (MWWorld::LocalScripts& localScripts,
+        MWWorld::CellRefList<T>& cellRefList,  MWWorld::Ptr::CellStore *cell)
+    {
+        for (typename MWWorld::CellRefList<T>::List::iterator iter (
+            cellRefList.mList.begin());
+            iter!=cellRefList.mList.end(); ++iter)
+        {
+           
+            MWWorld::Ptr containerPtr (&*iter, cell); 
+            
+            MWWorld::ContainerStore& container = MWWorld::Class::get(containerPtr).getContainerStore(containerPtr);
+            for(MWWorld::ContainerStoreIterator it3 = container.begin(); it3 != container.end(); ++it3)
+            {
+                std::string script = MWWorld::Class::get(*it3).getScript(*it3);
+                if(script != "")
+                {
+                    MWWorld::Ptr item = *it3;
+                    item.mCell = cell;
+                    localScripts.add (script, item);
+                }
+            }
+        }
+    }
 }
 
 MWWorld::LocalScripts::LocalScripts (const MWWorld::ESMStore& store) : mStore (store) {}
@@ -78,13 +108,16 @@ void MWWorld::LocalScripts::addCell (Ptr::CellStore *cell)
     listCellScripts (*this, cell->mBooks, cell);
     listCellScripts (*this, cell->mClothes, cell);
     listCellScripts (*this, cell->mContainers, cell);
+    listCellScriptsCont (*this, cell->mContainers, cell);
     listCellScripts (*this, cell->mCreatures, cell);
+    listCellScriptsCont (*this, cell->mCreatures, cell);
     listCellScripts (*this, cell->mDoors, cell);
     listCellScripts (*this, cell->mIngreds, cell);
     listCellScripts (*this, cell->mLights, cell);
     listCellScripts (*this, cell->mLockpicks, cell);
     listCellScripts (*this, cell->mMiscItems, cell);
     listCellScripts (*this, cell->mNpcs, cell);
+    listCellScriptsCont (*this, cell->mNpcs, cell);
     listCellScripts (*this, cell->mProbes, cell);
     listCellScripts (*this, cell->mRepairs, cell);
     listCellScripts (*this, cell->mWeapons, cell);
@@ -101,7 +134,7 @@ void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
 
     while (iter!=mScripts.end())
     {
-        if (iter->second.getCell()==cell)
+        if (iter->second.mCell==cell)
         {
             if (iter==mIter)
                ++mIter;
@@ -113,6 +146,20 @@ void MWWorld::LocalScripts::clearCell (Ptr::CellStore *cell)
     }
 }
 
+void MWWorld::LocalScripts::remove (RefData *ref)
+{
+    for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
+        iter!=mScripts.end(); ++iter)
+        if (&(iter->second.getRefData()) == ref)
+        {
+            if (iter==mIter)
+                ++mIter;
+
+            mScripts.erase (iter);
+            break;
+        }
+}
+
 void MWWorld::LocalScripts::remove (const Ptr& ptr)
 {
     for (std::list<std::pair<std::string, Ptr> >::iterator iter = mScripts.begin();
diff --git a/apps/openmw/mwworld/localscripts.hpp b/apps/openmw/mwworld/localscripts.hpp
index 028dcdeda..840243fff 100644
--- a/apps/openmw/mwworld/localscripts.hpp
+++ b/apps/openmw/mwworld/localscripts.hpp
@@ -10,6 +10,7 @@ namespace MWWorld
 {
     struct ESMStore;
     class CellStore;
+    class RefData;
 
     /// \brief List of active local scripts
     class LocalScripts
@@ -47,6 +48,8 @@ namespace MWWorld
 
             void clearCell (CellStore *cell);
             ///< Remove all scripts belonging to \a cell.
+            
+            void remove (RefData *ref);
 
             void remove (const Ptr& ptr);
             ///< Remove script for given reference (ignored if reference does not have a scirpt listed).
diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp
index 594ddef2d..d97ebcc6e 100644
--- a/apps/openmw/mwworld/ptr.hpp
+++ b/apps/openmw/mwworld/ptr.hpp
@@ -74,7 +74,7 @@ namespace MWWorld
 
             bool isInCell() const
             {
-                return (mCell != 0);
+                return (mContainerStore == 0);
             }
 
             void setContainerStore (ContainerStore *store);
diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp
index 5630bfd5c..4be287810 100644
--- a/apps/openmw/mwworld/refdata.cpp
+++ b/apps/openmw/mwworld/refdata.cpp
@@ -6,6 +6,9 @@
 #include "customdata.hpp"
 #include "cellstore.hpp"
 
+#include "../mwbase/environment.hpp"
+#include "../mwbase/world.hpp"
+
 namespace MWWorld
 {
     void RefData::copy (const RefData& refData)
@@ -107,6 +110,9 @@ namespace MWWorld
 
     void RefData::setCount (int count)
     {
+        if(count == 0)
+            MWBase::Environment::get().getWorld()->removeRefScript(this);
+        
         mCount = count;
     }
 
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index de4cb84ef..5d9250ab6 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -341,6 +341,11 @@ namespace MWWorld
         return name;
     }
 
+    void World::removeRefScript (MWWorld::RefData *ref)
+    {
+        mLocalScripts.remove (ref);
+    }
+
     Ptr World::getPtr (const std::string& name, bool activeOnly)
     {
         // the player is always in an active cell.
@@ -396,23 +401,62 @@ namespace MWWorld
         return MWWorld::Ptr();
     }
 
+    void World::addContainerScripts(const Ptr& reference, Ptr::CellStore * cell)
+    {
+        if( reference.getTypeName()==typeid (ESM::Container).name() ||
+            reference.getTypeName()==typeid (ESM::NPC).name() ||
+            reference.getTypeName()==typeid (ESM::Creature).name())
+        {
+            MWWorld::ContainerStore& container = MWWorld::Class::get(reference).getContainerStore(reference);
+            for(MWWorld::ContainerStoreIterator it = container.begin(); it != container.end(); ++it)
+            {
+                std::string script = MWWorld::Class::get(*it).getScript(*it);
+                if(script != "")
+                {
+                    MWWorld::Ptr item = *it;
+                    item.mCell = cell;
+                    mLocalScripts.add (script, item);
+                }
+            }
+        }
+    }
+
     void World::enable (const Ptr& reference)
     {
         if (!reference.getRefData().isEnabled())
         {
             reference.getRefData().enable();
-
+            
             if(mWorldScene->getActiveCells().find (reference.getCell()) != mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
                 mWorldScene->addObjectToScene (reference);
         }
     }
+    
+    void World::removeContainerScripts(const Ptr& reference)
+    {
+        if( reference.getTypeName()==typeid (ESM::Container).name() ||
+            reference.getTypeName()==typeid (ESM::NPC).name() ||
+            reference.getTypeName()==typeid (ESM::Creature).name())
+        {
+            MWWorld::ContainerStore& container = MWWorld::Class::get(reference).getContainerStore(reference);
+            for(MWWorld::ContainerStoreIterator it = container.begin(); it != container.end(); ++it)
+            {
+                std::string script = MWWorld::Class::get(*it).getScript(*it);
+                if(script != "")
+                {
+                    MWWorld::Ptr item = *it;
+                    mLocalScripts.remove (item);
+                }
+            }
+        }
+    }
 
     void World::disable (const Ptr& reference)
     {
         if (reference.getRefData().isEnabled())
         {
             reference.getRefData().disable();
-
+            
             if(mWorldScene->getActiveCells().find (reference.getCell())!=mWorldScene->getActiveCells().end() && reference.getRefData().getCount())
                 mWorldScene->removeObjectFromScene (reference);
         }
@@ -635,6 +679,7 @@ namespace MWWorld
             {
                 mWorldScene->removeObjectFromScene (ptr);
                 mLocalScripts.remove (ptr);
+                removeContainerScripts (ptr);
             }
         }
     }
@@ -648,6 +693,8 @@ namespace MWWorld
         CellStore *currCell = ptr.getCell();
         bool isPlayer = ptr == mPlayer->getPlayer();
         bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer;
+        
+        removeContainerScripts(ptr);
 
         if (*currCell != newCell)
         {
@@ -675,6 +722,8 @@ namespace MWWorld
                     MWWorld::Ptr copy =
                         MWWorld::Class::get(ptr).copyToCell(ptr, newCell);
 
+                    addContainerScripts(copy, &newCell);
+
                     mRendering->moveObjectToCell(copy, vec, currCell);
 
                     if (MWWorld::Class::get(ptr).isActor())
@@ -1272,6 +1321,7 @@ namespace MWWorld
             if (!script.empty()) {
                 mLocalScripts.add(script, dropped);
             }
+            addContainerScripts(dropped, &cell);
         }
     }
 
diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp
index 67185833f..4899a8807 100644
--- a/apps/openmw/mwworld/worldimp.hpp
+++ b/apps/openmw/mwworld/worldimp.hpp
@@ -106,6 +106,9 @@ namespace MWWorld
             float getNpcActivationDistance ();
             float getObjectActivationDistance ();
 
+            void removeContainerScripts(const Ptr& reference);
+            void addContainerScripts(const Ptr& reference, Ptr::CellStore* cell);
+
         public:
 
             World (OEngine::Render::OgreRenderer& renderer,
@@ -173,6 +176,9 @@ namespace MWWorld
             virtual std::vector<std::string> getGlobals () const;
             
             virtual std::string getCurrentCellName () const;
+            
+            virtual void removeRefScript (MWWorld::RefData *ref);
+            //< Remove the script attached to ref from mLocalScripts
 
             virtual Ptr getPtr (const std::string& name, bool activeOnly);
             ///< Return a pointer to a liveCellRef with the given name.
diff --git a/files/mygui/openmw_font.xml b/files/mygui/openmw_font.xml
index 0383c9942..b1446fae1 100644
--- a/files/mygui/openmw_font.xml
+++ b/files/mygui/openmw_font.xml
@@ -11,6 +11,7 @@
             <Code range="33 126"/>
             <Code range="192 382"/> <!-- Central and Eastern European languages glyphs -->
             <Code range="1025 1105"/>
+            <Code range="2026"/> <!-- Ellipsis -->
             <Code range="8470"/>
             <Code range="8211"/>   <!-- Minus -->
             <Code range="8216 8217"/> <!-- Single quotes -->