# Path: smc/base/decorators.py
# class cached_property(object):
#     """
#     Use for caching a property value on the instance. If the
#     attribute is deleted, it will be recreated when called.
#     """
# 
#     def __init__(self, func):
#         self.func = func
#         #self.__doc__ = func.__doc__
# 
#     def __get__(self, obj, cls):
#         if obj is None:
#             return self
#         value = obj.__dict__[self.func.__name__] = self.func(obj)
#         return value
# 
# class classproperty(object):
#     """
#     Used for collection manager so objects can be accessed as a
#     class property and also from the instance
#     """
# 
#     def __init__(self, fget):
#         self.fget = fget
# 
#     def __get__(self, instance, owner_cls):
#         return self.fget(owner_cls)
# 
# Path: smc/api/exceptions.py
# class FetchElementFailed(SMCException):
#     """
#     Failure when fetching results
#     """
# 
# class InvalidSearchFilter(SMCException):
#     """
#     Thrown by collections when using invalid search sequences.
#     """
# 
# Path: smc/api/common.py
# def entry_point():
#     return _get_session().entry_points


import re
import copy
import smc.base.model
from itertools import islice
from smc.base.decorators import cached_property, classproperty
from smc.api.exceptions import FetchElementFailed, InvalidSearchFilter
from smc.api.common import entry_point
        ...
        Search.objects.context_filter('engine_clusters') # by context filter
        ...
        Search.objects.filter('2.2.2.2') # All element types with filter
        ...
        Search.objects.entry_point('router,host')) # Search using multiple element types
        ...
        Search.objects.entry_point('router,host').filter('2.2.2.2') # with filter
        
    Search also provides convenience shortcuts to find duplicate and unused elements::
    
        Search.objects.unused()
        ...
        Search objects.duplicates()
    
    If searching a broad range of elements, it is advisable to return results in
    batches::
    
        for batch in Search.objects.batch(100): # All elements search
            ...
    
    .. note:: If no entry point is specified, the search is done at the 'elements'
        entry point which contains all SMC elements. It is recommended
        to use ``filter`` and possibly ``batch`` to control the result set.
    """

    def __init__(self, **params):
        super(Search, self).__init__(**params)
        self._resource = entry_point()
    

# Path: smc/base/decorators.py
# class cached_property(object):
#     """
#     Use for caching a property value on the instance. If the
#     attribute is deleted, it will be recreated when called.
#     """
# 
#     def __init__(self, func):
#         self.func = func
#         #self.__doc__ = func.__doc__
# 
#     def __get__(self, obj, cls):
#         if obj is None:
#             return self
#         value = obj.__dict__[self.func.__name__] = self.func(obj)
#         return value
# 
# class classproperty(object):
#     """
#     Used for collection manager so objects can be accessed as a
#     class property and also from the instance
#     """
# 
#     def __init__(self, fget):
#         self.fget = fget
# 
#     def __get__(self, instance, owner_cls):
#         return self.fget(owner_cls)
# 
# Path: smc/api/exceptions.py
# class FetchElementFailed(SMCException):
#     """
#     Failure when fetching results
#     """
# 
# class InvalidSearchFilter(SMCException):
#     """
#     Thrown by collections when using invalid search sequences.
#     """
# 
# Path: smc/api/common.py
# def entry_point():
#     return _get_session().entry_points


# Path: smc/base/collection.py
import re
import copy
import smc.base.model
from itertools import islice
from smc.base.decorators import cached_property, classproperty
from smc.api.exceptions import FetchElementFailed, InvalidSearchFilter
from smc.api.common import entry_point

        ...
        Search.objects.context_filter('engine_clusters') # by context filter
        ...
        Search.objects.filter('2.2.2.2') # All element types with filter
        ...
        Search.objects.entry_point('router,host')) # Search using multiple element types
        ...
        Search.objects.entry_point('router,host').filter('2.2.2.2') # with filter
        
    Search also provides convenience shortcuts to find duplicate and unused elements::
    
        Search.objects.unused()
        ...
        Search objects.duplicates()
    
    If searching a broad range of elements, it is advisable to return results in
    batches::
    
        for batch in Search.objects.batch(100): # All elements search
            ...
    
    .. note:: If no entry point is specified, the search is done at the 'elements'
        entry point which contains all SMC elements. It is recommended
        to use ``filter`` and possibly ``batch`` to control the result set.
    """

    def __init__(self, **params):
        super(Search, self).__init__(**params)
        self._resource = entry_point()
    

    @classproperty