Add support for pickling Driver instances.
diff --git a/libcloud/common/base.py b/libcloud/common/base.py
index ac0fdd7..f2365e4 100644
--- a/libcloud/common/base.py
+++ b/libcloud/common/base.py
@@ -1102,6 +1102,11 @@
                             'backoff': kwargs.pop('backoff', None)})
         self.connection = self.connectionCls(*args, **conn_kwargs)
 
+        # Note: We store this attributes on the class so we can re-create
+        # connection when unpickling driver instance
+        self._connection_cls_args = args
+        self._connection_cls_kwargs = conn_kwargs
+
         self.connection.driver = self
         self.connection.connect()
 
@@ -1111,3 +1116,21 @@
         Connection class constructor.
         """
         return {}
+
+    def __getstate__(self):
+        # Note: "connection" attribute contains many unpicklable objects which
+        # is why we only store attributes which can be used to re-create the
+        # instance later when unpickling.
+        state = self.__dict__.copy()
+        del state['connection']
+        return state
+
+    def __setstate__(self, state):
+        for key, value in state.items():
+            setattr(self, key, value)
+
+        # Re-create connection class instance
+        args = self._connection_cls_args
+        kwargs = self._connection_cls_kwargs
+        self.connection = self.connectionCls(*args, **kwargs)
+        self.connection.connect()
diff --git a/libcloud/test/common/test_pickling.py b/libcloud/test/common/test_pickling.py
new file mode 100644
index 0000000..eda31e9
--- /dev/null
+++ b/libcloud/test/common/test_pickling.py
@@ -0,0 +1,72 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import pickle
+
+from libcloud.compute.drivers.rackspace import RackspaceNodeDriver
+from libcloud.compute.drivers.digitalocean import DigitalOceanNodeDriver
+from libcloud.test.compute.test_digitalocean_v2 import DigitalOceanMockHttp
+from libcloud.test import unittest
+from libcloud.test.secrets import DIGITALOCEAN_v2_PARAMS
+
+
+class PickleDriverClassTestCase(unittest.TestCase):
+
+    def setUp(self):
+        DigitalOceanNodeDriver.connectionCls.conn_classes = \
+            (None, DigitalOceanMockHttp)
+        DigitalOceanMockHttp.type = None
+        self.driver = DigitalOceanNodeDriver(*DIGITALOCEAN_v2_PARAMS)
+
+    def test_pickle_and_unpickle_driver_instance(self):
+        driver = RackspaceNodeDriver('testkey', 'testsecret', region='iad')
+
+        self.assertEqual(driver.key, 'testkey')
+        self.assertEqual(driver.secret, 'testsecret')
+        self.assertTrue(driver.connection)
+        self.assertEqual(driver.connection.user_id, 'testkey')
+        self.assertEqual(driver.connection.key, 'testsecret')
+
+        pickled = pickle.dumps(driver)
+        unpickled = pickle.loads(pickled)
+
+        self.assertEqual(unpickled.key, 'testkey')
+        self.assertEqual(unpickled.secret, 'testsecret')
+        self.assertTrue(unpickled.connection)
+        self.assertEqual(unpickled.connection.user_id, 'testkey')
+        self.assertEqual(unpickled.connection.key, 'testsecret')
+
+    def test_pickle_and_unpickle_node_instance(self):
+        node = self.driver.list_nodes()[0]
+
+        self.assertEqual(node.name, 'example.com')
+        self.assertEqual(node.public_ips, ['104.236.32.182'])
+        self.assertEqual(node.extra['image']['id'], 6918990)
+        self.assertEqual(node.extra['size_slug'], '512mb')
+        self.assertEqual(node.driver.name, self.driver.name)
+
+        pickled = pickle.dumps(node)
+        unpickled = pickle.loads(pickled)
+
+        self.assertEqual(unpickled.name, 'example.com')
+        self.assertEqual(unpickled.public_ips, ['104.236.32.182'])
+        self.assertEqual(unpickled.extra['image']['id'], 6918990)
+        self.assertEqual(unpickled.extra['size_slug'], '512mb')
+        self.assertEqual(unpickled.driver.name, self.driver.name)
+
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())