public function lookup($sAddress = '')
    {
        $sAddress = trim($sAddress);

        if (empty($sAddress)){
            return null;
        }

        //  Check caches; local cache first followed by DB cache
        $oCache = $this->getCache($sAddress);

        if (!empty($oCache)) {
            return $oCache;
        }

        $oDb = Factory::service('Database');
        $oDb->select('X(latlng) lat, Y(latlng) lng');
        $oDb->where('address', $sAddress);
        $oDb->limit(1);
        $oResult = $oDb->get(self::DB_CACHE_TABLE)->row();

        if (!empty($oResult)) {

            $oLatLng = Factory::factory('LatLng', 'nails/module-geo-code');
            $oLatLng->setAddress($sAddress);
            $oLatLng->setLat($oResult->lat);
            $oLatLng->setLng($oResult->lng);

        } else {

            $oLatLng = $this->oDriver->lookup($sAddress);

            if (!($oLatLng instanceof \Nails\GeoCode\Result\LatLng)) {

                throw new GeoCodeException(
                    'Geo Code Driver did not return a \Nails\GeoCode\Result\LatLng result',
                    3
                );
            }

            $sLat = $oLatLng->getLat();
            $sLng = $oLatLng->getLng();

            //  Save to the DB Cache
            if (!empty($sLat) && !empty($sLng)) {

                $oDb->set('address', $sAddress);
                $oDb->set('latlng', 'POINT(' . $sLat . ', ' . $sLng . ')', false);
                $oDb->set('created', 'NOW()', false);
                $oDb->insert(self::DB_CACHE_TABLE);
            }
        }

        $this->setCache($sAddress, $oLatLng);

        return $oLatLng;
    }