def get_property_names(obj):
        """
        Recursively gets names of all properties implemented in specified object and its subobjects.

        The object can be a user defined object, map or array.
        Returned property name correspondently are object properties, map keys or array indexes.

        :param obj: an object to introspect.

        :return: a list with property names.
        """
        property_names = []
        
        if obj != None:
            cycle_detect = []
            RecursiveObjectReader._perform_get_property_names(obj, None, property_names, cycle_detect)

        return property_names