public function parse() {
        global $argv;

        $options = array();
        $parameters = array();
        $argc = count( $argv );
        $paramCount = count( $this->parameters );
        
        //get parameters
        if( $argc - 1 < $paramCount ) {
            throw new \Exception("The command requires $paramCount parameters.");
        }
        
        //last items are the params
        for( $i = $paramCount - 1; $i >= 0; $i-- ) {
            $this->abstractParameters[$this->parameters[$i]] = $argv[$argc - $i - 1];
        }
        
        //go through each arg
        for( $i = 1; $i < $argc - $paramCount; $i++ ) {
            $arg = $argv[$i];
            
            //cannot start without a switch
            if( !$this->isOption( $arg ) ) {
                throw new \Exception("Invalid argument \"$arg\".");
            }
            
            //check if it's a valid option
            $option = $arg[1];

            if( $this->isParam( $option ) ) {
                //the arg stands on its own, such as -f, not -ffile.txt
                //set next as its value, move $i ahead
                if( $this->isSolitary( $arg ) ) {
                    //last item
                    if( $i == $argc - $paramCount - 1 ) {
                        throw new \Exception("Parameter does not follow the option \"$option\".");
                    }
                    
                    $this->abstractOptions[$option] = $argv[$i+1];
                    $i++;
                } else {
                    $this->abstractOptions[$option] = substr( $arg, 2 );
                }
            } else if( $this->isSwitch( $option ) ) {
                //loop through all switches in the param
                for( $i = 1; $i < strlen( $param ) - 1; $i++ ) {
                    $s = $arg[$i];
                    
                    //not a switch
                    if( !$this->isSwitch( $arg[$i] ) ) {
                        throw new \Exception("An invalid switch \"$s\" was provided.");
                    }
                    
                    $this->abstractOptions[$s] = true;
                }
            }
        }
    }