Defines a particular method as being deprecated - the 
    method will exist for backwards compatibility, but will 
    contain information as to how update code to become 
    compatible with the current system.
                
    Code that is deprecated will only be supported through the 
    end of a minor release cycle and will be cleaned during a 
    major release upgrade.
    
    :usage      |from projex.decorators import deprecated
                |
                |class A(object):
                |   @deprecatedmethod('A', 'Use A.printout instead')
                |   def format( self ):
                |       print 'test'
                |
                |   def printout( self ):
                :       print 'new test'

def deprecatedmethod(classname='', info=''):
    """
    Defines a particular method as being deprecated - the 
    method will exist for backwards compatibility, but will 
    contain information as to how update code to become 
    compatible with the current system.
                
    Code that is deprecated will only be supported through the 
    end of a minor release cycle and will be cleaned during a 
    major release upgrade.
    
    :usage      |from projex.decorators import deprecated
                |
                |class A(object):
                |   @deprecatedmethod('A', 'Use A.printout instead')
                |   def format( self ):
                |       print 'test'
                |
                |   def printout( self ):
                :       print 'new test'
    """

    def decorated(func):
        @wraps(func)
        def wrapped(*args, **kwds):
            frame = last_frame = None
            try:
                frame = inspect.currentframe()
                last_frame = frame.f_back
                fname = last_frame.f_code.co_filename
                func_file = func.func_code.co_filename

                opts = {
                    'func': func.__name__,
                    'line': last_frame.f_lineno,
                    'file': fname,
                    'class': classname,
                    'info': info,
                    'package': projex.packageFromPath(func_file)
                }

                msg = 'Deprecated method called from %(file)s, line %(line)d.' \
                      '\n  %(package)s.%(class)s.%(func)s is deprecated.' \
                      '  %(info)s' % opts

                logger.warning(errors.DeprecatedMethodWarning(msg))

            finally:
                del frame
                del last_frame

            return func(*args, **kwds)

        wrapped.__name__ = func.__name__

        wrapped.__doc__ = ':warning  This method is deprecated!  %s\n\n' % info
        if func.__doc__:
            wrapped.__doc__ += func.__doc__

        wrapped.__dict__.update(func.__dict__)
        wrapped.__dict__['func_type'] = 'deprecated method'

        return wrapped

    return decorated