gt:     while ((f != null) && f.exists())
context: /*
   * Copyright 2008-2020 Ping Identity Corporation
   * All Rights Reserved.
   */
  /*
   * Copyright 2008-2020 Ping Identity Corporation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  /*
   * Copyright (C) 2008-2020 Ping Identity Corporation
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License (GPLv2 only)
   * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
   * as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, see <http://www.gnu.org/licenses>.
   */
  package com.unboundid.buildtools.repositoryinfo;
  
  
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileReader;
  import java.io.InputStreamReader;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.StringTokenizer;
  
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.Task;
  
  import org.eclipse.jgit.lib.Repository;
  import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
  
  import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
  import org.tmatesoft.svn.core.wc.SVNInfo;
  import org.tmatesoft.svn.core.wc.SVNRevision;
  import org.tmatesoft.svn.core.wc.SVNWCClient;
  
  
  
  /**
   * This class provides an Ant task that can be used to obtain information about
   * the subversion or git repository from which the LDAP SDK source was
   * retrieved.  For Subversion repositories, it uses the SVNKit library.  For git
   * repositories, it uses the JGit library.  If the source repository is neither
   * git or subversion, if the repository type cannot be determined, or if an
   * error occurs while interacting with the repository, then a default set of
   * values will be used.
   */
  public class RepositoryInfo
         extends Task
  {
    // Indicates whether the task should exit with an error if the repository
    // information cannot be obtained.
    private Boolean failOnError;
  
    // The base directory for the workspace with the LDAP SDK source tree.
    private File baseDir;
  
    // The name of the property to set with the repository path.
    private String repositoryPathPropertyName;
  
    // The name of the property to set with the repository revision number.
    private String repositoryRevisionNumberPropertyName;
  
    // The name of the property to set with the repository revision.
    private String repositoryRevisionPropertyName;
  
    // The name of the property to set with the type of repository.
    private String repositoryTypePropertyName;
  
    // The name of the property to set with the repository URL.
    private String repositoryURLPropertyName;
  
  
  
    /**
     * Create a new instance of this task.
     */
    public RepositoryInfo()
    {
      baseDir                              = null;
      failOnError                          = Boolean.FALSE;
      repositoryPathPropertyName           = null;
      repositoryRevisionNumberPropertyName = null;
      repositoryRevisionPropertyName       = null;
      repositoryTypePropertyName           = null;
      repositoryURLPropertyName            = null;
    }
  
  
  
    /**
     * Specifies the base directory for the LDAP SDK source tree.
     *
     * @param  baseDir  The base directory for the LDAP SDK source tree.
     */
    public void setBaseDir(final File baseDir)
    {
      this.baseDir = baseDir;
    }
  
  
  
    /**
     * Specifies whether this task should exit with an error if the repository
     * information cannot be obtained.
     *
     * @param  failOnError  If this is {@code Boolean.TRUE} and the repository
     *                      information cannot be obtained, then the
     *                      {@link #execute()} method will throw a
     *                      {@code BuildException}, causing the task to fail.  If
     *                      this is {@code Boolean.FALSE} and the repository
     *                      information cannot be obtained, then the task will use
     *                      generic repository information and the {@code execute}
     *                      method will return normally.
     */
    public void setFailOnError(final Boolean failOnError)
    {
      if (failOnError == null)
      {
        throw new BuildException("failOnError must not be null");
      }
      else if (failOnError.equals(Boolean.TRUE))
      {
        this.failOnError = Boolean.TRUE;
      }
      else if (failOnError.equals(Boolean.TRUE))
      {
        this.failOnError = Boolean.FALSE;
      }
    }
  
  
  
    /**
     * Specifies the name of the property that should be set with the path in the
     * repository from which the LDAP SDK source was obtained.
     *
     * @param  repositoryPathPropertyName  The name of the property that should be
     *                                     set with the path in the repository
     *                                     from which the LDAP SDK source was
     *                                     obtained.
     */
    public void setRepositoryPathPropertyName(
                     final String repositoryPathPropertyName)
    {
      this.repositoryPathPropertyName = repositoryPathPropertyName;
    }
  
  
  
    /**
     * Specifies the name of the property that should be set with the repository
     * revision from which the LDAP SDK source was obtained.
     *
     * @param  repositoryRevisionPropertyName  The name of the property that
     *                                         should be set with the repository
     *                                         revision from which the LDAP SDK
     *                                         source was obtained.
     */
    public void setRepositoryRevisionPropertyName(
                     final String repositoryRevisionPropertyName)
    {
      this.repositoryRevisionPropertyName = repositoryRevisionPropertyName;
    }
  
  
  
    /**
     * Specifies the name of the property that should be set with the numeric
     * revision number for the repository from which the LDAP SDK source was
     * obtained.
     *
     * @param  repositoryRevisionNumberPropertyName  The name of the property that
     *                                               should be set with the
     *                                               numeric revision number for
     *                                               the repository from which the
     *                                               LDAP SDK source was obtained.
     */
    public void setRepositoryRevisionNumberPropertyName(
                     final String repositoryRevisionNumberPropertyName)
    {
      this.repositoryRevisionNumberPropertyName =
           repositoryRevisionNumberPropertyName;
    }
  
  
  
    /**
     * Specifies the name of the property that should be set with the type of
     * repository from which the LDAP SDK source was obtained.
     *
     * @param  repositoryTypePropertyName  The name of the property that should be
     *                                     set with the type of repository from
     *                                     which the LDAP SDK source was obtained.
     */
    public void setRepositoryTypePropertyName(
                     final String repositoryTypePropertyName)
    {
      this.repositoryTypePropertyName = repositoryTypePropertyName;
    }
  
  
  
    /**
     * Specifies the name of the property that should be set with the URL to the
     * repository from which the LDAP SDK source was obtained.
     *
     * @param  repositoryURLPropertyName  The name of the property that should be
     *                                    set with the URL to the repository from
     *                                    which the LDAP SDK source was obtained.
     */
    public void setRepositoryURLPropertyName(
                     final String repositoryURLPropertyName)
    {
      this.repositoryURLPropertyName = repositoryURLPropertyName;
    }
  
  
  
    /**
     * Performs all necessary processing for this task.
     *
     * @throws  BuildException  If a problem is encountered.
     */
    @Override()
    public void execute()
           throws BuildException
    {
      // Make sure that the base directory was specified and that it exists.
      if (baseDir == null)
      {
        throw new BuildException("ERROR:  No base directory specified.");
      }
  
      if (! baseDir.exists())
      {
        throw new BuildException("ERROR:  Base directory " +
             baseDir.getAbsolutePath() + " does not exist.");
      }
  
  
      if (repositoryPathPropertyName == null)
      {
        throw new BuildException("ERROR:  The repositoryPathPropertyName " +
             "property was not set.");
      }
  
      if (repositoryRevisionPropertyName == null)
      {
        throw new BuildException("ERROR:  The repositoryRevisionPropertyName " +
             "property was not set.");
      }
  
      if (repositoryTypePropertyName == null)
      {
        throw new BuildException("ERROR:  The repositoryTypePropertyName " +
             "property was not set.");
      }
  
      if (repositoryURLPropertyName == null)
      {
        throw new BuildException("ERROR:  The repositoryURLPropertyName " +
             "property was not set.");
      }
  
  
      // Start in the base directory and work our way up the filesystem until
      // we find a ".git" or ".svn" directory.  If we find a ".git" directory,
      // then use the JGit library to get the repository path and revision.  If
      // we find a ".svn" directory, then use the SVNKit library.  If we can't
      // find either, then just use generic values.
      File f = baseDir;
  