# Path: rx/disposables/disposable.py
# class Disposable(object):
#     """Main disposable class"""
#     def __init__(self, action):
#         """Creates a disposable object that invokes the specified action when 
#         disposed.
#         
#         Keyword arguments:
#         dispose -- Action to run during the first call to Disposable.dispose. 
#             The action is guaranteed to be run at most once.
#         
#         Returns the disposable object that runs the given action upon disposal.
#         """
#         self.is_disposed = False
#         self.action = action
# 
#     def dispose(self):
#         """Performs the task of cleaning up resources."""
# 
#         if not self.is_disposed:
#             self.action()
#             self.is_disposed = True
# 
#     @classmethod
#     def empty(cls):
#         return cls(noop)


from .disposable import Disposable
    class InnerDisposable(Disposable):
        def __init__(self, disposable):
            self.disposable = disposable
            self.disposable.count += 1
            self.is_inner_disposed = False

        def dispose(self):
            if not self.disposable.is_disposed:
                if not self.is_inner_disposed:
                    self.is_inner_disposed = True
                    self.disposable.count -= 1
                    if self.disposable.count == 0 and self.disposable.is_primary_disposed:
                        self.disposable.is_disposed = True
                        self.disposable.underlying_disposable.dispose()
                    
    def __init__(self, disposable):
        self.underlying_disposable = disposable
        self.is_disposed = False
        self.is_primary_disposed = False
        self.count = 0
    
    def dispose(self):
        if not self.is_disposed:
            if not self.is_primary_disposed:
                self.is_primary_disposed = True
                if self.count == 0:
                    self.is_disposed = True
                    self.underlying_disposable.dispose()
                
    def get_disposable(self):

# Path: rx/disposables/disposable.py
# class Disposable(object):
#     """Main disposable class"""
#     def __init__(self, action):
#         """Creates a disposable object that invokes the specified action when 
#         disposed.
#         
#         Keyword arguments:
#         dispose -- Action to run during the first call to Disposable.dispose. 
#             The action is guaranteed to be run at most once.
#         
#         Returns the disposable object that runs the given action upon disposal.
#         """
#         self.is_disposed = False
#         self.action = action
# 
#     def dispose(self):
#         """Performs the task of cleaning up resources."""
# 
#         if not self.is_disposed:
#             self.action()
#             self.is_disposed = True
# 
#     @classmethod
#     def empty(cls):
#         return cls(noop)


# Path: rx/disposables/refcountdisposable.py
from .disposable import Disposable

    class InnerDisposable(Disposable):
        def __init__(self, disposable):
            self.disposable = disposable
            self.disposable.count += 1
            self.is_inner_disposed = False

        def dispose(self):
            if not self.disposable.is_disposed:
                if not self.is_inner_disposed:
                    self.is_inner_disposed = True
                    self.disposable.count -= 1
                    if self.disposable.count == 0 and self.disposable.is_primary_disposed:
                        self.disposable.is_disposed = True
                        self.disposable.underlying_disposable.dispose()
                    
    def __init__(self, disposable):
        self.underlying_disposable = disposable
        self.is_disposed = False
        self.is_primary_disposed = False
        self.count = 0
    
    def dispose(self):
        if not self.is_disposed:
            if not self.is_primary_disposed:
                self.is_primary_disposed = True
                if self.count == 0:
                    self.is_disposed = True
                    self.underlying_disposable.dispose()
                
    def get_disposable(self):

        return Disposable.empty() if self.is_disposed else self.InnerDisposable(self)