text:
using Rubin
using Tests
using Elliptic
using HypergeometricFunctions
using Polylogarithms
using SpecialFunctions

@test integrate(cot(a+b*x), x) == :(b^-1*log(sin(a+b*x)))
@test integrate(cot(a+b*x)^2, x) == :(-1x+-1*b^-1*cot(a+b*x))
@test integrate(cot(a+b*x)^3, x) == :(-1*b^-1*log(sin(a+b*x))+-1//2*b^-1*cot(a+b*x)^2)
@test integrate(cot(a+b*x)^4, x) == :(x+b^-1*cot(a+b*x)+-1//3*b^-1*cot(a+b*x)^3)
@test integrate(cot(a+b*x)^5, x) == :(b^-1*log(sin(a+b*x))+(1/2)*b^-1*cot(a+b*x)^2+-1//4*b^-1*cot(a+b*x)^4)
@test integrate(cot(a+b*x)^6, x) == :(-1x+-1*b^-1*cot(a+b*x)+-1//5*b^-1*cot(a+b*x)^5+1//3*b^-1*cot(a+b*x)^3)
@test integrate(cot(a+b*x)^7, x) == :(-1*b^-1*log(sin(a+b*x))+-1//2*b^-1*cot(a+b*x)^2+-1//6*b^-1*cot(a+b*x)^6+1//4*b^-1*cot(a+b*x)^4)
@test integrate(cot(a+b*x)^8, x) == :(x+b^-1*cot(a+b*x)+-1//3*b^-1*cot(a+b*x)^3+-1//7*b^-1*cot(a+b*x)^7+1//5*b^-1*cot(a+b*x)^5)
@test integrate((c*cot(a+b*x))^7//2, x) == :(2*b^-1*c^3*(c*cot(a+b*x))^(1/2)+-2//5*c*b^-1*(c*cot(a+b*x))^5//2+(1/2)*2^(1/2)*b^-1*c^7//2*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^7//2*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^7//2*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x))+1//4*2^(1/2)*b^-1*c^7//2*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2)))
@test integrate((c*cot(a+b*x))^5//2, x) == :(-2//3*c*b^-1*(c*cot(a+b*x))^3//2+(1/2)*2^(1/2)*b^-1*c^5//2*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^5//2*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^5//2*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x))+1//4*2^(1/2)*b^-1*c^5//2*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2)))
@test integrate((c*cot(a+b*x))^3//2, x) == :(-2*c*b^-1*(c*cot(a+b*x))^(1/2)+(1/2)*2^(1/2)*b^-1*c^3//2*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^3//2*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^3//2*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2))+1//4*2^(1/2)*b^-1*c^3//2*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x)))
@test integrate((c*cot(a+b*x))^(1/2), x) == :((1/2)*2^(1/2)*b^-1*c^(1/2)*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^(1/2)*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^(1/2)*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2))+1//4*2^(1/2)*b^-1*c^(1/2)*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x)))
@test integrate((c*cot(a+b*x))^-1//2, x) == :((1/2)*2^(1/2)*b^-1*c^-1//2*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^-1//2*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^-1//2*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x))+1//4*2^(1/2)*b^-1*c^-1//2*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2)))
@test integrate((c*cot(a+b*x))^-3//2, x) == :(2*b^-1*c^-1*(c*cot(a+b*x))^-1//2+(1/2)*2^(1/2)*b^-1*c^-3//2*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^-3//2*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^-3//2*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x))+1//4*2^(1/2)*b^-1*c^-3//2*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2)))
@test integrate((c*cot(a+b*x))^-5//2, x) == :(2//3*b^-1*c^-1*(c*cot(a+b*x))^-3//2+(1/2)*2^(1/2)*b^-1*c^-5//2*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^-5//2*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^-5//2*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2))+1//4*2^(1/2)*b^-1*c^-5//2*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x)))
@test integrate((c*cot(a+b*x))^-7//2, x) == :(-2*b^-1*c^-3*(c*cot(a+b*x))^-1//2+2//5*b^-1*c^-1*(c*cot(a+b*x))^-5//2+(1/2)*2^(1/2)*b^-1*c^-7//2*arctan(1+-1*2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//2*2^(1/2)*b^-1*c^-7//2*arctan(1+2^(1/2)*c^-1//2*(c*cot(a+b*x))^(1/2))+-1//4*2^(1/2)*b^-1*c^-7//2*log(c^(1/2)+c^(1/2)*cot(a+b*x)+-1*2^(1/2)*(c*cot(a+b*x))^(1/2))+1//4*2^(1/2)*b^-1*c^-7//2*log(c^(1/2)+2^(1/2)*(c*cot(a+b*x))^(1/2)+c^(1/2)*cot(a+b*x)))
@test integrate((c*cot(a+b*x))^4//3, x) == :(b^-1*c^4//3*arctan(c^-1//3*(c*cot(a+b*x))^1//3)+(1/2)*b^-1*c^4//3*arctan(3^(1/2)+2*c^-1//3*(c*cot(a+b*x))^1//3)+-3*c*b^-1*(c*cot(a+b*x))^1//3+-1//2*b^-1*c^4//3*arctan(3^(1/2)+-2*c^-1//3*(c*cot(a+b*x))^1//3)+-1//4*3^(1/2)*b^-1*c^4//3*log(c^2//3+(c*cot(a+b*x))^2//3+-1*3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3)+1//4*3^(1/2)*b^-1*c^4//3*log(c^2//3+(c*cot(a+b*x))^2//3+3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3))
@test integrate((c*cot(a+b*x))^2//3, x) == :((1/2)*b^-1*c^2//3*arctan(3^(1/2)+-2*c^-1//3*(c*cot(a+b*x))^1//3)+-1*b^-1*c^2//3*arctan(c^-1//3*(c*cot(a+b*x))^1//3)+-1//2*b^-1*c^2//3*arctan(3^(1/2)+2*c^-1//3*(c*cot(a+b*x))^1//3)+-1//4*3^(1/2)*b^-1*c^2//3*log(c^2//3+(c*cot(a+b*x))^2//3+-1*3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3)+1//4*3^(1/2)*b^-1*c^2//3*log(c^2//3+(c*cot(a+b*x))^2//3+3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3))
@test integrate((c*cot(a+b*x))^1//3, x) == :((1/2)*b^-1*c^1//3*log(c^2//3+(c*cot(a+b*x))^2//3)+-1//4*b^-1*c^1//3*log(c^4//3+(c*cot(a+b*x))^4//3+-1*c^2//3*(c*cot(a+b*x))^2//3)+(1/2)*3^(1/2)*b^-1*c^1//3*arctan(1//3*3^(1/2)*c^-2//3*(c^2//3+-2*(c*cot(a+b*x))^2//3)))
@test integrate((c*cot(a+b*x))^-1//3, x) == :(-1//2*b^-1*c^-1//3*log(c^2//3+(c*cot(a+b*x))^2//3)+1//4*b^-1*c^-1//3*log(c^4//3+(c*cot(a+b*x))^4//3+-1*c^2//3*(c*cot(a+b*x))^2//3)+(1/2)*3^(1/2)*b^-1*c^-1//3*arctan(1//3*3^(1/2)*c^-2//3*(c^2//3+-2*(c*cot(a+b*x))^2//3)))
@test integrate((c*cot(a+b*x))^-2//3, x) == :((1/2)*b^-1*c^-2//3*arctan(3^(1/2)+-2*c^-1//3*(c*cot(a+b*x))^1//3)+-1*b^-1*c^-2//3*arctan(c^-1//3*(c*cot(a+b*x))^1//3)+-1//2*b^-1*c^-2//3*arctan(3^(1/2)+2*c^-1//3*(c*cot(a+b*x))^1//3)+-1//4*3^(1/2)*b^-1*c^-2//3*log(c^2//3+(c*cot(a+b*x))^2//3+3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3)+1//4*3^(1/2)*b^-1*c^-2//3*log(c^2//3+(c*cot(a+b*x))^2//3+-1*3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3))
@test integrate((c*cot(a+b*x))^-4//3, x) == :(b^-1*c^-4//3*arctan(c^-1//3*(c*cot(a+b*x))^1//3)+(1/2)*b^-1*c^-4//3*arctan(3^(1/2)+2*c^-1//3*(c*cot(a+b*x))^1//3)+3*b^-1*c^-1*(c*cot(a+b*x))^-1//3+-1//2*b^-1*c^-4//3*arctan(3^(1/2)+-2*c^-1//3*(c*cot(a+b*x))^1//3)+-1//4*3^(1/2)*b^-1*c^-4//3*log(c^2//3+(c*cot(a+b*x))^2//3+3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3)+1//4*3^(1/2)*b^-1*c^-4//3*log(c^2//3+(c*cot(a+b*x))^2//3+-1*3^(1/2)*c^1//3*(c*cot(a+b*x))^1//3))
@test integrate((a*cot(x)^2)^3//2, x) == :(-1//2*a*(a*cot(x)^2)^(1/2)*cot(x)+-1*a*(a*cot(x)^2)^(1/2)*log(sin(x))*tan(x))
@test integrate((a*cot(x)^2)^(1/2), x) == :((a*cot(x)^2)^(1/2)*log(sin(x))*tan(x))
@test integrate((a*cot(x)^2)^-1//2, x) == :(-1*(a*cot(x)^2)^-1//2*cot(x)*log(cos(x)))
@test integrate((a*cot(x)^2)^-3//2, x) == :((1/2)*a^-1*(a*cot(x)^2)^-1//2*tan(x)+a^-1*(a*cot(x)^2)^-1//2*cot(x)*log(cos(x)))
@test integrate((a*cot(x)^3)^3//2, x) == :(2//3*a*(a*cot(x)^3)^(1/2)+-2//7*a*(a*cot(x)^3)^(1/2)*cot(x)^2+(1/2)*a*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*arctan(1+-1*2^(1/2)*cot(x)^(1/2))+-1//2*a*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*arctan(1+2^(1/2)*cot(x)^(1/2))+-1//4*a*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*log(1+-1*2^(1/2)*cot(x)^(1/2)+cot(x))+1//4*a*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*log(1+2^(1/2)*cot(x)^(1/2)+cot(x)))
@test integrate((a*cot(x)^3)^(1/2), x) == :(-2*(a*cot(x)^3)^(1/2)*tan(x)+(1/2)*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*arctan(1+2^(1/2)*cot(x)^(1/2))+-1//2*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*arctan(1+-1*2^(1/2)*cot(x)^(1/2))+-1//4*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*log(1+-1*2^(1/2)*cot(x)^(1/2)+cot(x))+1//4*2^(1/2)*(a*cot(x)^3)^(1/2)*cot(x)^-3//2*log(1+2^(1/2)*cot(x)^(1/2)+cot(x)))
@test integrate((a*cot(x)^3)^-1//2, x) == :(2*(a*cot(x)^3)^-1//2*cot(x)+(1/2)*2^(1/2)*(a*cot(x)^3)^-1//2*cot(x)^3//2*arctan(1+2^(1/2)*cot(x)^(1/2))+-1//2*2^(1/2)*(a*cot(x)^3)^-1//2*cot(x)^3//2*arctan(1+-1*2^(1/2)*cot(x)^(1/2))+-1//4*2^(1/2)*(a*cot(x)^3)^-1//2*cot(x)^3//2*log(1+2^(1/2)*cot(x)^(1/2)+cot(x))+1//4*2^(1/2)*(a*cot(x)^3)^-1//2*cot(x)^3//2*log(1+-1*2^(1/2)*cot(x)^(1/2)+cot(x)))
@test integrate((a*cot(x)^3)^-3//2, x) == :(-2//3*a^-1*(a*cot(x)^3)^-1//2+2//7*a^-1*(a*cot(x)^3)^-1//2*tan(x)^2+(1/2)*2^(1/2)*a^-1*(a*cot(x)^3)^-1//2*cot(x)^3//2*arctan(1+-1*2^(1/2)*cot(x)^(1/2))+-1//2*2^(1/2)*a^-1*(a*cot(x)^3)^-1//2*cot(x)^3//2*arctan(1+2^(1/2)*cot(x)^(1/2))+-1//4*2^(1/2)*a^-1*(a*cot(x)^3)^-1//2*cot(x)^3//2*log(1+2^(1/2)*cot(x)^(1/2)+cot(x))+1//4*2^(1/2)*a^-1*(a*cot(x)^3)^-1//2*cot(x)^3//2*log(1+-1*2^(1/2)*cot(x)^(1/2)+cot(x)))
@test integrate((a*cot(x)^4)^3//2, x) == :(-1*a*(a*cot(x)^4)^(1/2)*tan(x)+-1//5*a*(a*cot(x)^4)^(1/2)*cot(x)^3+1//3*a*(a*cot(x)^4)^(1/2)*cot(x)+-1*a*x*(a*cot(x)^4)^(1/2)*tan(x)^2)
@test integrate((a*cot(x)^4)^(1/2), x) == :(-1*(a*cot(x)^4)^(1/2)*tan(x)+-1*x*(a*cot(x)^4)^(1/2)*tan(x)^2)
@test integrate((a*cot(x)^4)^-1//2, x) == :((a*cot(x)^4)^-1//2*cot(x)+-1*x*(a*cot(x)^4)^-1//2*cot(x)^2)
@test integrate((a*cot(x)^4)^-3//2, x) == :(a^-1*(a*cot(x)^4)^-1//2*cot(x)+-1//3*a^-1*(a*cot(x)^4)^-1//2*tan(x)+1//5*a^-1*(a*cot(x)^4)^-1//2*tan(x)^3+-1*x*a^-1*(a*cot(x)^4)^-1//2*cot(x)^2)
@test integrate((d*cot(e+f*x))^n*csc(e+f*x)^6, x) == :(-1*d^-1*f^-1*(d*cot(e+f*x))^(1+n)*(1+n)^-1+-1*d^-5*f^-1*(d*cot(e+f*x))^(5+n)*(5+n)^-1+-2*d^-3*f^-1*(d*cot(e+f*x))^(3+n)*(3+n)^-1)
@test integrate((d*cot(e+f*x))^n*csc(e+f*x)^4, x) == :(-1*d^-1*f^-1*(d*cot(e+f*x))^(1+n)*(1+n)^-1+-1*d^-3*f^-1*(d*cot(e+f*x))^(3+n)*(3+n)^-1)
@test integrate((d*cot(e+f*x))^n*csc(e+f*x)^2, x) == :(-1*d^-1*f^-1*(d*cot(e+f*x))^(1+n)*(1+n)^-1)

max_stars_repo_path: test/4 Trig functions/4.4 Cotangent/4.4.0 (a trg)^m (b cot)^n.jl


text:
#!/usr/bin/env julia

if length(ARGS) < 2
    println("Usage: ./hit_stats.jl DETX HDF5FILE OUTFILE")
    exit(1)
end

using NeRCA
using HDF5
using ProgressMeter

function main()
    detx, filename, outfile = ARGS
    if isfile(outfile)
        println("Output file already exists, aborting...")
        exit(1)
    end

    events = NeRCA.MCEventReader(filename, detx)

    fobj = h5open(filename, "r")

    outf = open(outfile, "w")
    write(outf, "time_residual,n_muons,tot,multiplicity,triggered,distance,bundle_energy,track_pmt_angle\n")

    @showprogress 1 for event in events
        n_muons = length(event.mc_tracks)
        bundle_energy = sum(map(m->m.E, event.mc_tracks))
        hits = calibrate(event.hits, event.calib)
        muon = NeRCA.Track(event.mc_tracks[1])
        NeRCA.count_multiplicities!(hits)
        ccalc = NeRCA.make_cherenkov_calculator(muon)
        mc_time = NeRCA.make_mc_time_converter(event.info)
        for hit in hits
            Δt = hit.t - mc_time(ccalc(hit.pos))
            d = NeRCA.pld3(hit.pos, muon.pos, muon.dir)
            η = NeRCA.angle_between(hit.dir, muon.dir)
            write(outf, "$(Δt),$(n_muons),$(hit.tot),$(hit.multiplicity.count),$(hit.triggered ? 1 : 0),$(d),$(bundle_energy),$(η)\n")
        end
    end

    close(outf)
    close(fobj)
end

main()

ext: jl


text:
#Image scraper using Julia and Selenium. Current build only scrapes google image

using PyCall
using WebDriver
using Requests
using JSON
using ArgParse

function scrollThroughPage(driver::WebDriver.Driver)

	#Scrolls down to the bottom of each page of the image search, to reveal all images

	const scrollScript = "window.scrollBy(0, 1000000)"
	const waitTime= 0.2
	const scrolls = 5
	for i in 1:scrolls
		execute_script(driver, scrollScript)
		sleep(waitTime)
	end
end

function clickThroughPage(driver::WebDriver.Driver)

	#clicks through to the next page of the image search automatically

	const nextButtonSelector = "//input[@value='Show more results']"
	const waitTime= 0.2
	click(find_element_by_xpath(driver, nextButtonSelector))
	sleep(waitTime)
end

function parseImageElement(img::WebDriver.WebElement, extensions::Tuple)

	#gets the image url and type of the html image elements extracted from the page

	innerhtml = JSON.parse(get_attribute(img, "innerHTML"))
	img_url = innerhtml["ou"]
	img_type = innerhtml["ity"]

	#we do our default type replacing here
	if !(img_type in extensions)
		img_type = "jpg"
	end
	return img_url, img_type
end

function requestAndSaveImage(url::AbstractString, fname::AbstractString,img_num::Integer, stream::Bool=false)

	#requests an image given a url and saves it or streams it to a file

	if stream == true
		try
			stream = Requests.get_streaming(url)
			open(fname, "w") do file
				while !eof(stream)
					write(file, readavailable(stream))
				end
			end
		catch Exception e
			println("Image stream failed: " * string(e))
		end
	end

	if stream ==false
		try
			res = Requests.get(url)
			#fname = basepath *"/" * string(img_num)
			Requests.save(res, fname)
		catch Exception e
			println("Image download failed: " *string(e))
		end
	end
end

function setupDirectories(basepath)
	if !isdir(basepath)
		mkdir(basepath)
	end
end

#the big function so we can see if anything works

function scrape_images_routine(searchTerm::AbstractString, num_images::Integer, basepath::AbstractString=searchTerm, streaming::Bool=false, parallel::Bool = false, extensions::Tuple=("jpg", "jpeg", "png", "gif"), verbose::Bool = true)

	#setup our constants
	const url = "https://www.google.co.in/search?q="*searchTerm*"&source=lnms&tbm=isch"
	const images_per_page = 400
	const number_of_scrolls = num_images/images_per_page +1

	const driver_path = "/home/beren/work/julia/misc/chromedriver"
	driver = init_chrome(driver_path)
	#also should allow driver customizatoin at some point, but can't be bothered - could perhaps pare this into a separate function also for  ease
	if verbose==true
		println("Driver initialized")
	end
	#get the search term
	get(driver, url)
	if verbose==true
		println("Searching for " * searchTerm)
	end

	#if all of this works, we make the dirs for our thing
	setupDirectories(basepath)

	img_counter::Integer = 0
	for i in 1:number_of_scrolls
		scrollThroughPage(driver) # scroll through page to load all images
		images = find_elements_by_xpath(driver,"//div[contains(@class, 'rg_meta')]") # get image urls
		println("Total Images found on this page: " * string(length(images)))
		for img in images

			img_url, img_type = parseImageElement(img, extensions) # parse our image
			fname = basepath*"/"*searchTerm * "_"*string(img_counter)*"."*img_type # create filename for saving
			requestAndSaveImage(img_url, fname,img_counter, streaming)
			img_counter +=1

			#and we check our loop functionality
			if img_counter >= num_images
				if verbose==true
					println(string(num_images) *" images found. Image scraper exiting")
				end
				return
			end
		end
	end
end

# okay, commandline functoins

function parseCommandLine()
	s = ArgParseSettings(prog="Julia Image Scraper with Selenium", description="An image scraper of google images written in Julia", commands_are_required=false, version="0.0.1", add_version=true)

	@add_arg_table s begin
		"search_term"
			help="the search you want to get images from"
			required=true
			arg_type = String
		"number_images"
			help="the number of images you want to scrape"
			required=true
			arg_type = Int
		"base_path"
			help="the base path of the directory you want to save the images in"
			arg_type=String
			default=""
		"-s"
			help="whether to stream images or download them and save all at once"
			action = :store_true
		"-p"
			help="whether to download images in parallel"
			action= :store_true
		"-v"
			help="run the scraper in verbose mode"
			action = :store_true
	end
	return parse_args(s)
end

function run_scrape_from_cmdline()
	args = parseCommandLine()
	const search_term = args["search_term"]
	const num = args["number_images"]
	const base_path = args["base_path"]
	const stream = args["-s"]
	const parallel = args["-p"]
	const verbose = args["-v"]
	scrape_images_routine(search_term, num, base_path, stream, parallel, verbose)
end

print(isinteractive())

#run the file from the commandline if it is active
if isinteractive()
	run_scrape_from_cmdline()
end

#run_scrape_from_cmdline()

# and now for our functions allowing a greater specialisation of arguments

function scrape_images(searchTerm::AbstractString, num_images::Integer, basepath::AbstractString, streaming::Bool=false, parallel::Bool = false, extensions::Tuple=("jpg", "jpeg", "png", "gif"), verbose::Bool = true)

	println(basepath)

	#this is identical to the routine, we just call it
	scrape_images_routine(searchTerm, num_images, basepath, streaming, parallel, extensions, verbose)
end

function scrape_images(searchTerm::Array{AbstractString}, num_images::Integer, basepath::AbstractString="", streaming::Bool=false, parallel::Bool = false, extensions::Tuple=("jpg", "jpeg", "png", "gif"), verbose::Bool = true)

	const len = length(searchTerm)
	for i in 1:len
		scrape_images_routine(searchTerm[i], num_images, basepath, streaming, parallel, extensions, verbose)
	end
end

function scrape_images(searchTerm::Array{AbstractString}, num_images::Array{Integer}, basepath::AbstractString="", streaming::Bool=false, parallel::Bool = false, extensions::Tuple=("jpg", "jpeg", "png", "gif"), verbose::Bool = true)

	const len = length(searchTerm)
	@assert len == length(num_images) "number of terms and number of images for each term must be the same length"
	for i in 1:len
		scrape_images_routine(searchTerm[i], num_images[i], basepath, streaming, parallel, extensions, verbose)
	end
end

function scrape_images(searchTerm::Array{AbstractString}, num_images::Array{Integer}, basepath::Array{AbstractString}, streaming::Bool=false, parallel::Bool = false, extensions::Tuple=("jpg", "jpeg", "png", "gif"), verbose::Bool = true)

	const len = length(searchTerm)
	@assert len == length(num_images) == length(basepath) "number of terms and number of images for each term must be the same length as must the number of different basepaths for each"
	for i in 1:len
		scrape_images_routine(searchTerm[i], num_images[i], basepath[i], streaming, parallel, extensions, verbose)
	end
end

function scrape_images(searchTerm::Array{AbstractString}, num_images::Integer, basepath::Array{AbstractString}, streaming::Bool=false, parallel::Bool = false, extensions::Tuple=("jpg", "jpeg", "png", "gif"), verbose::Bool = true)

	const len = length(searchTerm)
	@assert len == length(basepath) "number of terms and number of images for each term must be the same length as must the number of different basepaths for each"
	for i in 1:len
		scrape_images_routine(searchTerm[i], num_images, basepath[i], streaming, parallel, extensions, verbose)
	end
end

max_stars_repo_name: Bmillidgework/Image-Scraper

max_issues_repo_name: Bmillidgework/Image-Scraper

max_forks_repo_name: Bmillidgework/Image-Scraper


text:
const DATAPATH = joinpath(@__DIR__, "data")

@testset "Trajectory" begin
    @testset "Errors handling" begin
        remove_chemfiles_warning() do
            @test_throws ChemfilesError Trajectory(joinpath(DATAPATH, "not-here.xyz"))
            @test_throws ChemfilesError Trajectory(joinpath(DATAPATH, "empty.unknown"))
        end
    end

    @testset "Read frames" begin
        trajectory = Trajectory(joinpath(DATAPATH, "water.xyz"))

        @test path(trajectory) == joinpath(DATAPATH, "water.xyz")

        @test length(trajectory) == 100

        frame = read(trajectory)

        @test size(frame) == 297
        pos = positions(frame)
        @test pos[:, 1] ≈ Float64[0.417219, 8.303366, 11.737172]
        @test pos[:, 125] ≈ Float64[5.099554, -0.045104, 14.153846]

        topology = Topology(frame)
        @test size(frame) == 297
        @test name(Atom(frame, 0)) == "O"
        @test name(Atom(frame, 1)) == "H"

        set_cell!(trajectory, UnitCell(30, 30, 30))
        frame = read_step(trajectory, 41)

        @test lengths(UnitCell(frame)) == [30.0, 30.0, 30.0]

        pos = positions(frame)
        @test pos[:, 1] ≈ Float64[0.761277, 8.106125, 10.622949]
        @test pos[:, 125] ≈ Float64[5.13242, 0.079862, 14.194161]

        topology = Topology(frame)
        @test size(topology) == 297
        @test bonds_count(topology) == 0

        guess_bonds!(frame)
        topology = Topology(frame)
        @test bonds_count(topology) == 181
        @test angles_count(topology) == 87

        topology = Topology()
        a = Atom("Cs")
        for i=1:297
            add_atom!(topology, a)
        end

        set_topology!(trajectory, topology)
        frame = read_step(trajectory, 10)
        @test name(Atom(frame, 10)) == "Cs"

        set_topology!(trajectory, joinpath(DATAPATH, "topology.xyz"))
        frame = read(trajectory)
        @test name(Atom(frame, 100)) == "Rd"
    end

    @testset "Iteration" begin
        trajectory = Trajectory(joinpath(DATAPATH, "water.xyz"))

        count = 0
        for frame in trajectory
            count += 1
        end

        @test count == length(trajectory)
    end

    @testset "Write frames" begin
        EXPECTED_CONTENT = """4
                              Written by the chemfiles library
                              X 1 2 3
                              X 1 2 3
                              X 1 2 3
                              X 1 2 3
                              """

        frame = Frame()
        resize!(frame, 4)
        pos = positions(frame)
        for i=1:4
            pos[:, i] = Float64[1, 2, 3]
        end

        topology = Topology()
        for i=1:4
            add_atom!(topology, Atom("X"))
        end
        set_topology!(frame, topology)

        trajectory = Trajectory("test-tmp.xyz", 'w');
        write(trajectory, frame)
        close(trajectory)
        @test isopen(trajectory) == false

        s = open("test-tmp.xyz") do file
            read(file, String)
        end

        @test s == EXPECTED_CONTENT

        rm("test-tmp.xyz")
    end

    @testset "Function syntax" begin
        trajectory = nothing
        Trajectory(joinpath(DATAPATH, "water.xyz")) do tr
            trajectory = tr
            @test isopen(trajectory)
        end
        @test !isopen(trajectory)
    end
end


text:
function circle_shape(x, y, r)
    θ = LinRange(0, 2π, 500)
    Shape(x .+ r*cos.(θ), y .+ r*sin.(θ))
end

function viz_path!(x_path, y_path; color=:blue, label="path")
    plot!(x_path, y_path, color=color, label=label)
end

function viz_solution!(qs, vals; marker=:dot, ms=1, colors=(:black, :yellow, :green, :red), label="sol")
    n_modes = vals.n_modes
    N = vals.N
    k_c = vals.k_c

    xs = qs[1, :]
    ys = qs[2, :]

    scatter!(xs[1:k_c], ys[1:k_c], marker=marker, color=colors[1], ms=ms, label=label)

    for j = 1:n_modes
        start_idx = k_c + 1 + (j - 1) * (N - k_c)
        end_idx = start_idx + N - k_c - 1
        scatter!(xs[start_idx:end_idx], ys[start_idx:end_idx], marker=marker, color=colors[j+1], ms=ms, label=label)
    end
end

function viz_obstacle!(vals; marker=:hexagon, ms=1, colors=(:yellow, :green, :red), label="")
    n_modes = vals.n_modes
    N = vals.N
    p_obs = vals.p_obs
    N_obs = vals.obs_horizon

    for j = 1:n_modes
        color = colors[j]
        for (obs_id, obs) in p_obs
            if obs.active == true
                unshaped_ps = obs.ps[j]
                ps = zeros((N, 2))
                for k in 1:N_obs
                    ps[k, :] = unshaped_ps[k]
                end
                scatter!(ps[:, 1], ps[:, 2], marker=marker, ms=ms, label=label)# colors=:yellow, label=label)
            end
        end
    end
end

function viz_obs_constraints!(obstacle, mode, vals; label="")
    p_obs = obstacle.ps[mode]
    for k = 1:vals_obj.obs_horizon
        n_vector = (vals_obj.ps[k] - p_obs[k]) / sqrt((vals_obj.ps[k] - p_obs[k])'*(vals_obj.ps[k] - p_obs[k]))
        p1 = [-10000:10:10000;]
        p2 = (-n_vector[1]*p1 .+p_obs[k][1]*n_vector[1] .+ p_obs[k][2]*n_vector[2] .+ 1.)./n_vector[2]
        scatter!([p_obs[k][1]], [p_obs[k][2]], marker=:dot, color=(:yellow, :green, :red)[mode], ms=1, label="")
        plot!(p1, p2, color=:black, label="")
    end
end

function fig_settings!(xlims, ylims; aspect_ratio=:equal, dpi=300)
    plot!(xlims=xlims, ylims=ylims, aspect_ratio=aspect_ratio, dpi=dpi)
end

max_stars_repo_name: StanfordASL/MATS

max_issues_repo_name: StanfordASL/MATS

max_forks_repo_name: StanfordASL/MATS


text:
@defcomp LGcycle begin
    e_globalLGemissions = Parameter(index=[time], unit="Mtonne/year")
    e_0globalLGemissions = Parameter(unit="Mtonne/year", default=631.2162983226708)
    c_LGconcentration = Variable(index=[time], unit="ppbv")
    pic_preindustconcLG = Parameter(unit="ppbv", default=0.)
    exc_excessconcLG = Variable(unit="ppbv")
    c0_LGconcbaseyr = Parameter(unit="ppbv", default=0.11)
    re_remainLG = Variable(index=[time], unit="Mtonne")
    nte_natLGemissions = Variable(index=[time], unit="Mtonne/year")
    air_LGfractioninatm = Parameter(unit="%", default=100.)
    tea_LGemissionstoatm = Variable(index=[time], unit="Mtonne/year")
    teay_LGemissionstoatm = Variable(index=[time], unit="Mtonne/t")
    y_year = Parameter(index=[time], unit="year")
    y_year_0 = Parameter(unit="year")
    res_LGatmlifetime = Parameter(unit="year", default=1000.)
    den_LGdensity = Parameter(unit="Mtonne/ppbv", default=100000.)
    stim_LGemissionfeedback = Parameter(unit="Mtonne/degreeC", default=0.)
    rtl_g0_baselandtemp = Parameter(unit="degreeC", default=1.1683981941310047)
    rtl_g_landtemperature = Parameter(index=[time], unit="degreeC")
    re_remainLGbase = Variable(unit="Mtonne")

    function run_timestep(p, v, d, t)
        if is_first(t)
            # eq.3 from Hope (2006) - natural emissions (carbon cycle) feedback, using global temperatures calculated in ClimateTemperature component
            nte0 = p.stim_LGemissionfeedback * p.rtl_g0_baselandtemp
            v.nte_natLGemissions[t] = p.stim_LGemissionfeedback * p.rtl_g0_baselandtemp
            # eq.6 from Hope (2006) - emissions to atmosphere depend on the sum of natural and anthropogenic emissions
            tea0 = (p.e_0globalLGemissions + nte0) * p.air_LGfractioninatm / 100
            v.tea_LGemissionstoatm[t] = (p.e_globalLGemissions[t] + v.nte_natLGemissions[t]) * p.air_LGfractioninatm / 100
            v.teay_LGemissionstoatm[t] = (v.tea_LGemissionstoatm[t] + tea0) * (p.y_year[t] - p.y_year_0) / 2
            # adapted from eq.1 in Hope(2006) - calculate excess concentration in base year
            v.exc_excessconcLG = p.c0_LGconcbaseyr - p.pic_preindustconcLG
            # Eq. 2 from Hope (2006) - base-year remaining emissions
            v.re_remainLGbase = v.exc_excessconcLG * p.den_LGdensity
            v.re_remainLG[t] = v.re_remainLGbase * exp(-(p.y_year[t] - p.y_year_0) / p.res_LGatmlifetime) +
                v.teay_LGemissionstoatm[t] * p.res_LGatmlifetime * (1 - exp(-(p.y_year[t] - p.y_year_0) / p.res_LGatmlifetime)) / (p.y_year[t] - p.y_year_0)
        else
            # eq.3 from Hope (2006) - natural emissions (carbon cycle) feedback, using global temperatures calculated in ClimateTemperature component
            # Here assume still using area-weighted average regional temperatures (i.e. land temperatures) for natural emissions feedback
            v.nte_natLGemissions[t] = p.stim_LGemissionfeedback * p.rtl_g_landtemperature[t - 1]
            # eq.6 from Hope (2006) - emissions to atmosphere depend on the sum of natural and anthropogenic emissions
            v.tea_LGemissionstoatm[t] = (p.e_globalLGemissions[t] + v.nte_natLGemissions[t]) * p.air_LGfractioninatm / 100
            # eq.7 from Hope (2006) - average emissions to atm over time period
            v.teay_LGemissionstoatm[t] = (v.tea_LGemissionstoatm[t] + v.tea_LGemissionstoatm[t - 1]) * (p.y_year[t] - p.y_year[t - 1]) / 2
            # eq.10 from Hope (2006) - remaining emissions in atmosphere
            v.re_remainLG[t] = v.re_remainLG[t - 1] * exp(-(p.y_year[t] - p.y_year[t - 1]) / p.res_LGatmlifetime) +
                v.teay_LGemissionstoatm[t] * p.res_LGatmlifetime * (1 - exp(-(p.y_year[t] - p.y_year[t - 1]) / p.res_LGatmlifetime)) / (p.y_year[t] - p.y_year[t - 1])
        end

    # eq.11 from Hope(2006) - LG concentration
        v.c_LGconcentration[t] = p.pic_preindustconcLG + v.exc_excessconcLG * v.re_remainLG[t] / v.re_remainLGbase

    end
end


text:
script_dict_m = DataStructures.OrderedDict{AbstractString, Vector{ScriptEntry}}(
  "02" => [
    scriptentry("m2.1m.jl")
  ],
  "04" => [
    scriptentry("m4.4m.jl")
  ]
);


text:
@testset begin
  Qx, x = QQ["x"]
  K, a = NumberField(x^3 + 2, "a")
  Kt, t = K["t"]
  L, b = number_field([t^2 - 3, t^2 - t - 50], "b")

  r, s = @inferred signature(L)
  @test (r, s) == (4, 4)

  m = rand(L, -1:1)

  Labs, LabstoL = absolute_simple_field(L)

  c = conjugates(m, 64)
  cc = conjugates(LabstoL\m, 64)

  for _c in c
    @test count(_cc -> overlaps(_cc, _c), cc) == count(_cc -> overlaps(_cc, _c), c)
  end

  f = x^2+1
  K, a = number_field(f, cached = false, check = false);
  Kt, t = K["t"]
  f1 = t^3 + 249*t - 830
  f2 = t^7 - 1162*a*t^5 + (-29050*a + 29050)*t^4 - 542073*t^3 + (-14412286*a - 14412286)*t^2 - 80411562*a*t + 3869576532*a - 3869576532
  L, gL = number_field([f1, f2], cached = false)
  s, t = gL
  el = (1//978369084*a + 5//978369084)*t^6 + (-4//7411887*a + 89//978369084)*t^5 + (3181//489184542*a - 2753//489184542)*t^4 + (128197//978369084*a + 52165//81530757)*t^3 + (-6920957//489184542*a + 273422//22235661)*t^2 + (1243580//9058973*a - 2545783//18117946)*t + 67078685//27176919*a + 133062707//27176919
  c = t2(el)
  Labs, mLabs = absolute_simple_field(L)
  cc = t2(mLabs\el)
  @test overlaps(c, cc)
end


text:
# % MAKE_SQUARES Returns a list of all the squares between A, B, and L
# Se,Le,LEw = make_squares(A,B,L,true); Si = build_Si(Se,Le);
function make_squares(A::SparseMatrixCSC{Int64,Int64},B::SparseMatrixCSC{Int64,Int64},
                        L::SparseMatrixCSC{Int64,Int64},undirected::Bool)

m = size(A,1)
n = size(B,1)

if undirected
    rpA = A.colptr
    ciA = A.rowval

    rpB = B.colptr
    ciB = B.rowval
else
    A = A'
    B = B'

    rpA = A.colptr
    ciA = A.rowval

    rpB = B.colptr
    ciB = B.rowval
end

L = L'
rpAB = L.colptr
ciAB = L.rowval
vAB = L.nzval

Se1 = Int64[]
Se2 = Int64[]

wv = zeros(Int64,n)
sqi = 0
@inbounds for i=1:m
    # label everything in to i in B
    # label all the nodes in B that are possible matches to the current i
    possible_matches = rpAB[i]:rpAB[i+1]-1

    # get the exact node ids via ciA[possible_matches]
    wv[ciAB[possible_matches]] = possible_matches

    # for each node in A, follow its neighbors in L, then in B
    @inbounds for ri1 = rpA[i]:rpA[i+1]-1
        # get the actual node index
        ip = ciA[ri1]
        if i == ip
            continue
        end
        # for node index ip, check the nodes that its related to in L
        @inbounds for ri2 = rpAB[ip]:rpAB[ip+1]-1
            jp = ciAB[ri2]
            # for each of the nodes found in L, find their exact index in B and see if they form a square
            @inbounds for ri3 = rpB[jp]:rpB[jp+1]-1
                j = ciB[ri3]
                if j == jp
                    continue
                end
                if wv[j]>0
                    # we have a square!
                    push!(Se1,ri2)
                    push!(Se2,wv[j])
                end
            end
        end
    end
    # remove labels for things in in adjacent to B
    wv[ciAB[possible_matches]] = 0
end

Le = zeros(Int64,nnz(L),3)
LeWeights = zeros(Float64,nnz(L))
@inbounds for i = 1:m
    j = rpAB[i]:rpAB[i+1]-1
    Le[j,1] = i
    Le[j,2] = ciAB[j]
    LeWeights[j] = vAB[j]
end

Se = zeros(Int64,length(Se1),2)
Se[:,1] = Se1
Se[:,2] = Se2
return (Se,Le,LeWeights)
end

function make_squares(A::SparseMatrixCSC{Int64,Int64},B::SparseMatrixCSC{Int64,Int64},
                        L::SparseMatrixCSC{Float64,Int64},undirected::Bool)

m = size(A,1)
n = size(B,1)

if undirected
    rpA = A.colptr
    ciA = A.rowval

    rpB = B.colptr
    ciB = B.rowval
else
    A = A'
    B = B'

    rpA = A.colptr
    ciA = A.rowval

    rpB = B.colptr
    ciB = B.rowval
end

L = L'
rpAB = L.colptr
ciAB = L.rowval
vAB = L.nzval

Se1 = Int64[]
Se2 = Int64[]

wv = zeros(Int64,n)
sqi = 0
@inbounds for i=1:m
    # label everything in to i in B
    # label all the nodes in B that are possible matches to the current i
    possible_matches = rpAB[i]:rpAB[i+1]-1

    # get the exact node ids via ciA[possible_matches]
    wv[ciAB[possible_matches]] = possible_matches

    # for each node in A, follow its neighbors in L, then in B
    @inbounds for ri1 = rpA[i]:rpA[i+1]-1
        # get the actual node index
        ip = ciA[ri1]
        if i == ip
            continue
        end
        # for node index ip, check the nodes that its related to in L
        @inbounds for ri2 = rpAB[ip]:rpAB[ip+1]-1
            jp = ciAB[ri2]
            # for each of the nodes found in L, find their exact index in B and see if they form a square
            @inbounds for ri3 = rpB[jp]:rpB[jp+1]-1
                j = ciB[ri3]
                if j == jp
                    continue
                end
                if wv[j]>0
                    # we have a square!
                    push!(Se1,ri2)
                    push!(Se2,wv[j])
                end
            end
        end
    end
    # remove labels for things in in adjacent to B
    wv[ciAB[possible_matches]] = 0
end

Le = zeros(Int64,nnz(L),2)
LeWeights = zeros(Float64,nnz(L))
@inbounds for i = 1:m
    j = rpAB[i]:rpAB[i+1]-1
    Le[j,1] = i
    Le[j,2] = ciAB[j]
    LeWeights[j] = vAB[j]
end

Se = zeros(Int64,length(Se1),2)
Se[:,1] = Se1
Se[:,2] = Se2
return (Se,Le,LeWeights)
end

function build_Si(Se::Array{Int64,2},Le::Array{Int64,2})
# to build Si
Se1 = Se[:,1]
Se2 = Se[:,2]
Si = zeros(Int64,4,length(Se1))
for i = 1:length(Se1)
    Si[1,i] = Le[Se2[i],1]
    Si[2,i] = Le[Se1[i],1]
    Si[3,i] = Le[Se2[i],2]
    Si[4,i] = Le[Se1[i],2]
end
return Si
end

max_stars_repo_name: nassarhuda/NetworkAlign

max_issues_repo_name: nassarhuda/NetworkAlign

max_forks_repo_name: nassarhuda/NetworkAlign


text:
"""
    use_style(style::String)
    use_style(style::Vector{String})

Use matplotlib style settings from a style specification `style`.

The style name of "default" is reserved for reverting back to the default style
settings.

ArviZ-specific styles are `["arviz-whitegrid", "arviz-darkgrid", "arviz-colors", "arviz-white"]`.
To see all available style specifications, use [`styles()`](@ref).

If a `Vector` of styles is provided, they are applied from first to last.
"""
use_style(style) = arviz.style.use(style)

"""
    styles() -> Vector{String}

Get all available matplotlib styles for use with [`use_style`](@ref)
"""
styles() = arviz.style.available

"""
    with_rc_context(f; rc = nothing, fname = nothing)

Execute the thunk `f` within a context controlled by rc params. To see
supported params, execute [`rc_params()`](@ref).

This allows one to do:

```julia
with_rc_context(fname = "pystan.rc") do
    idata = load_arviz_data("radon")
    plot_posterior(idata; var_names=["gamma"])
end
```

The plot would have settings from `pystan.rc`.

A dictionary can also be passed to the context manager:

```julia
with_rc_context(rc = Dict("plot.max_subplots" => 1), fname = "pystan.rc") do
    idata = load_arviz_data("radon")
    plot_posterior(idata, var_names=["gamma"])
end
```

The `rc` dictionary takes precedence over the settings loaded from `fname`.
Passing a dictionary only is also valid.
"""
function with_rc_context(f; kwargs...)
    @pywith arviz.rc_context(; kwargs...) as _ begin
        f()
    end
end

"""
    rc_params() > Dict{String,Any}

Get the list of customizable `rc` params using [`with_rc_context`](@ref).
"""
rc_params() = Dict(k => v for (k, v) in ArviZ.arviz.rcParams)

"""
    with_interactive_backend(f; backend::Symbol = nothing)

Execute the thunk `f` in a temporary interactive context with the chosen
`backend`, or provide no arguments to use a default.

# Example

```julia
idata = load_arviz_data("centered_eight")
plot_posterior(idata) # inline
with_interactive_backend() do
    plot_density(idata) # interactive
end
plot_trace(idata) # inline
```
"""
function with_interactive_backend(f; backend = nothing)
    oldisint = PyPlot.isinteractive()
    oldgui = pygui()
    backend === nothing || pygui(Symbol(backend))
    pygui(true)
    f()
    pygui(oldisint)
    pygui(oldgui)
end

forwarddoc(f::Symbol) =
    "See documentation for [`arviz.$(f)`](https://arviz-devs.github.io/arviz/generated/arviz.$(f).html)."

forwardgetdoc(f::Symbol) = Docs.getdoc(getproperty(arviz, f))

"""
    @forwardfun f
    @forwardfun(f)

Wrap a function `arviz.f` in `f`, forwarding its docstrings.
"""
macro forwardfun(f)
    fdoc = forwarddoc(f)
    quote
        @doc $fdoc
        $(f)(args...; kwargs...) = arviz.$(f)(args...; kwargs...)

        Docs.getdoc(::typeof($(f))) = forwardgetdoc(Symbol($(f)))
    end |> esc
end

"""
    replacemissing(x)

Replace `missing` values with `NaN` and do type inference on the result.
"""
replacemissing(x) = map(identity, replace(x, missing => NaN))
replacemissing(x::AbstractArray{<:Real}) = x
replacemissing(x::Missing) = NaN

function rekey(d, keymap)
    dnew = empty(d)
    for (k, v) in d
        knew = get(keymap, k, k)
        haskey(dnew, knew) && throw(ArgumentError("$knew in `keymap` is already in `d`."))
        dnew[knew] = d[k]
    end
    return dnew
end

removekeys!(dict, keys) = map(k -> delete!(dict, k), keys)

function popsubdict!(dict, names)
    (dict === nothing || names === nothing) && return nothing
    subdict = empty(dict)
    for k in names
        subdict[k] = pop!(dict, k)
    end
    return subdict
end

popsubdict!(dict, key::String) = popsubdict!(dict, [key])

snakecase(s) = replace(lowercase(s), " " => "_")

enforce_stat_types(dict) =
    Dict(k => get(sample_stats_types, k, eltype(v)).(v) for (k, v) in dict)
enforce_stat_types(::Nothing) = nothing


text:
abstract type Potential{N} end
abstract type RepulsivePotential{N}  <: Potential{N} end
abstract type AttractivePotential{N} <: Potential{N} end

struct CompositePotential{N, U₁<:Potential{N}, U₂<:Potential{N}} <: Potential{N}
    u₁::U₁
    u₂::U₂

    function CompositePotential{N, U₁, U₂}(u₁::U₁, u₂::U₂) where
        {N, U₁<:Potential{N}, U₂<:Potential{N}}
        return new(u₁, u₂)
    end
end
#
function CompositePotential(u₁::U₁, u₂::U₂) where
    {N, U₁<:Potential{N}, U₂<:Potential{N}}
    return CompositePotential{N, U₁, U₂}(u₁, u₂)
end
#

struct HardCore{T, N} <: RepulsivePotential{N}
    σ::T
end
#
HardCore{N}(σ::T) where {T, N} = (@assert σ > 0; HardCore{T, N}(σ))
HardCore{N}() where {N} = HardCore{N}(1)

struct DipoleDipole{T} <: Potential{3}
    μ::T
end
#
DipoleDipole() = DipoleDipole(1)

struct Yukawa{T, N} <: AttractivePotential{N}
    z::T
    ϵ::T
end
#
function Yukawa{N}(z, ϵ) where {N}
    @assert z > 0
    z′, ϵ′ = promote(z, ϵ)

    return Yukawa{typeof(z′), N}(z′, ϵ′)
end
#
Yukawa{N}(z; ϵ = 1) where {N} = Yukawa{N}(z, ϵ)

struct SquareWell{T, N} <: AttractivePotential{N}
    λ::T
    ϵ::T
end
#
function SquareWell{N}(λ, ϵ) where {N}
    @assert λ > 1
    λ′, ϵ′ = promote(λ, ϵ)

    return SquareWell{typeof(λ′), N}(λ′, ϵ′)
end
#
SquareWell{N}(λ; ϵ = 1) where {N} = SquareWell{N}(λ, ϵ)

# Aliases for composite potentials
const DHSPotential = CompositePotential{3, <:HardCore, <:DipoleDipole}
const YHSPotential = CompositePotential{3, <:HardCore, <:Yukawa}
const SWHSPotential = CompositePotential{3, <:HardCore, <:SquareWell}

energy_scale(potential::Potential) = 1
energy_scale(potential::AttractivePotential) = potential.ϵ

length_scale(potential::Potential) = 1
length_scale(potential::HardCore) = potential.σ
length_scale(potential::SquareWell) = potential.λ
length_scale(potential::Yukawa) = potential.z
length_scale(potential::DHSPotential) = length_scale(potential.u₁)
length_scale(potential::CompositePotential) =
    (length_scale(potential.u₁), length_scale(potential.u₂))


text:
module Pidoh

abstract type AbstractProblem end
abstract type AbstractAlgorithm end
abstract type AbstractStop end
abstract type AbstractIP end

include("problems/problems.jl")
export AbstractProblem, AbstractBitstringProblem, AbstractGraphProblem, AbstractAlgorithm
export OneMax, ZeroMax, Jump
export MST, MaximumMatching
export MaxSAT, MaxSATgeneratorP
export TG, ER, Kn, GHL
export fitness, optimum

include("instance.jl")
export Instance
export initial
export fitness

include("utils/utils.jl")
export UniformlyIndependentMutation, HeavyTailedMutation
export mutation, flip, mutationpositions
export visualize, unmarkededges, markededges, graph_bitstring
export RandBitStringIP
export generate

include("trace.jl")
export Trace, info, record

include("algorithms/algorithms.jl")

include("experiments/experiments.jl")
# include("experiments/engines.jl")
export Experiment
export HPC
export cluster,
    createworkspaceinserver, createworkspace, loadexperiment, fetch, mergeexperiments

include("benchmark/benchmark.jl")
export benchmark

end


text:
function flux(u, q, w, v, x, t, mu, eta)
    f = mu[1]*q;
    return f;
end
function source(u, q, w, v, x, t, mu, eta)
    s = 0.0;
    return s;
end
function ubou(u, q, w, v, x, t, mu, eta, uhat, n, tau)
    ub = [mu[2] u];
    return ub;
end
function fbou(u, q, w, v, x, t, mu, eta, uhat, n, tau)
    f = flux(u, q, w, v, x, t, mu, eta);
    tm = f[1]*n[1] + f[2]*n[2] + f[3]*n[3] + tau[1]*(u[1]-uhat[1]);
    fb = [tm mu[3]*n[1]+mu[4]*n[2]+mu[5]*n[3]];
    return fb;
end
function initu(x, mu, eta)
    u0 = 1.0;
    return u0;
end

max_stars_repo_name: glwagner/Exasim

max_issues_repo_name: glwagner/Exasim

max_forks_repo_name: glwagner/Exasim


text:
module DWARF
    using StrPack
    using ObjFileBase

    include("constants.jl")

    import Base: read, write, zero, bswap, isequal, show, print, hash

    abstract DWARFHeader
    abstract DWARFCUHeader <: DWARFHeader # Compilation Unit Header
    abstract DWARFTUHeader <: DWARFHeader # Type Unit Header
    abstract DWARFARHeader <: DWARFHeader # Address Range Header
    abstract DWARFPUBHeader <: DWARFHeader
    abstract PUBTableEntry
    abstract PUBTableSet

    export AbbrevTableEntry, AbbrevTableSet, ULEB128, SLEB128,
        DIETree, attributes, dies

    module DWARF32
        using StrPack
        using DWARF

        @struct immutable CUHeader <: DWARF.DWARFCUHeader
            unit_length::Uint32
            version::Uint16
            debug_abbrev_offset::Uint32
            address_size::Uint8
        end align_packed

        @struct immutable TUHeader <: DWARF.DWARFTUHeader
            unit_length::Uint32
            version::Uint16
            debug_abbrev_offset::Uint32
            address_size::Uint8
            type_signature::Uint64
            type_offset::Uint32
        end align_packed

        @struct immutable ARHeader <: DWARF.DWARFARHeader
            unit_length::Uint32
            version::Uint16
            debug_info_offset::Uint32
            address_size::Uint8
            segment_size::Uint8
        end align_packed

        @struct immutable PUBHeader <: DWARF.DWARFPUBHeader
            unit_length::Uint32
            version::Uint16
            debug_info_offset::Uint32
            debug_info_length::Uint32
        end align_packed

        immutable PUBTableEntry <: DWARF.PUBTableEntry
            offset::Uint32
            name::ASCIIString
        end

        immutable PUBTableSet <: DWARF.PUBTableSet
            header::PUBHeader
            entries::Array{PUBTableEntry,1}
        end

    end

    module DWARF64
        using StrPack
        using DWARF

        @struct immutable CUHeader <: DWARF.DWARFCUHeader
            unit_length::Uint64
            version::Uint16
            debug_abbrev_offset::Uint64
            address_size::Uint8
            type_offset::Uint64
        end align_packed

        @struct immutable TUHeader <: DWARF.DWARFTUHeader
            unit_length::Uint32
            version::Uint16
            debug_abbrev_offset::Uint32
            address_size::Uint8
            type_signature::Uint64
            type_offset::Uint64
        end align_packed

        @struct immutable ARHeader <: DWARF.DWARFARHeader
            unit_length::Uint32
            version::Uint16
            debug_info_offset::Uint64
            address_size::Uint8
            segment_size::Uint8
        end align_packed

        @struct immutable PUBHeader <: DWARF.DWARFPUBHeader
            unit_length::Uint32
            version::Uint16
            debug_info_offset::Uint64
            debug_info_length::Uint64
        end align_packed

        immutable PUBTableEntry <: DWARF.PUBTableEntry
            offset::Uint64
            name::ASCIIString
        end

        immutable PUBTableSet <: DWARF.PUBTableSet
            header::PUBHeader
            entries::Array{PUBTableEntry,1}
        end
    end

    ### Display
    function show(io::IO, header::DWARFCUHeader)
        is64 = isa(header,DWARF64.CUHeader)
        printentry(io,"Length","0x",hex(header.unit_length))
        printentry(io,"Version",dec(header.version))
        printentry(io,"Abbrev Offset","0x",hex(header.debug_abbrev_offset))
        printentry(io,"Address Size","0x",hex(header.address_size))
        is64 && printentry(io,"Type Offset","0x",hex(header.type_offset))
    end

    ### LEB 128 types
    abstract LEB128

    Base.convert{T<:LEB128}(::Type{T},x::Int64) = T(big(x))
    Base.convert{T<:LEB128}(::Type{BigInt},x::T) = x.val

    immutable ULEB128 <: LEB128
        val::BigInt
    end

    immutable SLEB128 <: LEB128
        val::BigInt
    end

    show(io::IO,s::SLEB128) = show(io,s.val)
    hash(x::LEB128, h::UInt64) = hash(x.val, h)
    isequal(a::LEB128,b::LEB128) = (a.val==b.val)
    isequal(a::LEB128,b::Integer) = (a.val==b)
    isequal(a::Integer,b::LEB128) = (b==a.val)
    ==(a::LEB128,b::LEB128) = isequal(a,b)
    ==(a::LEB128,b::Integer) = isequal(a.val, b)
    ==(a::Integer,b::LEB128) = isequal(b, a.val)

    function read(io::IO, ::Type{ULEB128})
        v = BigInt(0)
        shift = 0
        while true
            c = read(io,Uint8)
            v |= BigInt(c&0x7f)<<shift
            if (c&0x80)==0 #is last bit
                break
            end
            shift+=7
        end
        ULEB128(v)
    end

    function write(io::IO, x::ULEB128)
        x = x.val
        while true
            v = (x % UInt8) & 0x7f
            x >>= 7
            if x != 0
                v |= 0x80 # = ~0x7f
            end
            write(io,v)
            x == 0 && break
        end
    end

    function decode(data::Array{Uint8,1}, offset, ::Type{ULEB128})
        v = BigInt(0)
        shift = 0
        i=0
        while true
            c = data[offset+i]
            i+=1
            v |= BigInt(c&0x7f)<<shift
            if (c&0x80)==0 #is last bit
                break
            end
            shift+=7
        end
        (offset+i,ULEB128(v))
    end

    function decode(data::Array{Uint8,1}, offset, ::Type{SLEB128})
        v = BigInt(0)
        shift = 0
        c=0
        i=0
        while true
            c = data[offset+i]
            i+=1
            v |= BigInt(c&0x7f)<<shift
            shift+=7
            if (c&0x80)==0 #is last bit
                break
            end
        end
        if (c & 0x40) != 0
            v |= -(BigInt(1)<<shift)
        end

        (offset+i,SLEB128(v))
    end

    function read(io::IO, ::Type{SLEB128})
        v = BigInt(0)
        shift = 0
        c=0
        while(true)
            c = read(io,Uint8)
            v |= BigInt(c&0x7f)<<shift
            if (c&0x80)==0 #is last bit
                break
            end
            shift+=7
        end
        if (c & 0x40) != 0
            v |= -(BigInt(1)<<shift)
        end

        SLEB128(v)
    end

    function write(io::IO, x::SLEB128)
        x = x.val
        more = true
        while more
            v = (x % Uint8) & 0x7f
            x >>= 7
            if ((x == 0 && ((v & 0x40) == 0)) || (x == -1 && ((v & 0x40) > 0)))
                more = false
            else
                v |= 0x80
            end
            write(io,v)
        end
    end

    fix_endian(x,endianness) = StrPack.endianness_converters[endianness][2](x)

    const attr_color = :cyan

    # Attributes
    module Attributes
        import DWARF
        import DWARF: ULEB128, SLEB128, attr_color, fix_endian, DW_AT
        using ObjFileBase
        import ObjFileBase: strtab_lookup

        import Base: isequal, read, show, bytestring
        export AttributeSpecification, Attribute, GenericStringAttribute,
            Constant1, Constant2, Constant4, Constant8, SConstant,
            UConstant, GenericStringAttribute, StrTableReference

        # Printing

        function print_name(io, x, kind; indent = 0)
            print(io," "^indent)
            if !haskey(DW_AT,x.name.val)
                printfield_with_color(:red, io, string("Unknown ($(x.name.val))"),17; align=:left)
            else
                printfield_with_color(attr_color, io, DW_AT[x.name.val],17; align=:left)
            end
            printfield(io,string(" [", kind, "] "),25, align = :left)
        end

        ###
        # Generic Attributes
        #
        # DWARF is designed in such a way that even consumers who may not understand
        # all the possible arguments can still parse any DAWRF file. To do so, they
        # have a fixed number of storage formats that need to be supported. In this
        # implementation attributes which have no specialized form are left as generic
        # attributes in the tree.
        ##

        abstract Attribute
        abstract GenericAttribute <: Attribute

        using StrPack

        immutable AddressAttribute{T} <: GenericAttribute
            name::ULEB128
            content::T
        end

        immutable BlockAttribute <: GenericAttribute
            name::ULEB128
            content::Array{UInt8,1}
        end

        immutable ExprLocAttribute{T} <: GenericAttribute
            name::ULEB128
            content::Array{UInt8,1}
        end

        function show(io::IO, x::AddressAttribute; indent = 0, kwargs...)
            print_name(io, x, :AddressAttribute; indent = indent)
            println(io, "0x",hex(x.content,2*sizeof(x.content)))
        end

        function show(io::IO, x::BlockAttribute; indent = 0, kwargs...)
            print_name(io, x, :BlockAttribute; indent = indent)
            println(io, x.content)
        end

        function show{T}(io::IO, x::ExprLocAttribute{T}; indent = 0, kwargs...)
            print_name(io, x, :ExprLocAttribute; indent = indent)
            DWARF.Expressions.print_expression(io,T,x.content,:NativeEndian)
            println(io)
        end

        abstract GenericConstantAttribute <: GenericAttribute

        macro gattr(attr_name,supertype,ctype)
            esc(quote
                immutable $attr_name <: $supertype
                    name::ULEB128
                    content::$ctype
                    ($(attr_name))(name::ULEB128) = new(name)
                    ($(attr_name))(name::ULEB128,content::$ctype) = new(name,content)
                end
                function Base.show(io::IO,x::$attr_name; indent = 0, kwargs...)
                    Attributes.print_name(io, x, $(string(attr_name)); indent = indent)
                    println(io, x.content)
                end
            end)
        end

        @gattr ExplicitFlag GenericAttribute Uint8
        @gattr ImplicitFlag GenericAttribute Void
        @gattr Constant1 GenericConstantAttribute Uint8
        @gattr Constant2 GenericConstantAttribute Uint16
        @gattr Constant4 GenericConstantAttribute Uint32
        @gattr Constant8 GenericConstantAttribute Uint64
        @gattr SConstant GenericConstantAttribute SLEB128
        @gattr UConstant GenericConstantAttribute ULEB128

        abstract GenericReferenceAttribute <: GenericAttribute

        @gattr Reference1 GenericReferenceAttribute Uint8
        @gattr Reference2 GenericReferenceAttribute Uint16
        @gattr Reference4 GenericReferenceAttribute Uint32
        @gattr Reference8 GenericReferenceAttribute Uint64
        @gattr UReference GenericReferenceAttribute ULEB128

        abstract GenericStringAttribute <: GenericAttribute

        # # # 32/64-bit dependent types
        abstract StrTableReference <: GenericStringAttribute
        abstract SectionOffset <: GenericAttribute
        module DWARF32
            import DWARF.ULEB128
            using ..Attributes
            immutable StrTableReference <: Attributes.StrTableReference
                name::ULEB128
                content::UInt32
            end
            @Attributes.gattr SectionOffset Attributes.GenericAttribute Uint32
        end

        module DWARF64
            import DWARF.ULEB128
            using ..Attributes
            immutable StrTableReference <: Attributes.StrTableReference
                name::ULEB128
                content::UInt64
            end
            @Attributes.gattr SectionOffset Attributes.GenericAttribute Uint64
        end
        function bytestring(x::StrTableReference, strtab = nothing)
            strtab_lookup(strtab, x.content)
        end
        function show(io::IO, x::StrTableReference; indent = 0, strtab = nothing)
            print_name(io, x, :StrTableReference; indent = indent)
            if strtab === nothing
                print(io, ".debug_str[0x",hex(x.content,2*sizeof(x.content))"]")
            else
                show(io, strtab_lookup(strtab, x.content))
            end
            println(io)
        end

        immutable StringAttribute <: GenericStringAttribute
            name::ULEB128
            content::ASCIIString
        end
        function show(io::IO, x::StringAttribute; indent = 0, kwargs...)
            print_name(io, x, :StringAttribute; indent = indent)
            show(io, x.content)
            println(io)
        end

        immutable UnimplementedAttribute
        end

        const form_mapping = [
            AddressAttribute,       # DW_FORM_addr
            UnimplementedAttribute, # -- Invalid
            BlockAttribute,         # DW_FORM_block2
            BlockAttribute,         # DW_FORM_block4
            Constant2,              # DW_FORM_data2
            Constant4,              # DW_FORM_data4
            Constant8,              # DW_FORM_data8
            StringAttribute,        # DW_FORM_string
            BlockAttribute,         # DW_FORM_block
            BlockAttribute,         # DW_FORM_block1
            Constant1,              # DW_FORM_data1
            ExplicitFlag,           # DW_FORM_flag
            SConstant,              # DW_FORM_sdata
            StrTableReference,      # DW_FORM_strp
            UConstant,              # DW_FORM_udata
            UnimplementedAttribute, # DW_FORM_ref_addr
            Reference1,             # DW_FORM_ref1
            Reference2,             # DW_FORM_ref2
            Reference4,             # DW_FORM_ref4
            Reference8,             # DW_FORM_ref8
            UReference,             # DW_FORM_ref_udata
            UnimplementedAttribute, # DW_FORM_indirect
            SectionOffset,          # DW_FORM_sec_offset
            ExprLocAttribute,       # DW_FORM_exprloc
            ImplicitFlag,           # DW_FORM_flag_present
            UnimplementedAttribute  # DW_FORM_ref_sig8
        ]

        function form2gattrT(form::ULEB128)
            mapping = form_mapping[form.val]
            if mapping == UnimplementedAttribute
                error("Unimplemented Attribute Form $form")
            end
            mapping
        end

        read(io::IO,name::ULEB128,::Type{UConstant}) = UConstant(name,read(io,ULEB128))
        read(io::IO,name::ULEB128,::Type{SConstant}) = SConstant(name,read(io,SLEB128))
        read(io::IO,name::ULEB128,::Type{UReference}) = UReference(name,read(io,ULEB128))
        read(io::IO,name::ULEB128,::Type{ExplicitFlag}) = ExplicitFlag(name,read(io,Uint8))
        read(io::IO,name::ULEB128,::Type{ImplicitFlag}) = ImplicitFlag(name,nothing)
        function read{T<:Union(GenericConstantAttribute,GenericReferenceAttribute)}(io::IO,::Type{T},
                                            header::DWARF.DWARFCUHeader,name,form,endianness::Symbol)
            t = T(name)
            t = T(name,fix_endian(read(io,typeof(t.content)),endianness))
            t
        end
        read(io::IO,name::ULEB128,T::Type{StringAttribute}) = StringAttribute(name,strip(readuntil(io,'\0'),'\0'))
        read{T<:GenericAttribute}(io::IO,::Type{T},header::DWARF.DWARFCUHeader,name,form,endianness::Symbol) = read(io,name,T)
        function read(io::IO,::Type{BlockAttribute},header::DWARF.DWARFCUHeader,name,form,endianness::Symbol)
            if form == DWARF.DW_FORM_block1
                length = read(io,Uint8)
            elseif form == DWARF.DW_FORM_block2
                length = fix_endian(read(io,Uint16),endianness)
            elseif form == DWARF.DW_FORM_block4
                length = fix_endian(read(io,Uint32),endianness)
            elseif form == DWARF.DW_FORM_block
                length = fix_endian(read(io,ULEB128),endianness)
            else
                error("Unkown Block Form $form")
            end
            content = Array(Uint8,length)
            read!(io,content)
            BlockAttribute(name,content)
        end
        function read(io::IO,::Type{ExprLocAttribute},header::DWARF.DWARFCUHeader,name,form,endianness::Symbol)
            length = read(io,ULEB128).val
            content = Array(Uint8,length)
            read!(io,content)
            T = DWARF.size_to_inttype(header.address_size)
            ExprLocAttribute{T}(name, content)
        end
        function read(io::IO,::Type{AddressAttribute},header::DWARF.DWARFCUHeader,name,form,endianness::Symbol)
            T = DWARF.size_to_inttype(header.address_size)
            AddressAttribute{T}(name,fix_endian(read(io,T),endianness))
        end
        function read(io::IO,::Type{StrTableReference},header::DWARF.DWARFCUHeader,name,form,endianness::Symbol)
            if typeof(header.debug_abbrev_offset) == Uint32
                DWARF32.StrTableReference(name,fix_endian(read(io,Uint32),endianness))
            elseif typeof(header.debug_abbrev_offset) == Uint64
                DWARF64.StrTableReference(name,fix_endian(read(io,Uint64),endianness))
            end
        end
        function read(io::IO,::Type{SectionOffset},header::DWARF.DWARFCUHeader,name,form,endianness::Symbol)
            if typeof(header.debug_abbrev_offset) == Uint32
                DWARF32.SectionOffset(name,fix_endian(read(io,Uint32),endianness))
            elseif typeof(header.debug_abbrev_offset) == Uint64
                DWARF64.SectionOffset(name,fix_endian(read(io,Uint64),endianness))
            end
        end

        immutable AttributeSpecification
            name::ULEB128
            form::ULEB128
        end
        isequal(a::AttributeSpecification,b::AttributeSpecification) = (a.name == b.name)&&(a.form == b.form)
        ==(a::AttributeSpecification,b::AttributeSpecification) = isequal(a,b)

        function read(io::IO,::Type{AttributeSpecification},endianness::Symbol)
            name = read(io,ULEB128)
            form = read(io,ULEB128)
            AttributeSpecification(name,form)
        end

        function read(io::IO,header::DWARF.DWARFCUHeader,a::AttributeSpecification,endianness::Symbol)
            generic = read(io,form2gattrT(a.form),header,a.name,a.form,endianness)
            # TODO: Return Actual Attributes
            generic
        end
    end
    using .Attributes

    module Expressions
        # TODO
        using DWARF
        import DWARF.fix_endian

        type StateMachine{T}
            stack::Array{T,1}
        end

        function operands(addr_type,opcode,opcodes,i,endianness)
            if opcode == DWARF.DW_OP_addr
                operand = fix_endian(reinterpret(addr_type,opcodes[i:(i+sizeof(addr_type)-1)])[1],endianness)
                i += sizeof(addr_type)
            elseif opcode == DWARF.DW_OP_const1u || opcode == DWARF.DW_OP_pick
                operand = convert(addr_type,opcodes[i])
                i += 1
            elseif opcode == DWARF.DW_OP_const1s
                operand = convert(addr_type,opcodes[i])
                # Yes, this is actually different from the above, since we need to sign extend properly
                push!(s.stack,convert(addr_type,fix_endian(reinterpret(Int8,opcodes[i]),endianness)))
                i += 1
            elseif opcode == DWARF.DW_OP_const2u # 1 2-byte constant
                operand = convert(addr_type,fix_endian(reinterpret(Uint16,opcodes[i:i+1])[1],endianness))
                i+=2
            elseif opcode == DWARF.DW_OP_const2s  || opcode == DWARF.DW_OP_bra || opcode == DWARF.DW_OP_skip # 1 2-byte constant
                operand = convert(addr_type,fix_endian(reinterpret(Int16,opcodes[i:i+1])[1],endianness))
                i+=2
            elseif opcode == DWARF.DW_OP_const4u # 1 4-byte constant
                operand = convert(addr_type,fix_endian(reinterpret(Uint32,opcodes[i:i+3])[1],endianness))
                i+=4
            elseif opcode == DWARF.DW_OP_const4u # 1 4-byte constant
                operand = convert(addr_type,fix_endian(reinterpret(Int32,opcodes[i:i+3])[1],endianness))
                i+=4
            elseif opcode == DWARF.DW_OP_const8u # 1 8-byte constant
                operand = convert(addr_type,fix_endian(reinterpret(Uint64,opcodes[i:i+7])[1],endianness))
                i+=8
            elseif opcode == DWARF.DW_OP_const8s # 1 8-byte constant
                operand = convert(addr_type,fix_endian(reinterpret(Int64,opcodes[i:i+7])[1],endianness))
                i+=8
            elseif opcode == DWARF.DW_OP_constu || opcode == DWARF.DW_OP_plus_uconst ||
                    opcode == DWARF.DW_OP_regx || opcode == DWARF.DW_OP_piece
                (i,operand) = DWARF.decode(opcodes,i,ULEB128)
            elseif opcode == DWARF.DW_OP_consts || opcode == DWARF.DW_OP_fbreg ||
                opcode >= DWARF.DW_OP_breg0 && opcode <= DWARF.DW_OP_breg31
                (i,operand) = DWARF.decode(opcodes,i,SLEB128)
            elseif opcode == DWARF.DW_OP_bregx
                (i,reg) = DWARF.decode(opcodes,i,ULEB128)
                (i,offset) = DWARF.decode(opcodes,i,SLEB128)
                operand = (reg,offset)
            elseif opcode == DWARF.DW_OP_bit_piece
                (i,reg) = DWARF.decode(opcodes,i,ULEB128)
                (i,offset) = DWARF.decode(opcodes,i,ULEB128)
                operand = (reg,offset)
            else
                return (i,)
            end
            return (i,operand)
        end

        function evaluate_generic_instruction{T}(s::StateMachine{T},opcodes,i,getreg_func::Function,getword_func,endianness::Symbol)
            opcode = opcodes[i]
            i+=1
            if opcode == DWARF.DW_OP_deref
                push!(s.stack,getword_func(pop!(s.stack)))
            elseif in(opcode,(DWARF.DW_OP_addr,DWARF.DW_OP_const1u,DWARF.DW_OP_const1s,DWARF.DW_OP_const2u,
                              DWARF.DW_OP_const2s,DWARF.DW_OP_const4u,DWARF.DW_OP_const4s,DWARF.DW_OP_const8u,
                              DWARF.DW_OP_const8s,DWARF.DW_OP_constu,DWARF.DW_OP_consts))
                (i,val) = operands(T,opcode,opcodes,i,endianness)
                push!(s.stack,convert(T,val))
            elseif opcode == DWARF.DW_OP_dup
                push!(s.stack,s.stack[length(s.stack)-1])
            elseif opcode == DWARF.DW_OP_pick
                (i,val) = operands(T,opcode,opcodes,i,endianness)
                push!(s.stack,s.stack[val])
            elseif opcode == DWARF.DW_OP_swap
                top = length(s.stack)
                val = s.stack[top]
                s.stack[top] = s.stack[top-1]
                s.stack[top-1] = val
            elseif opcode == DWARF.DW_OP_rot
                top = length(s.stack)
                val = s.stack[top]
                s.stack[top] = s.stack[top-1]
                s.stack[top-1] = s.stack[top-2]
                s.stack[top-2] = val
            elseif opcode == DWARF.DW_OP_xderef
                error("Unimplemented")
            elseif opcode == DWARF.DW_OP_abs
                push!(s.stack,abs(signed(pop!(s.stack))))
            elseif opcode == DWARF.DW_OP_and
                push!(s.stack,pop!(s.stack)&pop!(s.stack))
            elseif opcode == DWARF.DW_OP_div
                top = pop!(s.stack)
                push!(s.stack,pop!(s.stack)/top)
            elseif opcode == DWARF.DW_OP_minus
                top = pop!(s.stack)
                push!(s.stack,pop!(s.stack)-top)
            elseif opcode == DWARF.DW_OP_minus
                top = pop!(s.stack)
                push!(s.stack,pop!(s.stack)%top)
            elseif opcode == DWARF.DW_OP_mul
                push!(s.stack,pop!(s.stack)*pop!(s.stack))
            elseif opcode == DWARF.DW_OP_neg
                push!(s.stack,-(signed(pop!(s.stack))))
            elseif opcode == DWARF.DW_OP_not
                push!(s.stack,~(pop!(s.stack)))
            elseif opcode == DWARF.DW_OP_plus_uconst
                (i,val) = DWARF.decode(opcodes,i,ULEB128)
                push!(s.stack,pop!(s.stack)+val)
            elseif opcode == DWARF.DW_OP_shl
                top = pop!(s.stack)
                push!(s.stack,pop!(s.stack)<<top)
            elseif opcode == DWARF.DW_OP_shr
                top = pop!(s.stack)
                push!(s.stack,pop!(s.stack)>>top)
            elseif opcode == DWARF.DW_OP_shra
                top = pop!(s.stack)
                push!(s.stack,convert(T,signed(pop!(s.stack))>>top))
            elseif opcode == DWARF.DW_OP_xor
                top = pop!(s.stack)
                push!(s.stack,pop!(s.stack)$top)
            elseif opcode == DWARF.DW_OP_le
                top = pop!(s.stack)
                push!(s.stack,convert(T,pop!(s.stack)<=top))
            elseif opcode == DWARF.DW_OP_ge
                top = pop!(s.stack)
                push!(s.stack,convert(T,pop!(s.stack)>=top))
            elseif opcode == DWARF.DW_OP_eq
                top = pop!(s.stack)
                push!(s.stack,convert(T,pop!(s.stack)==top))
            elseif opcode == DWARF.DW_OP_lt
                top = pop!(s.stack)
                push!(s.stack,convert(T,pop!(s.stack)<top))
            elseif opcode == DWARF.DW_OP_gt
                top = pop!(s.stack)
                push!(s.stack,convert(T,pop!(s.stack)>top))
            elseif opcode == DWARF.DW_OP_ne
                top = pop!(s.stack)
                push!(s.stack,convert(T,pop!(s.stack)!=top))
            elseif opcode == DWARF.DW_OP_skip
                i += fix_endian(reinterrept(Int16,opcodes[i:i+1])[1],endianness)
            elseif opcode == DWARF.DW_OP_bra
                (i,skip) = operands(T,opcode,opcodes,i,endianness)
                if(pop!(s.stack) != 0)
                    i += skip
                end
            elseif opcode == DWARF.DW_OP_call2 || opcode == DWARF.DW_OP_call4 || opcode == DWARF.DW_OP_call_ref
                error("Unimplemented")
            elseif opcode >= DWARF.DW_OP_lit1 && opcode <= DWARF.DW_OP_lit31
                push!(s.stack,opcode-DW_OP_lit1+1)
            elseif opcode >= DWARF.DW_OP_breg0 && opcode <= DWARF.DW_OP_breg31
                (i,offset) = operands(T,opcode,opcodes,i,endianness)
                push!(s.stack,getreg_func(opcode-DWARF.DW_OP_breg0) + offset)
            elseif opcode == DWARF.DW_OP_bregx
                (i,(val,offset)) = operands(T,opcode,opcodes,i,endianness)
                push!(s.stack,getreg_func(val) + offset)
            elseif opcode == DWARF.DW_OP_nop
                #NOP
            else
                return (i-1,false)
            end
            (i,true)
        end

        function evaluate_generic{T}(s::StateMachine{T},opcodes::Array{Uint8,1},getreg_func::Function,getword_func,endianness::Symbol)
            i=1
            while true
                i,res = evaluate_generic_instruction(s,opcodes,i,getreg_func,getword_func,endianness)
                if !res
                    error("Unrecognized Opcode ",opcodes[i])
                end
                if i==length(opcodes)
                    break
                end
            end
        end

        function op_name(opcode)
            if DWARF.DW_OP_lit1 <= opcode <= DWARF.DW_OP_lit31
                return string("DW_OP_lit",1+opcode-DWARF.DW_OP_lit1)
            elseif DWARF.DW_OP_reg0 <= opcode <= DWARF.DW_OP_reg31
                return string("DW_OP_reg",opcode-DWARF.DW_OP_reg0)
            elseif DWARF.DW_OP_breg0 <= opcode <= DWARF.DW_OP_breg31
                return string("DW_OP_breg",opcode-DWARF.DW_OP_breg0)
            else
                return DWARF.DW_OP[opcode]
            end
        end

        function print_expression(io::IO, addr_type, opcodes::Array{UInt8,1},endianness::Symbol)
            i = 1
            while i <= length(opcodes)
                opcode = opcodes[i]
                i += 1
                ops = operands(addr_type, opcode, opcodes, i, endianness)
                i = ops[1]
                print_with_color(:blue, io, op_name(opcode))
                print(io," ")
                if length(ops) > 1
                    operand = ops[2]
                    if !isa(operand,Tuple)
                        operand = (operand,)
                    end
                    print(io,join(map(repr,operand)," ")," ")
                end
            end
        end

        immutable RegisterLocation
            i::Int32
        end

        immutable MemoryLocation{T}
            i::T
        end

        function evaluate_simple_location{T}(s::StateMachine{T},opcodes::Array{Uint8,1},getreg_func::Function,getword_func,endianness::Symbol)
            i=1
            opcode = opcodes[i]
            if opcode >= DWARF.DW_OP_reg0 && opcode <= DWARF.DW_OP_reg31
                return RegisterLocation(opcode-DWARF.DW_OP_reg0)
            elseif opcode == DWARF.DW_OP_regx
                (i,val) = DWARF.decode(opcodes,i,ULEB128)
                return RegisterLocation(val)
            else
                evaluate_generic(s,opcodes,getreg_func,getword_func,endianness)
                return MemoryLocation{T}(last(s.stack))
            end
        end
    end

    # The line table is encoded as a state machine program
    # operating on a register machine, whose register represent the
    # values the debugger needs to know about the current source location
    module LineTableSupport
        using StrPack

        import ..ULEB128, ..SLEB128, ..DWARF

        immutable HeaderStub{T}
            length::T
            version::Uint16
            header_length::T
            minimum_instruction_length::Uint8
            maximum_operations_per_instruction::Uint8
            default_is_stmt::Uint8
            line_base::Int8
            line_range::Int8
            opcode_base::Uint8
        end

        immutable FileEntry
            name::UTF8String
            dir_idx::BigInt
            timestamp::BigInt
            filelength::BigInt
        end

        Base.isequal(x::FileEntry,y::FileEntry) =
            (x.name == y.name && x.dir_idx == y.dir_idx && x.timestamp == y.timestamp && x.filelength == y.filelength)
        ==(x::FileEntry, y::FileEntry) = isequal(x,y)

        function Base.read(io::IO,::Type{FileEntry})
            s = readstring(io)
            if endof(s) == 0
                return FileEntry(s,0,0,0)
            end
            return FileEntry(s,read(io,ULEB128),read(io,ULEB128),read(io,ULEB128))
        end

        function unpack(io,::Type{HeaderStub})
            T = Uint32
            length = read(io,T)
            if length == 0xffffffff
                T = Uint64
                length = read(io,T)
            end
            version = read(io,Uint16)
            header_length = read(io,T)
            minimum_instruction_length = read(io,Uint8)
            maximum_operations_per_instruction = version >= 4 ? read(io,Uint8) : 1
            HeaderStub{T}(length,version,header_length,minimum_instruction_length,maximum_operations_per_instruction,
                read(io,Uint8),read(io,Int8),read(io,Int8),read(io,Uint8))
        end

        immutable Header{T}
            stub::HeaderStub{T}
            standard_opcode_lengths::Vector{Uint8}
            include_directories::Vector{UTF8String}
            file_names::Vector{FileEntry}
        end

        function readstring(io)
            ret = Array(Uint8,0)
            while true
                c = read(io,Uint8)
                c == 0 && break
                push!(ret,c)
            end
            UTF8String(ret)
        end

        function read_header(io)
            stub = unpack(io,HeaderStub)
            standard_opcode_lengths = Array(Uint8,stub.opcode_base-1)
            read(io,standard_opcode_lengths)
            include_directories = UTF8String[]
            while true
                s = readstring(io)
                endof(s) == 0 && break
                push!(include_directories,s)
            end
            file_names = FileEntry[]
            while true
                f = read(io,FileEntry)
                endof(f.name) == 0 && break
                push!(file_names,f)
            end
            Header{header_type(stub)}(stub,standard_opcode_lengths,include_directories,file_names)
        end

        header_type{T}(h::Header{T}) = T
        header_type{T}(h::HeaderStub{T}) = T

        immutable RegisterState
            address::BigInt
            op_index::BigInt
            file::BigInt
            line::BigInt
            column::BigInt
            is_stmt::Bool
            basic_block::Bool
            end_sequence::Bool
            prologue_end::Bool
            epilogue_begin::Bool
            isa::BigInt
            discriminator::BigInt

            # Initial Register state as defined by DWARF standard
            function RegisterState(default_is_stmt::Bool)
                new(BigInt(0),BigInt(0),BigInt(1),BigInt(1),BigInt(0),default_is_stmt,
                    false,false,false,false,BigInt(0),BigInt(0))
            end

            function RegisterState(x::RegisterState;
                    address = x.address, op_index = x.op_index, file = x.file, line = x.line,
                    column = x.column, is_stmt = x.is_stmt, basic_block = x.basic_block,
                    end_sequence = x.end_sequence, prologue_end = x.prologue_end,
                    epilogue_begin = x.epilogue_begin, isa = x.isa, discriminator = x.discriminator)
                new(address,op_index,file,line,column,is_stmt,basic_block,end_sequence,prologue_end,
                    epilogue_begin,isa,discriminator)
            end

            RegisterState(address,op_index,file,line,column,is_stmt,basic_block,end_sequence,
                    prologue_end,epilogue_begin,isa,discriminator) =
                new(address,op_index,file,line,column,is_stmt,basic_block,end_sequence,
                    prologue_end,epilogue_begin,isa,discriminator)
        end

        Base.isequal(x::RegisterState,y::RegisterState) = (
            x.address == y.address &&
            x.op_index == y.op_index &&
            x.file == y.file &&
            x.line == y.line &&
            x.column == y.column &&
            x.is_stmt == y.is_stmt &&
            x.basic_block == y.basic_block &&
            x.end_sequence == y.end_sequence &&
            x.prologue_end == y.prologue_end &&
            x.epilogue_begin == y.epilogue_begin &&
            x.isa == y.isa &&
            x.discriminator == y.discriminator)
        ==(x::RegisterState, y::RegisterState) = isequal(x,y)

        type StateMachine
            header::Header
            state::RegisterState
        end

        function pc_adv!(m::StateMachine,op_adv)
            m.state = RegisterState(m.state,
                address = m.state.address + m.header.stub.minimum_instruction_length *
                    div(m.state.op_index + op_adv,m.header.stub.maximum_operations_per_instruction),
                op_index = m.state.op_index +
                    mod(m.state.op_index + op_adv,m.header.stub.maximum_operations_per_instruction))
        end

        function pcl_adv!(m::StateMachine,op)
            adj_opc = op - m.header.stub.opcode_base
            pc_adv!(m,div(adj_opc,m.header.stub.line_range))
            m.state = RegisterState(m.state,
                line = m.state.line + m.header.stub.line_base + mod(adj_opc,m.header.stub.line_range))
        end

        function step(io,m::StateMachine)
            op = read(io,Uint8)
            if op == 0
                # Extended opcode
                pos = position(io)
                size::BigInt = read(io,ULEB128)
                ex_op = read(io,Uint8)
                if ex_op == DWARF.DW_LNE_end_sequence
                    m.state = RegisterState(m.state,end_sequence = true)
                    ret = (true,m.state)
                    m.state = RegisterState(m.header.stub.default_is_stmt > 0)
                    position(io) > pos+size+1 && error("Malformed extended instruction")
                    return ret
                elseif ex_op == DWARF.DW_LNE_set_address
                    addrsize = pos+size - position(io) + 1
                    if addrsize == 4
                        m.state = RegisterState(m.state,address = read(io,Uint32))
                    elseif addrsize == 8
                        m.state = RegisterState(m.state,address = read(io,Uint64))
                    else
                        error("Unsupported target address size $addrsize")
                    end
                elseif ex_op == DWARF.DW_LNE_define_file
                    push!(m.file_names,read(io,FileEntry))
                elseif ex_op == DWARF.DW_LNE_set_discriminator
                    m.state = RegisterState(m.state,discriminator = read(io,ULEB128))
                else
                    error("Unrecognized extended opcode $ex_op")
                end
                position(io) > pos+size+1 && error("Malformed extended instruction (op=$ex_op, pos=$pos, size=$size, iopos=$(position(io)))")
            elseif op < m.header.stub.opcode_base
                # standard opcode
                if op == DWARF.DW_LNS_copy
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_copy] != 0
                        error("Malformed Instruction")
                    end
                    ret = (true,m.state)
                    m.state = RegisterState(m.state,
                        discriminator = 0,
                        basic_block = false,
                        prologue_end = false,
                        epilogue_begin = false)
                    return ret
                elseif op == DWARF.DW_LNS_advance_pc
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_advance_pc] != 1
                        error("Malformed Instruction")
                    end
                    pc_adv!(m,read(io,ULEB128).val)
                elseif op == DWARF.DW_LNS_advance_line
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_advance_line] != 1
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state,line = m.state.line + read(io,SLEB128).val)
                elseif op == DWARF.DW_LNS_set_file
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_set_file] != 1
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state,line = read(io,ULEB128))
                elseif op == DWARF.DW_LNS_set_column
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_set_column] != 1
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state,column = read(io,ULEB128))
                elseif op == DWARF.DW_LNS_negate_stmt
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_negate_stmt] != 0
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state,is_stmt = !m.state.is_stmt)
                elseif op == DWARF.DW_LNS_set_basic_block
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_set_basic_block] != 0
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state,basic_block = true)
                elseif op == DWARF.DW_LNS_const_add_pc
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_const_add_pc] != 0
                        error("Malformed Instruction")
                    end
                    pc_adv!(m,255)
                elseif op == DWARF.DW_LNS_fixed_advance_pc
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_fixed_advance_pc] != 1
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state,
                        address = m.state.address + read(io,Uint16),
                        op_index = 0)
                elseif op == DWARF.DW_LNS_set_prologue_end
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_set_prologue_end] != 0
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state, prologue_end = false)
                elseif op == DWARF.DW_LNS_set_epilogue_begin
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_set_epilogue_begin] != 0
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state, epilogue_begin = false)
                elseif op == DWARF.DW_LNS_set_epilogue_begin
                    if m.header.standard_opcode_lengths[DWARF.DW_LNS_set_epilogue_begin] != 0
                        error("Malformed Instruction")
                    end
                    m.state = RegisterState(m.state, isa = read(io,ULEB128))
                end
            else
                # special opcode
                # standard actions
                m.state = RegisterState(m.state,
                    basic_block = false,
                    prologue_end = false,
                    epilogue_begin = false,
                    discriminator = 0)
                # decode the opcode
                pc_adv!(m,op)
            end
            return (false,m.state)
        end

        function state_step(io,m::StateMachine)
            stop = false
            state = m.state
            while !stop
                (stop, state) = step(io,m)
            end
            return state
        end

        # Iterate over the line table
        immutable LineTable
            io::IO
            header::Header
            start::Int
            LineTable(io,header,start) = new(io,header,start)
            LineTable(io) = (pos=position(io);new(io,read_header(io),pos))
        end

        import Base: start, next, done

        function start(x::LineTable)
            # The header length is the number of bytes after the header length
            # The fields from the start are length (header_type), version (Uint16) and header_length(header_type)
            # plus an additional Uint32 if the header_type is Uint64
            seek(x.io,x.start + x.header.stub.header_length + 2*sizeof(header_type(x.header)) + sizeof(Uint16) +
                (header_type(x.header) == Uint64 ? sizeof(Uint32) : 0))
            StateMachine(x.header,RegisterState(x.header.stub.default_is_stmt > 0))
        end
        next(x::LineTable,m::StateMachine) = (state_step(x.io,m),m)
        done(x::LineTable,m::StateMachine) = position(x.io) > (x.start + x.header.stub.length)
    end

    import .LineTableSupport.LineTable
    export LineTable

    zero(::Type{AttributeSpecification}) = AttributeSpecification(ULEB128(BigInt(0)),ULEB128(BigInt(0)))

    immutable DIE
        tag::ULEB128
        attributes::Array{Attribute,1}
    end

    tag(x::DIE) = x.tag
    tag{T<:Attributes.GenericAttribute}(x::T) = x.name
    attributes(x::DIE) = x.attributes

    const tag_color = :blue

    tag_name(tag) = DW_TAG[tag]

    showcompact(io::IO,d::DIE) = print(io,"DIE(type ",d.tag.val,", ",length(d.attributes)," Attributes)")
    function show(io::IO, d::DIE; indent = 0, strtab = nothing)
        print_with_color(tag_color, io, tag_name(d.tag), "\n")
        for attr in d.attributes
            show(io, attr; indent = indent + 2, strtab = strtab)
        end
    end

    immutable ARTableEntry{S,T}
        segment::S
        address::T
        length::T
    end

    immutable LocationListEntry{T}
        first::T
        last::T
        data::Array{Uint8,1}
    end

    immutable LocationList{T}
        entries::Vector{LocationListEntry{T}}
    end

    function show{T}(io::IO, x::LocationListEntry{T})
        print(io,repr(x.first)," - ", repr(x.last), ": ")
        Expressions.print_expression(io, T, x.data,:NativeEndian)
        println(io)
    end

    function show(io::IO, x::LocationList)
        println(io,"Location List:")
        for e in x.entries
            show(io, e)
        end
    end

    isequal{S,T}(a::ARTableEntry{S,T},b::ARTableEntry{S,T}) = (a.segment==b.segment)&&(a.address==b.address)&&(a.length==b.length)
    =={S,T}(a::ARTableEntry{S,T},b::ARTableEntry{S,T}) = isequal(a,b)

    zero{S,T}(::Type{ARTableEntry{S,T}}) = ARTableEntry{S,T}(zero(S),zero(T),zero(T))

    const DEBUG_SECTIONS = [
        "debug_abbrev",
        "debug_aranges",
        "debug_frame",
        "debug_info",
        "debug_line",
        "debug_loc",
        "debug_macinfo",
        "debug_pubnames",
        "debug_ranges",
        "debug_str",
        "debug_types"]

    @struct immutable InitialLength
        val::Uint32
    end

    for (t,t32,t64) in ((:(DWARF.DWARFCUHeader),:(DWARF32.CUHeader),:(DWARF32.CUHeader)),
                      (:(DWARF.DWARFTUHeader),:(DWARF32.TUHeader),:(DWARF32.TUHeader)),
                      (:(DWARF.DWARFARHeader),:(DWARF32.ARHeader),:(DWARF32.ARHeader)),
                      (:(DWARF.DWARFPUBHeader),:(DWARF32.PUBHeader),:(DWARF32.PUBHeader)))
        @eval function read(io::IO,::Type{($t)},endianness::Symbol)
                # XXX: Is there a better way to do this?
                l = unpack(io,InitialLength,endianness)
                if l.val<0xfffffff0 #Is a 32bit DWARF record
                    skip(io,-sizeof(InitialLength)) #Try to rewind
                    return unpack(io,($t32),endianness)
                elseif l.val == 0xffffffff
                    return unpack(io,($t64),endianness)
                else
                    error("Unkown Compilation Unit Header Type")
                end
            end
        @eval read(io::IO,::Type{$t}) = read(io,$t,:NativeEndian)
    end

    immutable Zero
    end

    bswap(::Zero) = Zero()
    read(io::IO,::Type{Zero}) = Zero()
    zero(::Type{Zero}) = Zero()

    function size_to_inttype(size)
        if size == 0
            return Zero
        elseif size == 1
            return Uint8
        elseif size == 2
            return Uint16
        elseif size == 4
            return Uint32
        elseif size == 8
            return Uint64
        elseif size == 16
            return Uint128
        else
            error("Unsupported size unit $size")
        end
    end

    immutable ARTableSet{S,T}
        header::DWARFARHeader
        entries::Array{ARTableEntry{S,T},1}
    end

    type ARTable
        sets::Array{ARTableSet,1}
    end

    const dummy_dict = Dict{None,Array{Integer,1}}() #Since we don't have StrPack support for Parametric types

    # aranges tables
    function read(io::IO,::Type{ARTableSet},endianness::Symbol)
        header = read(io,DWARFARHeader,endianness)
        t = ARTableEntry{size_to_inttype(header.segment_size),size_to_inttype(header.address_size)}
        table = ARTableSet(header,Array(t,0))
        entry_size = StrPack.calcsize(t,dummy_dict,align_packed)
        while true
            skip(io,position(io)%entry_size) # Align to a boundary that is a multiple of the entry size
            r = unpack(io,t,dummy_dict,align_packed,endianness)
            if r==zero(t)
                break
            end
            push!(table.entries,r)
        end
        table
    end
    read(io::IO,::Type{ARTableSet}) = read(io,ARTableSet,:NativeEndian)

    # pubnames/pubtypes
    type PUBTable
        sets::Array{PUBTableSet,1}
    end

    function read{T<:PUBTableEntry}(io::IO,::Type{T},endianness::Symbol)
        offset = StrPack.endianness_converters[endianness][2](read(io,T.types[1]))
        if offset != 0
            name = strip(readuntil(io,'\0'),'\0')
        else
            name = ""
        end
        T(offset,name)
    end

    function read(io::IO,::Type{PUBTableSet},endianness::Symbol)
        header = read(io,DWARFPUBHeader,endianness)
        if typeof(header) == DWARF32.PUBHeader
            t=DWARF32.PUBTableSet(header,Array(DWARF32.PUBTableEntry,0))
        elseif typeof(header) == DWARF64.PUBHeader
            t=DWARF64.PUBTableSet(header,Array(DWARF64.PUBTableEntry,0))
        end
        while true
            entry = read(io,eltype(t.entries),endianness)
            if entry.offset == 0
                break
            end
            push!(t.entries,entry)
        end
        t
    end
    read(io::IO,::Type{PUBTableSet}) = read(io,PUBTableSet,:NativeEndian)

    immutable AbbrevTableEntry
        code::ULEB128
        tag::ULEB128
        has_children::Uint8
        attributes::Array{AttributeSpecification,1}
    end

    immutable AbbrevTableSet
        entries::Array{AbbrevTableEntry,1}
    end
    zero(::Type{AbbrevTableEntry}) = AbbrevTableEntry(ULEB128(BigInt(0)),ULEB128(BigInt(0)),UInt8(0),Array(AttributeSpecification,0))

    function read(io::IO,::Type{AbbrevTableEntry},endianness::Symbol)
        code = read(io,ULEB128)
        if code != 0
            tag = read(io,ULEB128)
            has_children = read(io,Uint8)
            ret = AbbrevTableEntry(code,tag,has_children,Array(AttributeSpecification,0))
            while true
                e = read(io,AttributeSpecification,endianness)
                if(e == zero(AttributeSpecification))
                    break
                end
                push!(ret.attributes,e)
            end
            return ret
        else
            return zero(AbbrevTableEntry)
        end
    end

    function read(io::IO,::Type{AbbrevTableSet},endianness::Symbol)
        ret = AbbrevTableSet(Array(AbbrevTableEntry,0))
        while true
            e = read(io,AbbrevTableEntry,endianness)
            if e.code == 0
                break
            end
            push!(ret.entries,e)
        end
        ret
    end

    # Assume position is right after number
    function read(io::IO,header::DWARFCUHeader,ate::AbbrevTableEntry,::Type{DIE},endianness::Symbol)
        ret = DIE(ate.tag,Array(Attribute,0))
        for a in ate.attributes
            push!(ret.attributes,read(io,header,a,endianness))
        end
        ret
    end
    function read(io::IO,header::DWARFCUHeader,ats::AbbrevTableSet,::Type{DIE},endianness::Symbol)
        num = read(io,ULEB128)
        ae = ats.entries[num.val]
        read(io,header,ae,DIE,endianness)
    end

    function read(io::IO,::Type{DIE},endianness::Symbol)
        tag = read(io,ULEB128)
        DIE(tag,Array(AttributeSpecification,0))
    end

    function read{T}(io::IO,::Type{LocationList{T}})
        ret = LocationListEntry{T}[]
        while true
            pos = position(io)
            start = read(io, T)
            last = read(io, T)
            if start == typemax(T)
                error("Base address seclection not implemented")
            elseif start == 0 && last == 0
                break
            else
                length = read(io, UInt16)
                push!(ret,LocationListEntry{T}(start,last,readbytes(io,length)))
            end
        end
        LocationList{T}(ret)
    end

    ## Tree Interface
    const zero_die = DIE(ULEB128(BigInt(0)),Array(Attribute,0))
    zero(::Type{DIE}) = zero_die

    abstract DIENode

    immutable DIETreeNode <: DIENode
        self::DIE
        children::Array{DIETreeNode,1}
        parent::DIENode
    end

    tag(x::DIETreeNode) = tag(x.self)
    attributes(x::DIETreeNode) = attributes(x.self)

    type DIETree <: DIENode
        children::Array{DIETreeNode,1}
    end

    showcompact(io::IO,node::DIETreeNode) = (print(io,"DIETreeNode(");showcompact(io,node.self);print(io,", ",length(node.children)," children)"))
    showcompact(io::IO,node::DIETree) = print(io,"DIETree(",length(node.children)," children)")

    function show(io::IO, node::DIETreeNode; indent = 0, strtab = nothing)
        show(io, node.self; indent = indent, strtab = strtab)
        for child in node.children
            show(io, child; indent = indent + 2, strtab = strtab)
        end
    end
    function show(io::IO, tree::DIETree, strtab = nothing)
        for child in tree.children
            show(io, child; strtab = strtab)
        end
    end

    const zero_node = DIETreeNode(zero(DIE),Array(DIETreeNode,0),DIETree(Array(DIETreeNode,0)))

    zero(::Type{DIETreeNode}) = zero_node
    zero(::Type{DIETree}) = DIETree(DIETreeNode[])

    function read(io::IO,header::DWARFCUHeader,ats::AbbrevTableSet,parent::Union(DIETree,DIETreeNode),::Type{DIETreeNode},endianness::Symbol)
        num = read(io,ULEB128)
        if num != 0
            ae = ats.entries[num.val]
            ret = DIETreeNode(read(io,header,ae,DIE,endianness),Array(DIETreeNode,0),parent)
            push!(parent.children,ret)
            if(ae.has_children == DW_CHILDREN_yes)
                read(io,header,ats,ret,DIETreeNode,endianness)
            else
                read(io,header,ats,parent,DIETreeNode,endianness)
            end
            return ret
        end
        zero(DIETreeNode)
    end

    include("utility.jl")
end #module

max_stars_repo_name: ambujone/DIDebug

max_issues_repo_name: ambujone/DIDebug

max_forks_repo_name: ambujone/DIDebug