FHIR gForge Tracker
The FHIR "Change Request" tracker is the formal mechanism for tracking all changes to the HL7 FHIR specification. It can also be used for tracking change requests for HL7 Int'l developed implementation guides. This wiki page provides guidance on using the tracker for both submitters as well as HL7 members responsible for managing tracker items. It also includes specific guidance for use of the tracker for ballot reconciliation.
If you have questions that aren't answered here, send an email to Lloyd McKenzie
- 1 Guidance for submitters
- 2 Tracker Elements
- 2.1 Summary
- 2.2 Submitted By
- 2.3 Open Date, Close Date
- 2.4 Priority
- 2.5 Assignee
- 2.6 Real Submitter
- 2.7 Ballot
- 2.8 Specification
- 2.9 URL
- 2.10 Section Number
- 2.11 Resource(s)
- 2.12 HTML Page(s)
- 2.13 Reviewing Work Group(s)
- 2.14 Category
- 2.15 Ballot-weight
- 2.16 In-Person
- 2.17 Group
- 2.18 Schedule
- 2.19 Status
- 2.20 Resolution
- 2.21 Ballot resolution
- 2.22 Resolution Date
- 2.23 Retract/Withdraw
- 2.24 Change Type
- 2.25 Mover/Seconder: For-Against-Abstain
- 2.26 Pre-applied
- 2.27 Target Release
- 2.28 Details
- 2.29 Follow-Ups
- 2.30 Files
- 2.31 Changes
- 2.32 Commits
- 2.33 Dependencies
- 2.34 Duplicates
- 2.35 Associations
- 2.36 Tags
- 3 Tracker Maintenance
- 4 Tracker processes
- 5 Tracker utilities
Guidance for submitters
Who can submit?
There is no requirement to be a member of HL7 or an affiliate. All that's necessary is to sign up for a gForge account, which is free and open to everyone. Simply click on the "Register New Account" link in the top-right-hand corner and fill in the minimal registration information. A human will review your account request and confirm that you look like a human (generally within a few hours, but may take up to a business day). After that, you'll receive an automated email to confirm your email address (check your spam folder if you haven't seen anything after a couple of days). Once that's complete, you'll be able to post change requests as well as able to more easily browse, filter and explore existing change requests.
There is a slight difference in how we treat requests from members and non-members. HL7 members are permitted to vote in the ballots that approve FHIR as an official standard. Non-members can do this as well, but for most votes they must pay for the privilege. Comments submitted as part of a vote may be prioritized as such comments usually *must* be resolved before the specification can be published, while informal comments submitted outside of ballot aren't subject to such requirements. That said, HL7 takes the feedback of implementers very seriously and we'll do our best to deal with all comments received. (If you love process stuff, you can find the formal rules governing the ballot process and other processes here and here.
Why do we use gForge?
HL7 entered into an agreement with gForge many years ago and it is fairly widely used throughout the organization. We're aware that it has several issues and doesn't offer the features available with more modern tools. HL7's gForge is currently under review. However, for now, it's the tool we have.
Submission Rules and Guidelines
- Requests should be concrete requests for change, not general questions or comments. (The latter can be raised on the FHIR Implementer Skype, Stack Overflow, the FHIR list server, the Disqus forum, etc. (Information on connecting to these sources can be found on the FHIR wiki.)
- Each distinct issue should be captured as a separate request. I.e. It should be possible to have a single disposition that applies to the entire tracker item. (One disposition can impact multiple pages or resources though.)
- Requests should be based on the continuous integration release of FHIR. Changes will only be applied to prior releases if they represent catastrophic issues.
- It should go without saying, but Please read through the relevant sections of the specification before requesting a change. Be sure you've looked at common extensions defined in profiles for the resource as well as the resource content itself. Also be familiar with the basics of how FHIR works
- You can search against the continuous integration build using Google by adding "site:http://hl7-fhir.github.io/" to limit your search to the FHIR website.
- Before submitting a request, please check for existing requests that deal with the same thing. (Filter by resource or page name is probably easiest, then scan the descriptions.)
- If the topic has previously been discussed and resolved in a manner you don't find satisfactory, please reference the tracker number of the original request and provide some sort of new information to justify re-opening the specification
- If you don't know how to fill out all of the tracker fields, that's ok. Your request will be triaged and properly categorized shortly after submission. Just fill in as much as you can.
- If you're a brand new submitter, your name might not be in the "Actual Submitter" drop-down yet. Don't worry about it - you'll get added during triage.
- If you're requesting that a new element be added to a resource, keep in mind the "80% rule" - we generally only add elements to the core specification if we expect 80% of all systems that use the resource throughout the world will use the element. Elements that are only common in a single country or a particular narrow discipline will likely be handled as extensions. Providing your arguments on why you feel the element fits within the 80% will increase the likelihood of it being added to core as opposed to being handled via an extension.
- Consider discussing your proposed change with the responsible work group on chat.fhir.org before submitting the request, especially if you think there might be some debate, you're not that familiar with the resource on which the proposal is being submitted or if you plan to submit multiple change requests.
What happens after a change is submitted?
- The first stage is triage - your request will be checked for completeness, assigned to the proper work group(s), etc. In some cases, it may be assigned a status of "Waiting for Input" if further clarification is required. Triage is usually done within 1-2 business days
- In some cases, requests might automatically get approved or rejected as part of the triage process based on pre-defined rules.
- In the second stage, the work group will review the request and may either make further comments or make a final decision. The timeline for this phase may be anywhere from days to months.
- If a change was agreed to, the change will then be made in the continuous integration build. Again, there may be a time lag before this occurs. If a request has urgency behind it, please indicate that in the initial posting.
- The revised specification will go to ballot and the ballot respondents will provide feedback. As a result of that feedback, the agreed change may be altered or even reversed
- A new official version of the FHIR specification will be published containing agreed changes
What else can I do with the tracker?
- Search to see what change requests have been submitted for resources or pages you care about (including what changes have been agreed to, but not yet applied)
- Add comments to existing tracker items (even if it's as simple as "+1")
- Subscribe to particular tracker items of interest or (if you don't mind a busy inbox), subscribe to the whole tracker.
- Note: When we migrate ballot content or make other mass changes, subscribing to the whole tracker may net you a thousand or so emails over the period of a few hours - so mail management rules are recommended
This section describes the various elements of the tracker and gives guidance on what they mean and how they should be used. Note that not all elements are available to be specified on submission - some can only be populated during triage and resolution.
This is the short description of the issue that is displayed in the "list" view of the tracker items. It should be relatively short (not more than 150 characters) but should cover enough details of the proposal that people scanning the list can get the gist of what the proposal is about. For ballot submissions, the summary will include the line item number from the ballot reconciliation spreadsheet.
This is the user under whose id the request was submitted. For "new" submitters who haven't been activated on the FHIR project, this may show up as "AAAA NonComitter" until triage is completed. For bulk uploads of ballot comments, this will show up as FHIR Bot. Because this element won't always be populated with the actual user (and because search on it requires exact name matching), the general advice is to look at Real Submitter instead.
Open Date, Close Date
The date when the tracker item was first submitted and the date on which its status was changed to a "resolved" status.
This defaults to Medium. Work Groups are encouraged to use this to triage comments for discussion. Statuses higher than Medium indicate items that should be resolved prior to the next release. Statuses below medium indicate items that can be deferred until after the next release. (The distinction between the two "high" levels and two "low" levels is left to the WG.
This can be used to indicate who should apply the change associated with this tracker item. (Note that tracker items can only be assigned to committers, so utility for the second use-case is limited.) Note that this element isn't frequently used.
This is the name of the person responsible for the comment. In the case of ballot submissions, it represents the actual commenter, not the user id responsible for bulk upload, nor the person who submitted the ballot. If there are follow-up questions, this is who should be reached out to.
This identifies the ballot the comment was submitted as part of. This element should not be edited unless manually entering in items from a ballot. Ballot submissions *must* come in through the HL7 ballot website. So even if you're raising a comment with the intention to associate it with a ballot, don't edit this field. It'll be automatically updated if you referenced the tracker item in your ballot submission spreadsheet.
This indicates whether the ballot comment applies to the FHIR core specification or one of the HL7-maintained implementation guides. The value here may be different than what's indicated by the ballot column. Sometimes implementation guide comments are submitted as part of the FHIR core ballot and it's common for comments relevant to FHIR Core to be submitted as part of implementation guide ballots. This element can be changed by work groups and projects as necessary based on their understanding of who should be responsible for the resolution.
This is the hyperlink to the page or to the specific area within the specification related to the comment. It should be filled in when possible.
E.g. 1.2.3. You can use this plus the table of contents to find the specific area of the specification being discussed.
This indicates the resource or resources associated with the change request. At least one resource or HTML page must be indicated on each change request. If a change applies to more than 5-6 resources, use the "(many)" option in HTML Page(s) instead.
Indicates the primary web page(s) for the section impacted by the change request. Note that not every single page is indicated. Some just have a page for the general topic area. As well, there are pseudo-pages listed for items that apply to numerous resources, apply to profiles, etc. NA gets used for reference implementation issues and other problems that aren't related to any pages in the specification at all.
Reviewing Work Group(s)
This is the work group responsible for reconciling the issue. In some cases, multiple work groups may be listed, in which case any of the work groups can resolve, though all should be notified of the intention to discuss (and any of them can force the item to be revisited once decided.) The list of work groups should be reduced to one at the time the final vote on the resolution is recorded. The single remaining work group indicates who made the final disposition.
This indicates the type of comment submitted. The "question" and "comment" categories are intended for use only for ballot submissions. (There are better ways to ask questions about FHIR or make comments about it than the gForge tracker.) The meaning of the various categories should be interpreted as follows:
- Typo: Indicates a spelling error, grammar error, broken link, failure to apply a name change in all areas of the specification or some similar issue that is blatantly in error and requires no discussion as to how it should be fixed
- Comment: A statement about the specification that requires no action - these should only appear for ballot-submitted items. E.g. "Good job!"
- Question: A request for information about the FHIR specification. This should only be used for ballot comments. In other circumstances, questions should be directed to one of the other mechanisms (see #Submission Rules and Guidelines
- Correction: The submitter believes the specification is erroneous/broken (i.e. won't meet its interoperability objective), but the issue is a design issue rather than a typing error
- Clarification: The submitter believes that the specification, as worded, is unclear.
- Enhancement: The submitter would like the specification to do something more than it currently does. (When using this one, pay particular attention to the 80% rule as discussed in #Submission Rules and Guidelines
This element is only populated for ballot submissions. It indicates the relative "strength" of the comment. Affirmative comments don't affect the ability of the specification to pass. Negative comments do. (Major ones represent significant objections, minor ones less so.)
If specified, this indicates that the submitter would like to be present at the face-to-face session or conference call where the request is resolved. This request will be respected if possible, but is not binding on the work group.
This element allows work groups to flag multiple items as being related to allow them to be discussed at the same time. Because gForge doesn't allow searching by non-drop-down elements, the values of this element are fixed (though additional values can be added - contact Lloyd McKenzie to add more if desired). The "ready for vote" group indicates that the item is ready for consideration as part of the work group's next block vote.
This element allows work groups to identify when particular items should be discussed. Again, if you want to add more, contact Lloyd McKenzie
One of the key elements about a tracker item is the status. This section describes each of the statuses and any rules or guidelines accompanying their use.
This is the initial status for all newly raised tracker items. It means that the various characteristics of the tracker item have not yet been checked and it may not be ready for work group resolution.
This means that the tracker item is believed to be properly categorized and sufficiently complete for a work group to resolve it. (It's entirely possible that the initial assessment was wrong, so don't be afraid to re-categorize or re-assign if it seems appropriate.) This is the status representing items that are "ready for actioning" by the WG.
Waiting for Input
This means that the tracker item can't be further actioned until someone responds to questions identified as comments within the tracker. This may be the original submitter, a member of the WG that owns the item or someone else who has volunteered to do research or otherwise needs to be contacted. Note that work groups must actively manage items with at status of "Waiting for Input" to ensure that whoever is being waited on is regularly prompted and that, once that input is received, it is added to the tracker item and the status is changed back to Triaged.
Resolved - No Change
This indicates that the resolution captured for the item does not involve changing the specification. It may have been found non-persuasive or might have been a question or a comment that did not require action. This is a final state (though an item can in theory be re-activated)
Resolved - Change Required
This indicates that the resolution captured for the item requires some sort of change to the specification. Note that this doesn't mean that the change being made is the one that was originally asked for. This is not a terminal state - it will move on to Applied and then Published.
This indicates that the tracker item is essentially identical to one already submitted. The resolution to the referenced tracker item will be considered to apply to this item as well. If this status is specified, then there must be a single tracker item pointed to in the Duplicates list. That tracker's resolution will apply to this item. If the tracker item was submitted as part of a ballot and "In person" was requested, make sure a comment is added to the referenced tracker noting the in-person request. If there are additional nuances noted in this item not captured in the referenced item, append those as a comment too.
This indicates that the tracker item will not be resolved as part of the current publication cycle but will instead be handled as part of a future release. From a balloting perspective, this will result in a reconciliation status of "Considered - for future consideration" or "Not persuasive", depending on the ballot strength of the comment submitted. All deferred items that are ballot items must be voted. Deferred items will be reset to Triaged after the publication of the next version of the specification
This is the statement of what action is to be taken in response to the tracker item. If no action is to be taken, then this field provides a description of why no action is being taken. This must be present for the item to have a status of Resolved, Applied or Published.
This categorizes the nature of the reconciliation taken. This MUST be populated if Resolution Date is specified, though it may be populated earlier if there is a proposed disposition (e.g. prior to a block vote)
- Persuasive: The work group agrees with the submitter and the specification will be changed as requested
- Persuasive with Mod: The work group agrees with the submitter, but the specification will be changed in a manner that is not identical to the manner requested by the submitter
- Not Persuasive: The work group disagrees with the submitter and will not make any change
- Not Persuasive with Mod: The work group disagrees with the submitter but will make a change anyhow (e.g. to better clarify the spec)
- Not Related: The work group has decided that the comment is out of scope for the ballot or for the specification overall
- Considered for Future Use: The work group is deferring any action on this item until a future version of the specification (use with Status = Deferred)
- Considered - No action required: No action was requested so none is being taken (use for category 'Comment') items
- Considered - Question Answered: No change is being made to the specification but an answer has been provided to whatever question was asked
The date on which the work group voted to approve the specified resolution or on which the item was retracted. It MUST NOT be populated if the status is Submitted, Triaged, Waiting for Input or Duplicate. It MUST be populated for all other statuses if the tracker item is associated with a ballot, however it's good practice to populate regardless.
If specified, indicates the user has chosen to Retract (treat the comment as if it was never submitted) or withdraw (accept disposition, treat the line item as affirmative). It is only relevant for ballot-related items. It can be set directly by the submitter (if they have permission to update trackers). If not, a comment must be added by the voter indicating intention to retract or withdraw or a comment must be added by someone else referencing the conference call or meeting whose minutes capture the voter's decision or reference the email from the voter in which the decision was documented.
This must be present for all tracker items that have a status of "Resolved - Change required", "Applied" or "Published".
- Non-substantive changes are changes that would not cause a reasonable implementer to change how their application is written. It could involve additional clarification, improved documentation, change to formatting, etc.
- Substantive, compatible changes are those that might change how a reasonable implementer would craft their application, but wouldn't cause an existing instance to become invalid. E.g. increasing the maximum cardinality, adding additional code options, significantly expanding a definition
- Non-compatible changes have the potential of causing existing instances to no longer be valid
This must be specified (and may only be specified) for all items with a Resolution Date that aren't marked as "Retracted". It contains the name of the mover and seconder at the work group meeting that approved the disposition as well as the vote results. It MUST be specified in the format indicated (with the '/', ':' and '-' values included in the specified positions. Names SHALL include both first and last name (and those people named should be noted as present in the minutes for the corresponding meeting).
Format: Mover name <slash>Seconder name<colon>For<dash>Against<dash>Abstain e.g. Infavor Person/Second Person:6-2-1
If true, indicates that the requested change (or proposed resolution) has already been applied. This might be done to demonstrate that the change/resolution would look like or because the editor believes the likely outcome is for the change to be approved.
This isn't generally used.
Full details of the requested change, including rationale/justification
Additional comments made about the item over time
This includes any supporting information, evidence, screen shots, etc.
This lists all changes made to the tracker item over time
This lists all SVN commits associated with the tracker. SVN commits associated with this element SHOULD include "[#" + tracker number + "]" as part of the commit to establish a link from the tracker item to the change made
This should only be populated if the status is "Duplicate", in which case it should only have one record listed - which points to the surviving change request. (If there are multiple duplicates, they should all have a single duplicate reference pointing to the surviving tracker item.)
What has to go into the tracker?
- When a new resource or profile is under development, changes made to the associated artifacts do not require change requests. However, once the artifact has appeared in a published specification (e.g. a ballot) with a status other than "Draft", all subsequent changes to that artifact require a change request
- This includes requests for change from the community as well as necessary changes identified by editors or work groups
- All FHIR Core ballot reconciliation must occur using the gForge tracker. (Reconciliation may be done using spreadsheets if online access isn't available, but the gForge tracker must be updated as soon as possible (preferably within 1-2 days
Who can do maintenance?
While creating tracker items and adding comments to tracker items is open to anyone, maintaining tracker items (changing statuses, filling in resolutions, etc.) requires additional privileges. These privileges are available to co-chairs or others working on behalf of HL7 WGs to manage the work group's artifacts. To request privileges, contact Lloyd McKenzie.
This section gives hints on how to perform common tracker-related tasks
You can filter by a wide variety of items. Filters will be remembered from one log-in to the next. To apply a filter, you must hit the "Browse" button. (You can also use the XML or Excel buttons to get a summary view, but they won't contain the full content for the tracker item - see below for other options.)
Re-assigning work groups
If a work group believes an item was assigned to them inappropriately, they can remove themselves from the item, but only if they add a different work group and add a comment explaining the reason for the transfer.
Sometimes a tracker item will be resolved and someone will ask that the resolution be revisited. This should be done by posting an email to the appropriate list, not by adding a comment to the tracker item. (Once an item is resolved, the work group might not look at it again to see the comment.) The work group decision making processes around revisiting a discussion need to be followed (this generally requires a 2/3 vote to revisit the item.)
Note: If an item is associated with a ballot, it cannot be re-opened once the final disposition spreadsheet has been prepared for that ballot. (If a WG isn't sure, contact the FHIR Management Group) It's always possible to raise a new tracker item, but that item should reference the original and provide some new argument for re-visiting the decision.
Items that are marked as "deferred" will automatically be re-opened after a new release of the product has been published. (Deferred is never a 'final' resolution.)
If there's a need to change the disposition on a re-opened item, the original disposition, date, disposition text and vote information should all be copied into the "comment" section so that there's a visible record of the past decision.
Items with multiple resolutions
Sometimes a ballot item will deal with multiple distinct issues if this occurs, then capture a single overall disposition and then describe the individual dispositions as part of the resolution.
Items resolved by multiple WGs
In some cases, approval will be required by multiple work groups. If this occurs, initial work groups should capture their disposition votes as comments and remove their work group name as being assigned to the tracker item. The final work group to vote on the item captures the final vote in the resolution, ballot resolution, vote and date elements.
Jumping to a tracker item
Rather than loosing all of your filter settings and filling in the tracker id on the the search screen, you can jump to a particular tracker id by clicking on the magnifying glass icon at the top of the screen and specifying the tracker id. All search filters will be retained.
Finding a tracker item by ballot id
The comments of one tracker item might reference another tracker by its ballot number rather than by tracker id. (Initial triage is done in the spreadsheet prior to loading into gForge.) To search for an item based on ballot line item number, clear all of your filters and then put the desired ballot row number in the summary field and search
Searching by summary or submitter name
Summary and submitter name are the only two fields that allow searching by free text. However, the text must completely match the word in the text. Searching on "Rob" will not match "Robert".
Searching for tracker items
Sometimes there's a need to search by more than just the summary. Clicking on the "Search" option allows searching by keywords within the tracker. Note that searching is independent of filters. There is no way to combine a keyword search and tracker filters
This section provides information about additional tools and links available to help support use of the tracker
Full tracker output as XML
The base tracker screen allows an XML export, but it doesn't include all information, such as changes, duplicates, resolutions, etc. However, we now have a background process running that automatically generates an XML snapshot of the whole FHIR tracker every 90 minutes or so. Once you've got the XML, you can do a text search on it, use XPath or even generate your own reports. (If you come up with something you think is generally useful, let the FMG know and they can look at getting it automatically generated for everyone.) To grab the current XML view of the tracker, use this link
Summaries and stats
If you want a quick overview of where your project or workgroup is with respect to tracker progress (or even where FHIR is at as a whole), or if you want to see what significant changes have been made to the tracker for your area of interest, there's a daily and weekly report generated. The weekly one is generated at the start of Monday GMT time. The daily one is generated just after midnight GMT time. If you have suggestions on how to improve the organization/rendering, they'd be welcome. (Editing the transform in the "trackers/tools" folder is a possibility too.)
Unfortunately, gForge doesn't let us encode validation rules to ensure that tracker items are "valid" before content is saved. There's a wide variety of ways that tracker items can be messed up, which results in items not being seen by work groups, not meeting ANSI requirements, not being extractable back into ballot reconciliation spreadsheets, etc. To deal with this, we now have a validation report that identifies tracker items that have issues. We'll start sending out friendly "pokes" to the individuals who likely created the issues to ensure they get resolved. (And as people learn the rules better, hopefully there will be fewer issues to poke about.) The validation report is generated every 90 minutes or so and can be found here.
Putting a list of tracker items in an email or agenda
After flagging multiple tracker items for inclusion in a block vote or for discussion on a particular call, there's often a need to paste them into an agenda or an email, ideally with hyperlinks, information on the submitter, proposed disposition, whether etc. To simplify this, the FHIR team has created a transform. The steps to use it are as follows:
- Set the tracker filter to include only the relevant items (e.g. Items assigned to a particular work group with a status of Triaged that have a Group of "Ready for Vote".)
- Press the XML button to retrieve a partial XML export of the item.
- Right-click and do a "save as"
- Open this XSLT transform using whatever transform tool you like to use (e.g. XML Spy). Ideally, the transform should be executed using Saxon.
- Use your gForge id when downloading the transform, or if you don't have one, "anonymous" and your email address
- Run the transform on the XML extract you just saved.
The transform provides:
- a list of submitters responsible for the list of items (you may wish to copy them if doing a block vote or scheduling discussion of their items)
- an HTML-formatted list of the tracker items (including links, summaries, submitters, proposed resolutions and whether the item is "in person requested"
- a wiki-markup formatted list of the same information suitable for pasting into a wiki page as an agenda
Generating a ballot reconciliation spreadsheet
At the conclusion of the ballot process, or for use as a back-up where internet (and thus gForge) availability is not assured, it's useful to be able to produce a spreadsheet view of the tracker items. There's a transform for that too. The process is the same as the email extract above, except use the transform listed here. The output will be an HTML file that mirrors the columns of a "current" ballot reconciliation spreadsheet. The content can then be pasted into the appropriate tab of a reconciliation spreadsheet. Unfortunately, there's no way to retain the formatting of the ballot spreadsheet without losing the formatting of the contentin the tracker, so you'll need to choose which of the two is more important to you (and choose either "paste" or "paste values".
A few caveats:
- While we do an XML export from the tracker to run the transform against, this process is only to select the tracker items to include in the spreadsheet. The actual content is grabbed from the continuously generated XML file, as it is the only file that contains everything needed to produce the ballot spreadsheet. As a result, you may need to wait 60+ minutes after making changes to a tracker item to see those changes reflected in the spreadsheet extract. As well, you must download the tracker XML file and label it as "tracker.xml", located in the same directory as you place the transform.
- To get the right formatting, use the Excel "import web page" function on the "data" tab, and be sure to select the "full HTML formatting" option.
- While work groups can export to a ballot reconciliation spreadsheet at any time, updates made to the spreadsheet CANNOT be imported back into gForge. And gForge is the source of truth for FHIR ballots. Any changes made to a local worksheet will have to be manually applied to gForge after the fact. The FMG will not accept reconciliation that is not captured in gForge. Furthermore, gForge should be kept current so that the FMG can monitor reconciliation progress. This means changes should be propagated back into gForge as quickly as possible.
- Appropriate population of the ballot spreadsheet is dependent on the contents of the exported tracker items being "valid". If there are issues with the formatting of vote information or other issues, the spreadsheet columns won't be populated correctly. So check the issues list prior to export
- NOTE In some versions of Excel, the import process is broken and will not properly handle line-breaks (
in the exported HTML). To get around this, do a search and replace to turn "
" to "#$#" or something else unique in the HTML file before you import. After importing, do a search and replace in Excel to change "#$#" to Ctrl-J.
Copyright © Health Level Seven International ® ALL RIGHTS RESERVED. The reproduction of this material in any form is strictly forbidden without the written permission of the publisher.