text:
module tf
using Cxx

__tf_buffers = []
__tf_listeners = []

"""
    TransformBroadcaster()

Constructor (needs a ros::Node reference).
"""
TransformBroadcaster() = icxx"return new tf2_ros::TransformBroadcaster();"

"""
    StaticTransformBroadcaster()

Constructor (needs a ros::Node reference).
"""
StaticTransformBroadcaster() = icxx"return new tf2_ros::StaticTransformBroadcaster();"

"""
    sendTransform(broadcaster, transform)

Send a TransformStamped message The stamped data structure includes frame_id, and time, and parent_id already.
"""
sendTransform(broadcaster::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::TransformBroadcaster")},(false, false, false)},(false, false, false)}, transform::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::TransformStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::TransformStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::TransformStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}) = @cxx broadcaster->sendTransform(*(transform))

"""
    function sendTransform(broadcaster, transforms::Union{Array,Vector})

Send a TransformStamped message The stamped data structure includes frame_id, and time, and parent_id already.
"""
function sendTransform(broadcaster::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::TransformBroadcaster")},(false, false, false)},(false, false, false)}, transforms::Union{Array,Vector})
    for transform in transforms
        sendTransform(broadcaster, transform)
    end
end

"""
    sendTransform(static_broadcaster, transform)

Send a TransformStamped message The stamped data structure includes frame_id, and time, and parent_id already.
"""
sendTransform(broadcaster::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::StaticTransformBroadcaster")},(false, false, false)},(false, false, false)}, transform::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::TransformStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::TransformStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::TransformStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}) = @cxx broadcaster->sendTransform(*(transform))

"""
    sendTransform(static_broadcaster, transforms::Union{Array,Vector})

Send a TransformStamped message The stamped data structure includes frame_id, and time, and parent_id already.
"""
function sendTransform(broadcaster::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::StaticTransformBroadcaster")},(false, false, false)},(false, false, false)}, transforms::Union{Array,Vector})
    for transform in transforms
        sendTransform(broadcaster, transform)
    end
end

"""
    Buffer()

Constructor for a Buffer object.
"""
function Buffer()
    push!(__tf_buffers, icxx"return new tf2_ros::Buffer();")
    return last(__tf_buffers)
end

"""
    TransformListener(buffer)

Constructor for transform listener.
"""
function TransformListener(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)})
    push!(__tf_listeners, icxx"return new tf2_ros::TransformListener(*$buffer);")
    return last(__tf_listeners)
end

"""
    canTransform(buffer, target_frame::String, source_frame::String, time, timeout)

Test if a transform is possible.
"""
canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = @cxx buffer->canTransform(pointer(target_frame), pointer(source_frame), *(time), *(timeout))

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = @cxx buffer->canTransform(pointer(target_frame), pointer(source_frame), time, *(timeout))

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = @cxx buffer->canTransform(pointer(target_frame), pointer(source_frame), *(time), timeout)

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = @cxx buffer->canTransform(pointer(target_frame), pointer(source_frame), time, timeout)

"""
    canTransform(buffer, target_frame::String, target_time, source_frame::String, source_time, fixed_frame::String, timeout)

Test if a transform is possible.
"""
canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = @cxx buffer->canTransform(pointer(target_frame), *(target_time), pointer(source_frame), *(source_time), pointer(fixed_frame), *(timeout))

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = @cxx buffer->canTransform(pointer(target_frame), target_time, pointer(source_frame), *(source_time), pointer(fixed_frame), *(timeout))

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = @cxx buffer->canTransform(pointer(target_frame), target_time, pointer(source_frame), source_time, pointer(fixed_frame), *(timeout))

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = @cxx buffer->canTransform(pointer(target_frame), target_time, pointer(source_frame), source_time, pointer(fixed_frame), timeout)

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = @cxx buffer->canTransform(pointer(target_frame), target_time, pointer(source_frame), *(source_time), pointer(fixed_frame), timeout)

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = @cxx buffer->canTransform(pointer(target_frame), *(target_time), pointer(source_frame), *(source_time), pointer(fixed_frame), timeout)

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = @cxx buffer->canTransform(pointer(target_frame), *(target_time), pointer(source_frame), source_time, pointer(fixed_frame), timeout)

canTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = @cxx buffer->canTransform(pointer(target_frame), *(target_time), pointer(source_frame), source_time, pointer(fixed_frame), *(timeout))

"""
    lookupTransform(buffer, target_frame::String, source_frame::String, time, timeout)

Get the transform between two frames by frame ID.
"""
lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $(pointer(source_frame)), *($time), *($timeout)));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $(pointer(source_frame)), $time, *($timeout)));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $(pointer(source_frame)), *($time), $timeout));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, source_frame::String, time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $(pointer(source_frame)), $time, $timeout));"

"""
    lookupTransform(buffer, target_frame::String, target_time, source_frame::String, source_time, fixed_frame::String, timeout)

Get the transform between two frames by frame ID assuming fixed frame.
"""
lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), *($target_time), $(pointer(source_frame)), *($source_time), $(pointer(fixed_frame)), *($timeout)));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $target_time, $(pointer(source_frame)), *($source_time), $(pointer(fixed_frame)), *($timeout)));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $target_time, $(pointer(source_frame)), $source_time, $(pointer(fixed_frame)), *($timeout)));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $target_time, $(pointer(source_frame)), $source_time, $(pointer(fixed_frame)), $timeout));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), $target_time, $(pointer(source_frame)), *($source_time), $(pointer(fixed_frame)), $timeout));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), *($target_time), $(pointer(source_frame)), *($source_time), $(pointer(fixed_frame)), $timeout));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), *($target_time), $(pointer(source_frame)), $source_time, $(pointer(fixed_frame)), $timeout));"

lookupTransform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, target_frame::String, target_time::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, source_frame::String, source_time::Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N, fixed_frame::String, timeout::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}) = icxx"return new geometry_msgs::TransformStamped($buffer->lookupTransform($(pointer(target_frame)), *($target_time), $(pointer(source_frame)), $source_time, $(pointer(fixed_frame)), *($timeout)));"

"""
    transform(buffer, in, target_frame::String, timeout)

Transform an input into the target frame.
"""
function transform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, in::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PoseStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PoseStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PoseStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}, target_frame::String, timeout::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N})
    if typeof(in) <: Cxx.CxxCore.CppPtr
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            icxx"return new geometry_msgs::PoseStamped($buffer->transform(*($in), $(pointer(target_frame)), *($timeout)));"
        else
            icxx"return new geometry_msgs::PoseStamped($buffer->transform(*($in), $(pointer(target_frame)), $timeout));"
        end
    else
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            icxx"return new geometry_msgs::PoseStamped($buffer->transform($in, $(pointer(target_frame)), *($timeout)));"
        else
            icxx"return new geometry_msgs::PoseStamped($buffer->transform($in, $(pointer(target_frame)), $timeout));"
        end
    end
end

"""
    transform(buffer, in, target_frame::String, target_time, fixed_frame::String, timeout)

Transform an input into the target frame.
"""
function transform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, in::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PoseStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PoseStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PoseStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}, target_frame::String, target_time::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N}, fixed_frame::String, timeout::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N})
    if typeof(in) <: Cxx.CxxCore.CppPtr
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PoseStamped($buffer->transform(*($in), $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), *($timeout)));"
            else
                icxx"return new geometry_msgs::PoseStamped($buffer->transform(*($in), $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), *($timeout)));"
            end
        else
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PoseStamped($buffer->transform(*($in), $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), $timeout));"
            else
                icxx"return new geometry_msgs::PoseStamped($buffer->transform(*($in), $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), $timeout));"
            end
        end
    else
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PoseStamped($buffer->transform($in, $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), *($timeout)));"
            else
                icxx"return new geometry_msgs::PoseStamped($buffer->transform($in, $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), *($timeout)));"
            end
        else
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PoseStamped($buffer->transform($in, $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), $timeout));"
            else
                icxx"return new geometry_msgs::PoseStamped($buffer->transform($in, $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), $timeout));"
            end
        end
    end
end

function transform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, in::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PointStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PointStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PointStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}, target_frame::String, timeout::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N})
    if typeof(in) <: Cxx.CxxCore.CppPtr
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            icxx"return new geometry_msgs::PointStamped($buffer->transform(*($in), $(pointer(target_frame)), *($timeout)));"
        else
            icxx"return new geometry_msgs::PointStamped($buffer->transform(*($in), $(pointer(target_frame)), $timeout));"
        end
    else
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            icxx"return new geometry_msgs::PointStamped($buffer->transform($in, $(pointer(target_frame)), *($timeout)));"
        else
            icxx"return new geometry_msgs::PointStamped($buffer->transform($in, $(pointer(target_frame)), $timeout));"
        end
    end
end

function transform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, in::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PointStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PointStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::PointStamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}, target_frame::String, target_time::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N}, fixed_frame::String, timeout::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N})
    if typeof(in) <: Cxx.CxxCore.CppPtr
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PointStamped($buffer->transform(*($in), $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), *($timeout)));"
            else
                icxx"return new geometry_msgs::PointStamped($buffer->transform(*($in), $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), *($timeout)));"
            end
        else
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PointStamped($buffer->transform(*($in), $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), $timeout));"
            else
                icxx"return new geometry_msgs::PointStamped($buffer->transform(*($in), $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), $timeout));"
            end
        end
    else
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PointStamped($buffer->transform($in, $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), *($timeout)));"
            else
                icxx"return new geometry_msgs::PointStamped($buffer->transform($in, $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), *($timeout)));"
            end
        else
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::PointStamped($buffer->transform($in, $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), $timeout));"
            else
                icxx"return new geometry_msgs::PointStamped($buffer->transform($in, $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), $timeout));"
            end
        end
    end
end

function transform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, in::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Vector3Stamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Vector3Stamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Vector3Stamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}, target_frame::String, timeout::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N})
    if typeof(in) <: Cxx.CxxCore.CppPtr
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            icxx"return new geometry_msgs::Vector3Stamped($buffer->transform(*($in), $(pointer(target_frame)), *($timeout)));"
        else
            icxx"return new geometry_msgs::Vector3Stamped($buffer->transform(*($in), $(pointer(target_frame)), $timeout));"
        end
    else
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            icxx"return new geometry_msgs::Vector3Stamped($buffer->transform($in, $(pointer(target_frame)), *($timeout)));"
        else
            icxx"return new geometry_msgs::Vector3Stamped($buffer->transform($in, $(pointer(target_frame)), $timeout));"
        end
    end
end

function transform(buffer::Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("tf2_ros::Buffer")},(false, false, false)},(false, false, false)}, in::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Vector3Stamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Vector3Stamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Vector3Stamped_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(true, false, false)},(false, false, false)}}, target_frame::String, target_time::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Time")},(false, false, false)},N} where N}, fixed_frame::String, timeout::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppBaseType{Symbol("ros::Duration")},(false, false, false)},N} where N})
    if typeof(in) <: Cxx.CxxCore.CppPtr
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform(*($in), $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), *($timeout)));"
            else
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform(*($in), $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), *($timeout)));"
            end
        else
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform(*($in), $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), $timeout));"
            else
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform(*($in), $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), $timeout));"
            end
        end
    else
        if typeof(timeout) <: Cxx.CxxCore.CppPtr
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform($in, $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), *($timeout)));"
            else
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform($in, $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), *($timeout)));"
            end
        else
            if typeof(target_time) <: Cxx.CxxCore.CppPtr
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform($in, $(pointer(target_frame)), *($target_time), $(pointer(fixed_frame)), $timeout));"
            else
                icxx"return new geometry_msgs::Vector3Stamped($buffer->transform($in, $(pointer(target_frame)), $target_time, $(pointer(fixed_frame)), $timeout));"
            end
        end
    end
end

"""
    setRPY(roll::Number, pitch::Number, yaw::Number)

Roll,Pitch,Yaw to geometry_msgs::Quaternion.
"""
function setRPY(roll::Number, pitch::Number, yaw::Number)
    icxx"""
        tf2::Quaternion tf_quat;
        tf_quat.setRPY($roll, $pitch, $yaw);
        return new geometry_msgs::Quaternion(tf2::toMsg(tf_quat));
    """
end

"""
    setEuler(yaw::Number, pitch::Number, roll::Number)

Euler angles (yaw/pitch/roll) to geometry_msgs::Quaternion.
"""
function setEuler(yaw::Number, pitch::Number, roll::Number)
    icxx"""
        tf2::Quaternion tf_quat;
        tf_quat.setEuler($yaw, $pitch, $roll);
        return new geometry_msgs::Quaternion(tf2::toMsg(tf_quat));
    """
end

"""
    normalize(quaternion)

Normalize a geometry_msgs::Quaternion (useful after calculations).
"""
function normalize(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion tf_quat;
        tf2::fromMsg(*$quaternion, tf_quat);
        tf_quat.normalize();
        return new geometry_msgs::Quaternion(tf2::toMsg(tf_quat));
    """
end

"""
    angle(q1, q2)

Return the half angle between q1 and q2 geometry_msgs::Quaternions.
"""
function angle(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, q2::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion q1, q2;
        tf2::fromMsg(*$q1, q1);
        tf2::fromMsg(*$q2, q2);
        return q1.angle(q2);
    """
end

"""
    angleShortestPath(q1, q2)

Return the angle between q1 and q2 geometry_msgs::Quaternions.
"""
function angleShortestPath(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, q2::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion q1, q2;
        tf2::fromMsg(*$q1, q1);
        tf2::fromMsg(*$q2, q2);
        return q1.angleShortestPath(q2);
    """
end

"""
    dot(q1, q2)

Return the dot product between q1 and q2 geometry_msgs::Quaternions.
"""
function dot(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, q2::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion q1, q2;
        tf2::fromMsg(*$q1, q1);
        tf2::fromMsg(*$q2, q2);
        return q1.dot(q2);
    """
end

"""
    getAngle(quaternion)

Return the angle [0, 2π] of rotation represented by this quaternion.
"""
function getAngle(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion tf_quat;
        tf2::fromMsg(*$quaternion, tf_quat);
        return tf_quat.getAngle();
    """
end

"""
    getAngleShortestPath(quaternion)

Return the angle [0, π] of rotation represented by this quaternion.
"""
function getAngleShortestPath(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion tf_quat;
        tf2::fromMsg(*$quaternion, tf_quat);
        return tf_quat.getAngleShortestPath();
    """
end

"""
    inverse(quaternion)

Return the inverse of this geometry_msgs::Quaternion.
"""
function inverse(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion tf_quat;
        tf2::fromMsg(*$quaternion, tf_quat);
        return new geometry_msgs::Quaternion(tf2::toMsg(tf_quat.inverse()));
    """
end

"""
    getAxis(quaternion)

Return the axis of the rotation represented by this geometry_msgs::Quaternion.
"""
function getAxis(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    unsafe_wrap(DenseArray,
        icxx"""
            tf2::Quaternion tf_quat;
            tf2::fromMsg(*$quaternion, tf_quat);
            tf2::Vector3 v3 = tf_quat.getAxis();
            std::vector<double> v = {v3.x(), v3.y(), v3.z()};
            return v;
        """
    )
end

"""
    length(quaternion)

Return the length of the quaternion.
"""
function length(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion tf_quat;
        tf2::fromMsg(*$quaternion, tf_quat);
        return tf_quat.length();
    """
end

"""
    length2(quaternion)

Return the length squared of the quaternion.
"""
function length2(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion tf_quat;
        tf2::fromMsg(*$quaternion, tf_quat);
        return tf_quat.length2();
    """
end

"""
    slerp(q1, q2, t::Number)

Return the geometry_msgs::Quaternion which is the result of Spherical Linear Interpolation between q1 and q2 geometry_msgs::Quaternions.
"""
function slerp(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, q2::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, t::Number)
    icxx"""
        tf2::Quaternion q1, q2;
        tf2::fromMsg(*$q1, q1);
        tf2::fromMsg(*$q2, q2);
        return new geometry_msgs::Quaternion(tf2::toMsg(q1.slerp(q2, $t)));
    """
end

"""
    setRotation(quaternion, axis::Union{Array,Vector}, angle::Number)

Set the rotation using axis angle notation.
"""
function setRotation(quaternion::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, axis::Union{Array,Vector}, angle::Number)
    icxx"""
        tf2::Quaternion tf_quat;
        tf2::fromMsg(*$quaternion, tf_quat);
        tf_quat.setRotation(tf2::Vector3($(axis[1]), $(axis[2]), $(axis[3])), $angle);
        return new geometry_msgs::Quaternion(tf2::toMsg(tf_quat));
    """
end

function Base.:-(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, q2::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion q1, q2;
        tf2::fromMsg(*$q1, q1);
        tf2::fromMsg(*$q2, q2);
        return new geometry_msgs::Quaternion(tf2::toMsg(q1-q2));
    """
end

function Base.:-(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion q($(-q1.x), $(-q1.y), $(-q1.z), $(-q1.w));
        return new geometry_msgs::Quaternion(tf2::toMsg(q));
    """
end

function Base.:*(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, q2::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion q1, q2;
        tf2::fromMsg(*$q1, q1);
        tf2::fromMsg(*$q2, q2);
        return new geometry_msgs::Quaternion(tf2::toMsg(q1*q2));
    """
end

function Base.:+(q1::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}}, q2::Union{Cxx.CxxCore.CppPtr{Cxx.CxxCore.CppValue{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},N} where N,(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}, Cxx.CxxCore.CppPtr{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("geometry_msgs::Quaternion_")},Tuple{Cxx.CxxCore.CxxQualType{Cxx.CxxCore.CppTemplate{Cxx.CxxCore.CppBaseType{Symbol("std::allocator")},Tuple{Nothing}},(false, false, false)}}},(false, false, false)},(false, false, false)}})
    icxx"""
        tf2::Quaternion q1, q2;
        tf2::fromMsg(*$q1, q1);
        tf2::fromMsg(*$q2, q2);
        return new geometry_msgs::Quaternion(tf2::toMsg(q1+q2));
    """
end

end


text:
"""
	api_pusher(mode::String, content::String, config::Config; format::String="", returnFormat::String="", file_loc::String="", kwargs...)

Pass the type of api call, the config struct, and any needed kwargs for that api call.
Handles creation of the Dict of fields to pass to REDCap, and file IO/formatting.

API documentation found here:
https://<your-redcap-site.com>/redcap/api/help/

#### Parameters:
* `mode` - "import", "export", or "delete"
* `content` - Passed by calling modules to indicate what data to access
* `config` - Struct containing url and api-key
* `format` - "json", "xml", "csv", or "odm". decides format of returned data
* `returnFormat` - Error message format
* `file_loc` - Location of file
* `kwargs...` - Any addtl. arguments passed by the calling module

#### Returns:
Formatted response body
"""
function api_pusher(mode::String, content::String, config::Config; format::String="", returnFormat::String="", file_loc::String="", kwargs...)
	#initialize dict with basic info and api calls
	fields = Dict{String, Any}("token" => config.key,
					"action" => mode,						#import, export, delete
					"content" => content,					#API call to access
					"returnFormat" => returnFormat)

	if format=="df"
		if mode=="import"
			fields["format"] = "json" 						#REDCap doesnt know what df is
		elseif mode=="export"
			fields["format"] = "csv"						#Julia can parse csv as a df
		end
	else
		fields["format"] = format
	end

	for (k,v) in kwargs
		k=String(k) 										#k is a Symbol, make easier to handle
		if mode=="import" && isequal(k, "data")				#Turn all imported data into an IOBuffer so HTTP won't mess with it OR turn filterLogic data into a buffer because it uses []'s and REDCap can't understand URI encoding
			fields[k]=IOBuffer(v)
		elseif isa(v, Array)								#Turn arrays into specially URI encoded arrays
			for (i, item) in enumerate(v)
			    fields["$k[$(i-1)]"]=String(item)
			end
		elseif isequal(k, "filterLogic") && v != ""
			fields[k]=IOBuffer(v)
		else
			fields[k]=string(v)
		end
	end

	#POST request and get response
	response = poster(config, fields)

	#check if user wanted to save the file here
	if mode=="export"
		if length(file_loc)>0
			export_to_file(file_loc, response)
		else
			return formatter(response, format, mode)
		end
	elseif mode=="import" || mode=="delete"
		return formatter(response, returnFormat, "export")
	end
end

"""
	poster(config::Config, body)

Handles the POST duties for all modules. Also does basic Status checking and SSL verification.

#### Parameters:
* `config` - Struct containing url and api-key
* `body` - Request body data

#### Returns:
The response body.
"""
function poster(config::Config, body)
	println("POSTing")

	response = HTTP.post(config.url; body=body, require_ssl_verification=config.ssl)#, verbose=3)

	println("POSTd")
	if response.status != 200
		#Error - handle errors way more robustly- check for "error" field? here or back at api_pusher?
		#an error is an error is an error, so it throws no matter what, on REDCaps end
		println(response.status)
	else
		return String(response.body)
	end
end

"""
	generate_next_record_id(config::Config)

#### Parameters:
* `config` - Struct containing url and api-key

#### Returns:
The next available ID number for project (Max record number +1)
"""
function generate_next_record_id(config::Config)
	fields = Dict("token" => config.key,
				  "content" => "generateNextRecordName")
	return parse(Int64, poster(config, fields)) 		#return as integer
end

"""
	formatter(data, format, mode::String)

Takes data and sends out to the proper formating function.

#### Parameters:
* `data` - The data to be formatted
* `format` - The target format
* `mode` - Formatting for Import (data to server) or Export (data from server)

#### Returns:
The specified formatted/unformatted object
"""
function formatter(data, format, mode::String)
	if format=="json"
		return json_formatter(data, mode)
	elseif format=="csv"
		return data 						#very little needs to be done, but still keep as a sep. case
	elseif format=="xml"
		return xml_formatter(data, mode)
	elseif format=="odm"
		return odm_formatter(data, mode)
	elseif format=="df"
		return df_formatter(data, mode)
	elseif format=="text"
		return data 						#Internal format
	else
		@error("$format is an invalid format.\nValid formats: \"json\", \"csv\", \"xml\", \"odm\", or \"df\"")
	end
end

"""
	json_formatter(data, mode::String)

#### Parameters:
* `data` - The data to be formatted
* `mode` - Formatting for Import (data to server) or Export (data from server)

#### Returns:
Either a JSON'ed object or a parsed Dict
"""
function json_formatter(data, mode::String)
	if mode=="import"
		return JSON.json(data)
	else
		try
			return JSON.parse(data)
		catch
			@warn("Data cannot be json formatted")
			return data 					#for things that arent dicts - a surprising amount of REDCap's output
		end
	end
end

"""
	xml_formatter(data, mode::String)

#### Parameters:
* `data` - The data to be formatted
* `mode` - Formatting for Import (data to server) or Export (data from server)

#### Returns:
Either an xml-formatted string, or an xml document
"""
function xml_formatter(data, mode::String)
	if mode=="import"
		return string(data)
	else
		return parse_string(string(data))
	end
end

"""
	odm_formatter(data, mode::String)

May just be XML in disguise - really weird format - Currently treated as just xml, but probably shouldnt be

#### Parameters:
* `data` - The data to be formatted
* `mode` - Formatting for Import (data to server) or Export (data from server)

#### Returns:
Either an xml-formatted string, or an xml document
"""
###BROKEN(?)###
function odm_formatter(data, mode::String)
	if mode=="import"
		return string(data)
	else
		try
			return parse_string(data)
		catch
			@warn("Data cannot be odm formatted")
			return data
		end
	end
end
#=
There is such sparse documentation on odm and Julia, and its so low priority- just use xml.
=#

"""
	df_formatter(data, mode::String)

#### Parameters:
* `data` - The data to be formatted
* `mode` - Formatting for Import (data to server) or Export (data from server)

#### Returns:
Either an JSON'ed dict, or a df
"""
function df_formatter(data, mode::String)
	if mode=="import"						#must turn df into a json'ed dict
		return json_formatter(df_parser(data), mode)
	else
		try
			return CSV.read(IOBuffer(data))
		catch
			@warn("Data cannot be df formatted")
			return data
		end
	end
end

"""
	df_parser(data::Union{DataFrame, Dict})

Takes a DF, turns it into a Dict
When a DF is passed, every row is turned into a dict() with the columns as keys, and pushed into an array to pass as a JSON object.

#### Parameters:
* `data` - Data to be formatted

#### Returns:
A JSON ready dictionary array.
"""
function df_parser(data::DataFrame)
	#df => dict
	chartDict=[]
	for row in DataFrames.eachrow(data)
		rowDict=Dict()
		for item in row
			if ismissing(item[2])
				rowDict[String(item[1])]="" #force things to be blanks
			else
				rowDict[String(item[1])]=string(item[2])
			end
		end
		push!(chartDict,rowDict)
	end
	return chartDict
end

"""
	import_from_file(file_loc::String, format::String)

Called by importing functions to load already formatted data directly from a designated file

#### Parameters:
* `file_loc` - Location of file
* `format` - The target format

#### Returns:
The formatted data
"""
function import_from_file(file_loc::String, format::String)
	valid_formats = ("json", "csv", "xml", "df", "odm") #redcap accepted formats (also df)
	try
		open(file_loc) do file
			if format ∈ valid_formats
				return String(read(file))
			else
				@error("$format is an invalid format.\nValid formats: \"json\", \"csv\", \"xml\", \"odm\", or \"df\"")
			end
		end
	catch
		@error("File could not be opened:\n$file_loc")
	end
end

"""
	import_file_checker()

Checks if the passed data is a valid path to a file, or data in itself.
If a path, calls a loading function; if data, calls a formatter.

#### Parametes:
* `data` - The data to check
* `format` - The format to pass along

#### Returns:
The retreived/formatted data
"""
function import_file_checker(data, format::String)
	if isa(data, String) && length(data)<143 && ispath(data) #143 characters seems to be the hard limit for ispath(); longer and it returns an ERROR: stat: name too long (ENAMETOOLONG)
		try
			return import_from_file(data, format)
		catch
			@error("File could not be opened:\n$data")
		end
	else
		return formatter(data, format, "import")
	end

end

"""
	export_to_file(fileLoc::String, format::String, data)

Called by exporting functions to dump data into designated file, or yell at you for a bad path.

#### Parameters:
* `file_loc` - Location of file - pass with proper extensions
* `data` - The data to save to file

#### Returns:
Nothing/error
"""
function export_to_file(file_loc::String, data)
	try
		open(file_loc, "w") do file
			write(file, data)
			return "Success"
		end
	catch
		@error("File could not be opened:\n$file_loc")
	end
end

ext: jl


text:
abstract type Potential end

type UFF <: Potential
end

max_stars_repo_name: NickMcNutt/Alpine

max_issues_repo_name: NickMcNutt/Alpine

max_forks_repo_name: NickMcNutt/Alpine


text:
@testset "4.1.8 (a+b sin)^m (c+d trig)^n" begin
    (A, B, a, b, c, x, ) = @variables A B a b c x

    #= ::Package:: =#

    #= ::Title:: =#
    #=Integrands*of*the*form*(A+B*Trig(c+d*x))*(a+b*sin(a+b*x))^n=#

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(A+B*cos(c+d*x))*(a+b*sin(c+d*x))^n=#

    @test_int [(A + B*cos(x))/(a + b*sin(x)), x, 7, (2*A*atan((b + a*tan(x/2))/sqrt(a^2 - b^2)))/sqrt(a^2 - b^2) + (B*log(a + b*sin(x)))/b]

    @test_int [(A + B*cos(x))/(1 + sin(x)), x, 5, B*log(1 + sin(x)) - (A*cos(x))/(1 + sin(x))]
    @test_int [(A + B*cos(x))/(1 - sin(x)), x, 5, (-B)*log(1 - sin(x)) + (A*cos(x))/(1 - sin(x))]

    @test_int [(b + c + cos(x))/(a + b*sin(x)), x, 7, (2*(b + c)*atan((b + a*tan(x/2))/sqrt(a^2 - b^2)))/sqrt(a^2 - b^2) + log(a + b*sin(x))/b]
    @test_int [(b + c + cos(x))/(a - b*sin(x)), x, 7, -((2*(b + c)*atan((b - a*tan(x/2))/sqrt(a^2 - b^2)))/sqrt(a^2 - b^2)) - log(a - b*sin(x))/b]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(A+B*tan(c+d*x))*(a+b*sin(c+d*x))^n=#

    @test_int [(A + B*tan(x))/(a + b*sin(x)), x, 8, (2*A*atan((b + a*tan(x/2))/sqrt(a^2 - b^2)))/sqrt(a^2 - b^2) - (B*log(1 - sin(x)))/(2*(a + b)) - (B*log(1 + sin(x)))/(2*(a - b)) + (a*B*log(a + b*sin(x)))/(a^2 - b^2)]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(A+B*cot(c+d*x))*(a+b*sin(c+d*x))^n=#

    @test_int [(A + B*cot(x))/(a + b*sin(x)), x, 9, (2*A*atan((b + a*tan(x/2))/sqrt(a^2 - b^2)))/sqrt(a^2 - b^2) + (B*log(sin(x)))/a - (B*log(a + b*sin(x)))/a]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(A+B*sec(c+d*x))*(a+b*sin(c+d*x))^n=#

    @test_int [(A + B*sec(x))/(a + b*sin(x)), x, 12, (2*A*atan((b + a*tan(x/2))/sqrt(a^2 - b^2)))/sqrt(a^2 - b^2) - (B*log(1 - sin(x)))/(2*(a + b)) + (B*log(1 + sin(x)))/(2*(a - b)) - (b*B*log(a + b*sin(x)))/(a^2 - b^2)]

    #= ::Section::Closed:: =#
    #=Integrands*of*the*form*(A+B*csc(c+d*x))*(a+b*sin(c+d*x))^n=#

    @test_int [(A + B*csc(x))/(a + b*sin(x)), x, 6, (2*(a*A - b*B)*atan((b + a*tan(x/2))/sqrt(a^2 - b^2)))/(a*sqrt(a^2 - b^2)) - (B*atanh(cos(x)))/a]
    end

max_stars_repo_path: test/4 Trig functions/4.1 Sine/4.1.8 (a+b sin)^m (c+d trig)^n.jl


text:
@testset "temporal" begin
    let x = Q.TimeStamp(2001, 1, 2, 3, 4, 5, 123, 456, 789)
        @test Dates.days(x) == Dates.value(Date(2001, 1, 2))
        @test Dates.year(x) == 2001
        @test Dates.month(x) == 1
        @test Dates.day(x) == 2
        @test Dates.hour(x) == 3
        @test Dates.minute(x) == 4
        @test Dates.second(x) == 5
        @test Dates.millisecond(x) == 123
        @test Dates.microsecond(x) == 456
        @test Dates.nanosecond(x) == 789
        @test string(x) == show_to_string(x) ==
            "2001.01.02D03:04:05.123456789"
    end
    let x = Q.Month(2012, 3)
        @test Dates.year(x) == 2012
        @test Dates.month(x) == 3
        @test string(x) == show_to_string(x) == "2012.03m"
    end
    let x = Q.Minute(1, 2)
        @test Dates.hour(x) == 1
        @test Dates.minute(x) == 2
        @test Dates.second(x) == 0
        @test Dates.millisecond(x) == 0
        @test Dates.microsecond(x) == 0
        @test Dates.nanosecond(x) == 0
        @test string(x) == show_to_string(x) == "01:02"
    end
    let x = Q.Second(1, 2, 3)
        @test Dates.hour(x) == 1
        @test Dates.minute(x) == 2
        @test Dates.second(x) == 3
        @test Dates.millisecond(x) == 0
        @test Dates.microsecond(x) == 0
        @test Dates.nanosecond(x) == 0
        @test string(x) == show_to_string(x) == "01:02:03"
    end
    let x = Q.Time(1, 2, 3, 123)
        @test Dates.hour(x) == 1
        @test Dates.minute(x) == 2
        @test Dates.second(x) == 3
        @test Dates.millisecond(x) == 123
        @test Dates.microsecond(x) == 0
        @test Dates.nanosecond(x) == 0
        @test string(x) == show_to_string(x) == "01:02:03.123"
    end
end


text:
using CachePath
using Test

# TODO: use filecmp to make kinda sure that
# files are not recompiled
@testset "CachePath.jl" begin
    depot1 = mktempdir()
    @test isdir(depot1)
    shortvers = string("v", VERSION.major, ".", VERSION.minor)
    com = `$(Base.julia_cmd()) --startup-file=no -e "using CachePath; CachePath.require(\"Example\", \"$depot1\")"`
    p1 = run(com)
    @test p1.exitcode == 0
    dirlist3 = readdir(joinpath(depot1, "compiled", shortvers))
    cachedir = joinpath(depot1, "compiled", shortvers, "Example")
    dirlist = readdir(cachedir)
    @test length(dirlist) == 1
    cachefile1 = only(dirlist)
    @test endswith(cachefile1, ".ji")
    cp(joinpath(cachedir, cachefile1), joinpath(depot1, cachefile1))
    p2 = run(com)
    @test p2.exitcode == 0
    # dirlist = readdir(cachedir)
    # cachefile2 = only(dirlist)
end


text:
using .ReinforcementLearningEnvironments

for f in readdir(@__DIR__)
    if f != splitdir(@__FILE__)[2]
        include(f)
    end
end


text:
module Permanents

export naive, naive_tensor, ryser, multi_dim_ryser, fast_glynn_perm, glynn, glynn_precision, ryser_tensor, positive_entry

using Combinatorics
using LinearAlgebra
using ArgCheck
using Distributions

"""
Computes the permanent of the matrix ``U`` of dimension ``n`` using the definition
```math
perm(U) = ∑_{σ∈S_n}∏_{i=1}^n U_{i,σ(i)}
```
as a naive implementation in ``n!`` arithmetic operations.
"""
function naive(U::AbstractMatrix)

    """ computes the permanent using the definition as a naive implementation"""

    n = size(U)[1]

    sum_diag(perm, U) = prod(U[i,perm[i]] for i = 1:n)

    return sum(sum_diag(sigma, U) for sigma in permutations(collect(1:n)))

end
function is_a_square_three_tensor(W::Array)

	length(size(W)) == 3 && all(size(W) .== size(W)[1])

end

"""
Compute the permanent the permanent of a ``n^3``-dimensional 3-tensor of the form
```math
W_{k,l,j} = M_{k,j} M_{l,j}^* S_{l,k}
```
following Ryser's algorithm in approximatively ``2^{2n-1}`` iterations following
[Sampling of partially distinguishable bosons and the relation to the multidimensional permanent](https://arxiv.org/pdf/1410.7687.pdf).
!!! warning
	The current implementation does not use Gray code.
"""
function naive_tensor(W::Array)

    if is_a_square_three_tensor(W)
        n = size(W)[1]

        sum_tensor_diag(sigma,rho, W) = prod(W[i,sigma[i],rho[i]] for i = 1:n)
        return sum(sum_tensor_diag(sigma,rho, W) for sigma in permutations(collect(1:n)) for rho in permutations(collect(1:n)))
    else
        error("tensor permanent implemented only for square 3-indices tensors")
    end

end

"""
Compute the permanent the permanent of a ``n^3``-dimensional 3-tensor of the form
```math
W_{k,l,j} = M_{k,j} M_{l,j}^* S_{l,k}
```
following Ryser's algorithm in approximatively ``2^{2n-1}`` iterations following
[Sampling of partially distinguishable bosons and the relation to the multidimensional permanent](https://arxiv.org/pdf/1410.7687.pdf).
!!! warning
	The current implementation uses Gray code.
"""
function ryser_tensor(W::Array)

	@argcheck is_a_square_three_tensor(W) "tensor permanent implemented only for square 3-indices tensors"

    n = size(W)[1]
	m1_r = 0
	m2_r = 0
	res = 0

	function add_term(R, S)
		R == S ? delta = 1 : delta = 0
		t = prod(sum(W[rr,ss,j] for rr in R for ss in S) for j in 1:n)
		res += (2-delta) * (-1)^(length(S)+length(R)) * real(t)
	end

	function next_subset(n::Int, k::Int, a::AbstractVector, repeat::Bool, m1, m2)

		if !repeat
			m2 = 0
			m1 = k
		else
			m2 < n-m1 ? m1 = 0 : nothing
			m1 += 1
			m2 = a[k+1-m1]
		end

		for j in 1:m1
			a[k+j-m1] = m2+j
		end

		repeat = Bool(a[1] != n-k+1)
		return a, repeat, m1, m2

	end

	for r in 1:n

		repeat_r_i = false
		repeat_r = true
		R = collect(1:r)

		while repeat_r
			repeat_r = repeat_r_i
			R, repeat_r, m1_r, m2_r = next_subset(n, r, R, repeat_r, m1_r, m2_r)
			add_term(R, R)
			repeat_r_i = repeat_r

			m1_s = m1_r
			m2_s = m2_r

			for s in r:n

				repeat_s = true

				if s == r
					if repeat_r
						S = copy(R)
						repeat_s_i = copy(repeat_r_i)
					else
						continue
					end
				else
					S = collect(1:s)
					repeat_s_i = false
				end

				while repeat_s
					repeat_s = repeat_s_i
					S, repeat_s, m1_s, m2_s = next_subset(n, s, S, repeat_s, m1_s, m2_s)
					repeat_s_i = repeat_s
					add_term(R, S)
				end

			end
		end

	end

	return res

end

function multi_dim_ryser(U, gram_matrix)

	@warn "obsolete, please convert to ryser_tensor(W::Array)"

    # https://arxiv.org/pdf/1410.7687.pdf

    n = size(U)[1]
    nstring = collect(1:n)
    sub_nstring = collect(powerset(nstring))
    sub_nstring = sub_nstring[2:length(sub_nstring)]
    res = 0

    function delta_set(S1, S2)
        if S1 == S2
            return 1
        else
            return 0
        end
    end

    for r = 1:length(sub_nstring)
        for s = r:length(sub_nstring)
            R = sub_nstring[r]
            S = sub_nstring[s]

            t = prod(
                sum(
                    U[ss, j] * conj(U[rr, j]) * gram_matrix[rr, ss] for rr in R for ss in S
                ) for j = 1:n
            )
            res +=
                (2 - delta_set(S, R)) * (-1)^(length(S) + length(R)) * real(t)
        end
    end
    return res
end

"""
Compute the permanent of a matrix ``A`` of dimension ``n`` using Ryser algorithm
with Gray ordering
```math
perm(A) = (-1)^n ∑_{S ⊆ 1 … n} (-1)^{|S|} ∏_{i=1}^n ∑_{j ∈ S} A_{i,j}
```
and time complexity ``O(2^{n-1}n)``.
!!! note
	source: [https://discourse.julialang.org/t/matrix-permanent/10766](https://discourse.julialang.org/t/matrix-permanent/10766)
"""
function ryser(A::AbstractMatrix)
	"""computes the permanent of A using ryser with Gray ordering"""
		# code from https://discourse.julialang.org/t/matrix-permanent/10766
		# see Combinatorial Algorithms for Computers and Calculators, Second Edition (Computer Science and Applied Mathematics) by Albert Nijenhuis, Herbert S. Wilf (z-lib.org)
		# chapter 23 for the permanent algorithm
		# chapter 1 for the gray code

	    function grayBitToFlip(n::Int)
	    	n1 = (n-1) ⊻ ((n-1)>>1)
	    	n2 = n ⊻ (n>>1)
	    	d = n1 ⊻ n2

	    	j = 0
	    	while d>0
	    		d >>= 1
	    		j += 1
	    	end
	    	j
	    end

	    n,m = size(A)
		if (n == m)
	        AA = 2*A
			D = true
			rho = [true for i = 1:n]
			v = sum(A, dims = 2)
			p = prod(v)
			@inbounds for i = 1:(2^(n-1)-1)
				a = grayBitToFlip(i)+1
	            if rho[a]
	                @simd for j=1:n
	                    v[j] -= AA[j,a]
	                end
	            else
	                @simd for j=1:n
	                    v[j] += AA[j,a]
	                end
	            end
	            rho[a] = !rho[a]
	            pv = one(typeof(p))
	            @simd for j=1:n
	                pv *= v[j] #most expensive part
	            end
				D = !D
	            if D
	                p += pv
	            else
	                p -= pv
	            end
			end

			return p * 2.0^(1-n)
		else
			throw(ArgumentError("perm: argument must be a square matrix"))
		end

end

"""
Compute the permanent of a matrix ``A`` of dimension ``n`` using Glynn formula
```math
perm(A) = (2^{n-1})^{-1} ∑_δ (∏_{k=1}^n δ_k) ∏_{j=1}^n ∑_{j=1}^n δ_i A_{i,j}
```
where ``δ ∈ (-1,+1)^n`` with time complexity ``O(n2^n)``.
!!! note
	source: [https://codegolf.stackexchange.com/questions/97060/calculate-the-permanent-as-quickly-as-possible](https://codegolf.stackexchange.com/questions/97060/calculate-the-permanent-as-quickly-as-possible)
"""
function fast_glynn_perm(U::AbstractMatrix{T}) where T

	""" https://codegolf.stackexchange.com/questions/97060/calculate-the-permanent-as-quickly-as-possible """

	size(U)[1] == size(U)[2] ? n=size(U)[1] : error("Non square matrix as input")

	row_ = [U[:,i] for i in 1:n]
	row_comb = [sum(row) for row in row_]

	res = 0
	old_gray = 0
	sign = +1
	binary_power_dict = Dict(2^k => k for k in 0:n)
	num_iter = 2^(n-1)

	for bin_index in 1:num_iter
		res += sign * reduce(*, row_comb)

		new_gray = bin_index ⊻ trunc(Int, bin_index/2)
		gray_diff = old_gray ⊻ new_gray
		gray_diff_index = binary_power_dict[gray_diff]

		new_vec = U[gray_diff_index+1,:]
		direction = 2 * cmp(old_gray, new_gray)

		for i in 1:n
			row_comb[i] += new_vec[i] * direction
		end

		sign = -sign
		old_gray = new_gray
	end

	return res/num_iter

end

function glynn(U; niter)

	"""approximates the permanent of U up to an additive error through the Gurvits/Glynn algorithm"""
	# see https://arxiv.org/abs/1212.0025

    function glynn_estimator(U,x)

        function product_U_x(U, x)
            result_product = one(typeof(U[1,1]))

            for j = 1:n
                result_product *= sum(U[j, :] .* x)
            end

            result_product
        end

        prod(x) * product_U_x(U, x)

    end

    n = size(U,1)
    result = zero(eltype(U))

    for i = 1:niter

        x = rand([-1,1], n)
        result += 1/niter * glynn_estimator(U,x)

    end

    result

end

function combine_glynn_estimators(est1, est2, n1, n2)

	"""combines two glynn estimations of n1,n2 trials to give one with (n1 + n2)"""

	(n1 * est1 + n2 * est2)/(n1 + n2)

end

function glynn_precision(U; rtol = 1e-5, miniter = 10^2, maxiter = 10^5, steps = 5)

	growth_factor = (maxiter/miniter)^(1/steps)

	growth_factor <= 2 ? (@warn "small growth factor, results may be inaccurate decrease steps") : nothing
	# the number of iterations is multiplied by this number at
	# each trial

	if miniter<1e2
		@warn "small miniter may give false results if the first estimations are by chance close to the next ones"
	end

	total_iter = 0
	estimates = []
	niters = []

	niter = miniter
	first_estimate = glynn(U; niter = niter)
	push!(estimates, first_estimate)
	push!(niters, niter)

	estimates[end]

	while total_iter < maxiter

		niter *= growth_factor
		new_estimate = glynn(U; niter = niter)
		push!(estimates, new_estimate)
		push!(niters, niter)
		rel_err = abs(estimates[end] - estimates[end-1]) / abs(0.5*(estimates[end] + estimates[end-1]))

		total_iter += niter

		if rel_err < rtol
			break
		end
	end

	estimates[end]

end

function number_of_steps(permanent_function, n)

    """gives the number of steps in an exact permanent function"""

    steps = Dict(ryser => n -> n*2^n, naive => n -> factorial(big(n)), naive_tensor => n -> factorial(big(n))^2, ryser_tensor => n -> 2^(2n))

    if permanent_function in keys(steps)
        steps[permanent_function](big(n))
    else
        error("not implemented")
    end
end

function error_permanent(permanent_function, n, T::Number)

    """gives an expected error on the permanent_function computed of a type T
    with a dimension n (matrix n*n, 3-tensor n*n*n)"""

    eps(T) * sqrt(number_of_steps(permanent_function, n))

end

function positive_entry(A::AbstractMatrix, niter=1e5)

	if !all(>=(0), A)
		throw(ArgumentError("Input matrix must be with non-negative entries"))
	elseif size(A)[1] != size(A)[2]
		throw(ArgumentError("Input matrix must be a square matrix"))
	end

	n = size(A)[1]
	# nb_success = zeros(Threads.nthreads())
	nb_success = 0

	function rescale_mat(A::AbstractMatrix, eps::Real)

		B = A
		n = size(A)[1]
		x = ones(n)
		y = x'

		row_sum = [sum(A[i,:]) for i in 1:n]

		while maximum([abs(r-1) for r in row_sum]) > eps
			x = x .* row_sum.^(-1)
			B = diagm(row_sum.^(-1)) * B
			col_sum = [sum(B[:,i]) for i in 1:n]
			y = y .* col_sum.^(-1)
			y = y[:,1]
			B *= diagm(col_sum.^(-1))
			row_sum = [sum(B[i,:]) for i in 1:n]
		end

		return [B, x, y]

	end

	function hl_factor(x::AbstractVector)

		x0 = [Bool(i==0) for i in x]
		x = x .+ 0.5*x0

		x_1 = [Bool(i>1) for i in x]
		x__1 = [Bool(i<=1) for i in x]
		log_x = [log(abs(i)) for i in x]

		return x_1 .* (x .+ 0.5.*log_x .+ exp(1) .- 1) + x__1 .* (1 .+ (exp(1)-1).*x)

	end

	B, x, y = rescale_mat(A, 1e-5)
	row_scaled = [maximum(B[i,:]) for i in 1:n].^(-1)
	C = diagm(row_scaled) * B
	C_i = copy(C)

	# Threads.@threads for i in 1:niter
	for i in 1:niter

		col = 1
		C = copy(C_i)
		row_sum = [sum(C[k,:]) for k in 1:n]

		while col <= n

			hl_i = hl_factor(row_sum)
			hl1 = prod(hl_i/exp(1))
			hl_i = hl_factor(row_sum - C[:,col])
		 	hl2 = prod(hl_i/exp(1))

			row_prob = exp(1) * C[:,col].*hl2/hl1./hl_factor(row_sum - C[:,col])
			val = rand()
			inter_bool = [Bool(sum_k < val) for sum_k in cumsum(row_prob)]
			row_samp = sum(inter_bool) + 1

			if row_samp == n+1
				col = n+2
				push!(row_sum, 0)
			else
				row_sum -= C[:,col]
				C[row_samp,:] = zeros(n)
				col += 1
				row_sum[row_samp] = 0
			end

		end

		col == n+1 ? nb_success += 1 : nothing
		# col == n+1 ? nb_success[Threads.threadid()] += 1 : nothing

	end

	C = C_i
	row_sum = sum(C[:,k] for k in 1:n)
	hl_C = prod(hl_factor(row_sum)/exp(1))
	res = hl_C * sum(nb_success)/niter

	return res /prod(row_scaled)/prod(x)/prod(y)

end

end


text:
#=
A point associated with an image (the frame of its coordinate system).
Better to explicitly associate a point to its frame.
So that it is harder to make the programming error: use a point coordinate in the wrong frame.

Some applications, use many images having differing bounds.

Not mutable.  See comments for MaskedImage

!!! Types fully specified so compiler can generate good code.
Fully specified means a concrete type (possibly parameterized) ?
=#
struct PointInMaskedImage
    point::CartesianIndex{N} where N
    maskedImage::MaskedImage{T,N} where {T,N}
end

# Custom pretty printing, omit the image
Base.show(io::IO, z::PointInMaskedImage) = print(io, z.point)

# getter for an image
#=
function colorAtPoint( framedPoint)
    # Not checking mask

    # Julia does not permit indexing an Array by a Vector
    return framedPoint.maskedImage.image[ framedPoint.point[1], framedPoint.point[2] ]
end
=#

max_stars_repo_name: bootchk/resynthesizerJulia

max_issues_repo_name: bootchk/resynthesizerJulia

max_forks_repo_name: bootchk/resynthesizerJulia