Understanding Solidity Libraries using Solidity Docs code example

I was going through this code (see code below) about how to use libraries in solidity docs : https://solidity.readthedocs.io/en/v0.4.24/contracts.html?highlight=library#libraries and there are some things I really don't understand.

pragma solidity ^0.4.16;

library BigInt {
struct bigint {
uint[] limbs;
}

function fromUint(uint x) internal pure returns (bigint r) {
r.limbs = new uint[](1);
r.limbs = x;
}

function add(bigint _a, bigint _b) internal pure returns (bigint r) {
r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length));
//I understand that in the line above we are tying to get the array with
//the greatest length then initializing a new r.limbs array with that
//length. Why is this being done?

uint carry = 0;
//What is the purpose of this "uint carry"?

for (uint i = 0; i < r.limbs.length; ++i) {
uint a = limb(_a, i);
uint b = limb(_b, i);// why are we running this function?
// What is the significance of the value we get from this
// function? limb()
r.limbs[i] = a + b + carry;
if (a + b < a || (a + b == uint(-1) && carry > 0))
carry = 1;
else
carry = 0;
}//Why is Carry = 1 or zero what is the significance?
if (carry > 0) {
// too bad, we have to add a limb

uint[] memory newLimbs = new uint[](r.limbs.length + 1);
for (i = 0; i < r.limbs.length; ++i)
newLimbs[i] = r.limbs[i];
newLimbs[i] = carry;
r.limbs = newLimbs;
}// What exactly is a limb? Is it an empty array slot? Because from
}// my understanding of the code above all that's happening is the
//addition of the array length but no value is passed to the new slot.

function limb(bigint _a, uint _limb) internal pure returns (uint) {
return _limb < _a.limbs.length ? _a.limbs[_limb] : 0;
}// What does the last line in this function mean?
// What is the use of the question mark?
// What is the use of the colon?

function max(uint a, uint b) private pure returns (uint) {
return a > b ? a : b;
}
}

contract C {
using BigInt for BigInt.bigint;

function f() public pure {
var x = BigInt.fromUint(7);
var y = BigInt.fromUint(uint(-1));
var z = x.add(y);
}
}
1. Is it a method to store big integers using arrays in solidity? I am asking because the library name and the struct name are both BigInt and the array in the first function has a length of 1... I mean why not just make it an Unsigned Integer?
2. In the library a struct bigint is defined, then in the functions bigint is used as a value type. E.g in the first function when defining the returns parameter ***returns (bigint r). Why is it being done like this?
3. Then, in the second function, this is where I get totally lost. I have so many questions I have commented them in the code...

Thank you in advance.