/// <exception cref="NGit.Api.Errors.GitAPIException"></exception>
        public override Repository Call()
        {
            CheckCallable();
            if (path == null || path.Length == 0)
            {
                throw new ArgumentException(JGitText.Get().pathNotConfigured);
            }
            if (uri == null || uri.Length == 0)
            {
                throw new ArgumentException(JGitText.Get().uriNotConfigured);
            }
            try
            {
                if (SubmoduleExists())
                {
                    throw new JGitInternalException(MessageFormat.Format(JGitText.Get().submoduleExists
                                                                         , path));
                }
            }
            catch (IOException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            string resolvedUri;

            try
            {
                resolvedUri = SubmoduleWalk.GetSubmoduleRemoteUrl(repo, uri);
            }
            catch (IOException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            // Clone submodule repository
            FilePath     moduleDirectory = SubmoduleWalk.GetSubmoduleDirectory(repo, path);
            CloneCommand clone           = Git.CloneRepository();

            Configure(clone);
            clone.SetDirectory(moduleDirectory);
            clone.SetURI(resolvedUri);
            if (monitor != null)
            {
                clone.SetProgressMonitor(monitor);
            }
            Repository subRepo = clone.Call().GetRepository();
            // Save submodule URL to parent repository's config
            StoredConfig config = repo.GetConfig();

            config.SetString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, ConfigConstants.
                             CONFIG_KEY_URL, resolvedUri);
            try
            {
                config.Save();
            }
            catch (IOException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            // Save path and URL to parent repository's .gitmodules file
            FileBasedConfig modulesConfig = new FileBasedConfig(new FilePath(repo.WorkTree, Constants
                                                                             .DOT_GIT_MODULES), repo.FileSystem);

            try
            {
                modulesConfig.Load();
                modulesConfig.SetString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, ConfigConstants
                                        .CONFIG_KEY_PATH, path);
                modulesConfig.SetString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, ConfigConstants
                                        .CONFIG_KEY_URL, uri);
                modulesConfig.Save();
            }
            catch (IOException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            catch (ConfigInvalidException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            AddCommand add = new AddCommand(repo);

            // Add .gitmodules file to parent repository's index
            add.AddFilepattern(Constants.DOT_GIT_MODULES);
            // Add submodule directory to parent repository's index
            add.AddFilepattern(path);
            try
            {
                add.Call();
            }
            catch (NoFilepatternException e)
            {
                throw new JGitInternalException(e.Message, e);
            }
            return(subRepo);
        }