This file is indexed.

/usr/include/arc/data/DataPoint.h is in nordugrid-arc-dev 5.0.5-1ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
// -*- indent-tabs-mode: nil -*-

// Summary page for libarcdata doxygen module
// Enclosed in Arc namespace so automatic linking to other classes works
namespace Arc {
/**
 * \defgroup data ARC data library (libarcdata)
 *
 * libarcdata is a library for access to data on the Grid. It provides a
 * uniform interface to several types of Grid storage and catalogs using
 * various protocols. The protocols usable on a given system depend on the
 * packages installed. The interface can be used to read, write, list, transfer
 * and delete data to and from storage systems and catalogs.
 *
 * The library uses ARC's dynamic plugin mechanism to load plugins for
 * specific protocols only when required at runtime. These plugins are
 * called Data Manager Components (DMCs). The DataHandle class takes care of
 * automatically loading the required DMC at runtime to create a DataPoint object
 * representing a resource accessible through a given protocol. DataHandle
 * should always be used instead of DataPoint directly.
 *
 * To create a new DMC for a protocol which is not yet supported see the
 * instruction and examples in the DataPoint class documentation. This
 * documentation also gives a complete overview of the interface.
 *
 * The following protocols are currently supported in standard distributions
 * of ARC.
 *
 * - File (%file://) - Regular local file system.
 *
 * - GridFTP (gsiftp://) - GridFTP is essentially the FTP protocol with GSI
 * security. Regular FTP can also be used.
 *
 * - HTTP(S/G) (%http://) - Hypertext Transfer Protocol. HTTP over SSL (HTTPS)
 * and HTTP over GSI (HTTPG) are also supported.
 *
 * - LDAP (ldap://) - Lightweight Directory Access Protocol. LDAP is used in
 * grids mainly to store information about grid services or resources rather
 * than to store data itself.
 *
 * - SRM (srm://) - The Storage Resource Manager (SRM) protocol allows access
 * to data distributed across physical storage through a unified namespace
 * and management interface.
 *
 * - XRootd (root://) - Protocol for data access across large scale storage
 * clusters. More information can be found at http://xrootd.slac.stanford.edu/
 *
 * - ACIX (acix://) - The ARC Cache Index contains locations of cached files
 * in ARC CE caches.
 *
 * DataMover provides a simple high-level interface to copy files. Fine-grained
 * control over data transfer is shown in the following example:
 *
 * \include partial_copy.cpp
 *
 * And the same example in python
 *
 * \include partial_copy.py
 */
} // namespace Arc

#ifndef __ARC_DATAPOINT_H__
#define __ARC_DATAPOINT_H__

#include <list>
#include <set>
#include <string>

#include <arc/DateTime.h>
#include <arc/URL.h>
#include <arc/UserConfig.h>
#include <arc/data/DataStatus.h>
#include <arc/data/FileInfo.h>
#include <arc/data/URLMap.h>
#include <arc/loader/Loader.h>
#include <arc/loader/Plugin.h>

namespace Arc {

  class Logger;
  class DataBuffer;
  class DataCallback;
  class XMLNode;
  class CheckSum;

  /// A DataPoint represents a data resource and is an abstraction of a URL.
  /**
   * DataPoint uses ARC's Plugin mechanism to dynamically load the required
   * Data Manager Component (DMC) when necessary. A DMC typically defines a
   * subclass of DataPoint (e.g. DataPointHTTP) and is responsible for a
   * specific protocol (e.g. http). DataPoints should not be used directly,
   * instead the DataHandle wrapper class should be used, which automatically
   * loads the correct DMC. Examples of how to use DataPoint methods are shown
   * in the DataHandle documentation.
   *
   * DataPoint defines methods for access to the data resource. To transfer
   * data between two DataPoints, DataMover::Transfer() can be used.
   *
   * There are two subclasses of DataPoint, DataPointDirect and DataPointIndex.
   * None of these three classes can be instantiated directly.
   * DataPointDirect and its subclasses handle "physical" resources through
   * protocols such as file, http and gsiftp. These classes implement methods
   * such as StartReading() and StartWriting(). DataPointIndex and its
   * subclasses handle resources such as indexes and catalogs and implement
   * methods like Resolve() and PreRegister().
   *
   * When creating a new DMC, a subclass of either DataPointDirect or
   * DataPointIndex should be created, and the appropriate methods implemented.
   * DataPoint itself has no direct external dependencies, but plugins may
   * rely on third-party components. The new DMC must also add itself to the
   * list of available plugins and provide an Instance() method which returns
   * a new instance of itself, if the supplied arguments are valid for the
   * protocol. Here is an example skeleton implementation of a new DMC for
   * protocol MyProtocol which represents a physical resource accessible through
   * protocol my://
   * \include DataPointMyProtocol.cpp
   *
   * \ingroup data
   * \headerfile DataPoint.h arc/data/DataPoint.h
   */
  class DataPoint
    : public Plugin {
  public:

    /// Callback for use in 3rd party transfer.
    /**
     * Will be called periodically during the transfer with the number of bytes
     * transferred so far.
     * \param bytes_transferred the number of bytes transferred so far
     */
    typedef void(*Callback3rdParty)(unsigned long long int bytes_transferred);

    /// Describes the latency to access this URL
    /**
     * For now this value is one of a small set specified
     * by the enumeration. In the future with more sophisticated
     * protocols or information it could be replaced by a more
     * fine-grained list of possibilities such as an int value.
     */
    enum DataPointAccessLatency {
      /// URL can be accessed instantly
      ACCESS_LATENCY_ZERO,
      /// URL has low (but non-zero) access latency, for example staged from disk
      ACCESS_LATENCY_SMALL,
      /// URL has a large access latency, for example staged from tape
      ACCESS_LATENCY_LARGE
    };

    /// Describes type of information about URL to request
    enum DataPointInfoType {
      INFO_TYPE_MINIMAL = 0,  ///< Whatever protocol can get with no additional effort.
      INFO_TYPE_NAME = 1,     ///< Only name of object (relative).
      INFO_TYPE_TYPE = 2,     ///< Type of object - currently file or dir.
      INFO_TYPE_TIMES = 4,    ///< Timestamps associated with object.
      INFO_TYPE_CONTENT = 8,  ///< Metadata describing content, like size, checksum, etc.
      INFO_TYPE_ACCESS = 16,  ///< Access control - ownership, permission, etc.
      INFO_TYPE_STRUCT = 32,  ///< Fine structure - replicas, transfer locations, redirections.
      INFO_TYPE_REST = 64,    ///< All the other parameters.
      INFO_TYPE_ALL = 127     ///< All the parameters.
    };

    /// Perform third party transfer.
    /**
     * Credentials are delegated to the destination and it pulls data from the
     * source, i.e. data flows directly between source and destination instead
     * of through the client. A callback function can be supplied to monitor
     * progress. This method blocks until the transfer is complete. It is
     * static because third party transfer requires different DMC plugins than
     * those loaded by DataHandle for the same protocol. The third party
     * transfer plugins are loaded internally in this method.
     * \param source Source URL to pull data from
     * \param destination Destination URL which pulls data to itself
     * \param usercfg Configuration information
     * \param callback Optional monitoring callback
     * \return outcome of transfer
     */
    static DataStatus Transfer3rdParty(const URL& source, const URL& destination,
                                       const UserConfig& usercfg, Callback3rdParty callback = NULL);

    /// Destructor.
    virtual ~DataPoint();

    /// Returns the URL that was passed to the constructor.
    virtual const URL& GetURL() const;

    /// Returns the UserConfig that was passed to the constructor.
    virtual const UserConfig& GetUserConfig() const;

    /// Assigns new URL.
    /**
     * The main purpose of this method is to reuse an existing connection for
     * accessing a different object on the same server. The DataPoint
     * implementation does not have to implement this method. If the supplied
     * URL is not suitable or method is not implemented false is returned.
     * \param url New URL
     * \return true if switching to new URL is supported and succeeded
     */
    virtual bool SetURL(const URL& url);

    /// Returns a string representation of the DataPoint.
    virtual std::string str() const;

    /// Is DataPoint valid?
    virtual operator bool() const;

    /// Is DataPoint valid?
    virtual bool operator!() const;

    /// Prepare DataPoint for reading.
    /**
     * This method should be implemented by protocols which require
     * preparation or staging of physical files for reading. It can act
     * synchronously or asynchronously (if protocol supports it). In the
     * first case the method will block until the file is prepared or the
     * specified timeout has passed. In the second case the method can
     * return with a ReadPrepareWait status before the file is prepared.
     * The caller should then wait some time (a hint from the remote service
     * may be given in wait_time) and call PrepareReading() again to poll for
     * the preparation status, until the file is prepared. In this case it is
     * also up to the caller to decide when the request has taken too long
     * and if so cancel it by calling FinishReading().
     * When file preparation has finished, the physical file(s)
     * to read from can be found from TransferLocations().
     * \param timeout If non-zero, this method will block until either the
     * file has been prepared successfully or the timeout has passed. A zero
     * value means that the caller would like to call and poll for status.
     * \param wait_time If timeout is zero (caller would like asynchronous
     * operation) and ReadPrepareWait is returned, a hint for how long to wait
     * before a subsequent call may be given in wait_time.
     * \return Status of the operation
     */
    virtual DataStatus PrepareReading(unsigned int timeout,
                                      unsigned int& wait_time);

    /// Prepare DataPoint for writing.
    /**
     * This method should be implemented by protocols which require
     * preparation of physical files for writing. It can act
     * synchronously or asynchronously (if protocol supports it). In the
     * first case the method will block until the file is prepared or the
     * specified timeout has passed. In the second case the method can
     * return with a WritePrepareWait status before the file is prepared.
     * The caller should then wait some time (a hint from the remote service
     * may be given in wait_time) and call PrepareWriting() again to poll for
     * the preparation status, until the file is prepared. In this case it is
     * also up to the caller to decide when the request has taken too long
     * and if so cancel or abort it by calling FinishWriting(true).
     * When file preparation has finished, the physical file(s)
     * to write to can be found from TransferLocations().
     * \param timeout If non-zero, this method will block until either the
     * file has been prepared successfully or the timeout has passed. A zero
     * value means that the caller would like to call and poll for status.
     * \param wait_time If timeout is zero (caller would like asynchronous
     * operation) and WritePrepareWait is returned, a hint for how long to wait
     * before a subsequent call may be given in wait_time.
     * \return Status of the operation
     */
    virtual DataStatus PrepareWriting(unsigned int timeout,
                                      unsigned int& wait_time);

    /// Start reading data from URL.
    /**
     * A separate thread to transfer data will be created. No other
     * operation can be performed while reading is in progress. Progress of the
     * transfer should be followed using the DataBuffer object.
     * \param buffer operation will use this buffer to put
     * information into. Should not be destroyed before StopReading()
     * was called and returned. If StopReading() is not called explicitly
     * to release buffer it will be released in destructor of DataPoint
     * which also usually calls StopReading().
     * \return success if a thread was successfully started to start reading
     */
    virtual DataStatus StartReading(DataBuffer& buffer) = 0;

    /// Start writing data to URL.
    /**
     * A separate thread to transfer data will be created. No other
     * operation can be performed while writing is in progress. Progress of the
     * transfer should be followed using the DataBuffer object.
     * \param buffer operation will use this buffer to get
     * information from. Should not be destroyed before StopWriting()
     * was called and returned. If StopWriting() is not called explicitly
     * to release buffer it will be released in destructor of DataPoint
     * which also usually calls StopWriting().
     * \param space_cb callback which is called if there is not
     * enough space to store data. May not implemented for all
     * protocols.
     * \return success if a thread was successfully started to start writing
     */
    virtual DataStatus StartWriting(DataBuffer& buffer,
                                    DataCallback *space_cb = NULL) = 0;

    /// Stop reading.
    /**
     * Must be called after corresponding StartReading() method,
     * either after all data is transferred or to cancel transfer.
     * Use buffer object to find out when data is transferred.
     * \return outcome of stopping reading (not outcome of transfer itself)
     */
    virtual DataStatus StopReading() = 0;

    /// Stop writing.
    /**
     * Must be called after corresponding StartWriting() method,
     * either after all data is transferred or to cancel transfer.
     * Use buffer object to find out when data is transferred.
     * \return outcome of stopping writing (not outcome of transfer itself)
     */
    virtual DataStatus StopWriting() = 0;

    /// Finish reading from the URL.
    /**
     * Must be called after transfer of physical file has completed if
     * PrepareReading() was called, to free resources, release requests that
     * were made during preparation etc.
     * \param error If true then action is taken depending on the error.
     * \return success if source was released properly
     */
    virtual DataStatus FinishReading(bool error = false);

    /// Finish writing to the URL.
    /**
     * Must be called after transfer of physical file has completed if
     * PrepareWriting() was called, to free resources, release requests that
     * were made during preparation etc.
     * \param error if true then action is taken depending on the error, for
     * example cleaning the file from the storage
     * \return success if destination was released properly
     */
    virtual DataStatus FinishWriting(bool error = false);

    /// Query the DataPoint to check if object is accessible.
    /**
     * If check_meta is true this method will also try to provide meta
     * information about the object. Note that for many protocols an access
     * check also provides meta information and so check_meta may have no
     * effect.
     * \param check_meta If true then the method will try to retrieve meta data
     * during the check.
     * \return success if the object is accessible by the caller.
     */
    virtual DataStatus Check(bool check_meta) = 0;

    /// Remove/delete object at URL.
    virtual DataStatus Remove() = 0;

    /// Retrieve information about this object
    /**
     * If the DataPoint represents a directory or something similar,
     * information about the object itself and not its contents will
     * be obtained.
     * \param file will contain object name and requested attributes.
     * There may be more attributes than requested. There may be less
     * if object can't provide particular information.
     * \param verb defines attribute types which method must try to
     * retrieve. It is not a failure if some attributes could not
     * be retrieved due to limitation of protocol or access control.
     * \return success if any information could be retrieved
     */
    virtual DataStatus Stat(FileInfo& file, DataPointInfoType verb = INFO_TYPE_ALL) = 0;

    /// Retrieve information about several DataPoints.
    /**
     * If a DataPoint represents a directory or something similar,
     * information about the object itself and not its contents will
     * be obtained. This method can use bulk operations if the protocol
     * supports it. The protocols and hosts of all the DataPoints in
     * urls must be the same and the same as this DataPoint's protocol
     * and host. This method can be called on any of the urls, for
     * example urls.front()->Stat(files, urls);
     * Calling this method with an empty list of urls returns success if
     * the protocol supports bulk Stat, and an error if it does not and this
     * can be used as a check for bulk support.
     * \param files will contain objects' names and requested attributes.
     * There may be more attributes than requested. There may be less
     * if objects can't provide particular information. The order of this
     * list matches the order of urls. If a stat of any url fails then
     * the corresponding FileInfo in this list will evaluate to false.
     * \param urls list of DataPoints to stat. Protocols and hosts must
     * match and match this DataPoint's protocol and host.
     * \param verb defines attribute types which method must try to
     * retrieve. It is not a failure if some attributes could not
     * be retrieved due to limitation of protocol or access control.
     * \return success if any information could be retrieved for any DataPoint
     */
    virtual DataStatus Stat(std::list<FileInfo>& files,
                            const std::list<DataPoint*>& urls,
                            DataPointInfoType verb = INFO_TYPE_ALL) = 0;

    /// List hierarchical content of this object.
    /**
     * If the DataPoint represents a directory or something similar its
     * contents will be listed and put into files. If the DataPoint is file-
     * like an error will be returned.
     * \param files will contain list of file names and requested
     * attributes. There may be more attributes than requested. There
     * may be less if object can't provide particular information.
     * \param verb defines attribute types which method must try to
     * retrieve. It is not a failure if some attributes could not
     * be retrieved due to limitation of protocol or access control.
     * \return success if DataPoint is a directory-like object and could be
     * listed.
     */
    virtual DataStatus List(std::list<FileInfo>& files, DataPointInfoType verb = INFO_TYPE_ALL) = 0;

    /// Create a directory.
    /**
     * If the protocol supports it, this method creates the last directory
     * in the path to the URL. It assumes the last component of the path is a
     * file-like object and not a directory itself, unless the path ends in a
     * directory separator. If with_parents is true then all missing parent
     * directories in the path will also be created. The access control on the
     * new directories is protocol-specific and may vary depending on protocol.
     * \param with_parents If true then all missing directories in the path
     * are created
     * \return success if the directory was created
     */
    virtual DataStatus CreateDirectory(bool with_parents=false) = 0;

    /// Rename a URL.
    /**
     * This method renames the file or directory specified in the constructor
     * to the new name specified in newurl. It only performs namespace
     * operations using the paths of the two URLs and in general ignores any
     * differences in protocol and host between them. It is assumed that checks
     * that the URLs are consistent are done by the caller of this method.
     * This method does not do any data transfer and is only implemented for
     * protocols which support renaming as an atomic namespace operation.
     * \param newurl The new name for the URL
     * \return success if the object was renamed
     */
    virtual DataStatus Rename(const URL& newurl) = 0;

    /// Allow/disallow DataPoint to read data out of order.
    /**
     * If set to true then data may be read from source out of order or in
     * parallel from multiple threads. For a transfer between two DataPoints
     * this should only be set to true if WriteOutOfOrder() returns true for
     * the destination. Only certain protocols support this option.
     * \param v true if allowed (default is false).
     */
    virtual void ReadOutOfOrder(bool v) = 0;

    /// Returns true if DataPoint supports receiving data out of order during writing.
    virtual bool WriteOutOfOrder() = 0;

    /// Allow/disallow additional checks on a source DataPoint before transfer
    /**
     * If set to true, extra checks will be performed in DataMover::Transfer()
     * before data transfer starts on for example existence of the source file
     * (and probably other checks too).
     * \param v true if allowed (default is true). */
    virtual void SetAdditionalChecks(bool v) = 0;

    /// Returns true unless SetAdditionalChecks() was set to false.
    virtual bool GetAdditionalChecks() const = 0;

    /// Allow/disallow heavy security (data encryption) during data transfer.
    /**
     * \param v true if allowed (default depends on protocol).
     */
    virtual void SetSecure(bool v) = 0;

    /// Returns true if heavy security during data transfer is allowed.
    virtual bool GetSecure() const = 0;

    /// Set passive transfers for FTP-like protocols.
    /**
     * \param v true if passive should be used.
     */
    virtual void Passive(bool v) = 0;

    /// Returns reason of transfer failure, as reported by callbacks.
    /**
     * This could be different from the failure returned by the methods themselves.
     */
    virtual DataStatus GetFailureReason(void) const;

    /// Set range of bytes to retrieve.
    /**
     * Default values correspond to whole file. Both start and end bytes are
     * included in the range, i.e. start - end + 1 bytes will be read.
     * \param start byte to start from
     * \param end byte to end at
     */
    virtual void Range(unsigned long long int start = 0,
                       unsigned long long int end = 0) = 0;

    /// Resolves index service URL into list of ordinary URLs.
    /**
     * Also obtains meta information about the file if possible. Resolve should
     * be called for both source and destination URLs before a transfer. If
     * source is true an error is returned if the file does not exist.
     * \param source true if DataPoint object represents source of information.
     * \return success if DataPoint was successfully resolved
     */
    virtual DataStatus Resolve(bool source) = 0;

    /// Resolves several index service URLs.
    /**
     * Can use bulk calls if protocol allows. The protocols and hosts of all
     * the DataPoints in urls must be the same and the same as this DataPoint's
     * protocol and host. This method can be called on any of the urls, for
     * example urls.front()->Resolve(true, urls);
     * \param source true if DataPoint objects represent source of information
     * \param urls List of DataPoints to resolve. Protocols and hosts must
     * match and match this DataPoint's protocol and host.
     * \return success if any DataPoint was successfully resolved
     */
    virtual DataStatus Resolve(bool source, const std::list<DataPoint*>& urls) = 0;

    /// Returns true if file is registered in indexing service (only known after Resolve())
    virtual bool Registered() const = 0;

    /// Index service pre-registration.
    /**
     * This function registers the physical location of a file into an indexing
     * service. It should be called *before* the actual transfer to that
     * location happens.
     * \param replication if true, the file is being replicated between two
     * locations registered in the indexing service under the same name.
     * \param force if true, perform registration of a new file even if it
     * already exists. Should be used to fix failures in indexing service.
     * \return success if pre-registration succeeded
     */
    virtual DataStatus PreRegister(bool replication, bool force = false) = 0;

    /// Index service post-registration.
    /**
     * Used for same purpose as PreRegister. Should be called after actual
     * transfer of file successfully finished to finalise registration in an
     * index service.
     * \param replication if true, the file is being replicated between two
     * locations registered in Indexing Service under the same name.
     * \return success if post-registration succeeded
     */
    virtual DataStatus PostRegister(bool replication) = 0;

    /// Index service pre-unregistration.
    /**
     * Should be called if file transfer failed. It removes changes made
     * by PreRegister().
     * \param replication if true, the file is being replicated between two
     * locations registered in Indexing Service under the same name.
     * \return success if pre-unregistration succeeded
     */
    virtual DataStatus PreUnregister(bool replication) = 0;

    /// Index service unregistration.
    /**
     * Remove information about file registered in indexing service.
     * \param all if true, information about file itself is (LFN) is
     * removed. Otherwise only particular physical instance in
     * CurrentLocation() is unregistered.
     * \return success if unregistration succeeded
     */
    virtual DataStatus Unregister(bool all) = 0;

    /// Check if meta-information 'size' is available.
    virtual bool CheckSize() const;

    /// Set value of meta-information 'size'.
    virtual void SetSize(const unsigned long long int val);

    /// Get value of meta-information 'size'.
    virtual unsigned long long int GetSize() const;

    /// Check if meta-information 'checksum' is available.
    virtual bool CheckCheckSum() const;

    /// Set value of meta-information 'checksum'.
    virtual void SetCheckSum(const std::string& val);

    /// Get value of meta-information 'checksum'.
    virtual const std::string& GetCheckSum() const;

    /// Default checksum type (varies by protocol)
    virtual const std::string DefaultCheckSum() const;

    /// Check if meta-information 'modification time' is available.
    virtual bool CheckModified() const;

    /// Set value of meta-information 'modification time'.
    virtual void SetModified(const Time& val);

    /// Get value of meta-information 'modification time'.
    virtual const Time& GetModified() const;

    /// Check if meta-information 'validity time' is available.
    virtual bool CheckValid() const;

    /// Set value of meta-information 'validity time'.
    virtual void SetValid(const Time& val);

    /// Get value of meta-information 'validity time'.
    virtual const Time& GetValid() const;

    /// Set value of meta-information 'access latency'
    virtual void SetAccessLatency(const DataPointAccessLatency& latency);

    /// Get value of meta-information 'access latency'
    virtual DataPointAccessLatency GetAccessLatency() const;

    /// Get suggested buffer size for transfers.
    virtual long long int BufSize() const = 0;

    /// Get suggested number of buffers for transfers.
    virtual int BufNum() const = 0;

    /// Returns true if file is cacheable.
    virtual bool Cache() const;

    /// Returns true if file is local, e.g. file:// urls.
    virtual bool Local() const = 0;

    /// Returns true if file is readonly.
    virtual bool ReadOnly() const = 0;

    /// Returns number of retries left.
    virtual int GetTries() const;

    /// Set number of retries.
    virtual void SetTries(const int n);

    /// Decrease number of retries left.
    virtual void NextTry();

    /// Returns true if some kind of credentials are needed to use this DataPoint
    virtual bool RequiresCredentials() const;

    /// Returns true if credentials must be stored in files.
    /**
     * Some protocols require that credentials exist in files (in which case
     * this method returns true), whereas others can use credentials in memory
     * (then this method returns false).
     * \since Added in 4.0.0.
     */
    virtual bool RequiresCredentialsInFile() const;

    /// Check if URL is an Indexing Service.
    virtual bool IsIndex() const = 0;

    /// Check if URL should be staged or queried for Transport URL (TURL)
    virtual bool IsStageable() const;

    /// Check if endpoint can have any use from meta information.
    virtual bool AcceptsMeta() const = 0;

    /// Check if endpoint can provide at least some meta information directly.
    virtual bool ProvidesMeta() const = 0;

    /// Copy meta information from another object.
    /**
     * Already defined values are not overwritten.
     * \param p object from which information is taken.
     */
    virtual void SetMeta(const DataPoint& p);

    /// Compare meta information from another object.
    /**
     * Undefined values are not used for comparison.
     * \param p object to which to compare.
     */
    virtual bool CompareMeta(const DataPoint& p) const;

    /// Returns physical file(s) to read/write, if different from CurrentLocation()
    /**
     * To be used with protocols which re-direct to different URLs such as
     * Transport URLs (TURLs). The list is initially filled by PrepareReading
     * and PrepareWriting. If this list is non-empty then real transfer
     * should use a URL from this list. It is up to the caller to choose the
     * best URL and instantiate new DataPoint for handling it.
     * For consistency protocols which do not require redirections return
     * original URL.
     * For protocols which need redirection calling StartReading and StartWriting
     * will use first URL in the list. */
    virtual std::vector<URL> TransferLocations() const;

    /// Clear list of physical file(s) to read/write.
    /**
     * To be used with protocols which re-direct to different URLs such as
     * Transport URLs (TURLs). Has no effect for other protocols.
     * \since Added in 4.0.0.
     */
    virtual void ClearTransferLocations() {};

    /// Returns current (resolved) URL.
    virtual const URL& CurrentLocation() const = 0;

    /// Returns meta information used to create current URL.
    /**
     * Usage differs between different indexing services.
     */
    virtual const std::string& CurrentLocationMetadata() const = 0;

    /// Returns a pointer to the DataPoint representing the current location.
    virtual DataPoint* CurrentLocationHandle() const = 0;

    /// Compare metadata of DataPoint and current location.
    /**
     * \return inconsistency error or error encountered during operation, or
     * success
     */
    virtual DataStatus CompareLocationMetadata() const = 0;
    
    /// Switch to next location in list of URLs.
    /**
     * At last location switch to first if number of allowed retries is not
     * exceeded.
     * \return false if no retries left.
     */
    virtual bool NextLocation() = 0;

    /// Returns false no more locations are left and out of retries.
    virtual bool LocationValid() const = 0;

    /// Returns true if the current location is the last.
    virtual bool LastLocation() = 0;

    /// Returns true if number of resolved URLs is not 0.
    virtual bool HaveLocations() const = 0;

    /// Add URL representing physical replica to list of locations.
    /**
     * \param url Location URL to add.
     * \param meta Location meta information.
     * \return LocationAlreadyExistsError if location already exists, otherwise
     * success
     */
    virtual DataStatus AddLocation(const URL& url,
                                   const std::string& meta) = 0;

    /// Remove current URL from list
    virtual DataStatus RemoveLocation() = 0;

    /// Remove locations present in another DataPoint object
    virtual DataStatus RemoveLocations(const DataPoint& p) = 0;

    /// Remove all locations
    virtual DataStatus ClearLocations() = 0;

    /// Add a checksum object which will compute checksum during data transfer.
    /**
     * \param cksum object which will compute checksum. Should not be destroyed
     * until DataPointer itself.
     * \return integer position in the list of checksum objects.
     */
    virtual int AddCheckSumObject(CheckSum *cksum) = 0;

    /// Get CheckSum object at given position in list
    virtual const CheckSum* GetCheckSumObject(int index) const = 0;

    /// Sort locations according to the specified pattern and URLMap.
    /**
     * See DataMover::set_preferred_pattern for a more detailed explanation of
     * pattern matching. Locations present in url_map are preferred over
     * others.
     * \param pattern a set of strings, separated by |, to match against.
     * \param url_map map of URLs to local URLs
     */
    virtual void SortLocations(const std::string& pattern,
                               const URLMap& url_map) = 0;

    /// Add URL options to this DataPoint's URL object.
    /**
     * Invalid options for the specific DataPoint instance will not be added.
     * \param options map of option, value pairs
     */
    virtual void AddURLOptions(const std::map<std::string, std::string>& options);

  protected:
    /// URL supplied in constructor.
    URL url;
    /// UserConfig supplied in constructor.
    const UserConfig usercfg;

    // attributes
    /// Size of object represented by DataPoint.
    unsigned long long int size;
    /// Checksum of object represented by DataPoint.
    std::string checksum;
    /// Modification time of object represented by DataPoint.
    Time modified;
    /// Validity time of object represented by DataPoint.
    Time valid;
    /// Access latency of object represented by DataPoint.
    DataPointAccessLatency access_latency;
    /// Retries left for data transfer.
    int triesleft;
    /// Result of data read/write carried out in separate thread.
    DataStatus failure_code; /* filled by callback methods */
    /// Whether this DataPoint is cacheable.
    bool cache;
    /// Whether this DataPoint requires staging.
    bool stageable;
    /// Valid URL options. Subclasses should add their own specific options to this list.
    std::set<std::string> valid_url_options;

    /// Logger object
    static Logger logger;

    /// Constructor.
    /**
     * Constructor is protected because DataPoints should not be created
     * directly. Subclasses should however call this in their constructors to
     * set various common attributes.
     * \param url The URL representing the DataPoint
     * \param usercfg User configuration object
     * \param parg plugin argument
     */
    DataPoint(const URL& url, const UserConfig& usercfg, PluginArgument* parg);

    /// Perform third party transfer.
    /**
     * This method is protected because the static version should be used
     * instead to load the correct DMC plugin for third party transfer.
     * \param source Source URL to pull data from
     * \param destination Destination URL which pulls data to itself
     * \param callback Optional monitoring callback
     * \return outcome of transfer
     */
    virtual DataStatus Transfer3rdParty(const URL& source, const URL& destination, Callback3rdParty callback = NULL);
  };

  /** \cond Class used by DataHandle to load the required DMC. */
  class DataPointLoader
    : public Loader {
  private:
    DataPointLoader();
    ~DataPointLoader();
    DataPoint* load(const URL& url, const UserConfig& usercfg);
    friend class DataHandle;
  };
  /** \endcond */

  /** \cond Class representing the arguments passed to DMC plugins. */
  class DataPointPluginArgument
    : public PluginArgument {
  public:
    DataPointPluginArgument(const URL& url, const UserConfig& usercfg)
      : url(url),
        usercfg(usercfg) {}
    ~DataPointPluginArgument() {}
    operator const URL&() {
      return url;
    }
    operator const UserConfig&() {
      return usercfg;
    }
  private:
    const URL& url;
    const UserConfig& usercfg;
  };
  /** \endcond */

} // namespace Arc

#endif // __ARC_DATAPOINT_H__