Index: include/AdblockPlus/JsEngine.h
===================================================================
--- a/include/AdblockPlus/JsEngine.h
+++ b/include/AdblockPlus/JsEngine.h
@@ -272,17 +272,17 @@
      */
     void SetLogSystem(const LogSystemPtr& val);
 
     /**
      * Sets a global property that can be accessed by all the scripts.
      * @param name Name of the property to set.
      * @param value Value of the property to set.
      */
-    void SetGlobalProperty(const std::string& name, const AdblockPlus::JsValuePtr& value);
+    void SetGlobalProperty(const std::string& name, const AdblockPlus::JsValue& value);
 
     /**
      * Returns a pointer to associated v8::Isolate.
      */
     v8::Isolate* GetIsolate()
     {
       return isolate->Get();
     }
@@ -293,17 +293,17 @@
       ~TimerTask();
       std::vector<std::unique_ptr<v8::Persistent<v8::Value>>> arguments;
     };
     typedef std::list<TimerTask> TimerTasks;
     void CallTimerTask(const TimerTasks::const_iterator& timerTaskIterator);
 
     explicit JsEngine(const ScopedV8IsolatePtr& isolate, TimerPtr timer);
 
-    JsValuePtr GetGlobalObject();
+    JsValue GetGlobalObject();
 
     /// Isolate must be disposed only after disposing of all objects which are
     /// using it.
     ScopedV8IsolatePtr isolate;
 
     FileSystemPtr fileSystem;
     WebRequestPtr webRequest;
     LogSystemPtr logSystem;
Index: include/AdblockPlus/JsValue.h
===================================================================
--- a/include/AdblockPlus/JsValue.h
+++ b/include/AdblockPlus/JsValue.h
@@ -82,28 +82,28 @@
     std::vector<std::string> GetOwnPropertyNames() const;
 
     /**
      * Returns a property value if this is an object (see `IsObject()`).
      * @param name Property name.
      * @return Property value, undefined (see `IsUndefined()`) if the property
      *         does not exist.
      */
-    JsValuePtr GetProperty(const std::string& name) const;
+    JsValue GetProperty(const std::string& name) const;
 
     //@{
     /**
      * Sets a property value if this is an object (see `IsObject()`).
      * @param name Property name.
      * @param val Property value.
      */
     void SetProperty(const std::string& name, const std::string& val);
     void SetProperty(const std::string& name, int64_t val);
     void SetProperty(const std::string& name, bool val);
-    void SetProperty(const std::string& name, const JsValuePtr& value);
+    void SetProperty(const std::string& name, const JsValue& value);
     inline void SetProperty(const std::string& name, const char* val)
     {
       SetProperty(name, std::string(val));
     }
     inline void SetProperty(const std::string& name, int val)
     {
       SetProperty(name, static_cast<int64_t>(val));
     }
Index: shell/src/FiltersCommand.cpp
===================================================================
--- a/shell/src/FiltersCommand.cpp
+++ b/shell/src/FiltersCommand.cpp
@@ -49,17 +49,17 @@
           break;
         case AdblockPlus::Filter::TYPE_INVALID:
           type = "invalid";
           break;
         default:
           type = "(unknown type)";
           break;
       }
-      std::cout << (*it)->GetProperty("text")->AsString() << " - " <<
+      std::cout << (*it)->GetProperty("text").AsString() << " - " <<
           type << std::endl;
     }
   }
 }
 
 FiltersCommand::FiltersCommand(AdblockPlus::FilterEngine& filterEngine)
   : Command("filters"), filterEngine(filterEngine)
 {
Index: shell/src/MatchesCommand.cpp
===================================================================
--- a/shell/src/MatchesCommand.cpp
+++ b/shell/src/MatchesCommand.cpp
@@ -48,19 +48,19 @@
     ShowUsage();
     return;
   }
 
   AdblockPlus::FilterPtr match = filterEngine.Matches(url, contentType, documentUrl);
   if (!match)
     std::cout << "No match" << std::endl;
   else if (match->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION)
-    std::cout << "Whitelisted by " << match->GetProperty("text")->AsString() << std::endl;
+    std::cout << "Whitelisted by " << match->GetProperty("text").AsString() << std::endl;
   else
-    std::cout << "Blocked by " << match->GetProperty("text")->AsString() << std::endl;
+    std::cout << "Blocked by " << match->GetProperty("text").AsString() << std::endl;
 }
 
 std::string MatchesCommand::GetDescription() const
 {
   return "Returns the first filter that matches the supplied URL";
 }
 
 std::string MatchesCommand::GetUsage() const
Index: shell/src/SubscriptionsCommand.cpp
===================================================================
--- a/shell/src/SubscriptionsCommand.cpp
+++ b/shell/src/SubscriptionsCommand.cpp
@@ -24,22 +24,22 @@
 {
   typedef std::vector<AdblockPlus::SubscriptionPtr> SubscriptionList;
 
   void ShowSubscriptionList(const SubscriptionList& subscriptions)
   {
     for (SubscriptionList::const_iterator it = subscriptions.begin();
          it != subscriptions.end(); it++)
     {
-      std::cout << (*it)->GetProperty("title")->AsString();
-      std::cout << " - " << (*it)->GetProperty("url")->AsString();
-      if (!(*it)->GetProperty("author")->IsUndefined())
-        std::cout << " - " << (*it)->GetProperty("author")->AsString();
-      if (!(*it)->GetProperty("specialization")->IsUndefined())
-        std::cout << " - " << (*it)->GetProperty("specialization")->AsString();
+      std::cout << (*it)->GetProperty("title").AsString();
+      std::cout << " - " << (*it)->GetProperty("url").AsString();
+      if (!(*it)->GetProperty("author").IsUndefined())
+        std::cout << " - " << (*it)->GetProperty("author").AsString();
+      if (!(*it)->GetProperty("specialization").IsUndefined())
+        std::cout << " - " << (*it)->GetProperty("specialization").AsString();
       std::cout << std::endl;
     }
   }
 }
 
 SubscriptionsCommand::SubscriptionsCommand(
   AdblockPlus::FilterEngine& filterEngine)
   : Command("subscriptions"), filterEngine(filterEngine)
Index: src/AppInfoJsObject.cpp
===================================================================
--- a/src/AppInfoJsObject.cpp
+++ b/src/AppInfoJsObject.cpp
@@ -18,18 +18,18 @@
 #include <AdblockPlus/AppInfo.h>
 #include <AdblockPlus/JsValue.h>
 
 #include "AppInfoJsObject.h"
 #include "Utils.h"
 
 using namespace AdblockPlus;
 
-JsValuePtr AppInfoJsObject::Setup(const AppInfo& appInfo, const JsValuePtr& obj)
+JsValue& AppInfoJsObject::Setup(const AppInfo& appInfo, JsValue& obj)
 {
-  obj->SetProperty("version", appInfo.version);
-  obj->SetProperty("name", appInfo.name);
-  obj->SetProperty("application", appInfo.application);
-  obj->SetProperty("applicationVersion", appInfo.applicationVersion);
-  obj->SetProperty("locale", appInfo.locale);
-  obj->SetProperty("developmentBuild", appInfo.developmentBuild);
+  obj.SetProperty("version", appInfo.version);
+  obj.SetProperty("name", appInfo.name);
+  obj.SetProperty("application", appInfo.application);
+  obj.SetProperty("applicationVersion", appInfo.applicationVersion);
+  obj.SetProperty("locale", appInfo.locale);
+  obj.SetProperty("developmentBuild", appInfo.developmentBuild);
   return obj;
 }
Index: src/AppInfoJsObject.h
===================================================================
--- a/src/AppInfoJsObject.h
+++ b/src/AppInfoJsObject.h
@@ -22,13 +22,13 @@
 #include <AdblockPlus/JsValue.h>
 
 namespace AdblockPlus
 {
   struct AppInfo;
 
   namespace AppInfoJsObject
   {
-    JsValuePtr Setup(const AppInfo& appInfo, const JsValuePtr& obj);
+    JsValue& Setup(const AppInfo& appInfo, JsValue& obj);
   }
 }
 
 #endif
Index: src/ConsoleJsObject.cpp
===================================================================
--- a/src/ConsoleJsObject.cpp
+++ b/src/ConsoleJsObject.cpp
@@ -99,19 +99,19 @@
     }
 
     AdblockPlus::LogSystemPtr callback = jsEngine->GetLogSystem();
     (*callback)(AdblockPlus::LogSystem::LOG_LEVEL_TRACE, traceback.str(), "");
     return v8::Undefined();
   }
 }
 
-AdblockPlus::JsValuePtr AdblockPlus::ConsoleJsObject::Setup(
-    AdblockPlus::JsEngine& jsEngine, const AdblockPlus::JsValuePtr& obj)
+AdblockPlus::JsValue& AdblockPlus::ConsoleJsObject::Setup(
+    AdblockPlus::JsEngine& jsEngine, AdblockPlus::JsValue& obj)
 {
-  obj->SetProperty("log", jsEngine.NewCallback(::LogCallback));
-  obj->SetProperty("debug", jsEngine.NewCallback(::DebugCallback));
-  obj->SetProperty("info", jsEngine.NewCallback(::InfoCallback));
-  obj->SetProperty("warn", jsEngine.NewCallback(::WarnCallback));
-  obj->SetProperty("error", jsEngine.NewCallback(::ErrorCallback));
-  obj->SetProperty("trace", jsEngine.NewCallback(::TraceCallback));
+  obj.SetProperty("log", *jsEngine.NewCallback(::LogCallback));
+  obj.SetProperty("debug", *jsEngine.NewCallback(::DebugCallback));
+  obj.SetProperty("info", *jsEngine.NewCallback(::InfoCallback));
+  obj.SetProperty("warn", *jsEngine.NewCallback(::WarnCallback));
+  obj.SetProperty("error", *jsEngine.NewCallback(::ErrorCallback));
+  obj.SetProperty("trace", *jsEngine.NewCallback(::TraceCallback));
   return obj;
 }
Index: src/ConsoleJsObject.h
===================================================================
--- a/src/ConsoleJsObject.h
+++ b/src/ConsoleJsObject.h
@@ -22,13 +22,13 @@
 #include <AdblockPlus/JsEngine.h>
 
 namespace AdblockPlus
 {
   class JsEngine;
 
   namespace ConsoleJsObject
   {
-    JsValuePtr Setup(JsEngine& jsEngine, const JsValuePtr& obj);
+    JsValue& Setup(JsEngine& jsEngine, JsValue& obj);
   }
 }
 
 #endif
Index: src/FileSystemJsObject.cpp
===================================================================
--- a/src/FileSystemJsObject.cpp
+++ b/src/FileSystemJsObject.cpp
@@ -344,18 +344,18 @@
     std::string resolved = jsEngine->GetFileSystem()->Resolve(converted[0]->AsString());
 
     return Utils::ToV8String(isolate, resolved);
   }
 
 }
 
 
-JsValuePtr FileSystemJsObject::Setup(JsEngine& jsEngine, const JsValuePtr& obj)
+JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj)
 {
-  obj->SetProperty("read", jsEngine.NewCallback(::ReadCallback));
-  obj->SetProperty("write", jsEngine.NewCallback(::WriteCallback));
-  obj->SetProperty("move", jsEngine.NewCallback(::MoveCallback));
-  obj->SetProperty("remove", jsEngine.NewCallback(::RemoveCallback));
-  obj->SetProperty("stat", jsEngine.NewCallback(::StatCallback));
-  obj->SetProperty("resolve", jsEngine.NewCallback(::ResolveCallback));
+  obj.SetProperty("read", *jsEngine.NewCallback(::ReadCallback));
+  obj.SetProperty("write", *jsEngine.NewCallback(::WriteCallback));
+  obj.SetProperty("move", *jsEngine.NewCallback(::MoveCallback));
+  obj.SetProperty("remove", *jsEngine.NewCallback(::RemoveCallback));
+  obj.SetProperty("stat", *jsEngine.NewCallback(::StatCallback));
+  obj.SetProperty("resolve", *jsEngine.NewCallback(::ResolveCallback));
   return obj;
 }
Index: src/FileSystemJsObject.h
===================================================================
--- a/src/FileSystemJsObject.h
+++ b/src/FileSystemJsObject.h
@@ -22,13 +22,13 @@
 #include <AdblockPlus/JsEngine.h>
 
 namespace AdblockPlus
 {
   class FileSystem;
 
   namespace FileSystemJsObject
   {
-    JsValuePtr Setup(JsEngine& jsEngine, const JsValuePtr& obj);
+    JsValue& Setup(JsEngine& jsEngine, JsValue& obj);
   }
 }
 
 #endif
Index: src/FilterEngine.cpp
===================================================================
--- a/src/FilterEngine.cpp
+++ b/src/FilterEngine.cpp
@@ -69,17 +69,17 @@
 void Filter::RemoveFromList()
 {
   JsValuePtr func = jsEngine->Evaluate("API.removeFilterFromList");
   func->Call(*this);
 }
 
 bool Filter::operator==(const Filter& filter) const
 {
-  return GetProperty("text")->AsString() == filter.GetProperty("text")->AsString();
+  return GetProperty("text").AsString() == filter.GetProperty("text").AsString();
 }
 
 Subscription::Subscription(JsValue&& value)
     : JsValue(std::move(value))
 {
   if (!IsObject())
     throw std::runtime_error("JavaScript value is not an object");
 }
@@ -116,17 +116,17 @@
 
 bool Subscription::IsAA() const
 {
   return jsEngine->Evaluate("API.isAASubscription")->Call(*this).AsBool();
 }
 
 bool Subscription::operator==(const Subscription& subscription) const
 {
-  return GetProperty("url")->AsString() == subscription.GetProperty("url")->AsString();
+  return GetProperty("url").AsString() == subscription.GetProperty("url").AsString();
 }
 
 namespace
 {
   class Sync
   {
   public:
     Sync()
@@ -196,19 +196,19 @@
   // until we are done.
   const JsContext context(jsEngine);
 
   // Set the preconfigured prefs
   JsValuePtr preconfiguredPrefsObject = jsEngine->NewObject();
   for (FilterEngine::Prefs::const_iterator it = params.preconfiguredPrefs.begin();
     it != params.preconfiguredPrefs.end(); it++)
   {
-    preconfiguredPrefsObject->SetProperty(it->first, it->second);
+    preconfiguredPrefsObject->SetProperty(it->first, *it->second);
   }
-  jsEngine->SetGlobalProperty("_preconfiguredPrefs", preconfiguredPrefsObject);
+  jsEngine->SetGlobalProperty("_preconfiguredPrefs", *preconfiguredPrefsObject);
   // Load adblockplus scripts
   for (int i = 0; !jsSources[i].empty(); i += 2)
     jsEngine->Evaluate(jsSources[i + 1], jsSources[i]);
 }
 
 FilterEnginePtr FilterEngine::Create(const JsEnginePtr& jsEngine,
   const FilterEngine::CreationParameters& params)
 {
Index: src/GlobalJsObject.cpp
===================================================================
--- a/src/GlobalJsObject.cpp
+++ b/src/GlobalJsObject.cpp
@@ -63,23 +63,23 @@
     }
     std::string eventName = converted.front()->AsString();
     converted.erase(converted.begin());
     jsEngine->TriggerEvent(eventName, converted);
     return v8::Undefined();
   }
 }
 
-JsValuePtr GlobalJsObject::Setup(JsEngine& jsEngine, const AppInfo& appInfo,
-    const JsValuePtr& obj)
+JsValue& GlobalJsObject::Setup(JsEngine& jsEngine, const AppInfo& appInfo,
+    JsValue& obj)
 {
-  obj->SetProperty("setTimeout", jsEngine.NewCallback(::SetTimeoutCallback));
-  obj->SetProperty("_triggerEvent", jsEngine.NewCallback(::TriggerEventCallback));
-  obj->SetProperty("_fileSystem",
-      FileSystemJsObject::Setup(jsEngine, jsEngine.NewObject()));
-  obj->SetProperty("_webRequest",
-      WebRequestJsObject::Setup(jsEngine, jsEngine.NewObject()));
-  obj->SetProperty("console",
-      ConsoleJsObject::Setup(jsEngine, jsEngine.NewObject()));
-  obj->SetProperty("_appInfo",
-      AppInfoJsObject::Setup(appInfo, jsEngine.NewObject()));
+  obj.SetProperty("setTimeout", *jsEngine.NewCallback(::SetTimeoutCallback));
+  obj.SetProperty("_triggerEvent", *jsEngine.NewCallback(::TriggerEventCallback));
+  obj.SetProperty("_fileSystem",
+      FileSystemJsObject::Setup(jsEngine, *jsEngine.NewObject()));
+  obj.SetProperty("_webRequest",
+      WebRequestJsObject::Setup(jsEngine, *jsEngine.NewObject()));
+  obj.SetProperty("console",
+      ConsoleJsObject::Setup(jsEngine, *jsEngine.NewObject()));
+  obj.SetProperty("_appInfo",
+      AppInfoJsObject::Setup(appInfo, *jsEngine.NewObject()));
   return obj;
 }
Index: src/GlobalJsObject.h
===================================================================
--- a/src/GlobalJsObject.h
+++ b/src/GlobalJsObject.h
@@ -23,13 +23,13 @@
 
 namespace AdblockPlus
 {
   class AppInfo;
   class JsEngine;
 
   namespace GlobalJsObject
   {
-    JsValuePtr Setup(JsEngine& jsEngine, const AppInfo& appInfo, const JsValuePtr& obj);
+    JsValue& Setup(JsEngine& jsEngine, const AppInfo& appInfo, JsValue& obj);
   }
 }
 
 #endif
Index: src/JsEngine.cpp
===================================================================
--- a/src/JsEngine.cpp
+++ b/src/JsEngine.cpp
@@ -140,24 +140,25 @@
   JsEnginePtr result(new JsEngine(isolate, std::move(timer)));
 
   const v8::Locker locker(result->GetIsolate());
   const v8::Isolate::Scope isolateScope(result->GetIsolate());
   const v8::HandleScope handleScope(result->GetIsolate());
 
   result->context.reset(new v8::Persistent<v8::Context>(result->GetIsolate(),
     v8::Context::New(result->GetIsolate())));
-  AdblockPlus::GlobalJsObject::Setup(*result, appInfo, result->GetGlobalObject());
+  auto global = result->GetGlobalObject();
+  AdblockPlus::GlobalJsObject::Setup(*result, appInfo, global);
   return result;
 }
 
-AdblockPlus::JsValuePtr AdblockPlus::JsEngine::GetGlobalObject()
+AdblockPlus::JsValue AdblockPlus::JsEngine::GetGlobalObject()
 {
   JsContext context(shared_from_this());
-  return JsValuePtr(new JsValue(shared_from_this(), context.GetV8Context()->Global()));
+  return JsValue(shared_from_this(), context.GetV8Context()->Global());
 }
 
 AdblockPlus::JsValuePtr AdblockPlus::JsEngine::Evaluate(const std::string& source,
     const std::string& filename)
 {
   const JsContext context(shared_from_this());
   const v8::TryCatch tryCatch;
   const v8::Handle<v8::Script> script = CompileScript(GetIsolate(), source,
@@ -321,15 +322,13 @@
   if (!val)
     throw std::runtime_error("LogSystem cannot be null");
 
   logSystem = val;
 }
 
 
 void AdblockPlus::JsEngine::SetGlobalProperty(const std::string& name,
-                                              const AdblockPlus::JsValuePtr& value)
+                                              const AdblockPlus::JsValue& value)
 {
   auto global = GetGlobalObject();
-  if (!global)
-    throw std::runtime_error("Global object cannot be null");
-  global->SetProperty(name, value);
+  global.SetProperty(name, value);
 }
Index: src/JsValue.cpp
===================================================================
--- a/src/JsValue.cpp
+++ b/src/JsValue.cpp
@@ -142,25 +142,25 @@
   JsValueList properties = JsValuePtr(new JsValue(jsEngine, object->GetOwnPropertyNames()))->AsList();
   std::vector<std::string> result;
   for (const auto& property : properties)
     result.push_back(property->AsString());
   return result;
 }
 
 
-AdblockPlus::JsValuePtr AdblockPlus::JsValue::GetProperty(const std::string& name) const
+AdblockPlus::JsValue AdblockPlus::JsValue::GetProperty(const std::string& name) const
 {
   if (!IsObject())
     throw new std::runtime_error("Attempting to get property of a non-object");
 
   const JsContext context(jsEngine);
   v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), name);
   v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(UnwrapValue());
-  return JsValuePtr(new JsValue(jsEngine, obj->Get(property)));
+  return JsValue(jsEngine, obj->Get(property));
 }
 
 void AdblockPlus::JsValue::SetProperty(const std::string& name, v8::Handle<v8::Value> val)
 {
   if (!IsObject())
     throw new std::runtime_error("Attempting to set property on a non-object");
 
   v8::Local<v8::String> property = Utils::ToV8String(jsEngine->GetIsolate(), name);
@@ -185,20 +185,20 @@
 }
 
 void AdblockPlus::JsValue::SetProperty(const std::string& name, int64_t val)
 {
   const JsContext context(jsEngine);
   SetProperty(name, v8::Number::New(jsEngine->GetIsolate(), val));
 }
 
-void AdblockPlus::JsValue::SetProperty(const std::string& name, const JsValuePtr& val)
+void AdblockPlus::JsValue::SetProperty(const std::string& name, const JsValue& val)
 {
   const JsContext context(jsEngine);
-  SetProperty(name, val->UnwrapValue());
+  SetProperty(name, val.UnwrapValue());
 }
 
 void AdblockPlus::JsValue::SetProperty(const std::string& name, bool val)
 {
   const JsContext context(jsEngine);
   SetProperty(name, v8::Boolean::New(val));
 }
 
Index: src/Notification.cpp
===================================================================
--- a/src/Notification.cpp
+++ b/src/Notification.cpp
@@ -59,48 +59,48 @@
 
 Notification::Notification(JsValue&& jsValue)
   : JsValue(std::move(jsValue))
 {
 }
 
 NotificationType Notification::GetType() const
 {
-  return StringToNotificationType(GetProperty("type")->AsString());
+  return StringToNotificationType(GetProperty("type").AsString());
 }
 
 NotificationTexts Notification::GetTexts() const
 {
   JsValue jsTexts = jsEngine->Evaluate("API.getNotificationTexts")->Call(*this);
   NotificationTexts notificationTexts;
-  JsValuePtr jsTitle = jsTexts.GetProperty("title");
-  if (jsTitle->IsString())
+  JsValue jsTitle = jsTexts.GetProperty("title");
+  if (jsTitle.IsString())
   {
-    notificationTexts.title = jsTitle->AsString();
+    notificationTexts.title = jsTitle.AsString();
   }
-  JsValuePtr jsMessage = jsTexts.GetProperty("message");
-  if (jsMessage->IsString())
+  JsValue jsMessage = jsTexts.GetProperty("message");
+  if (jsMessage.IsString())
   {
-    notificationTexts.message = jsMessage->AsString();
+    notificationTexts.message = jsMessage.AsString();
   }
   return notificationTexts;
 }
 
 std::vector<std::string> Notification::GetLinks() const
 {
   std::vector<std::string> retValue;
-  JsValuePtr jsLinks = GetProperty("links");
-  if (!jsLinks->IsArray())
+  JsValue jsLinks = GetProperty("links");
+  if (!jsLinks.IsArray())
   {
     return retValue;
   }
-  JsValueList urlLinksList = jsLinks->AsList();
+  JsValueList urlLinksList = jsLinks.AsList();
   for (const auto& link : urlLinksList)
   {
     retValue.push_back(link->AsString());
   }
   return retValue;
 }
 
 void Notification::MarkAsShown()
 {
-  jsEngine->Evaluate("API.markNotificationAsShown")->Call(*GetProperty("id"));
+  jsEngine->Evaluate("API.markNotificationAsShown")->Call(GetProperty("id"));
 }
Index: src/WebRequestJsObject.cpp
===================================================================
--- a/src/WebRequestJsObject.cpp
+++ b/src/WebRequestJsObject.cpp
@@ -38,17 +38,17 @@
       {
         AdblockPlus::JsConstValuePtr headersObj = arguments[1];
         if (!headersObj->IsObject())
           throw std::runtime_error("Second argument to GET must be an object");
 
         std::vector<std::string> properties = headersObj->GetOwnPropertyNames();
         for (const auto& header : properties)
         {
-          std::string headerValue = headersObj->GetProperty(header)->AsString();
+          std::string headerValue = headersObj->GetProperty(header).AsString();
           if (header.length() && headerValue.length())
             headers.push_back(std::pair<std::string, std::string>(header, headerValue));
         }
       }
 
       callback = arguments[2];
       if (!callback->IsFunction())
         throw std::runtime_error("Third argument to GET must be a function");
@@ -74,17 +74,17 @@
       resultObject->SetProperty("responseStatus", result.responseStatus);
       resultObject->SetProperty("responseText", result.responseText);
 
       AdblockPlus::JsValuePtr headersObject = jsEngine->NewObject();
       for (const auto& header : result.responseHeaders)
       {
         headersObject->SetProperty(header.first, header.second);
       }
-      resultObject->SetProperty("responseHeaders", headersObject);
+      resultObject->SetProperty("responseHeaders", *headersObject);
 
       AdblockPlus::JsConstValueList params;
       params.push_back(resultObject);
       callback->Call(params);
     }
 
   private:
     AdblockPlus::JsEnginePtr jsEngine;
@@ -110,14 +110,14 @@
       v8::Isolate* isolate = arguments.GetIsolate();
       return v8::ThrowException(ToV8String(isolate, e.what()));
     }
     thread->Start();
     return v8::Undefined();
   }
 }
 
-AdblockPlus::JsValuePtr AdblockPlus::WebRequestJsObject::Setup(
-    AdblockPlus::JsEngine& jsEngine, const AdblockPlus::JsValuePtr& obj)
+AdblockPlus::JsValue& AdblockPlus::WebRequestJsObject::Setup(
+    AdblockPlus::JsEngine& jsEngine, AdblockPlus::JsValue& obj)
 {
-  obj->SetProperty("GET", jsEngine.NewCallback(::GETCallback));
+  obj.SetProperty("GET", *jsEngine.NewCallback(::GETCallback));
   return obj;
 }
Index: src/WebRequestJsObject.h
===================================================================
--- a/src/WebRequestJsObject.h
+++ b/src/WebRequestJsObject.h
@@ -22,13 +22,13 @@
 #include <AdblockPlus/JsEngine.h>
 
 namespace AdblockPlus
 {
   class JsEngine;
 
   namespace WebRequestJsObject
   {
-    JsValuePtr Setup(JsEngine& jsEngine, const JsValuePtr& obj);
+    JsValue& Setup(JsEngine& jsEngine, JsValue& obj);
   }
 }
 
 #endif
Index: test/FilterEngine.cpp
===================================================================
--- a/test/FilterEngine.cpp
+++ b/test/FilterEngine.cpp
@@ -236,31 +236,31 @@
       };
       jsEngine->SetEventCallback("filterChange", [this](const JsConstValueList& params/*action, item*/)
       {
         ASSERT_EQ(2u, params.size());
         if (params[0]->AsString() == "subscription.downloadStatus")
         {
           {
             std::lock_guard<std::mutex> lock(downloadStatusChanged.mutex);
-            downloadStatusChanged.url = params[1]->GetProperty("url")->AsString();
+            downloadStatusChanged.url = params[1]->GetProperty("url").AsString();
           }
           downloadStatusChanged.cv.notify_one();
         }
       });
     }
 
     SubscriptionPtr EnsureExampleSubscriptionAndForceUpdate(const std::string& apppendToUrl = std::string())
     {
       if (!filterEngine)
         filterEngine = FilterEngine::Create(jsEngine, createParams);
       auto subscriptionUrl = subscriptionUrlPrefix + apppendToUrl;
       auto subscription = filterEngine->GetSubscription(subscriptionUrl);
-      EXPECT_EQ(0u, subscription->GetProperty("filters")->AsList().size()) << subscriptionUrl;
-      EXPECT_TRUE(subscription->GetProperty("downloadStatus")->IsNull()) << subscriptionUrl;
+      EXPECT_EQ(0u, subscription->GetProperty("filters").AsList().size()) << subscriptionUrl;
+      EXPECT_TRUE(subscription->GetProperty("downloadStatus").IsNull()) << subscriptionUrl;
       subscription->UpdateFilters();
       {
         std::unique_lock<std::mutex> lock(downloadStatusChanged.mutex);
         downloadStatusChanged.cv.wait_for(lock,
           /*don't block tests forever*/std::chrono::seconds(5),
           [this, subscriptionUrl]()->bool
         {
           return subscriptionUrl == downloadStatusChanged.url;
@@ -288,26 +288,26 @@
   AdblockPlus::FilterPtr filter5 = filterEngine->GetFilter("  foo  ");
   ASSERT_EQ(*filter1, *filter5);
 }
 
 TEST_F(FilterEngineTest, FilterProperties)
 {
   AdblockPlus::FilterPtr filter = filterEngine->GetFilter("foo");
 
-  ASSERT_TRUE(filter->GetProperty("stringFoo")->IsUndefined());
-  ASSERT_TRUE(filter->GetProperty("intFoo")->IsUndefined());
-  ASSERT_TRUE(filter->GetProperty("boolFoo")->IsUndefined());
+  ASSERT_TRUE(filter->GetProperty("stringFoo").IsUndefined());
+  ASSERT_TRUE(filter->GetProperty("intFoo").IsUndefined());
+  ASSERT_TRUE(filter->GetProperty("boolFoo").IsUndefined());
 
   filter->SetProperty("stringFoo", "y");
   filter->SetProperty("intFoo", 24);
   filter->SetProperty("boolFoo", true);
-  ASSERT_EQ("y", filter->GetProperty("stringFoo")->AsString());
-  ASSERT_EQ(24, filter->GetProperty("intFoo")->AsInt());
-  ASSERT_TRUE(filter->GetProperty("boolFoo")->AsBool());
+  ASSERT_EQ("y", filter->GetProperty("stringFoo").AsString());
+  ASSERT_EQ(24, filter->GetProperty("intFoo").AsInt());
+  ASSERT_TRUE(filter->GetProperty("boolFoo").AsBool());
 }
 
 TEST_F(FilterEngineTest, AddRemoveFilters)
 {
   ASSERT_EQ(0u, filterEngine->GetListedFilters().size());
   AdblockPlus::FilterPtr filter = filterEngine->GetFilter("foo");
   ASSERT_EQ(0u, filterEngine->GetListedFilters().size());
   ASSERT_FALSE(filter->IsListed());
@@ -326,26 +326,26 @@
   ASSERT_EQ(0u, filterEngine->GetListedFilters().size());
   ASSERT_FALSE(filter->IsListed());
 }
 
 TEST_F(FilterEngineTest, SubscriptionProperties)
 {
   AdblockPlus::SubscriptionPtr subscription = filterEngine->GetSubscription("foo");
 
-  ASSERT_TRUE(subscription->GetProperty("stringFoo")->IsUndefined());
-  ASSERT_TRUE(subscription->GetProperty("intFoo")->IsUndefined());
-  ASSERT_TRUE(subscription->GetProperty("boolFoo")->IsUndefined());
+  ASSERT_TRUE(subscription->GetProperty("stringFoo").IsUndefined());
+  ASSERT_TRUE(subscription->GetProperty("intFoo").IsUndefined());
+  ASSERT_TRUE(subscription->GetProperty("boolFoo").IsUndefined());
 
   subscription->SetProperty("stringFoo", "y");
   subscription->SetProperty("intFoo", 24);
   subscription->SetProperty("boolFoo", true);
-  ASSERT_EQ("y", subscription->GetProperty("stringFoo")->AsString());
-  ASSERT_EQ(24, subscription->GetProperty("intFoo")->AsInt());
-  ASSERT_TRUE(subscription->GetProperty("boolFoo")->AsBool());
+  ASSERT_EQ("y", subscription->GetProperty("stringFoo").AsString());
+  ASSERT_EQ(24, subscription->GetProperty("intFoo").AsInt());
+  ASSERT_TRUE(subscription->GetProperty("boolFoo").AsBool());
 }
 
 TEST_F(FilterEngineTest, AddRemoveSubscriptions)
 {
   ASSERT_EQ(0u, filterEngine->GetListedSubscriptions().size());
   AdblockPlus::SubscriptionPtr subscription = filterEngine->GetSubscription("foo");
   ASSERT_EQ(0u, filterEngine->GetListedSubscriptions().size());
   ASSERT_FALSE(subscription->IsListed());
@@ -737,17 +737,17 @@
   }
   else if (subscriptions[1]->IsAA())
   {
     aaSubscription = subscriptions[1];
     langSubscription = subscriptions[0];
   }
   ASSERT_NE(nullptr, aaSubscription);
   ASSERT_NE(nullptr, langSubscription);
-  EXPECT_EQ(langSubscriptionUrl, langSubscription->GetProperty("url")->AsString());
+  EXPECT_EQ(langSubscriptionUrl, langSubscription->GetProperty("url").AsString());
   EXPECT_TRUE(filterEngine->IsAAEnabled());
 }
 
 TEST_F(FilterEngineWithFreshFolder, DisableSubscriptionsAutoSelectOnFirstRun)
 {
   auto jsEngine = createJsEngine();
   FilterEngine::CreationParameters createParams;
   createParams.preconfiguredPrefs["first_run_subscription_auto_select"] = jsEngine->NewValue(false);
@@ -910,17 +910,17 @@
       if (otherSubscriptionsNumber == 1u)
       {
         auto subscription = filterEngine->GetSubscription(kOtherSubscriptionUrl);
         ASSERT_TRUE(subscription);
         subscription->AddToList();
         const auto subscriptions = filterEngine->GetListedSubscriptions();
         ASSERT_EQ(1u, subscriptions.size());
         EXPECT_FALSE(subscriptions[0]->IsAA());
-        EXPECT_EQ(kOtherSubscriptionUrl, subscriptions[0]->GetProperty("url")->AsString());
+        EXPECT_EQ(kOtherSubscriptionUrl, subscriptions[0]->GetProperty("url").AsString());
       }
       if (isAASatusPresent(aaStatus))
       {
         filterEngine->SetAAEnabled(true); // add AA by enabling it
         if (aaStatus == AAStatus::disabled_present)
         {
           filterEngine->SetAAEnabled(false);
         }
@@ -1006,90 +1006,90 @@
     testSubscriptionState(parameter.expectedAAStatus, otherSubscriptionsNumber);
   }
 }
 
 TEST_F(FilterEngineIsAllowedConnectionTest, AbsentCallbackAllowsUpdating)
 {
   createParams.isConnectionAllowedCallback = FilterEngine::IsConnectionAllowedCallback();
   auto subscription = EnsureExampleSubscriptionAndForceUpdate();
-  EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
-  EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+  EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus").AsString());
+  EXPECT_EQ(1u, subscription->GetProperty("filters").AsList().size());
 }
 
 TEST_F(FilterEngineIsAllowedConnectionTest, AllowingCallbackAllowsUpdating)
 {
   // no stored allowed_connection_type preference
   auto subscription = EnsureExampleSubscriptionAndForceUpdate();
-  EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
-  EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+  EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus").AsString());
+  EXPECT_EQ(1u, subscription->GetProperty("filters").AsList().size());
   auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
   ASSERT_EQ(1u, capturedConnectionTypes.size());
   EXPECT_FALSE(capturedConnectionTypes[0].first);
 }
 
 TEST_F(FilterEngineIsAllowedConnectionTest, NotAllowingCallbackDoesNotAllowUpdating)
 {
   isConnectionAllowed = false;
   // no stored allowed_connection_type preference
   auto subscription = EnsureExampleSubscriptionAndForceUpdate();
-  EXPECT_EQ("synchronize_connection_error", subscription->GetProperty("downloadStatus")->AsString());
-  EXPECT_EQ(0u, subscription->GetProperty("filters")->AsList().size());
+  EXPECT_EQ("synchronize_connection_error", subscription->GetProperty("downloadStatus").AsString());
+  EXPECT_EQ(0u, subscription->GetProperty("filters").AsList().size());
   auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
   EXPECT_EQ(1u, capturedConnectionTypes.size());
 }
 
 TEST_F(FilterEngineIsAllowedConnectionTest, PredefinedAllowedConnectionTypeIsPassedToCallback)
 {
   std::string predefinedAllowedConnectionType = "non-metered";
   createParams.preconfiguredPrefs["allowed_connection_type"] = jsEngine->NewValue(predefinedAllowedConnectionType);
   auto subscription = EnsureExampleSubscriptionAndForceUpdate();
-  EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
-  EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+  EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus").AsString());
+  EXPECT_EQ(1u, subscription->GetProperty("filters").AsList().size());
   auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
   ASSERT_EQ(1u, capturedConnectionTypes.size());
   EXPECT_TRUE(capturedConnectionTypes[0].first);
   EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second);
 }
 
 TEST_F(FilterEngineIsAllowedConnectionTest, ConfiguredConnectionTypeIsPassedToCallback)
 {
   // FilterEngine->RemoveSubscription is not usable here because subscriptions
   // are cached internally by URL. So, different URLs are used in diffirent
   // checks.
   {
     std::string predefinedAllowedConnectionType = "non-metered";
     createParams.preconfiguredPrefs["allowed_connection_type"] = jsEngine->NewValue(predefinedAllowedConnectionType);
     auto subscription = EnsureExampleSubscriptionAndForceUpdate();
-    EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
-    EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+    EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus").AsString());
+    EXPECT_EQ(1u, subscription->GetProperty("filters").AsList().size());
     auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
     ASSERT_EQ(1u, capturedConnectionTypes.size());
     EXPECT_TRUE(capturedConnectionTypes[0].first);
     EXPECT_EQ(predefinedAllowedConnectionType, capturedConnectionTypes[0].second);
   }
   capturedConnectionTypes.Clear();
   {
     // set no value
     filterEngine->SetAllowedConnectionType(nullptr);
     auto subscription = EnsureExampleSubscriptionAndForceUpdate("subA");
-    EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
-    EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+    EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus").AsString());
+    EXPECT_EQ(1u, subscription->GetProperty("filters").AsList().size());
     auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
     ASSERT_EQ(1u, capturedConnectionTypes.size());
     EXPECT_FALSE(capturedConnectionTypes[0].first);
     subscription->RemoveFromList();
     this->capturedConnectionTypes.Clear();
   }
   capturedConnectionTypes.Clear();
   {
     // set some value
     std::string testConnection = "test connection";
     filterEngine->SetAllowedConnectionType(&testConnection);
     auto subscription = EnsureExampleSubscriptionAndForceUpdate("subB");
-    EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus")->AsString());
-    EXPECT_EQ(1u, subscription->GetProperty("filters")->AsList().size());
+    EXPECT_EQ("synchronize_ok", subscription->GetProperty("downloadStatus").AsString());
+    EXPECT_EQ(1u, subscription->GetProperty("filters").AsList().size());
     auto capturedConnectionTypes = this->capturedConnectionTypes.GetStrings();
     ASSERT_EQ(1u, capturedConnectionTypes.size());
     EXPECT_TRUE(capturedConnectionTypes[0].first);
     EXPECT_EQ(testConnection, capturedConnectionTypes[0].second);
   }
 }
Index: test/JsEngine.cpp
===================================================================
--- a/test/JsEngine.cpp
+++ b/test/JsEngine.cpp
@@ -123,14 +123,14 @@
   AdblockPlus::WebRequestPtr webRequest(new AdblockPlus::DefaultWebRequest());
   jsEngine->SetWebRequest(webRequest);
   ASSERT_EQ(webRequest, jsEngine->GetWebRequest());
 }
 
 TEST(NewJsEngineTest, GlobalPropertyTest)
 {
   AdblockPlus::JsEnginePtr jsEngine(AdblockPlus::JsEngine::New());
-  jsEngine->SetGlobalProperty("foo", jsEngine->NewValue("bar"));
+  jsEngine->SetGlobalProperty("foo", *jsEngine->NewValue("bar"));
   AdblockPlus::JsValuePtr foo = jsEngine->Evaluate("foo");
   ASSERT_TRUE(foo->IsString());
   ASSERT_EQ(foo->AsString(), "bar");
 }
 
Index: test/JsValue.cpp
===================================================================
--- a/test/JsValue.cpp
+++ b/test/JsValue.cpp
@@ -148,21 +148,21 @@
   ASSERT_FALSE(value->IsNumber());
   ASSERT_TRUE(value->IsObject());
   ASSERT_FALSE(value->IsArray());
   ASSERT_FALSE(value->IsFunction());
   ASSERT_EQ("foo", value->AsString());
   ASSERT_EQ(123, value->AsInt());
   ASSERT_TRUE(value->AsBool());
   ASSERT_ANY_THROW(value->AsList());
-  ASSERT_EQ(2, value->GetProperty("x")->AsInt());
+  ASSERT_EQ(2, value->GetProperty("x").AsInt());
   value->SetProperty("x", 12);
-  ASSERT_EQ(12, value->GetProperty("x")->AsInt());
-  value->SetProperty("x", jsEngine->NewValue(15));
-  ASSERT_EQ(15, value->GetProperty("x")->AsInt());
+  ASSERT_EQ(12, value->GetProperty("x").AsInt());
+  value->SetProperty("x", *jsEngine->NewValue(15));
+  ASSERT_EQ(15, value->GetProperty("x").AsInt());
   ASSERT_EQ("Foo", value->GetClass());
   ASSERT_EQ(3u, value->GetOwnPropertyNames().size());
   ASSERT_ANY_THROW(value->Call());
 }
 
 TEST_F(JsValueTest, ArrayValue)
 {
   AdblockPlus::JsValuePtr value = jsEngine->Evaluate("[5,8,12]");
@@ -173,17 +173,17 @@
   ASSERT_FALSE(value->IsNumber());
   ASSERT_TRUE(value->IsObject());
   ASSERT_TRUE(value->IsArray());
   ASSERT_FALSE(value->IsFunction());
   ASSERT_EQ("5,8,12", value->AsString());
   ASSERT_TRUE(value->AsBool());
   ASSERT_EQ(3u, value->AsList().size());
   ASSERT_EQ(8, value->AsList()[1]->AsInt());
-  ASSERT_EQ(3, value->GetProperty("length")->AsInt());
+  ASSERT_EQ(3, value->GetProperty("length").AsInt());
   ASSERT_EQ("Array", value->GetClass());
   ASSERT_ANY_THROW(value->Call());
 }
 
 TEST_F(JsValueTest, FunctionValue)
 {
   AdblockPlus::JsValuePtr value = jsEngine->Evaluate("(function(foo, bar) {return this.x + '/' + foo + '/' + bar;})");
   ASSERT_FALSE(value->IsUndefined());
@@ -191,17 +191,17 @@
   ASSERT_FALSE(value->IsString());
   ASSERT_FALSE(value->IsBool());
   ASSERT_FALSE(value->IsNumber());
   ASSERT_TRUE(value->IsObject());
   ASSERT_FALSE(value->IsArray());
   ASSERT_TRUE(value->IsFunction());
   ASSERT_TRUE(value->AsBool());
   ASSERT_ANY_THROW(value->AsList());
-  ASSERT_EQ(2, value->GetProperty("length")->AsInt());
+  ASSERT_EQ(2, value->GetProperty("length").AsInt());
 
   AdblockPlus::JsValuePtr thisPtr = jsEngine->Evaluate("({x:2})");
   AdblockPlus::JsConstValueList params;
   params.push_back(jsEngine->NewValue(5));
   params.push_back(jsEngine->NewValue("xyz"));
   ASSERT_EQ("2/5/xyz", value->Call(params, thisPtr).AsString());
 }
 
