package BranchTracker;

use strict;

my $oneTrueSelf;
 
sub instance {
	unless (defined $oneTrueSelf) {
		my $type = shift;
		my $this = {
			'path' => [],
			'pathStack' => [],
		};
		$oneTrueSelf = bless $this, $type;
	}

	return $oneTrueSelf;
}

sub push($$) {
	my( $self, @elements ) = @_;
	push @{ $self->{ 'path' } }, @elements;
}

sub getPathAsArray($) {
	my $self = shift;
	return @{ $self->{ 'path' } };
}

sub save($) {
	my $self = shift;
	my $currentPath = $self->{ 'path' };
	
	# array copy is necessary
	push @{ $self->{ 'pathStack' } }, [ @{ $currentPath } ];
}

sub restore($) {
	my $self = shift;
	my $newPath = pop @{ $self->{ 'pathStack' } };
	$self->{ 'path' } = $newPath;
}

1;
package BranchTracker;

use strict;

my $oneTrueSelf;
 
sub instance {
	unless (defined $oneTrueSelf) {
		my $type = shift;
		my $this = {
			'path' => [],
			'pathStack' => [],
		};
		$oneTrueSelf = bless $this, $type;
	}

	return $oneTrueSelf;
}

sub push($$) {
	my( $self, @elements ) = @_;
	push @{ $self->{ 'path' } }, @elements;
}

sub getPathAsArray($) {
	my $self = shift;
	return @{ $self->{ 'path' } };
}

sub save($) {
	my $self = shift;
	my $currentPath = $self->{ 'path' };
	
	# array copy is necessary
	push @{ $self->{ 'pathStack' } }, [ @{ $currentPath } ];
}

sub restore($) {
	my $self = shift;
	my $newPath = pop @{ $self->{ 'pathStack' } };
	$self->{ 'path' } = $newPath;
}

1;
